#include "Library/Collision/KCollisionServer.h" #include "Library/Math/MathUtil.h" namespace al { void SphereInterpolator::startInterp(const sead::Vector3f& posStart, const sead::Vector3f& posEnd, f32 sizeStart, f32 sizeEnd, f32 steps) { mCurrentStep = 0.0f; mPrevStep = 0.0f; mPos = posStart; mMove = posEnd - posStart; mSizeStart = sizeStart; mSizeEnd = sizeEnd; f32 dist = mMove.length() + sizeEnd - sizeStart; mStepSize = (dist <= 0.0f) ? 1.0f : steps / dist; } void SphereInterpolator::nextStep() { // re-interpreting between f32/s32 required to match s32 curStep = *(s32*)&mCurrentStep; f32 stepAsFloat = *(f32*)&curStep; f32 newStep = sead::Mathf::clampMax(stepAsFloat + mStepSize, 1.0f); *(s32*)&mPrevStep = curStep; mCurrentStep = newStep; } void SphereInterpolator::calcInterpPos(sead::Vector3f* pos) const { f32 step = mCurrentStep; pos->x = mMove.x * step + mPos.x; pos->y = mMove.y * step + mPos.y; pos->z = mMove.z * step + mPos.z; } void SphereInterpolator::calcInterp(sead::Vector3f* pos, f32* size, sead::Vector3f* remainMoveVec) const { calcInterpPos(pos); *size = mSizeStart + (mSizeEnd - mSizeStart) * mCurrentStep; calcRemainMoveVector(remainMoveVec); } void SphereInterpolator::calcRemainMoveVector(sead::Vector3f* remainMoveVec) const { if (remainMoveVec) { f32 remainStep = 1.0f - mCurrentStep; remainMoveVec->x = mMove.x * remainStep; remainMoveVec->y = mMove.y * remainStep; remainMoveVec->z = mMove.z * remainStep; } } void SphereInterpolator::getMoveVector(sead::Vector3f* moveVec) { f32 step = mCurrentStep; moveVec->x = mMove.x * step; moveVec->y = mMove.y * step; moveVec->z = mMove.z * step; } void SphereInterpolator::calcStepMoveVector(sead::Vector3f* moveVec) const { f32 step = mCurrentStep - mPrevStep; moveVec->x = mMove.x * step; moveVec->y = mMove.y * step; moveVec->z = mMove.z * step; } void SpherePoseInterpolator::startInterp(const sead::Vector3f& posStart, const sead::Vector3f& posEnd, f32 sizeStart, f32 sizeEnd, const sead::Quatf& quatStart, const sead::Quatf& quatEnd, f32 steps) { mCurrentStep = 0.0f; mPrevStep = 0.0f; mPos = posStart; mMove = posEnd - posStart; mQuatStart.x = quatStart.x; mQuatStart.y = quatStart.y; mQuatStart.z = quatStart.z; mQuatStart.w = quatStart.w; mQuatEnd.x = quatEnd.x; mQuatEnd.y = quatEnd.y; mQuatEnd.z = quatEnd.z; mQuatEnd.w = quatEnd.w; mSizeStart = sizeStart; mSizeEnd = sizeEnd; f32 dist = mMove.length() + sizeEnd - sizeStart; mStepSize = (dist <= 0.0f) ? 1.0f : steps / dist; } void SpherePoseInterpolator::nextStep() { // re-interpreting between f32/s32 required to match s32 curStep = *(s32*)&mCurrentStep; f32 stepAsFloat = *(f32*)&curStep; f32 newStep = sead::Mathf::clampMax(stepAsFloat + mStepSize, 1.0f); *(s32*)&mPrevStep = curStep; mCurrentStep = newStep; } void SpherePoseInterpolator::calcInterpPos(sead::Vector3f* pos) const { f32 step = mCurrentStep; pos->x = mMove.x * step + mPos.x; pos->y = mMove.y * step + mPos.y; pos->z = mMove.z * step + mPos.z; } void SpherePoseInterpolator::calcInterp(sead::Vector3f* pos, f32* size, sead::Quatf* quat, sead::Vector3f* remainMoveVec) const { calcInterpPos(pos); *size = mSizeStart + (mSizeEnd - mSizeStart) * mCurrentStep; slerpQuat(quat, mQuatStart, mQuatEnd, mCurrentStep); quat->normalize(); calcRemainMoveVector(remainMoveVec); } void SpherePoseInterpolator::calcRemainMoveVector(sead::Vector3f* remainMoveVec) const { if (remainMoveVec) { f32 remainStep = 1.0f - mCurrentStep; remainMoveVec->x = mMove.x * remainStep; remainMoveVec->y = mMove.y * remainStep; remainMoveVec->z = mMove.z * remainStep; } } f32 SpherePoseInterpolator::calcRadiusBaseScale(f32 unk) const { return calcRate01(unk, 0.0f, mSizeEnd); } void SpherePoseInterpolator::getMoveVector(sead::Vector3f* moveVec) { f32 step = mCurrentStep; moveVec->x = mMove.x * step; moveVec->y = mMove.y * step; moveVec->z = mMove.z * step; } } // namespace al