From a43ff198f71d4d86748ed6d94eaa5e6235d461ff Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Tue, 31 Dec 2024 01:09:01 +0100 Subject: [PATCH] dump --- data/odyssey_functions.csv | 38 +- lib/al/Library/Camera/CameraInterpole.cpp | 553 ++++++++++++++++++++ lib/al/Library/Camera/CameraInterpole.h | 46 ++ lib/al/Library/Camera/CameraPoser.h | 17 +- lib/al/Library/Camera/CameraPoserFlag.h | 29 + lib/al/Library/Camera/CameraPoserFunction.h | 12 +- lib/al/Library/Math/MathLengthUtil.h | 1 + lib/al/Library/Math/MathUtil.h | 5 + lib/sead | 2 +- 9 files changed, 672 insertions(+), 31 deletions(-) create mode 100644 lib/al/Library/Camera/CameraInterpole.cpp create mode 100644 lib/al/Library/Camera/CameraInterpole.h create mode 100644 lib/al/Library/Camera/CameraPoserFlag.h diff --git a/data/odyssey_functions.csv b/data/odyssey_functions.csv index 32d45bc1..ee182b75 100644 --- a/data/odyssey_functions.csv +++ b/data/odyssey_functions.csv @@ -65903,25 +65903,25 @@ Address,Quality,Size,Name 0x0000007100a49c50,U,000008,_ZNK2al28CameraAngleVerticalRequester18getAreaObjDirectorEv 0x0000007100a49c58,U,000020,_ZN2al26CameraCollisionPartsFilterC2Ev 0x0000007100a49c6c,U,000056,_ZNK2al26CameraCollisionPartsFilter14isInvalidPartsERKNS_14CollisionPartsE -0x0000007100a49ca4,U,000384,_ZN2al15CameraInterpoleC2Ev -0x0000007100a49e24,U,001088,_ZN2al15CameraInterpole5startEPKNS_12CameraTicketEfi -0x0000007100a4a264,U,001876,_ZN2al15CameraInterpole6updateERKN4sead12LookAtCameraE -0x0000007100a4a9b8,U,000036,_ZNK2al15CameraInterpole8isActiveEv -0x0000007100a4a9dc,U,000436,_ZNK2al15CameraInterpole16makeLookAtCameraEPN4sead12LookAtCameraE -0x0000007100a4ab90,U,000076,_ZN2al15CameraInterpole14lerpFovyDegreeEf -0x0000007100a4abdc,U,000108,_ZN2al15CameraInterpole11exeDeactiveEv -0x0000007100a4ac48,U,000360,_ZN2al15CameraInterpole16exeActiveHermiteEv -0x0000007100a4adb0,U,000520, -0x0000007100a4afb8,U,000996,_ZN2al15CameraInterpole26exeActiveHermiteDistanceHVEv -0x0000007100a4b39c,U,001164,_ZN2al15CameraInterpole20exeActiveRotateAxisYEv -0x0000007100a4b828,U,000416,_ZN2al15CameraInterpole16exeActiveBrigadeEv -0x0000007100a4b9c8,U,000084,_ZN2al15CameraInterpoleD2Ev -0x0000007100a4ba1c,U,000092,_ZN2al15CameraInterpoleD0Ev -0x0000007100a4ba78,U,000112, -0x0000007100a4bae8,U,000008, -0x0000007100a4baf0,U,000008, -0x0000007100a4baf8,U,000008, -0x0000007100a4bb00,U,000176, +0x0000007100a49ca4,O,000384,_ZN2al15CameraInterpoleC2Ev +0x0000007100a49e24,O,001088,_ZN2al15CameraInterpole5startEPKNS_12CameraTicketEfi +0x0000007100a4a264,M,001876,_ZN2al15CameraInterpole6updateERKN4sead12LookAtCameraE +0x0000007100a4a9b8,O,000036,_ZNK2al15CameraInterpole8isActiveEv +0x0000007100a4a9dc,O,000436,_ZNK2al15CameraInterpole16makeLookAtCameraEPN4sead12LookAtCameraE +0x0000007100a4ab90,O,000076,_ZN2al15CameraInterpole14lerpFovyDegreeEf +0x0000007100a4abdc,O,000108,_ZN2al15CameraInterpole11exeDeactiveEv +0x0000007100a4ac48,O,000360,_ZN2al15CameraInterpole16exeActiveHermiteEv +0x0000007100a4adb0,W,000520,_ZN2al13sub_somethingEPN4sead7Vector3IfEERKNS0_12LookAtCameraES6_S2_S2_f +0x0000007100a4afb8,M,000996,_ZN2al15CameraInterpole26exeActiveHermiteDistanceHVEv +0x0000007100a4b39c,M,001164,_ZN2al15CameraInterpole20exeActiveRotateAxisYEv +0x0000007100a4b828,O,000416,_ZN2al15CameraInterpole16exeActiveBrigadeEv +0x0000007100a4b9c8,O,000084,_ZN2al15CameraInterpoleD2Ev +0x0000007100a4ba1c,O,000092,_ZN2al15CameraInterpoleD0Ev +0x0000007100a4ba78,O,000112,_ZNK12_GLOBAL__N_126CameraInterpoleNrvDeactive7executeEPN2al11NerveKeeperE +0x0000007100a4bae8,O,000008,_ZNK12_GLOBAL__N_135CameraInterpoleNrvActiveRotateAxisY7executeEPN2al11NerveKeeperE +0x0000007100a4baf0,O,000008,_ZNK12_GLOBAL__N_141CameraInterpoleNrvActiveHermiteDistanceHV7executeEPN2al11NerveKeeperE +0x0000007100a4baf8,O,000008,_ZNK12_GLOBAL__N_131CameraInterpoleNrvActiveHermite7executeEPN2al11NerveKeeperE +0x0000007100a4bb00,O,000176,_ZN2al15cameraGetHAngleERKN4sead12LookAtCameraE 0x0000007100a4bbb0,U,000016,_ZN2al17CameraOffsetCtrlY4loadERKNS_9ByamlIterE 0x0000007100a4bbc0,U,000064,_ZN2al22CameraOffsetCtrlPresetC2Ev 0x0000007100a4bc00,U,000008,_ZN2al22CameraOffsetCtrlPreset4loadERKNS_9ByamlIterE diff --git a/lib/al/Library/Camera/CameraInterpole.cpp b/lib/al/Library/Camera/CameraInterpole.cpp new file mode 100644 index 00000000..f95b740b --- /dev/null +++ b/lib/al/Library/Camera/CameraInterpole.cpp @@ -0,0 +1,553 @@ +#include "Library/Camera/CameraInterpole.h" + +#include "Library/Camera/CameraPoser.h" +#include "Library/Camera/CameraPoserFlag.h" +#include "Library/Camera/CameraPoserFunction.h" +#include "Library/Camera/CameraTicket.h" +#include "Library/Math/MathAngleUtil.h" +#include "Library/Math/MathLengthUtil.h" +#include "Library/Math/MathUtil.h" +#include "Library/Math/VectorUtil.h" +#include "Library/Nerve/NerveSetupUtil.h" +#include "Library/Nerve/NerveUtil.h" +#include "math/seadQuat.h" + +namespace { +using namespace al; +NERVE_IMPL(CameraInterpole, Deactive); +NERVE_IMPL(CameraInterpole, ActiveRotateAxisY); +NERVE_IMPL(CameraInterpole, ActiveHermiteDistanceHV); +NERVE_IMPL(CameraInterpole, ActiveHermite); +// NERVE_IMPL(CameraInterpole, ActiveBrigade); + +NERVES_MAKE_STRUCT(CameraInterpole, Deactive, ActiveRotateAxisY, ActiveHermiteDistanceHV, + ActiveHermite); +} // namespace + +namespace al { + +CameraInterpole::CameraInterpole() : NerveExecutor("カメラ補間") { + initNerve(&NrvCameraInterpole.Deactive, 0); +} + +const f32 interpoleMinDistance = 150.0f; +const f32 interpoleMaxDistance = 2000.0f; +const f32 maxStepsNoEaseOut = 60.0f; +const f32 maxStepsEaseOut = 90.0f; + +void CameraInterpole::start(const CameraTicket* ticket, f32 prevFovyDegree, s32 endInterpoleStep) { + _48.getPos() = _118.getPos(); + _48.getAt() = _118.getAt(); + _48.getUp() = _118.getUp(); + _48.getUp().normalize(); + + if (mPrevPoser) { + mPrevPoser->setField98(false); + mPrevPoser = nullptr; + } + + const CameraTicket* prevTicket = mNextTicket; + mNextTicket = ticket; + mPrevTicket = prevTicket; + mPrevFovyDegree = prevFovyDegree; + + if (endInterpoleStep >= 0) { + mEndInterpoleStep = endInterpoleStep; + } else if (prevTicket->getPoser()->isEndInterpoleByStep()) { + mEndInterpoleStep = mPrevTicket->getPoser()->getEndInterpoleStep(); + } else if (ticket->getPoser()->isInterpoleByCameraDistance()) { + f32 normalizedDistance = + normalize((_118.getPos() - ticket->getPoser()->getPosition()).length(), + interpoleMinDistance, interpoleMaxDistance); + f32 maxSteps = + ticket->getPoser()->isInterpoleEaseOut() ? maxStepsEaseOut : maxStepsNoEaseOut; + s32 interpoleSteps = (s32)lerpValue(30.0f, maxSteps, normalizedDistance); + + sead::Vector3f prevCamDir = {0.0f, 0.0f, 0.0f}; + sead::Vector3f nextCamDir = {0.0f, 0.0f, 0.0f}; + alCameraPoserFunction::calcCameraDir(&prevCamDir, mPrevTicket->getPoser()); + alCameraPoserFunction::calcCameraDir(&nextCamDir, ticket->getPoser()); + f32 yDiffDegrees = sead::Mathf::abs(sead::Mathf::rad2deg(sead::Mathf::asin(prevCamDir.y)) - + sead::Mathf::rad2deg(sead::Mathf::asin(nextCamDir.y))); + s32 yDiffInterpoleSteps = yDiffDegrees < 0.75f ? 0 : (int)(yDiffDegrees / 0.75f); + + mEndInterpoleStep = sead::Mathi::max(interpoleSteps, yDiffInterpoleSteps); + } else { + mEndInterpoleStep = ticket->getPoser()->getInterpoleStep(); + } + + if (mEndInterpoleStep < 1 || mIsRequestCancel) { + mIsRequestCancel = false; + setNerve(this, &NrvCameraInterpole.Deactive); + return; + } + + if (mPrevTicket) { + if (!isActive() && !alCameraPoserFunction::isChangeTarget(mPrevTicket->getPoser()) && + alCameraPoserFunction::isTargetEnableEndAfterInterpole(mPrevTicket->getPoser()) && + !alCameraPoserFunction::isInvalidPreCameraEndAfterInterpole(ticket->getPoser())) { + if (mPrevTicket->getPoser() != ticket->getPoser()) { + mPrevPoser = mPrevTicket->getPoser(); + mPrevPoser->setField98(true); + } + } + + sead::Vector3f x = + mPrevTicket->getPoser()->getPosition() - mPrevTicket->getPoser()->getTargetTrans(); + sead::Vector3f v45 = + ticket->getPoser()->getPosition() - ticket->getPoser()->getTargetTrans(); + x.y = 0.0; + v45.y = 0.0; + if (tryNormalizeOrZero(&x) && tryNormalizeOrZero(&v45)) { + f32 v41 = calcAngleDegree(x, v45); + if (v41 > 105.0f) { + if (!ticket->getPoser()->isInterpoleByCameraDistance()) + mEndInterpoleStep = + (int)lerpValue(60.0f, 90.0f, normalize(v41, 105.0f, 180.0f)); + + setNerve(this, &NrvCameraInterpole.ActiveRotateAxisY); + return; + } + } + } + + if (isNear(_3c_at, mNextTicket->getPoser()->getTargetTrans(), 250.0f) || + (mNextTicket->getPoser()->getTargetTrans() - _3c_at) + .dot(mNextTicket->getPoser()->getPosition() - _30_pos) >= 0.0f) + setNerve(this, &NrvCameraInterpole.ActiveHermiteDistanceHV); + + else + setNerve(this, &NrvCameraInterpole.ActiveHermite); +} + +void CameraInterpole::update(const sead::LookAtCamera& camera) { + _178.getPos() = camera.getPos(); + _178.getAt() = camera.getAt(); + _178.getUp() = camera.getUp(); + _178.getUp().normalize(); + + if (mIsRequestCancel) { + mIsRequestCancel = false; + if (isActive()) + setNerve(this, &NrvCameraInterpole.Deactive); + } + + updateNerve(); + if (isActive() && isNear(_30_pos, _3c_at, 0.001f)) { + _30_pos.set(_178.getPos()); + _3c_at.set(_178.getAt()); + _49_up.set(_178.getUp()); + setNerve(this, &NrvCameraInterpole.Deactive); + } + + if (isActive() && mNextTicket) { + if ((mPrevTicket && !alCameraPoserFunction::isInvalidCollider(mPrevTicket->getPoser())) || + !alCameraPoserFunction::isInvalidCollider(mNextTicket->getPoser()) || + mNextTicket->getPoser()->getPoserFlag()->_C) { + sead::Vector3f v11v = _30_pos - _3c_at; + float v14 = v11v.length(); + sead::Vector3f a2 = v11v; + normalize(&a2); + sead::Vector3f a3 = _49_up; + verticalizeVec(&a3, a2, a3); + if (tryNormalizeOrZero(&a3)) { + sead::Vector2f v54[5]; + /* = { + sead::Vector2f::zero, + {-((75.0f / (v14 * sead::Mathf::pi2())) * 360.0f), 0.0f}, + {(75.0f / (v14 * sead::Mathf::pi2())) * 360.0f, 0.0f}, + {0.0f, -(15.0f / (v14 * sead::Mathf::pi2())) * 360.0f}, + {0.0f, (15.0f / (v14 * sead::Mathf::pi2())) * 360.0f}, + };*/ + f32 p15 = (15.0f / (v14 * sead::Mathf::pi2())) * 360.0f; + f32 p75 = (75.0f / (v14 * sead::Mathf::pi2())) * 360.0f; + + sead::Vector3f a1; + a1.setCross(a3, a2); + normalize(&a1); + + // NON_MATCHING: order of loading/storing values + v54[0] = sead::Vector2f::zero; + v54[1] = {-p75, 0.0f}; + v54[2] = {p75, 0.0f}; + v54[3] = {0.0f, -p15}; + v54[4] = {0.0f, p15}; + + bool v16 = false; + for (u64 v15 = 0; v15 != 5; v15++) { + sead::Vector3f v53 = v11v; + rotateVectorDegree(&v53, v53, a3, v54[v15].x); + rotateVectorDegree(&v53, v53, a1, v54[v15].y); + alCameraPoserFunction::CameraCollisionHitResult v52; + memset(&v52, 0, 24); + v52.mCollisionLocation = 3; + + if (alCameraPoserFunction::checkFirstCameraCollisionArrow( + &v52, mNextTicket->getPoser(), _3c_at, v53) && + !v52.mCollisionLocation) { + sead::Vector3f v51 = v52.mCollisionHitPos - _30_pos; + sead::Vector3f v50 = {0.0f, 0.0f, 0.0f}; + if (!isNearZero(v51, 0.001f)) { + // NON_MATCHING: somehow stores an unused boolean pair per result + // first: false;false + // second: true;false + // third: true;true + if (alCameraPoserFunction::checkFirstCameraCollisionArrow( + &v50, 0LL, mNextTicket->getPoser(), _30_pos, v51) || + alCameraPoserFunction::checkFirstCameraCollisionArrow( + &v50, 0LL, mNextTicket->getPoser(), _30_pos + a1 * 10.0f, + v51) || + alCameraPoserFunction::checkFirstCameraCollisionArrow( + &v50, 0LL, mNextTicket->getPoser(), _30_pos - a1 * 10.0f, + v51)) { + if ((_30_pos - v50).length() < 75.0f) { + } else { + continue; + } + } + } + + sead::Vector3f v47 = v51; + float v33 = v51.length(); + float v34 = v47.length(); + if (v34 > 0.0) + v47 *= (v33 + 75.0f) / v34; + + parallelizeVec(&v47, a2, v47); + float v36 = v47.length(); + if (_1f0 < v36) { + v16 = true; + _1f4 = 0.0f; + _1f0 = sead::Mathf::min(v36, (v14 + -100.0f)); + } + } + } + if (v16) { + makeLookAtCamera(&_118); + return; + } + } + } + } + + float v37 = lerpValue(_1f4, 1.0f, 0.3f); + _1f4 = lerpValue(_1f4, v37, 0.3f); + // NON_MATCHING: order of loads/argument setup + f32 v38 = lerpValue(_1f0, 0.0f, _1f4 * 0.3f); + _1f0 = lerpValue(_1f0, v38, _1f4 * 0.3f); + float v44 = (_30_pos - _3c_at).length(); + if ((v44 + -100.0f) < _1f0) + _1f0 = sead::Mathf::clampMax(_1f0, sead::Mathf::max(v44, (v44 + -100.0f))); + + makeLookAtCamera(&_118); +} + +bool CameraInterpole::isActive() const { + return !isNerve(this, &NrvCameraInterpole.Deactive); +} + +void CameraInterpole::makeLookAtCamera(sead::LookAtCamera* camera) const { + sead::Vector3f v5v = {0.0f, 0.0f, 0.0f}; + + if (isActive() && _1f0 > 0.1f) { + v5v.set(_3c_at - _30_pos); + f32 v8 = v5v.length(); + f32 f10 = _1f0; + f32 v9 = v5v.length(); + if (v9 > 0.0f) + v5v *= sead::Mathf::min(v8 + -100.0f, f10) / v9; + } + + camera->getPos() = _30_pos + v5v; + camera->getAt() = _3c_at; + camera->getUp() = _49_up; + camera->getUp().normalize(); +} + +void CameraInterpole::lerpFovyDegree(f32 a2) { + _1d8 = lerpValue(mPrevFovyDegree, mNextTicket->getPoser()->getFovyDegree(), a2); +} + +void CameraInterpole::exeDeactive() { + if (isFirstStep(this)) { + if (mPrevPoser) { + mPrevPoser->setField98(false); + mPrevPoser = nullptr; + } + _1f0 = 0.0f; + } + + _30_pos.set(_178.getPos()); + _3c_at.set(_178.getAt()); + _49_up.set(_178.getUp()); +} + +void sub_something(sead::Vector3f*, const sead::LookAtCamera&, const sead::LookAtCamera&, + sead::Vector3f, sead::Vector3f, f32); + +void CameraInterpole::exeActiveHermite() { + sead::LookAtCamera* cam = &_48; + if (mPrevPoser) { + if (alCameraPoserFunction::isChangeTarget(mPrevPoser)) + mPrevPoser = nullptr; + else { + mPrevPoser->movement(); + mPrevPoser->calcCameraPose(cam); + } + } + + CameraPoser* poser = mNextTicket->getPoser(); + s32 v28 = mEndInterpoleStep; + f32 v8 = normalize(sead::Mathi::clampMin(getNerveStep(this) + 1, 1), 0, v28); + f32 v10 = hermiteRate(v8, 1.5f, 0.0f); + + if (poser->isInterpoleEaseOut()) + v10 = easeOut(v10); + + lerpVec(&_30_pos, _48.getPos(), _178.getPos(), v10); + lerpVec(&_3c_at, _48.getAt(), _178.getAt(), v10); + + sub_something(&_49_up, _48, _178, _30_pos, _3c_at, v10); + + lerpFovyDegree(v10); + + if (isGreaterEqualStep(this, mEndInterpoleStep - 1)) + setNerve(this, &NrvCameraInterpole.Deactive); +} + +f32 cameraGetHAngle(const sead::LookAtCamera&); + +void rotate(sead::Vector3f* result, const sead::Vector3f& vec, const sead::Quatf& quat) { + f32 v19 = (vec.z * quat.y) - (vec.y * quat.z) + (vec.x * quat.w); + f32 v20 = (vec.x * quat.z) - (vec.z * quat.x) + (vec.y * quat.w); + f32 v22 = (vec.y * quat.x) - (vec.x * quat.y) + (vec.z * quat.w); + f32 v23 = -(vec.x * quat.x) - (vec.y * quat.y) - (vec.z * quat.z); + result->x = (quat.y * v22) - (quat.z * v20) + (quat.w * v19) - (quat.x * v23); + result->y = (quat.z * v19) - (quat.x * v22) + (quat.w * v20) - (quat.y * v23); + result->z = (quat.x * v20) - (quat.y * v19) + (quat.w * v22) - (quat.z * v23); +} + +void sub_something(sead::Vector3f* up, const sead::LookAtCamera& cam1, + const sead::LookAtCamera& cam2, sead::Vector3f pos, sead::Vector3f at, + f32 interpole) { + sead::Vector3f back = at - pos; + if (tryNormalizeOrZero(&back) && !isParallelDirection(sead::Vector3f::ey, back, 0.01f)) { + sead::Vector3f side; + side.setCross(sead::Vector3f::ey, back); + normalize(&side); + rotateVectorDegree(up, sead::Vector3f::ey, side, + lerpValue(cameraGetHAngle(cam1), cameraGetHAngle(cam2), interpole)); + return; + } + + if (isNearDirection(cam1.getUp(), cam2.getUp(), 0.01f)) + return; + + sead::Quatf quat = sead::Quatf::unit; + makeQuatRotationRate(&quat, cam1.getUp(), cam2.getUp(), interpole); + rotate(up, cam1.getUp(), quat); + normalize(up); +} + +const sead::Vector3f stru_something = {0.0f, 1.0f, 0.0f}; + +void CameraInterpole::exeActiveHermiteDistanceHV() { + sead::LookAtCamera* cam = &_48; + if (mPrevPoser) { + if (alCameraPoserFunction::isChangeTarget(mPrevPoser)) + mPrevPoser = nullptr; + else { + mPrevPoser->movement(); + mPrevPoser->calcCameraPose(cam); + } + } + + CameraPoser* poser1 = mNextTicket->getPoser(); + s32 v28_ = mEndInterpoleStep; + f32 v7 = normalize(sead::Mathi::clampMin(getNerveStep(this), 1), 0, v28_); + f32 v9 = hermiteRate(v7, 1.5f, 0.0f); + + if (poser1->isInterpoleEaseOut()) + v9 = easeOut(v9); + + CameraPoser* poser2 = mNextTicket->getPoser(); + s32 v28_2 = mEndInterpoleStep; + f32 v14 = normalize(sead::Mathi::clampMin(getNerveStep(this) + 1, 1), 0, v28_2); + f32 v16 = hermiteRate(v14, 1.5f, 0.0f); + + if (poser2->isInterpoleEaseOut()) + v16 = easeOut(v16); + + sead::Vector3f a3 = _30_pos - _3c_at; + verticalizeVec(&a3, stru_something, a3); + if (!tryNormalizeOrZero(&a3)) { + setNerve(this, &NrvCameraInterpole.Deactive); + return; + } + + lerpVec(&_3c_at, _48.getAt(), _178.getAt(), v16); + + sead::Vector3f x = _48.getPos() - _48.getAt(); + sead::Vector3f a1 = _178.getPos() - _178.getAt(); + + f32 v25 = lerpValue(x.length(), a1.length(), v16); + + tryNormalizeOrZero(&a1); + if (!tryNormalizeOrZero(&x)) + x.set(a1); + + f32 v28 = lerpValue(sead::Mathf::rad2deg(sead::Mathf::asin(x.y)), + sead::Mathf::rad2deg(sead::Mathf::asin(a1.y)), v16); + + verticalizeVec(&a1, stru_something, a1); + tryNormalizeOrZero(&a1); + if (!isNormalize(a1, 0.001f)) { + setNerve(this, &NrvCameraInterpole.Deactive); + return; + } + + sead::Vector3f v49 = {0.0f, 0.0f, 0.0f}; + turnVecToVecRate(&v49, a3, a1, normalize(v16 - v9, 0.0f, 1.0f - v9)); + normalize(&v49); + + sead::Vector3f v333435 = sead::Mathf::cos(sead::Mathf::deg2rad(v28)) * v49; + v49 = v333435 + sead::Mathf::sin(sead::Mathf::deg2rad(v28)) * sead::Vector3f{0.0f, 1.0f, 0.0f}; + normalize(&v49); + + _30_pos = (v25 * v49) + _3c_at; + + // NON_MATCHING: Stores reference to _178 in local variable + sub_something(&_49_up, _48, _178, _30_pos, _3c_at, v16); + + lerpFovyDegree(v16); + + if (isGreaterEqualStep(this, mEndInterpoleStep - 1)) + setNerve(this, &NrvCameraInterpole.Deactive); +} + +void CameraInterpole::exeActiveRotateAxisY() { + sead::LookAtCamera* cam = &_48; + if (mPrevPoser) { + if (alCameraPoserFunction::isChangeTarget(mPrevPoser)) + mPrevPoser = nullptr; + else { + mPrevPoser->movement(); + mPrevPoser->calcCameraPose(cam); + } + } + + CameraPoser* poser = mNextTicket->getPoser(); + s32 v28_ = mEndInterpoleStep; + f32 v8 = normalize(sead::Mathi::clampMin(getNerveStep(this) + 1, 1), 0, v28_); + f32 v10 = hermiteRate(v8, 1.5f, 0.0f); + + if (poser->isInterpoleEaseOut()) + v10 = easeOut(v10); + + lerpVec(&_3c_at, _48.getAt(), _178.getAt(), v10); + + sead::Vector3f v47 = {0.0f, 0.0f, 0.0f}; + sead::Vector3f a1 = {0.0f, 0.0f, 0.0f}; + sead::Vector3f a3 = _48.getPos() - _48.getAt(); + normalize(&a3); + v47.set(a3); + verticalizeVec(&a1, sead::Vector3f::ey, a3); + normalize(&a1); + + sead::Vector3f v45 = {0.0f, 0.0f, 0.0f}; + sead::Vector3f v44 = {0.0f, 0.0f, 0.0f}; + a3 = _178.getPos() - _178.getAt(); + normalize(&a3); + v45.set(a3); + verticalizeVec(&v44, sead::Vector3f::ey, a3); + normalize(&v44); + + if (isFirstStep(this)) { + mAngleRotateY = 0.0f; + _1e4.set(a1); + } + + mAngleRotateY = calcAngleOnPlaneDegree(_1e4, v44, sead::Vector3f::ey) + mAngleRotateY; + a3.set(a1); + rotateVectorDegreeY(&a3, mAngleRotateY); + + mAngleRotateY = calcAngleOnPlaneDegree(a3, v44, sead::Vector3f::ey) + mAngleRotateY; + a3.set(a1); + rotateVectorDegreeY(&a3, v10 * mAngleRotateY); + + _1e4.set(v44); + + sead::Vector3f v43; + v43.setCross(a3, sead::Vector3f::ey); + sead::Vector3f v42; + v42.setCross(a1, sead::Vector3f::ey); + f32 v18 = calcAngleOnPlaneDegree(a1, v47, v42); + sead::Vector3f v41; + v41.setCross(v44, sead::Vector3f::ey); + f32 v19 = calcAngleOnPlaneDegree(v44, v45, v41); + f32 v20 = lerpValue(v18, v19, v10); + v42.set(a3); + rotateVectorDegree(&v42, v42, v43, v20); + + f32 v28 = lerpValue((_48.getPos() - _3c_at).length(), (_178.getPos() - _3c_at).length(), v10); + //_30_pos = (v28 * v42) + _3c_at; + _30_pos.x = v28 * v42.x + _3c_at.x; + _30_pos.y = v28 * v42.y + _3c_at.y; + _30_pos.z = v28 * v42.z + _3c_at.z; + + sub_something(&_49_up, _48, _178, _30_pos, _3c_at, v10); + + lerpFovyDegree(v10); + + if (isGreaterEqualStep(this, mEndInterpoleStep - 1)) + setNerve(this, &NrvCameraInterpole.Deactive); +} + +void CameraInterpole::exeActiveBrigade() { + if (mPrevPoser) { + if (alCameraPoserFunction::isChangeTarget(mPrevPoser)) + mPrevPoser = nullptr; + else { + sead::LookAtCamera* cam = &_48; + mPrevPoser->movement(); + mPrevPoser->calcCameraPose(cam); + } + } + + s32 v28 = mEndInterpoleStep; + f32 v7 = normalize(sead::Mathi::clampMin(getNerveStep(this) + 1, 1), 0, v28); + f32 v9 = easeInOut(v7); + + lerpVec(&_30_pos, _48.getPos(), _178.getPos(), v9); + lerpVec(&_3c_at, _48.getAt(), _178.getAt(), v9); + + f32 v10 = calcAngleDegree(_48.getUp(), _178.getUp()); + if (isReverseDirection(_48.getUp(), _178.getUp(), 0.01f)) { + sead::Vector3f v19 = {0.0f, 0.0f, 0.0f}; + calcDirVerticalAny(&v19, _48.getUp()); + sead::Vector3f v17 = _48.getUp(); + rotateVectorDegree(&v17, v17, v19, v9 * v10); + _49_up.set(v17); + } else { + turnVecToVecDegree(&_49_up, _48.getUp(), _178.getUp(), v9 * v10); + } + + lerpFovyDegree(v9); + + if (isGreaterEqualStep(this, mEndInterpoleStep - 1)) + setNerve(this, &NrvCameraInterpole.Deactive); +} + +f32 cameraGetHAngle(const sead::LookAtCamera& camera) { + // back = -front + sead::Vector3f back = camera.getAt() - camera.getPos(); + if (!tryNormalizeOrZero(&back)) + return 0.0f; + + sead::Vector3f side; + side.setCross(camera.getUp(), back); + normalize(&side); + return calcAngleOnPlaneDegree(sead::Vector3f::ey, camera.getUp(), side); +} + +} // namespace al diff --git a/lib/al/Library/Camera/CameraInterpole.h b/lib/al/Library/Camera/CameraInterpole.h new file mode 100644 index 00000000..7edb0e99 --- /dev/null +++ b/lib/al/Library/Camera/CameraInterpole.h @@ -0,0 +1,46 @@ +#pragma once + +#include "Library/Nerve/NerveExecutor.h" +#include "gfx/seadCamera.h" + +namespace al { +class CameraPoser; +class CameraTicket; + +class CameraInterpole : public NerveExecutor { +public: + CameraInterpole(); + + void start(const CameraTicket* ticket, f32 prevFovyDegree, s32 endInterpoleStep); + void update(const sead::LookAtCamera& camera); + bool isActive() const; + void makeLookAtCamera(sead::LookAtCamera* camera) const; + void lerpFovyDegree(f32); + void exeDeactive(); + void exeActiveHermite(); + void exeActiveHermiteDistanceHV(); + void exeActiveRotateAxisY(); + void exeActiveBrigade(); + +private: + const al::CameraTicket* mNextTicket = nullptr; + const al::CameraTicket* mPrevTicket = nullptr; + al::CameraPoser* mPrevPoser = nullptr; + s32 mEndInterpoleStep = -1; + bool mIsRequestCancel = false; + sead::Vector3f _30_pos = {0.0f, 0.0f, 0.0f}; + sead::Vector3f _3c_at = {0.0f, 0.0f, 0.0f}; + sead::Vector3f _49_up = sead::Vector3f::ey; + sead::LookAtCamera _48; + sead::LookAtCamera _B8; + sead::LookAtCamera _118; + sead::LookAtCamera _178; + f32 _1d8 = 30.0f; + f32 mPrevFovyDegree = 30.0f; + f32 mAngleRotateY = 0.0f; + sead::Vector3f _1e4 = {0.0f, 0.0f, 0.0f}; + f32 _1f0 = 0.0f; + f32 _1f4 = 0.0f; +}; + +} // namespace al diff --git a/lib/al/Library/Camera/CameraPoser.h b/lib/al/Library/Camera/CameraPoser.h index 74f9c124..bf2d7fcf 100644 --- a/lib/al/Library/Camera/CameraPoser.h +++ b/lib/al/Library/Camera/CameraPoser.h @@ -87,14 +87,13 @@ class CameraPoser : public HioNode, void makeLookAtCameraLast(sead::LookAtCamera*) const; void makeLookAtCameraCollide(sead::LookAtCamera*) const; - void getInterpoleStep(); + s32 getInterpoleStep(); void setInterpoleStep(s32); void resetInterpoleStep(); void setInterpoleEaseOut(); - void getEndInterpoleStep(); + s32 getEndInterpoleStep(); void appear(const CameraStartInfo&); - void calcCameraPose(sead::LookAtCamera*); void receiveRequestFromObjectCore(const CameraObjectRequestInfo&); void startSnapShotModeCore(); @@ -102,14 +101,18 @@ class CameraPoser : public HioNode, f32 getFovyDegree() const; - sead::Vector3f getPosition() const { return mPosition; }; + const sead::Vector3f& getPosition() const { return mPosition; }; - sead::Vector3f getTargetTrans() const { return mTargetTrans; }; + const sead::Vector3f& getTargetTrans() const { return mTargetTrans; }; - sead::Vector3f getCameraUp() const { return mCameraUp; }; + const sead::Vector3f& getCameraUp() const { return mCameraUp; }; const sead::Matrix34f& getViewMtx() const { return mViewMtx; }; + CameraPoserFlag* getPoserFlag() const { return mPoserFlag; } + + void setField98(bool flag) { field_98 = flag; } + private: const char* mPoserName; f32 field_38; @@ -122,7 +125,7 @@ class CameraPoser : public HioNode, bool field_98 = false; CameraViewInfo* mViewInfo; AreaObjDirector* mAreaDirector; - CameraPoserFlag* mPoserFlags; + CameraPoserFlag* mPoserFlag; CameraVerticalAbsorber* mVerticalAbsorber; CameraAngleCtrlInfo* mAngleCtrlInfo; CameraAngleSwingInfo* mAngleSwingInfo; diff --git a/lib/al/Library/Camera/CameraPoserFlag.h b/lib/al/Library/Camera/CameraPoserFlag.h new file mode 100644 index 00000000..e00644f0 --- /dev/null +++ b/lib/al/Library/Camera/CameraPoserFlag.h @@ -0,0 +1,29 @@ +#pragma once + +namespace al { +class ByamlIter; + +struct CameraPoserFlag { + bool mIsFirstCalc; + bool mIsOffVerticalAbsorb; + bool mIsInvalidCollider; + bool _3; + bool mIsValidKeepPreSelfPoseNextCameraByParam; + bool _5; + bool mIsInvalidKeepPreSelfPoseNextCameraOverWriteProgram; + bool mIsInvalidKeepDistanceNextCamera; + bool mIsInvalidKeepDistanceNextCameraIfNoCollide; + bool mIsValidCtrlSubjective; + bool mIsInvalidChangeSubjective; + bool mIsInvalidCameraBlur; + bool _C; + bool mIsInvalidPreCameraEndAfterInterpole; + bool mIsStopUpdateGyro; + +public: + CameraPoserFlag(); + void load(const al::ByamlIter& iter); + bool isValidKeepPreSelfPoseNextCamera() const; +}; + +} // namespace al diff --git a/lib/al/Library/Camera/CameraPoserFunction.h b/lib/al/Library/Camera/CameraPoserFunction.h index fadc6ad3..7dc6eaea 100644 --- a/lib/al/Library/Camera/CameraPoserFunction.h +++ b/lib/al/Library/Camera/CameraPoserFunction.h @@ -14,7 +14,11 @@ class PlacementInfo; } // namespace al namespace alCameraPoserFunction { -class CameraCollisionHitResult; +struct CameraCollisionHitResult { + sead::Vector3f mCollisionHitPos; + sead::Vector3f mTriangleNormal; + int mCollisionLocation; +}; void getViewIndex(const al::CameraPoser*); sead::LookAtCamera* getLookAtCamera(const al::CameraPoser*); @@ -193,11 +197,11 @@ bool isSceneCameraFirstCalc(const al::CameraPoser*); bool isActiveInterpole(const al::CameraPoser*); bool isInvalidEndEntranceCamera(const al::CameraPoser*); bool isPause(const al::CameraPoser*); -void checkFirstCameraCollisionArrow(sead::Vector3f*, sead::Vector3f*, const al::IUseCollision*, +bool checkFirstCameraCollisionArrow(sead::Vector3f*, sead::Vector3f*, const al::IUseCollision*, const sead::Vector3f&, const sead::Vector3f&); -void checkFirstCameraCollisionArrow(CameraCollisionHitResult*, const al::IUseCollision*, +bool checkFirstCameraCollisionArrow(CameraCollisionHitResult*, const al::IUseCollision*, const sead::Vector3f&, const sead::Vector3f&); -void checkFirstCameraCollisionArrowOnlyCeiling(sead::Vector3f*, sead::Vector3f*, +bool checkFirstCameraCollisionArrowOnlyCeiling(sead::Vector3f*, sead::Vector3f*, const al::IUseCollision*, const sead::Vector3f&, const sead::Vector3f&); void checkCameraCollisionMoveSphere(sead::Vector3f*, const al::IUseCollision*, diff --git a/lib/al/Library/Math/MathLengthUtil.h b/lib/al/Library/Math/MathLengthUtil.h index bf23bc46..7edeed73 100644 --- a/lib/al/Library/Math/MathLengthUtil.h +++ b/lib/al/Library/Math/MathLengthUtil.h @@ -21,6 +21,7 @@ bool isParallelDirection(const sead::Vector2f&, const sead::Vector2f&, f32); bool isParallelDirection(const sead::Vector3f&, const sead::Vector3f&, f32); bool isReverseDirection(const sead::Vector3f&, const sead::Vector3f&, f32); bool isNearDirection(const sead::Vector2f&, const sead::Vector2f&, f32); +bool isNearDirection(const sead::Vector3f&, const sead::Vector3f&, f32); bool isInRange(s32, s32, s32); bool isInRange(f32, f32, f32); diff --git a/lib/al/Library/Math/MathUtil.h b/lib/al/Library/Math/MathUtil.h index 75058869..95db2f4b 100755 --- a/lib/al/Library/Math/MathUtil.h +++ b/lib/al/Library/Math/MathUtil.h @@ -78,4 +78,9 @@ void separateScalarAndDirection(f32*, sead::Vector3f*, const sead::Vector3f&); void calcParabolicFunctionParam(f32*, f32*, f32, f32 verticalDistance); +f32 hermiteRate(f32, f32, f32); +void calcDirVerticalAny(sead::Vector3f*, const sead::Vector3f&); + +void makeQuatRotationRate(sead::Quatf*, const sead::Vector3f&, const sead::Vector3f&, f32); + } // namespace al diff --git a/lib/sead b/lib/sead index 72bb3307..aaec48c7 160000 --- a/lib/sead +++ b/lib/sead @@ -1 +1 @@ -Subproject commit 72bb33075d5e7ddd2b90a59e011a83a1d72ae2c0 +Subproject commit aaec48c701cfb8e9527a6d7a8abd60bfb66a8e83