mirror of
https://github.com/MonsterDruide1/OdysseyDecomp
synced 2026-04-23 09:04:21 +00:00
Area: Implement MoveArea2D (#949)
This commit is contained in:
parent
cf148f369e
commit
f6329cb6d1
|
|
@ -1093,43 +1093,43 @@ Area/MoveArea2D.o:
|
|||
- offset: 0x005f48
|
||||
size: 84
|
||||
label: _ZN10MoveArea2DC2EPKc
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x005f9c
|
||||
size: 96
|
||||
label: _ZN10MoveArea2DC1EPKc
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x005ffc
|
||||
size: 244
|
||||
label: _ZN10MoveArea2D4initERKN2al12AreaInitInfoE
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x0060f0
|
||||
size: 88
|
||||
label: _ZNK10MoveArea2D13calcSnapPowerEPN4sead7Vector3IfEEPfRKS2_f
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x006148
|
||||
size: 296
|
||||
label: _ZNK10MoveArea2D17calcSnapPowerCubeEPN4sead7Vector3IfEEPfRKS2_f
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x006270
|
||||
size: 276
|
||||
label: _ZNK10MoveArea2D21calcSnapPowerCylinderEPN4sead7Vector3IfEEPfRKS2_f
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x006384
|
||||
size: 296
|
||||
label: _ZNK10MoveArea2D17calcSnapPowerDiskEPN4sead7Vector3IfEEPfRKS2_f
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x0064ac
|
||||
size: 500
|
||||
label: _ZNK10MoveArea2D14calcGravityDirEPN4sead7Vector3IfEEPfRKS2_
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x0066a0
|
||||
size: 56
|
||||
label: _ZNK10MoveArea2D15calcGravityYDirEPN4sead7Vector3IfEEPf
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
- offset: 0x0066d8
|
||||
size: 260
|
||||
label: _ZNK10MoveArea2D29calcGravityCylinderCenterAxisEPN4sead7Vector3IfEEPfRKS2_b
|
||||
status: NotDecompiled
|
||||
status: Matching
|
||||
Area/NpcForceMaterialCodeArea.o:
|
||||
'.text':
|
||||
- offset: 0x0067dc
|
||||
|
|
|
|||
182
src/Area/MoveArea2D.cpp
Normal file
182
src/Area/MoveArea2D.cpp
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
#include "Area/MoveArea2D.h"
|
||||
|
||||
#include "Library/Area/AreaInitInfo.h"
|
||||
#include "Library/Area/AreaObjUtil.h"
|
||||
#include "Library/Base/StringUtil.h"
|
||||
#include "Library/Math/MathUtil.h"
|
||||
#include "Library/Placement/PlacementFunction.h"
|
||||
|
||||
MoveArea2D::MoveArea2D(const char* name) : al::AreaObj(name) {}
|
||||
|
||||
void MoveArea2D::init(const al::AreaInitInfo& info) {
|
||||
al::AreaObj::init(info);
|
||||
al::tryGetAreaObjArg(&mSurfaceDistance, this, "SurfaceDistance");
|
||||
al::tryGetAreaObjArg(&mGravityOffset, this, "GravityOffset");
|
||||
|
||||
const char* shapeName = nullptr;
|
||||
alPlacementFunction::tryGetModelName(&shapeName, info);
|
||||
|
||||
SnapGravityType gravityType = SnapGravityType::Default;
|
||||
al::tryGetAreaObjArg((s32*)&gravityType, this, "SnapGravityType");
|
||||
|
||||
if (al::isEqualString(shapeName, "AreaCubeBase")) {
|
||||
mShapeType = ShapeType::CubeBase;
|
||||
} else if (al::isEqualString(shapeName, "AreaCylinder")) {
|
||||
mShapeType = ShapeType::Cylinder;
|
||||
} else if (al::isEqualString(shapeName, "AreaCylinderCenter")) {
|
||||
switch (gravityType) {
|
||||
case SnapGravityType::Default:
|
||||
case SnapGravityType::Reverse:
|
||||
mShapeType = ShapeType::CylinderCenterReverse;
|
||||
break;
|
||||
case SnapGravityType::Normal:
|
||||
mShapeType = ShapeType::CylinderCenter;
|
||||
break;
|
||||
default:
|
||||
mShapeType = ShapeType::CylinderCenterReverse;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
bool MoveArea2D::calcSnapPower(sead::Vector3f* outDir, f32* outPower, const sead::Vector3f& pos,
|
||||
f32 surfaceDistance) const {
|
||||
switch (mShapeType) {
|
||||
case ShapeType::CubeBase:
|
||||
return calcSnapPowerCube(outDir, outPower, pos, surfaceDistance);
|
||||
case ShapeType::Cylinder:
|
||||
return calcSnapPowerCylinder(outDir, outPower, pos, surfaceDistance);
|
||||
case ShapeType::CylinderCenter:
|
||||
return calcSnapPowerDisk(outDir, outPower, pos, surfaceDistance);
|
||||
case ShapeType::CylinderCenterReverse:
|
||||
return calcSnapPowerDisk(outDir, outPower, pos, surfaceDistance);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MoveArea2D::calcSnapPowerDisk(sead::Vector3f* outDir, f32* outPower, const sead::Vector3f& pos,
|
||||
f32 surfaceDistance) const {
|
||||
const sead::Matrix34f& mtx = getAreaMtx();
|
||||
sead::Vector3f axis = mtx.getBase(1);
|
||||
sead::Vector3f diff = mtx.getTranslation() - pos;
|
||||
|
||||
f32 distance = axis.dot(diff);
|
||||
|
||||
f32 power;
|
||||
if (al::isNearZeroOrLess(distance)) {
|
||||
*outDir = -axis;
|
||||
power = sead::Mathf::abs(distance) - surfaceDistance;
|
||||
} else {
|
||||
*outDir = axis;
|
||||
power = sead::Mathf::abs(distance) + surfaceDistance;
|
||||
}
|
||||
|
||||
if (!al::isNearZeroOrGreater(power)) {
|
||||
outDir->negate();
|
||||
power = -power;
|
||||
}
|
||||
|
||||
*outPower = power;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MoveArea2D::calcSnapPowerCube(sead::Vector3f* outDir, f32* outPower, const sead::Vector3f& pos,
|
||||
f32 surfaceDistance) const {
|
||||
const sead::Matrix34f& mtx = getAreaMtx();
|
||||
sead::Vector3f axis = mtx.getBase(2);
|
||||
sead::Vector3f diff = mtx.getTranslation() - pos;
|
||||
|
||||
f32 distance = axis.dot(diff);
|
||||
|
||||
f32 power;
|
||||
if (al::isNearZeroOrLess(distance)) {
|
||||
*outDir = -axis;
|
||||
power = sead::Mathf::abs(distance) - surfaceDistance;
|
||||
} else {
|
||||
*outDir = axis;
|
||||
power = sead::Mathf::abs(distance) + surfaceDistance;
|
||||
}
|
||||
|
||||
if (!al::isNearZeroOrGreater(power)) {
|
||||
outDir->negate();
|
||||
power = -power;
|
||||
}
|
||||
|
||||
*outPower = power;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MoveArea2D::calcSnapPowerCylinder(sead::Vector3f* dirH, f32* outPower,
|
||||
const sead::Vector3f& pos, f32 surfaceDistance) const {
|
||||
const sead::Matrix34f& mtx = getAreaMtx();
|
||||
sead::Vector3f offH = mtx.getTranslation();
|
||||
offH -= pos;
|
||||
sead::Vector3f upAxis;
|
||||
mtx.getBase(upAxis, 1);
|
||||
|
||||
al::verticalizeVec(&offH, upAxis, offH);
|
||||
|
||||
if (!al::tryNormalizeOrZero(dirH, offH))
|
||||
return false;
|
||||
|
||||
f32 delta = offH.length() - surfaceDistance;
|
||||
|
||||
if (!al::isNearZeroOrGreater(delta)) {
|
||||
dirH->negate();
|
||||
delta = -delta;
|
||||
}
|
||||
|
||||
*outPower = delta;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MoveArea2D::calcGravityDir(sead::Vector3f* outDir, f32* outDist,
|
||||
const sead::Vector3f& pos) const {
|
||||
switch (mShapeType) {
|
||||
case ShapeType::CubeBase:
|
||||
return calcGravityYDir(outDir, outDist);
|
||||
case ShapeType::Cylinder:
|
||||
return calcGravityYDir(outDir, outDist);
|
||||
case ShapeType::CylinderCenter:
|
||||
return calcGravityCylinderCenterAxis(outDir, outDist, pos, false);
|
||||
case ShapeType::CylinderCenterReverse:
|
||||
return calcGravityCylinderCenterAxis(outDir, outDist, pos, true);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MoveArea2D::calcGravityYDir(sead::Vector3f* outDir, f32* outDist) const {
|
||||
const sead::Matrix34f& mtx = getAreaMtx();
|
||||
mtx.getBase(*outDir, 1);
|
||||
outDir->negate();
|
||||
*outDist = 1.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MoveArea2D::calcGravityCylinderCenterAxis(sead::Vector3f* dirH, f32* outDist,
|
||||
const sead::Vector3f& pos, bool isReverse) const {
|
||||
const sead::Matrix34f& mtx = getAreaMtx();
|
||||
sead::Vector3f offH = mtx.getTranslation();
|
||||
offH -= pos;
|
||||
|
||||
*outDist = offH.length();
|
||||
|
||||
sead::Vector3f upAxis;
|
||||
mtx.getBase(upAxis, 1);
|
||||
al::verticalizeVec(&offH, upAxis, offH);
|
||||
|
||||
if (!al::tryNormalizeOrZero(dirH, offH)) {
|
||||
*outDist = 0.0f;
|
||||
*dirH = {0.0f, 0.0f, 0.0f};
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isReverse)
|
||||
dirH->negate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -6,23 +6,40 @@
|
|||
|
||||
class MoveArea2D : public al::AreaObj {
|
||||
public:
|
||||
enum class ShapeType { Cube = 1, Cylinder, CylinderCenter, Disk };
|
||||
enum class ShapeType {
|
||||
None = 0,
|
||||
CubeBase = 1,
|
||||
Cylinder = 2,
|
||||
CylinderCenter = 3,
|
||||
CylinderCenterReverse = 4,
|
||||
};
|
||||
|
||||
enum class SnapGravityType {
|
||||
Default = 0,
|
||||
Normal = 1,
|
||||
Reverse = 2,
|
||||
};
|
||||
|
||||
MoveArea2D(const char* name);
|
||||
|
||||
void init(const al::AreaInitInfo& info) override;
|
||||
|
||||
bool calcGravityCylinderCenterAxis(sead::Vector3f*, f32*, const sead::Vector3f&, bool) const;
|
||||
bool calcGravityDir(sead::Vector3f*, f32*, const sead::Vector3f&) const;
|
||||
bool calcGravityYDir(sead::Vector3f*, f32*) const;
|
||||
bool calcGravityCylinderCenterAxis(sead::Vector3f* dirH, f32* outDist,
|
||||
const sead::Vector3f& pos, bool isReverse) const;
|
||||
bool calcGravityDir(sead::Vector3f* outDir, f32* outDist, const sead::Vector3f& pos) const;
|
||||
bool calcGravityYDir(sead::Vector3f* outDir, f32* outDist) const;
|
||||
|
||||
bool calcSnapPower(sead::Vector3f*, f32*, const sead::Vector3f&, f32);
|
||||
bool calcSnapPowerCube(sead::Vector3f*, f32*, const sead::Vector3f&, f32);
|
||||
bool calcSnapPowerCylinder(sead::Vector3f*, f32*, const sead::Vector3f&, f32);
|
||||
bool calcSnapPowerDisk(sead::Vector3f*, f32*, const sead::Vector3f&, f32);
|
||||
bool calcSnapPower(sead::Vector3f* outDir, f32* outPower, const sead::Vector3f& pos,
|
||||
f32 surfaceDistance) const;
|
||||
bool calcSnapPowerCube(sead::Vector3f* outDir, f32* outPower, const sead::Vector3f& pos,
|
||||
f32 surfaceDistance) const;
|
||||
bool calcSnapPowerCylinder(sead::Vector3f* dirH, f32* outPower, const sead::Vector3f& pos,
|
||||
f32 surfaceDistance) const;
|
||||
bool calcSnapPowerDisk(sead::Vector3f* outDir, f32* outPower, const sead::Vector3f& pos,
|
||||
f32 surfaceDistance) const;
|
||||
|
||||
private:
|
||||
ShapeType mShapeType;
|
||||
f32 mSurfaceDistance;
|
||||
f32 mGravityOffset;
|
||||
ShapeType mShapeType = ShapeType::None;
|
||||
f32 mSurfaceDistance = 0.0f;
|
||||
f32 mGravityOffset = 0.0f;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue