A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectCarA.cc
1#include "ObjectCarA.hh"
2
3#include "game/field/ObjectCollisionCylinder.hh"
4
5#include "game/kart/KartCollide.hh"
6#include "game/kart/KartObject.hh"
7
8namespace Field {
9
11ObjectCarA::ObjectCarA(const System::MapdataGeoObj &params)
12 : ObjectCollidable(params), StateManager(this, STATE_ENTRIES),
13 m_finalVel(static_cast<f32>(params.setting(0))),
14 m_accel(static_cast<f32>(params.setting(1)) / 10.0f),
15 m_stopTime(static_cast<u32>(params.setting(2))) {}
16
18ObjectCarA::~ObjectCarA() = default;
19
21void ObjectCarA::init() {
22 constexpr f32 RADIUS = 400.0f;
23
24 m_railInterpolator->init(0, 0);
25
26 // Time to reach final velocity
27 f32 finalTime = m_finalVel / m_accel;
28 m_cruiseTime =
29 (m_railInterpolator->railLength() - finalTime * m_accel * finalTime) / m_finalVel;
30
31 setMatrixFromOrthonormalBasisAndPos(m_railInterpolator->curTangentDir());
32
33 m_flags.setBit(eFlags::Position);
34 m_pos = m_railInterpolator->curPos();
35 m_currVel = 0.0f;
36 m_motionState = MotionState::Accelerating;
37 m_changingDir = false;
38 m_currUp = EGG::Vector3f::ey;
39 m_currTangent = m_railInterpolator->curTangentDir();
40 resize(RADIUS, 0.0f);
41 m_nextStateId = 0;
42}
43
45void ObjectCarA::calc() {
46 StateManager::calc();
47
48 m_railInterpolator->setCurrVel(m_currVel);
49
50 auto status = m_railInterpolator->calc();
51 m_changingDir = (status == RailInterpolator::Status::ChangingDirection);
52
53 calcPos();
54}
55
57void ObjectCarA::createCollision() {
58 constexpr f32 RADIUS = 210.0f;
59 constexpr f32 HEIGHT = 200.0f;
60
61 m_collision = new ObjectCollisionCylinder(RADIUS, HEIGHT, collisionCenter());
62}
63
65void ObjectCarA::calcCollisionTransform() {
66 ObjectCollisionBase *objCol = collision();
67 if (!objCol) {
68 return;
69 }
70
71 calcTransform();
72
74 SetRotTangentHorizontal(mat, m_transform.base(2), EGG::Vector3f::ey);
75 mat.setBase(3, m_transform.base(3) + 50.0f * m_transform.base(1));
76
77 objCol->transform(mat, m_scale,
78 -m_railInterpolator->curTangentDir() * m_railInterpolator->getCurrVel());
79}
80
82Kart::Reaction ObjectCarA::onCollision(Kart::KartObject *kartObj, Kart::Reaction reactionOnKart,
83 Kart::Reaction /*reactionOnObj*/, EGG::Vector3f & /*hitDepth*/) {
84 return kartObj->speedRatioCapped() < 0.5f ? Kart::Reaction::WallAllSpeed : reactionOnKart;
85}
86
88void ObjectCarA::enterStop() {
89 m_currVel = 0.0f;
90}
91
93void ObjectCarA::enterCruising() {
94 m_currVel = m_finalVel;
95}
96
98void ObjectCarA::calcStop() {
99 if (m_currentFrame > m_stopTime) {
100 m_motionState = MotionState::Accelerating;
101 m_currentStateId = 1;
102 }
103}
104
106void ObjectCarA::calcAccel() {
107 if (m_motionState == MotionState::Accelerating) {
108 m_currVel += m_accel;
109
110 if (m_currVel > m_finalVel) {
111 m_currVel = m_finalVel;
112 m_motionState = MotionState::Cruising;
113 m_nextStateId = 2;
114 }
115 } else if (m_motionState == MotionState::Decelerating) {
116 // The cruising time might've had decimals and needed to end early.
117 // If we undershot it, keep a velocity of 0.01f so we can reach the end.
118 m_currVel = std::max(0.01f, m_currVel - m_accel);
119
120 if (m_changingDir) {
121 m_currVel = 0.0f;
122
123 if (m_railInterpolator->isMovementDirectionForward()) {
124 m_railInterpolator->init(0.0f, 0);
125 }
126
127 m_motionState = MotionState::Cruising;
128 m_nextStateId = 0;
129 }
130 }
131}
132
134void ObjectCarA::calcCruising() {
135 // We might've had decimals, better to undershoot the cruising time and handle it in decel
136 if (static_cast<f32>(m_currentFrame) > m_cruiseTime - 1.0f) {
137 m_motionState = MotionState::Decelerating;
138 m_nextStateId = 1;
139 }
140}
141
143void ObjectCarA::calcPos() {
144 m_currUp = Interpolate(0.1f, m_currUp, EGG::Vector3f::ey);
145 m_currUp.normalise2();
146
147 setMatrixTangentTo(m_currUp, m_currTangent);
148
149 m_pos = m_railInterpolator->curPos();
150 m_flags.setBit(eFlags::Position);
151}
152
153} // 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:181
The highest level abstraction for a kart.
Definition KartObject.hh:11
Pertains to collision.
A 3D float vector.
Definition Vector.hh:88