| 1 | #include "Library/Play/Camera/CameraVerticalAbsorber.h" |
| 2 | |
| 3 | #include "Library/Camera/CameraPoser.h" |
| 4 | #include "Library/Camera/CameraStartInfo.h" |
| 5 | #include "Library/Math/MathUtil.h" |
| 6 | #include "Library/Nerve/NerveSetupUtil.h" |
| 7 | #include "Library/Nerve/NerveUtil.h" |
| 8 | #include "Library/Yaml/ByamlUtil.h" |
| 9 | |
| 10 | namespace { |
| 11 | using namespace al; |
| 12 | NERVE_IMPL(CameraVerticalAbsorber, FollowGround); |
| 13 | NERVE_IMPL(CameraVerticalAbsorber, FollowAbsolute); |
| 14 | NERVE_IMPL_(CameraVerticalAbsorber, FollowClimbPoleNoInterp, Follow); |
| 15 | NERVE_IMPL_(CameraVerticalAbsorber, FollowSlow, Absorb); |
| 16 | NERVE_IMPL(CameraVerticalAbsorber, Absorb); |
| 17 | NERVE_IMPL(CameraVerticalAbsorber, Follow); |
| 18 | NERVE_IMPL(CameraVerticalAbsorber, FollowClimbPole); |
| 19 | |
| 20 | NERVES_MAKE_STRUCT(CameraVerticalAbsorber, FollowGround, FollowAbsolute, FollowClimbPoleNoInterp, |
| 21 | FollowSlow, Absorb, Follow, FollowClimbPole); |
| 22 | } // namespace |
| 23 | |
| 24 | namespace al { |
| 25 | |
| 26 | void CameraVerticalAbsorber::exeFollowAbsolute() { |
| 27 | mTargetInterp *= 0.8f; |
| 28 | } |
| 29 | |
| 30 | void CameraVerticalAbsorber::invalidate() { |
| 31 | mIsInvalidated = true; |
| 32 | if (!isNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowAbsolute)) |
| 33 | setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowAbsolute); |
| 34 | } |
| 35 | |
| 36 | // NON_MATCHING |
| 37 | void CameraVerticalAbsorber::start(const sead::Vector3f& pos, const CameraStartInfo& info) { |
| 38 | alCameraPoserFunction::calcTargetFront(&mPrevTargetFront, mCameraPoser); |
| 39 | |
| 40 | mTargetInterp.x = 0.0f; |
| 41 | mTargetInterp.y = 0.0f; |
| 42 | mTargetInterp.z = 0.0f; |
| 43 | |
| 44 | mPrevTargetTrans = pos; |
| 45 | |
| 46 | if (unk_unusedBool || mIsInvalidated || |
| 47 | alCameraPoserFunction::isPlayerTypeNotTouchGround(mCameraPoser)) |
| 48 | return setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowAbsolute); |
| 49 | if (alCameraPoserFunction::isTargetClimbPole(mCameraPoser)) |
| 50 | return setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowClimbPoleNoInterp); |
| 51 | if (alCameraPoserFunction::isTargetGrabCeil(mCameraPoser)) |
| 52 | return setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowSlow); |
| 53 | if (!info.isGrounded || alCameraPoserFunction::isTargetCollideGround(mCameraPoser)) |
| 54 | return setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowGround); |
| 55 | |
| 56 | mPrevTargetTrans = alCameraPoserFunction::getPreLookAtPos(mCameraPoser); |
| 57 | |
| 58 | sead::Vector3f target; |
| 59 | |
| 60 | alCameraPoserFunction::calcTargetGravity(&target, mCameraPoser); |
| 61 | mTargetInterp = pos - mPrevTargetTrans; |
| 62 | parallelizeVec(&mTargetInterp, target, mTargetInterp); |
| 63 | setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.Absorb); |
| 64 | } |
| 65 | |
| 66 | void CameraVerticalAbsorber::load(const ByamlIter& data) { |
| 67 | ByamlIter it; |
| 68 | if (!data.tryGetIterByKey(iter: &it, key: "VerticalAbsorb" )) |
| 69 | return; |
| 70 | |
| 71 | tryGetByamlF32(&mAbsorbScreenPosUp, it, "AbsorbScreenPosUp" ); |
| 72 | tryGetByamlF32(&mAbsorbScreenPosDown, it, "AbsorbScreenPosDown" ); |
| 73 | tryGetByamlF32(&mHighJumpJudgeSpeedV, it, "HighJumpJudgeSpeedV" ); |
| 74 | ByamlIter it2; |
| 75 | |
| 76 | if (!it.tryGetIterByKey(iter: &it2, key: "AdvanceAbsorbUp" )) |
| 77 | return; |
| 78 | mIsAdvanceAbsorbUp = true; |
| 79 | mAdvanceAbsorbScreenPosUp = getByamlKeyFloat(it2, "AdvanceAbsorbScreenPosUp" ); |
| 80 | } |
| 81 | |
| 82 | // NON_MATCHING |
| 83 | void CameraVerticalAbsorber::update() { |
| 84 | if (mIsStopUpdate) |
| 85 | return; |
| 86 | sead::Vector3f gravity{}; |
| 87 | alCameraPoserFunction::calcTargetGravity(&gravity, mCameraPoser); |
| 88 | mTargetInterp = mCameraPoser->getPosition() - mPrevTargetTrans; |
| 89 | parallelizeVec(&mTargetInterp, gravity, mTargetInterp); |
| 90 | mLookAtCamera.getPos() = mCameraPoser->getPosition(); |
| 91 | mLookAtCamera.getAt() = mCameraPoser->getTargetTrans(); |
| 92 | mLookAtCamera.getUp() = mCameraPoser->getCameraUp(); |
| 93 | if (mLookAtCamera.getUp().length() > 0.0f) |
| 94 | mLookAtCamera.getUp().normalize(); |
| 95 | if (!unk_unusedBool && !mIsInvalidated) { |
| 96 | mLookAtCamera.getAt() -= mTargetInterp; |
| 97 | if (!mIsNoCameraPosAbsorb) |
| 98 | mLookAtCamera.getPos() -= mTargetInterp; |
| 99 | } |
| 100 | mLookAtCamera.doUpdateMatrix(dst: &mLookAtCamera.getMatrix()); |
| 101 | mProjection.set(near: alCameraPoserFunction::getNear(mCameraPoser), |
| 102 | far: alCameraPoserFunction::getFar(mCameraPoser), |
| 103 | fovy_rad: sead::Mathf::deg2rad(deg: mCameraPoser->getFovyDegree()), |
| 104 | aspect: alCameraPoserFunction::getAspect(mCameraPoser)); |
| 105 | alCameraPoserFunction::calcTargetFront(&mTargetFront, mCameraPoser); |
| 106 | if (!isNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowGround) && |
| 107 | alCameraPoserFunction::isTargetCollideGround(mCameraPoser)) |
| 108 | setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowGround); |
| 109 | if (!isNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowAbsolute) && |
| 110 | alCameraPoserFunction::isPlayerTypeNotTouchGround(mCameraPoser)) |
| 111 | setNerve(user: this, nerve: &NrvCameraVerticalAbsorber.FollowAbsolute); |
| 112 | updateNerve(); |
| 113 | sead::Vector3f prevTargetTrans = sead::Vector3f::zero; |
| 114 | if (!mIsKeepInFrame) { |
| 115 | prevTargetTrans = mTargetInterp; |
| 116 | } else { |
| 117 | sead::Vector3f offsetTrans = sead::Vector3f::zero; |
| 118 | alCameraPoserFunction::calcTargetTransWithOffset(&offsetTrans, mCameraPoser); |
| 119 | alCameraPoserFunction::calcOffsetCameraKeepInFrameV( |
| 120 | &gravity, &mLookAtCamera, offsetTrans, mCameraPoser, mKeepInFrameOffsetUp, |
| 121 | alCameraPoserFunction::isPlayerTypeHighJump(mCameraPoser) ? 300.0f : |
| 122 | mKeepInFrameOffsetDown); |
| 123 | prevTargetTrans = mTargetInterp - gravity; |
| 124 | } |
| 125 | mPrevTargetTrans = mCameraPoser->getTargetTrans() - prevTargetTrans; |
| 126 | mPrevTargetFront = mTargetFront; |
| 127 | } |
| 128 | |
| 129 | } // namespace al |
| 130 | |