1#include "Library/Camera/CameraParamMoveLimit.h"
2
3#include <gfx/seadCamera.h>
4
5#include "Library/Camera/CameraPoser.h"
6#include "Library/Matrix/MatrixUtil.h"
7#include "Library/Yaml/ByamlIter.h"
8#include "Library/Yaml/ByamlUtil.h"
9
10namespace al {
11
12CameraParamMoveLimit* CameraParamMoveLimit::create(const CameraPoser* poser) {
13 CameraParamMoveLimit* result = new CameraParamMoveLimit();
14 result->mViewMtx = poser->getViewMtx();
15 result->mInvViewMtx.setInverse(poser->getViewMtx());
16 return result;
17}
18
19CameraParamMoveLimit::CameraParamMoveLimit() {}
20
21void CameraParamMoveLimit::load(const ByamlIter& iter) {
22 ByamlIter moveLimitIter;
23 if (!iter.tryGetIterByKey(iter: &moveLimitIter, key: "MoveLimit"))
24 return;
25
26 if (tryGetByamlF32(&mPlus.x, moveLimitIter, "PlusX"))
27 mHasPlusX = true;
28 if (tryGetByamlF32(&mMinus.x, moveLimitIter, "MinusX"))
29 mHasMinusX = true;
30 if (tryGetByamlF32(&mPlus.y, moveLimitIter, "PlusY"))
31 mHasPlusY = true;
32 if (tryGetByamlF32(&mMinus.y, moveLimitIter, "MinusY"))
33 mHasMinusY = true;
34 if (tryGetByamlF32(&mPlus.z, moveLimitIter, "PlusZ"))
35 mHasPlusZ = true;
36 if (tryGetByamlF32(&mMinus.z, moveLimitIter, "MinusZ"))
37 mHasMinusZ = true;
38}
39
40void CameraParamMoveLimit::apply(sead::LookAtCamera* camera) const {
41 sead::Vector3f constrainedViewAt;
42
43 // required to enforce lifetimes of variables
44 {
45 f32 preRotYDegree = -mRotYDegree;
46 sead::Vector3f inverseViewAt;
47 inverseViewAt.setMul(m: mInvViewMtx, a: camera->getAt());
48 sead::Matrix34f mtxRotateY = sead::Matrix34f::ident;
49 rotateMtxYDirDegree(outMtx: &mtxRotateY, baseMtx: mtxRotateY, angle: preRotYDegree);
50
51 constrainedViewAt.setMul(m: mtxRotateY, a: inverseViewAt);
52
53 if (mHasPlusX)
54 constrainedViewAt.x = constrainedViewAt.x > mPlus.x ? mPlus.x : constrainedViewAt.x;
55 if (mHasPlusY)
56 constrainedViewAt.y = constrainedViewAt.y > mPlus.y ? mPlus.y : constrainedViewAt.y;
57 if (mHasPlusZ)
58 constrainedViewAt.z = constrainedViewAt.z > mPlus.z ? mPlus.z : constrainedViewAt.z;
59
60 if (mHasMinusX)
61 constrainedViewAt.x = constrainedViewAt.x < mMinus.x ? mMinus.x : constrainedViewAt.x;
62 if (mHasMinusY)
63 constrainedViewAt.y = constrainedViewAt.y < mMinus.y ? mMinus.y : constrainedViewAt.y;
64 if (mHasMinusZ)
65 constrainedViewAt.z = constrainedViewAt.z < mMinus.z ? mMinus.z : constrainedViewAt.z;
66 }
67
68 f32 rotYDegree = mRotYDegree;
69 sead::Matrix34f mtxRotateY = sead::Matrix34f::ident;
70 rotateMtxYDirDegree(outMtx: &mtxRotateY, baseMtx: mtxRotateY, angle: rotYDegree);
71
72 sead::Vector3f finalInverseViewAt;
73 finalInverseViewAt.setMul(m: mtxRotateY, a: constrainedViewAt);
74
75 sead::Vector3f finalViewAt;
76 finalViewAt.setMul(m: mViewMtx, a: finalInverseViewAt);
77
78 sead::Vector3f constraintAdjustment = finalViewAt - camera->getAt();
79
80 camera->setAt(constraintAdjustment + camera->getAt());
81 camera->setPos(constraintAdjustment + camera->getPos());
82}
83
84} // namespace al
85