diff --git a/data/file_list.yml b/data/file_list.yml index f5f6c5b477..1249ae0bf3 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -292194,47 +292194,47 @@ Project/Camera/SimpleCameraShooter.o: label: - _ZN2al19SimpleCameraShooterC1EPKc - _ZN2al19SimpleCameraShooterC2EPKc - status: NotDecompiled + status: Matching - offset: 0xa4c460 size: 20 label: _ZN2al19SimpleCameraShooter27calcAspectRatioByScreenSizeEii - status: NotDecompiled + status: Matching - offset: 0xa4c474 size: 200 label: _ZNK2al19SimpleCameraShooter13calcCameraPosEPN4sead7Vector3IfEEPKNS_13IUseCollisionE - status: NotDecompiled + status: Matching - offset: 0xa4c53c size: 36 label: _ZNK2al19SimpleCameraShooter12calcFrontDirEPN4sead7Vector3IfEE - status: NotDecompiled + status: Matching - offset: 0xa4c560 size: 136 label: _ZNK2al19SimpleCameraShooter14checkCollisionEfPKNS_13IUseCollisionE - status: NotDecompiled + status: Matching - offset: 0xa4c5e8 size: 352 label: _ZNK2al19SimpleCameraShooter24applyCameraWithCollisionEPN4sead12LookAtCameraEPKNS_13IUseCollisionE - status: NotDecompiled + status: Matching - offset: 0xa4c748 size: 28 label: _ZNK2al19SimpleCameraShooter15applyProjectionEPN4sead21PerspectiveProjectionE - status: NotDecompiled + status: Matching - offset: 0xa4c764 size: 120 label: _ZN2al19SimpleCameraShooter6lookAtERKN4sead7Vector3IfEE - status: NotDecompiled + status: Matching - offset: 0xa4c7dc size: 540 label: _ZN2al19SimpleCameraShooter15applyLimitationEv - status: NotDecompiled + status: Matching - offset: 0xa4c9f8 size: 60 label: _ZN2al19SimpleCameraShooter9rotateYawEf - status: NotDecompiled + status: Matching - offset: 0xa4ca34 size: 60 label: _ZN2al19SimpleCameraShooter11rotatePitchEf - status: NotDecompiled + status: Matching Project/Clipping/ClippingDirector.o: '.text': - offset: 0xa4ca70 diff --git a/lib/al/Project/Camera/SimpleCameraShooter.cpp b/lib/al/Project/Camera/SimpleCameraShooter.cpp new file mode 100644 index 0000000000..046d5936a9 --- /dev/null +++ b/lib/al/Project/Camera/SimpleCameraShooter.cpp @@ -0,0 +1,120 @@ +#include "Project/Camera/SimpleCameraShooter.h" + +#include +#include + +#include "Library/Collision/CollisionPartsKeeperUtil.h" +#include "Library/Math/MathUtil.h" + +namespace al { + +SimpleCameraShooter::SimpleCameraShooter(const char* _name) { + mAspectRatio = 4.0f / 3.0f; +} + +f32 SimpleCameraShooter::calcAspectRatioByScreenSize(s32 width, s32 height) { + mAspectRatio = (f32)width / (f32)height; + return mAspectRatio; +} + +void SimpleCameraShooter::calcCameraPos(sead::Vector3f* cameraPos, + const IUseCollision* collision) const { + sead::Vector3f backDir = mBackDir; + f32 distance = mDistance; + if (collision) { + if (alCollisionUtil::checkStrikeSphereMove(collision, mHitInfos, 8, mPosition, 30.0f, + distance * mBackDir, nullptr, nullptr)) + distance *= mHitInfos[0]._0; + } + + cameraPos->set(mPosition); + *cameraPos += backDir * distance; +} + +void SimpleCameraShooter::calcFrontDir(sead::Vector3f* frontDir) const { + *frontDir = -mBackDir; +} + +f32 SimpleCameraShooter::checkCollision(f32 distance, const IUseCollision* collision) const { + sead::Vector3f backDir = mBackDir; + if (alCollisionUtil::checkStrikeSphereMove(collision, mHitInfos, 8, mPosition, 30.0f, + backDir * distance, nullptr, nullptr)) + distance *= mHitInfos[0]._0; + return distance; +} + +void SimpleCameraShooter::applyCameraWithCollision(sead::LookAtCamera* camera, + const IUseCollision* collision) const { + sead::Vector3f backDir = mBackDir; + f32 distance = mDistance; + if (collision) + distance = checkCollision(distance, collision); + + sead::Vector3f cameraPos = mPosition; + cameraPos = backDir * distance + cameraPos; + camera->setPos(cameraPos); + camera->setAt(mPosition - backDir); + camera->setUp(mUpDir); + camera->normalizeUp(); + camera->updateViewMatrix(); +} + +void SimpleCameraShooter::applyProjection(sead::PerspectiveProjection* projection) const { + projection->set(mNear, mFar, sead::Mathf::deg2rad(mFovyDegree), mAspectRatio); +} + +void SimpleCameraShooter::lookAt(const sead::Vector3f& position) { + sead::Vector3f direction = position - mPosition; + if (tryNormalizeOrZero(&direction)) { + mBackDir = -direction; + applyLimitation(); + } +} + +void SimpleCameraShooter::applyLimitation() { + sead::Vector3f upperLimit = sead::Vector3f::ey; + sead::Vector3f lowerLimit = sead::Vector3f::ey; + rotateVectorDegree(&upperLimit, upperLimit, mSideDir, 110.0f); + rotateVectorDegree(&lowerLimit, lowerLimit, mSideDir, 70.0f); + tryNormalizeOrZero(&upperLimit); + tryNormalizeOrZero(&lowerLimit); + + const sead::Vector3f* limit = nullptr; + f32 dot = upperLimit.dot(mBackDir); + if (dot < 0.0f) { + limit = &upperLimit; + } else { + dot = lowerLimit.dot(mBackDir); + if (dot < 0.0f) + limit = &lowerLimit; + } + + if (limit) { + sead::Vector3f offset = *limit; + offset.multScalar(-dot); + mBackDir += offset; + } + + tryNormalizeOrZero(&mBackDir); + if (isParallelDirection(mBackDir, sead::Vector3f::ey, 0.01f)) { + mUpDir = mBackDir.cross(mSideDir); + mSideDir = mUpDir.cross(mBackDir); + } else { + mSideDir = sead::Vector3f::ey.cross(mBackDir); + mUpDir = mBackDir.cross(mSideDir); + } + tryNormalizeOrZero(&mSideDir); + tryNormalizeOrZero(&mUpDir); +} + +void SimpleCameraShooter::rotateYaw(f32 degree) { + rotateVectorDegree(&mBackDir, mBackDir, mUpDir, sead::Mathf::deg2rad(degree)); + applyLimitation(); +} + +void SimpleCameraShooter::rotatePitch(f32 degree) { + rotateVectorDegree(&mBackDir, mBackDir, mSideDir, sead::Mathf::deg2rad(degree)); + applyLimitation(); +} + +} // namespace al diff --git a/lib/al/Project/Camera/SimpleCameraShooter.h b/lib/al/Project/Camera/SimpleCameraShooter.h new file mode 100644 index 0000000000..ea20611145 --- /dev/null +++ b/lib/al/Project/Camera/SimpleCameraShooter.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include "Library/Collision/CollisionPartsKeeperUtil.h" + +namespace sead { +class LookAtCamera; +class PerspectiveProjection; +} // namespace sead + +namespace al { +class IUseCollision; + +class SimpleCameraShooter { +public: + SimpleCameraShooter(const char* _name); + + f32 calcAspectRatioByScreenSize(s32 width, s32 height); + void calcCameraPos(sead::Vector3f* cameraPos, const IUseCollision* collision) const; + void calcFrontDir(sead::Vector3f* frontDir) const; + f32 checkCollision(f32 distance, const IUseCollision* collision) const; + void applyCameraWithCollision(sead::LookAtCamera* camera, const IUseCollision* collision) const; + void applyProjection(sead::PerspectiveProjection* projection) const; + void lookAt(const sead::Vector3f& position); + void applyLimitation(); + void rotateYaw(f32 degree); + void rotatePitch(f32 degree); + +private: + sead::Vector3f mPosition = sead::Vector3f::zero; + sead::Vector3f mSideDir = sead::Vector3f::ex; + sead::Vector3f mUpDir = sead::Vector3f::ey; + sead::Vector3f mBackDir = sead::Vector3f::ez; + f32 mDistance = 100.0f; + f32 mFovyDegree = 45.0f; + f32 mNear = 100.0f; + f32 mFar = 1000000.0f; + f32 mAspectRatio = 1.0f; + u32 _44; + alCollisionUtil::SphereMoveHitInfo* mHitInfos = new alCollisionUtil::SphereMoveHitInfo[8]; +}; + +static_assert(sizeof(SimpleCameraShooter) == 0x50); + +} // namespace al