Area: Implement In2DAreaMoveControl (#935)

This commit is contained in:
guymakinggames 2026-03-08 21:10:18 +00:00 committed by GitHub
parent 9a9eeefb89
commit 5338d060fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 113 additions and 9 deletions

View file

@ -1059,35 +1059,35 @@ Area/In2DAreaMoveControl.o:
label:
- _ZN19In2DAreaMoveControlC1Ev
- _ZN19In2DAreaMoveControlC2Ev
status: NotDecompiled
status: Matching
- offset: 0x0059c4
size: 148
label: _ZN19In2DAreaMoveControl6updateERKN4sead13FixedPtrArrayIN2al7AreaObjELi8EEE
status: NotDecompiled
status: Matching
- offset: 0x005a58
size: 228
label: _ZNK19In2DAreaMoveControl14calcGravityDirEPN4sead7Vector3IfEERKS2_S5_
status: NotDecompiled
status: Matching
- offset: 0x005b3c
size: 276
label: _ZNK19In2DAreaMoveControl11calcLockDirEPN4sead7Vector3IfEEPfRKS2_
status: NotDecompiled
status: Matching
- offset: 0x005c50
size: 228
label: _ZNK19In2DAreaMoveControl15calcLastLockDirEPN4sead7Vector3IfEERKS2_
status: NotDecompiled
status: Matching
- offset: 0x005d34
size: 284
label: _ZNK19In2DAreaMoveControl17isNearSnapSurfaceERKN4sead7Vector3IfEEf
status: NotDecompiled
status: Matching
- offset: 0x005e50
size: 124
label: _ZNK19In2DAreaMoveControl25isLastAreaPushOutOppositeEv
status: NotDecompiled
status: Matching
- offset: 0x005ecc
size: 124
label: _ZNK19In2DAreaMoveControl23isLastAreaFaceToPushOutEv
status: NotDecompiled
status: Matching
Area/MoveArea2D.o:
'.text':
- offset: 0x005f48

View file

@ -0,0 +1,103 @@
#include "Area/In2DAreaMoveControl.h"
#include "Library/Math/MathUtil.h"
#include "Util/AreaUtil.h"
In2DAreaMoveControl::In2DAreaMoveControl() = default;
void In2DAreaMoveControl::update(const sead::FixedPtrArray<al::AreaObj, 8>& areas) {
s32 size = areas.size();
mAreas.clear();
if (size > 0) {
mLastAreas.clear();
for (s32 i = 0; i < size; i++) {
al::AreaObj* area = areas[i];
mAreas.pushBack(area);
mLastAreas.pushBack(area);
}
}
}
void In2DAreaMoveControl::calcGravityDir(sead::Vector3f* out, const sead::Vector3f& pos,
const sead::Vector3f& defaultGravity) const {
out->set(0.0f, 0.0f, 0.0f);
s32 size = mAreas.size();
for (s32 i = 0; i < size; i++) {
sead::Vector3f gravity = {0.0f, 0.0f, 0.0f};
if (rs::calc2DAreaDistanceGravity(&gravity, mAreas[i], pos))
*out += gravity;
}
if (!al::tryNormalizeOrZero(out))
out->set(defaultGravity);
}
void In2DAreaMoveControl::calcLockDir(sead::Vector3f* out, f32* closestSurfaceDist,
const sead::Vector3f& pos) const {
out->set(0.0f, 0.0f, 0.0f);
*closestSurfaceDist = 100000.0f;
s32 size = mAreas.size();
for (s32 i = 0; i < size; i++) {
al::AreaObj* area = mAreas[i];
sead::Vector3f snapDir = {0.0f, 0.0f, 0.0f};
f32 snapPower = 0.0f;
rs::calc2DAreaSnapPower(&snapDir, &snapPower, area, pos);
*out += snapDir;
*closestSurfaceDist = sead::Mathf::min(*closestSurfaceDist, snapPower);
}
if (!al::tryNormalizeOrZero(out))
out->set(sead::Vector3f::ey);
}
void In2DAreaMoveControl::calcLastLockDir(sead::Vector3f* out, const sead::Vector3f& pos) const {
out->set(0.0f, 0.0f, 0.0f);
s32 size = mLastAreas.size();
for (s32 i = 0; i < size; i++) {
sead::Vector3f lockDir = {0.0f, 0.0f, 0.0f};
rs::calc2DAreaLockDir(&lockDir, mLastAreas[i], pos);
*out += lockDir;
}
if (!al::tryNormalizeOrZero(out))
out->set(sead::Vector3f::ey);
}
bool In2DAreaMoveControl::isNearSnapSurface(const sead::Vector3f& pos, f32 threshold) const {
s32 size = mAreas.size();
for (s32 i = 0; i < size; i++) {
al::AreaObj* area = mAreas[i];
f32 surfaceDistance = rs::get2DAreaSurfaceDistance(area);
// Calculate snap direction with surface distance offset
sead::Vector3f snapDirWithOffset = {0.0f, 0.0f, 0.0f};
f32 snapDistWithOffset = 0.0f;
rs::calc2DAreaSnapPowerSurfaceDistance(&snapDirWithOffset, &snapDistWithOffset, area, pos,
surfaceDistance);
// Calculate snap direction at the actual surface (no offset)
sead::Vector3f snapDirAtSurface = {0.0f, 0.0f, 0.0f};
f32 snapDistAtSurface = 0.0f;
rs::calc2DAreaSnapPowerSurfaceDistance(&snapDirAtSurface, &snapDistAtSurface, area, pos,
0.0f);
// Check if directions point opposite ways or if close to surface
if (snapDirWithOffset.dot(snapDirAtSurface) < 0.0f || snapDistWithOffset <= threshold)
return true;
}
return false;
}
bool In2DAreaMoveControl::isLastAreaPushOutOpposite() const {
s32 size = mLastAreas.size();
for (s32 i = 0; i < size; i++)
if (rs::isPushOut2DAreaOpposite(mLastAreas[i]))
return true;
return false;
}
bool In2DAreaMoveControl::isLastAreaFaceToPushOut() const {
s32 size = mLastAreas.size();
for (s32 i = 0; i < size; i++)
if (rs::isFaceTo2DAreaPushOutDir(mLastAreas[i]))
return true;
return false;
}

View file

@ -20,7 +20,8 @@ public:
bool isLastAreaFaceToPushOut() const;
private:
void* filler[0xA0 / 8];
sead::FixedPtrArray<al::AreaObj, 8> mAreas;
sead::FixedPtrArray<al::AreaObj, 8> mLastAreas;
};
static_assert(sizeof(In2DAreaMoveControl) == 0xA0);