mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
Area: Implement In2DAreaMoveControl (#935)
This commit is contained in:
parent
9a9eeefb89
commit
5338d060fb
|
|
@ -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
|
||||
|
|
|
|||
103
src/Area/In2DAreaMoveControl.cpp
Normal file
103
src/Area/In2DAreaMoveControl.cpp
Normal 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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue