Boss/Koopa: Implement KoopaLandPointHolder (#1010)

This commit is contained in:
Narr the Reg 2026-04-12 12:41:33 -06:00 committed by GitHub
parent 00fb866836
commit bc392ae108
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 159 additions and 7 deletions

View file

@ -17145,31 +17145,31 @@ Boss/Koopa/KoopaLandPointHolder.o:
label:
- _ZN20KoopaLandPointHolderC1ERKN2al13ActorInitInfoE
- _ZN20KoopaLandPointHolderC2ERKN2al13ActorInitInfoE
status: NotDecompiled
status: Matching
- offset: 0x0956b8
size: 252
label: _ZN20KoopaLandPointHolder18decidePointFarFromERKN4sead7Vector3IfEE
status: NotDecompiled
status: Matching
- offset: 0x0957b4
size: 32
label: _ZN20KoopaLandPointHolder15invalidatePointEi
status: NotDecompiled
status: Matching
- offset: 0x0957d4
size: 452
label: _ZN20KoopaLandPointHolder24decidePointEitherFarSideERKN4sead7Vector3IfEE
status: NotDecompiled
status: Matching
- offset: 0x095998
size: 252
label: _ZN20KoopaLandPointHolder19decidePointNearFromERKN4sead7Vector3IfEE
status: NotDecompiled
status: Matching
- offset: 0x095a94
size: 44
label: _ZN20KoopaLandPointHolder5resetEv
status: NotDecompiled
status: Matching
- offset: 0x095ac0
size: 264
label: _ZNK20KoopaLandPointHolder21findNearestPointTransERKN4sead7Vector3IfEE
status: NotDecompiled
status: Matching
Boss/Koopa/KoopaLv1.o:
'.text':
- offset: 0x095bc8

View file

@ -0,0 +1,120 @@
#include "Boss/Koopa/KoopaLandPointHolder.h"
#include "Library/Math/MathUtil.h"
#include "Library/Placement/PlacementFunction.h"
#include "Library/Placement/PlacementInfo.h"
KoopaLandPointHolder::KoopaLandPointHolder(const al::ActorInitInfo& initInfo) {
al::getTrans(&mTrans, initInfo);
al::getQuat(&mQuat, initInfo);
mLandPoints = al::calcLinkChildNum(initInfo, "LandPoint");
if (mLandPoints <= 0)
return;
mPointsQuat = new sead::Quatf[mLandPoints];
mPointsTrans = new sead::Vector3f[mLandPoints];
mInvalidPoints = new bool[mLandPoints];
for (s32 i = 0; i < mLandPoints; i++) {
mInvalidPoints[i] = false;
al::PlacementInfo placementInfo;
al::getLinksInfoByIndex(&placementInfo, initInfo, "LandPoint", i);
al::getQuat(&mPointsQuat[i], placementInfo);
al::getTrans(&mPointsTrans[i], placementInfo);
}
}
inline f32 getKoopaLandPointDistance(const sead::Vector3f& posA, const sead::Vector3f& posB) {
sead::Vector3f distance = posA - posB;
return sead::Mathf::sqrt(distance.x * distance.x + distance.z * distance.z);
}
void KoopaLandPointHolder::decidePointFarFrom(const sead::Vector3f& pos) {
s32 selectedPoint = -1;
f32 maxDistance = 0.0f;
for (s32 i = 0; i < mLandPoints; i++) {
if (mInvalidPoints[i])
continue;
f32 dist = getKoopaLandPointDistance(mPointsTrans[i], pos);
if (selectedPoint < 0 || maxDistance < dist) {
selectedPoint = i;
maxDistance = dist;
}
}
invalidatePoint(selectedPoint);
mCurrentLandPoint = selectedPoint;
}
void KoopaLandPointHolder::invalidatePoint(s32 index) {
mInvalidPoints[index] = true;
if (mCurrentLandPoint > -1)
mInvalidPoints[mCurrentLandPoint] = false;
}
void KoopaLandPointHolder::decidePointEitherFarSide(const sead::Vector3f& pos) {
if (mCurrentLandPoint < 0) {
decidePointFarFrom(pos);
return;
}
mInvalidPoints[mCurrentLandPoint] = false;
s32 prevPoint = al::modi(mCurrentLandPoint - 1 + mLandPoints, mLandPoints);
s32 nextPoint = al::modi(mCurrentLandPoint + 1 + mLandPoints, mLandPoints);
f32 prevDist = getKoopaLandPointDistance(mPointsTrans[prevPoint], pos);
f32 nextDist = getKoopaLandPointDistance(mPointsTrans[nextPoint], pos);
if (prevDist < nextDist)
mCurrentLandPoint = nextPoint;
else
mCurrentLandPoint = prevPoint;
}
void KoopaLandPointHolder::decidePointNearFrom(const sead::Vector3f& pos) {
s32 selectedPoint = -1;
f32 minDistance = 0.0f;
for (s32 i = 0; i < mLandPoints; i++) {
if (mInvalidPoints[i])
continue;
f32 dist = getKoopaLandPointDistance(mPointsTrans[i], pos);
if (selectedPoint < 0 || dist < minDistance) {
selectedPoint = i;
minDistance = dist;
}
}
invalidatePoint(selectedPoint);
mCurrentLandPoint = selectedPoint;
}
void KoopaLandPointHolder::reset() {
for (s32 i = 0; i < mLandPoints; i++)
mInvalidPoints[i] = false;
}
// NOTE: does not care about `mInvalidPoints`
const sead::Vector3f& KoopaLandPointHolder::findNearestPointTrans(const sead::Vector3f& pos) const {
f32 minDistance = getKoopaLandPointDistance(mPointsTrans[0], pos);
s32 selectedPoint = 0;
for (s32 i = 1; i < mLandPoints; i++) {
f32 dist = getKoopaLandPointDistance(mPointsTrans[i], pos);
if (dist < minDistance) {
selectedPoint = i;
minDistance = dist;
}
}
return mPointsTrans[selectedPoint];
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <basis/seadTypes.h>
#include <math/seadQuat.h>
#include <math/seadVector.h>
namespace al {
struct ActorInitInfo;
} // namespace al
class KoopaLandPointHolder {
public:
KoopaLandPointHolder(const al::ActorInitInfo& initInfo);
void decidePointFarFrom(const sead::Vector3f& pos);
void invalidatePoint(s32 index);
void decidePointEitherFarSide(const sead::Vector3f& pos);
void decidePointNearFrom(const sead::Vector3f& pos);
void reset();
const sead::Vector3f& findNearestPointTrans(const sead::Vector3f& pos) const;
private:
sead::Vector3f mTrans = {0.0f, 0.0f, 0.0f};
sead::Quatf mQuat = sead::Quatf::unit;
s32 mCurrentLandPoint = -1;
s32 mLandPoints = 0;
sead::Quatf* mPointsQuat = nullptr;
sead::Vector3f* mPointsTrans = nullptr;
bool* mInvalidPoints = nullptr;
};
static_assert(sizeof(KoopaLandPointHolder) == 0x40);