1#include "Player/PlayerActionVelocityControl.h"
2
3#include "Library/LiveActor/ActorMovementFunction.h"
4#include "Library/LiveActor/ActorPoseUtil.h"
5#include "Library/Math/MathUtil.h"
6
7#include "Player/PlayerActionFunction.h"
8#include "Util/PlayerCollisionUtil.h"
9
10PlayerActionVelocityControl::PlayerActionVelocityControl(al::LiveActor* actor,
11 const IUsePlayerCollision* collision)
12 : mActor(actor) {
13 sead::Vector3f negGravity = -al::getGravity(actor);
14 if (collision)
15 rs::calcGroundNormalOrGravityDir(&negGravity, actor, collision);
16
17 sead::Vector3f up;
18 al::calcUpDir(up: &up, actor: mActor);
19 al::normalize(vec: &up);
20
21 sead::Vector3f front;
22 al::calcFrontDir(front: &front, actor: mActor);
23 al::alongVectorNormalH(&front, front, up, negGravity);
24 al::normalize(vec: &front);
25
26 mUp = negGravity;
27 mSide.setCross(a: negGravity, b: front);
28 al::normalize(vec: &mSide);
29
30 al::parallelizeVec(&mVelocityFront, front, al::getVelocity(actor));
31 al::parallelizeVec(&mVelocitySide, mSide, al::getVelocity(actor));
32 mVelocityUp = al::getVelocity(actor) - mVelocityFront - mVelocitySide;
33}
34
35void PlayerActionVelocityControl::calcFrontBrake(f32 decel) {
36 mVelocityFront *= decel;
37}
38
39void PlayerActionVelocityControl::calcSideVelocityLimit(const sead::Vector3f& moveInput,
40 f32 brakeSideAccel, f32 brakeSideRate,
41 f32 maxSideSpeed) {
42 f32 stickPow = PlayerActionFunction::calcStickPow(moveInput.dot(t: mSide));
43 if (al::isNearZero(value: stickPow, tolerance: 0.01f)) {
44 mVelocitySide *= brakeSideRate;
45 return;
46 }
47
48 mVelocitySide += (stickPow * brakeSideAccel) * mSide;
49 al::limitLength(out: &mVelocitySide, vec: mVelocitySide, limit: maxSideSpeed);
50}
51
52void PlayerActionVelocityControl::calcSideBrake(f32 decel) {
53 mVelocitySide *= decel;
54}
55
56void PlayerActionVelocityControl::calcTrample(f32 downVel) {
57 al::verticalizeVec(out: &mVelocityUp, vertical: al::getGravity(actor: mActor), vec: mVelocityUp);
58 mVelocityUp += al::getGravity(actor: mActor) * downVel;
59}
60
61void PlayerActionVelocityControl::calcSnap(const sead::Vector3f& snapDir, f32 snapDistance) {
62 // requires to be this explicit to match. Both += and vector operations mismatch.
63 mVelocityUp.x = (snapDir.x * snapDistance) + mVelocityUp.x;
64 mVelocityUp.y = (snapDir.y * snapDistance) + mVelocityUp.y;
65 mVelocityUp.z = (snapDir.z * snapDistance) + mVelocityUp.z;
66}
67
68void PlayerActionVelocityControl::calcOnGround(const sead::Vector3f& groundNormal) {
69 al::verticalizeVec(out: &mVelocityFront, vertical: groundNormal, vec: mVelocityFront);
70 al::verticalizeVec(out: &mVelocitySide, vertical: groundNormal, vec: mVelocitySide);
71 al::verticalizeVec(out: &mVelocityUp, vertical: groundNormal, vec: mVelocityUp);
72}
73
74void PlayerActionVelocityControl::apply() {
75 *al::getVelocityPtr(actor: mActor) = mVelocityFront + mVelocitySide + mVelocityUp;
76}
77