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 Field {
7
8class ObjectPoihanaBase : public ObjectCollidable, virtual public StateManager {
9public:
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:
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 calcPosAndTransform();
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 calcPosAndTransform() {
97 m_flags.setBit(eFlags::Matrix);
98 m_transform = m_workMat;
99 m_pos = m_workMat.base(3);
100 }
101
103 void calcPosAndCollision() {
104 m_extVel += m_accel;
105 m_workMat.setBase(3, m_workMat.base(3) + (m_extVel + m_vel));
106 calcCollision();
107 }
108
110 [[nodiscard]] static EGG::Vector3f Project(const EGG::Vector3f &v0, const EGG::Vector3f &v1) {
111 f32 scale = (v0.z * v1.z + (v0.x * v1.x + v0.y * v1.y)) /
112 EGG::Mathf::fma(v1.z, v1.z, v1.x * v1.x + v1.y * v1.y);
113
114 return v1 * scale;
115 }
116
117 static constexpr std::array<StateManagerEntry, 8> STATE_ENTRIES = {{
118 {StateEntry<ObjectPoihana, &ObjectPoihana::enterState0, &ObjectPoihana::calcState0And1>(
119 0)},
120 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
121 &ObjectPoihana::calcState0And1>(1)},
122 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
123 &ObjectPoihana::calcStateStub>(2)},
124 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
125 &ObjectPoihana::calcStateStub>(3)},
126 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
127 &ObjectPoihana::calcStateStub>(4)},
128 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
129 &ObjectPoihana::calcStateStub>(5)},
130 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
131 &ObjectPoihana::calcStateStub>(6)},
132 {StateEntry<ObjectPoihana, &ObjectPoihana::enterStateStub,
133 &ObjectPoihana::calcStateStub>(7)},
134 }};
135};
136
137} // namespace Field
A 3 x 4 matrix.
Definition Matrix.hh:8
void setBase(size_t col, const Vector3f &base)
Sets one column of a matrix.
Definition Matrix.cc:194
Vector3f base(size_t col) const
Get a particular column from a matrix.
Definition Matrix.hh:72
EGG::Vector3f m_targetVel
Derived from m_targetPos and current position.
f32 m_heightOffset
Accounts for cataquack leg height.
Represents the cataquacks on GCN Peach Beach.
Base class that represents different "states" for an object.
static f32 fma(f32 x, f32 y, f32 z)
Fused multiply-add operation.
Definition Math.hh:77
Pertains to collision.
constexpr TBitFlag< T, E > & setBit(Es... es)
Sets the corresponding bits for the provided enum values.
Definition BitFlag.hh:62
A 3D float vector.
Definition Vector.hh:88