Library/Movement: Implement WheelMovement (#754)

This commit is contained in:
Narr the Reg 2025-10-24 10:16:53 -06:00 committed by GitHub
parent bf48978446
commit 6de13a8b6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 144 additions and 35 deletions

View file

@ -264957,27 +264957,27 @@ Library/Movement/WheelMovement.o:
- offset: 0x956f18
size: 264
label: _ZN2al13WheelMovement10receiveMsgEPNS_9LiveActorEPKNS_9SensorMsgEPNS_9HitSensorES7_
status: NotDecompiled
status: Matching
- offset: 0x957020
size: 128
label: _ZN2al13WheelMovement6updateEPNS_9LiveActorE
status: NotDecompiled
status: Matching
- offset: 0x9570a0
size: 552
label: _ZN2al13WheelMovement12updateRotateEv
status: NotDecompiled
status: Matching
- offset: 0x9572c8
size: 124
label: _ZN2al13WheelMovement23updateActorPoseAndTransEPNS_9LiveActorE
status: NotDecompiled
status: Matching
- offset: 0x957344
size: 100
label: _ZN2al13WheelMovement5resetEv
status: NotDecompiled
status: Matching
- offset: 0x9573a8
size: 192
label: _ZN2al13WheelMovement5resetEPNS_9LiveActorE
status: NotDecompiled
status: Matching
- offset: 0x957468
size: 36
label: _ZN2al13WheelMovementD0Ev

View file

@ -51,7 +51,7 @@ void WheelMapParts::init(const ActorInitInfo& info) {
void WheelMapParts::control() {
sead::Vector3f moveDir = mWheelMovement->getMoveDir();
if (mWheelMovement->get_50() < 0.0f)
if (mWheelMovement->deltaAngle() < 0.0f)
moveDir *= -1;
makeMtxUpFrontPos(&mSurfaceEffectMtx, sead::Vector3f::ey, moveDir, getTrans(this));
@ -106,24 +106,24 @@ void WheelMapParts::appearAndSetStart() {
void WheelMapParts::exeWait() {
mWheelMovement->update(this);
if (mWheelMovement->get_66())
if (mWheelMovement->isInvertDirection())
startHitReaction(this, "端点接触");
if (!isNearZero(mWheelMovement->get_48(), 0.2f))
if (!isNearZero(mWheelMovement->nextDeltaAngle(), 0.2f))
startNerveAction(this, "Move");
}
void WheelMapParts::exeMove() {
mWheelMovement->update(this);
if (mWheelMovement->get_66())
if (mWheelMovement->isInvertDirection())
startHitReaction(this, "端点接触");
f32 fVar3 = mWheelMovement->get_48();
if (isNearZero(fVar3, 0.2f))
f32 nextDeltaAngle = mWheelMovement->nextDeltaAngle();
if (isNearZero(nextDeltaAngle, 0.2f))
startNerveAction(this, "Wait");
else
tryHoldSeWithParam(this, "Rotate", sead::Mathf::abs(fVar3), "回転速度");
tryHoldSeWithParam(this, "Rotate", sead::Mathf::abs(nextDeltaAngle), "回転速度");
}
void WheelMapParts::exeAssistStop() {

View file

@ -1,5 +1,8 @@
#include "Library/Movement/WheelMovement.h"
#include "Library/LiveActor/ActorMovementFunction.h"
#include "Library/LiveActor/ActorPoseUtil.h"
#include "Library/LiveActor/ActorSensorUtil.h"
#include "Library/LiveActor/LiveActor.h"
#include "Library/Math/MathUtil.h"
#include "Library/Placement/PlacementFunction.h"
@ -13,11 +16,11 @@ WheelMovement::WheelMovement(LiveActor* actor, const ActorInitInfo& info)
tryGetArg(&mMoveEndDegree, info, "MoveEndDegree");
tryGetArg(&mNoRotateWidth, info, "NoRotateWidth");
getQuat(&_20, info);
_10 = _20;
getQuat(&mInitialActorQuat, info);
mActorQuat = mInitialActorQuat;
sead::Vector3f localRotateAxis = sead::Vector3f::ex;
calcQuatLocalAxis(&localRotateAxis, _20, (s32)mRotateAxis);
calcQuatLocalAxis(&localRotateAxis, mInitialActorQuat, (s32)mRotateAxis);
mMoveDir.setCross(localRotateAxis, sead::Vector3f::ey);
if (isNearZero(mMoveDir))
@ -25,18 +28,124 @@ WheelMovement::WheelMovement(LiveActor* actor, const ActorInitInfo& info)
if (isExistRail(actor)) {
setSyncRailToNearestPos(actor);
_64 = true;
mIsOnRail = true;
mIsRailPlusDir = isRailPlusDir(actor, mMoveDir);
f32 railProgress = getRailCoord(actor) / getRailTotalLength(actor);
_5c = railProgress;
_60 = railProgress;
mRailProgress = railProgress;
mInitialRailProgress = railProgress;
if (mIsRailPlusDir)
_44 = railProgress * mMoveEndDegree;
mWheelAngle = railProgress * mMoveEndDegree;
else
_44 = -(railProgress * mMoveEndDegree);
mWheelAngle = -(railProgress * mMoveEndDegree);
rotateQuatLocalDirDegree(&_10, _20, (s32)mRotateAxis, modf(_44 + 360.0f, 360.0f) + 0.0f);
rotateQuatLocalDirDegree(&mActorQuat, mInitialActorQuat, (s32)mRotateAxis,
modf(mWheelAngle + 360.0f, 360.0f) + 0.0f);
}
}
bool WheelMovement::receiveMsg(LiveActor* actor, const SensorMsg* message, HitSensor* other,
HitSensor* self) {
if (isMsgFloorTouch(message)) {
sead::Vector3f pos;
if (isMySensor(self, actor))
pos = getSensorPos(other);
else
pos = getActorTrans(self);
f32 width = normalizeAbs(mMoveDir.dot(pos - getTrans(actor)), mNoRotateWidth,
mNoRotateWidth + 50.0f);
mRotateWidth += isMsgEnemyFloorTouch(message) ? width * 0.9f : width;
return true;
}
return false;
}
void WheelMovement::update(LiveActor* actor) {
updateRotate();
updateActorPoseAndTrans(actor);
}
void WheelMovement::updateRotate() {
mRotateWidth = sead::Mathf::clamp(mRotateWidth, -1.25f, 1.25f);
mDeltaAngle = (mRotateWidth * mRotateAccel * 0.001f + mNextDeltaAngle) * 0.97f;
mWheelAngle = mWheelAngle + mDeltaAngle;
mNextDeltaAngle = mDeltaAngle;
mIsInvertDirection = false;
if (mIsOnRail) {
if (mIsRailPlusDir) {
if (mWheelAngle < 0.0f) {
mWheelAngle = 0.0f;
if (mNextDeltaAngle < 0.0f) {
if (mNextDeltaAngle < mRotateAccel * -0.001f)
mIsInvertDirection = true;
else
mNextDeltaAngle = 0.0f;
}
}
if (mWheelAngle > mMoveEndDegree) {
mWheelAngle = mMoveEndDegree;
if (mNextDeltaAngle > 0.0f) {
if (mNextDeltaAngle > mRotateAccel * 0.001f)
mIsInvertDirection = true;
else
mNextDeltaAngle = 0.0f;
}
}
mRailProgress = mWheelAngle / mMoveEndDegree;
} else {
if (mWheelAngle < -mMoveEndDegree) {
mWheelAngle = -mMoveEndDegree;
if (mNextDeltaAngle < 0.0f) {
if (mNextDeltaAngle < mRotateAccel * -0.001f)
mIsInvertDirection = true;
else
mNextDeltaAngle = 0.0f;
}
}
if (mWheelAngle > 0.0f) {
mWheelAngle = 0.0f;
if (mNextDeltaAngle > 0.0f) {
if (mNextDeltaAngle > mRotateAccel * 0.001f)
mIsInvertDirection = true;
else
mNextDeltaAngle = 0.0f;
}
}
mRailProgress = -mWheelAngle / mMoveEndDegree;
}
if (mIsInvertDirection)
mNextDeltaAngle *= -0.2f;
} else {
mWheelAngle = modf(mWheelAngle + 360.0f, 360.0f) + 0.0f;
}
mRotateWidth = 0.0f;
rotateQuatLocalDirDegree(&mActorQuat, mInitialActorQuat, (s32)mRotateAxis,
modf(mWheelAngle + 360.0f, 360.0f) + 0.0f);
}
void WheelMovement::updateActorPoseAndTrans(LiveActor* actor) {
setQuat(actor, mActorQuat);
if (isExistRail(actor))
setSyncRailToCoord(actor, mRailProgress * getRailTotalLength(actor));
}
void WheelMovement::reset() {
mWheelAngle = 0.0f;
mNextDeltaAngle = 0.0f;
mRotateWidth = 0.0f;
mIsInvertDirection = false;
mRailProgress = mInitialRailProgress;
rotateQuatLocalDirDegree(&mActorQuat, mInitialActorQuat, (s32)mRotateAxis,
modf(360.0f, 360.0f) + 0.0f);
}
void WheelMovement::reset(LiveActor* actor) {
reset();
updateActorPoseAndTrans(actor);
resetPosition(actor);
}
} // namespace al

View file

@ -25,29 +25,29 @@ public:
const sead::Vector3f& getMoveDir() const { return mMoveDir; }
f32 get_48() const { return _48; }
f32 nextDeltaAngle() const { return mNextDeltaAngle; }
f32 get_50() const { return _50; }
f32 deltaAngle() const { return mDeltaAngle; }
bool get_66() const { return _66; }
bool isInvertDirection() const { return mIsInvertDirection; }
private:
sead::Quatf _10 = sead::Quatf::unit;
sead::Quatf _20 = sead::Quatf::unit;
sead::Quatf mActorQuat = sead::Quatf::unit;
sead::Quatf mInitialActorQuat = sead::Quatf::unit;
sead::Vector3f mMoveDir = sead::Vector3f::ez;
Axis mRotateAxis = Axis::None;
f32 mMoveEndDegree = 360.0f;
f32 _44 = 0.0f;
f32 _48 = 0.0f;
f32 mWheelAngle = 0.0f;
f32 mNextDeltaAngle = 0.0f;
f32 mRotateAccel = 20.0f;
f32 _50 = 0.0f;
f32 _54 = 0.0f;
f32 mDeltaAngle = 0.0f;
f32 mRotateWidth = 0.0f;
f32 mNoRotateWidth = 25.0f;
f32 _5c = 0.0f;
f32 _60 = 0.0f;
bool _64 = false;
f32 mRailProgress = 0.0f;
f32 mInitialRailProgress = 0.0f;
bool mIsOnRail = false;
bool mIsRailPlusDir = true;
bool _66 = false;
bool mIsInvertDirection = false;
};
static_assert(sizeof(WheelMovement) == 0x68);