A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectPoihana.hh
1#pragma once
2
3#include "game/field/StateManager.hh"
4#include "game/field/obj/ObjectCollidable.hh"
5
6namespace Kinoko::Field {
7
8class ObjectPoihanaBase : public ObjectCollidable, virtual public StateManager {
9public:
10 ObjectPoihanaBase(const System::MapdataGeoObj &params);
11 ~ObjectPoihanaBase() override;
12
13 void init() override;
14
16 void calc() override {
17 StateManager::calc();
18 }
19
21 [[nodiscard]] u32 loadFlags() const override {
22 return 1;
23 }
24
25protected:
26 enum class WalkState {
27 NeedTarget = 0,
28 HasTarget = 1,
29 };
30
31 WalkState m_walkState;
32 EGG::Vector3f m_curRot;
33 EGG::Vector3f m_up;
34 EGG::Matrix34f m_workMat;
35 EGG::Vector3f m_accel;
36 EGG::Vector3f m_extVel;
37 EGG::Vector3f m_vel;
38 EGG::Vector3f m_floorNrm;
40 f32 m_radius;
41 EGG::Vector3f m_targetPos;
42 EGG::Vector3f m_dir;
43 EGG::Vector3f m_initPos;
45};
46
48class ObjectPoihana final : public ObjectPoihanaBase {
49public:
50 ObjectPoihana(const System::MapdataGeoObj &params);
51 ~ObjectPoihana() override;
52
53 void init() override;
54
56 void calc() override {
57 ObjectPoihanaBase::calc();
58 }
59
60private:
61 void enterStateStub() {}
62
64 void enterState0() {
65 m_walkState = WalkState::NeedTarget;
66 }
67
68 void calcStateStub() {}
69
71 void calcState0And1() {
72 calcStep();
73 calcPosAndCollision();
74 calcOrthonormalBasis();
75 setTransform(m_workMat);
76 }
77
79 [[nodiscard]] EGG::Vector3f curPos() const {
80 return m_workMat.base(3);
81 }
82
83 void calcCurRot(f32 t);
84 void calcOrthonormalBasis();
85 void calcCollision();
86 void calcStep();
87 void calcDir();
88 void calcUp();
89
91 [[nodiscard]] EGG::Vector3f collisionPos() const {
92 return curPos() + m_floorNrm * m_heightOffset;
93 }
94
96 void calcPosAndCollision() {
97 m_extVel += m_accel;
98 m_workMat.setBase(3, m_workMat.base(3) + (m_extVel + m_vel));
99 calcCollision();
100 }
101
103 [[nodiscard]] static EGG::Vector3f Project(const EGG::Vector3f &v0, const EGG::Vector3f &v1) {
104 f32 scale = (v0.z * v1.z + (v0.x * v1.x + v0.y * v1.y)) /
105 EGG::Mathf::fma(v1.z, v1.z, v1.x * v1.x + v1.y * v1.y);
106
107 return v1 * scale;
108 }
109
110 static constexpr std::array<StateManagerEntry, 8> STATE_ENTRIES = {{
111 {StateEntry<ObjectPoihana, &ObjectPoihana::enterState0, &ObjectPoihana::calcState0And1>(
112 0)},
113 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
114 &ObjectPoihana::calcState0And1>(1)},
115 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
116 &ObjectPoihana::calcStateStub>(2)},
117 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
118 &ObjectPoihana::calcStateStub>(3)},
119 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
120 &ObjectPoihana::calcStateStub>(4)},
121 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
122 &ObjectPoihana::calcStateStub>(5)},
123 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
124 &ObjectPoihana::calcStateStub>(6)},
125 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
126 &ObjectPoihana::calcStateStub>(7)},
127 }};
128};
129
130} // namespace Kinoko::Field
A 3 x 4 matrix.
Definition Matrix.hh:10
EGG::Vector3f m_targetVel
Derived from m_targetPos and current position.
f32 m_heightOffset
Accounts for cataquack leg height.
static constexpr f32 fma(f32 x, f32 y, f32 z)
Fused multiply-add operation.
Definition Math.hh:33
Pertains to collision.
A 3D float vector.
Definition Vector.hh:107