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), m_finalVel(static_cast<f32>(params.setting(0))),
13 m_accel(static_cast<f32>(params.setting(1)) / 10.0f),
14 m_stopTime(static_cast<u32>(params.setting(2))) {}
15
17ObjectCarA::~ObjectCarA() = default;
18
20void ObjectCarA::init() {
21 constexpr f32 RADIUS = 400.0f;
22
23 m_railInterpolator->init(0, 0);
24
25 // Time to reach final velocity
26 f32 finalTime = m_finalVel / m_accel;
27 m_cruiseTime =
28 (m_railInterpolator->railLength() - finalTime * m_accel * finalTime) / m_finalVel;
29
30 setMatrixFromOrthonormalBasisAndPos(m_railInterpolator->curTangentDir());
31
32 m_flags.setBit(eFlags::Position);
33 m_pos = m_railInterpolator->curPos();
34 m_currVel = 0.0f;
35 m_motionState = MotionState::Accelerating;
36 m_changingDir = false;
37 m_currUp = EGG::Vector3f::ey;
38 m_currTangent = m_railInterpolator->curTangentDir();
39 resize(RADIUS, 0.0f);
40 m_nextStateId = 0;
41}
42
44void ObjectCarA::calc() {
45 StateManager::calc();
46
47 m_railInterpolator->setCurrVel(m_currVel);
48
49 auto status = m_railInterpolator->calc();
50 m_changingDir = (status == RailInterpolator::Status::ChangingDirection);
51
52 calcPos();
53}
54
56void ObjectCarA::createCollision() {
57 constexpr f32 RADIUS = 210.0f;
58 constexpr f32 HEIGHT = 200.0f;
59
60 m_collision = new ObjectCollisionCylinder(RADIUS, HEIGHT, collisionCenter());
61}
62
64void ObjectCarA::calcCollisionTransform() {
65 ObjectCollisionBase *objCol = collision();
66 if (!objCol) {
67 return;
68 }
69
70 calcTransform();
71
73 SetRotTangentHorizontal(mat, m_transform.base(2), EGG::Vector3f::ey);
74 mat.setBase(3, m_transform.base(3) + 50.0f * m_transform.base(1));
75
76 objCol->transform(mat, m_scale,
77 -m_railInterpolator->curTangentDir() * m_railInterpolator->getCurrVel());
78}
79
81Kart::Reaction ObjectCarA::onCollision(Kart::KartObject *kartObj, Kart::Reaction reactionOnKart,
82 Kart::Reaction /*reactionOnObj*/, EGG::Vector3f & /*hitDepth*/) {
83 return kartObj->speedRatioCapped() < 0.5f ? Kart::Reaction::WallAllSpeed : reactionOnKart;
84}
85
87void ObjectCarA::enterStop() {
88 m_currVel = 0.0f;
89}
90
92void ObjectCarA::enterCruising() {
93 m_currVel = m_finalVel;
94}
95
97void ObjectCarA::calcStop() {
98 if (m_currentFrame > m_stopTime) {
99 m_motionState = MotionState::Accelerating;
100 m_currentStateId = 1;
101 }
102}
103
105void ObjectCarA::calcAccel() {
106 if (m_motionState == MotionState::Accelerating) {
107 m_currVel += m_accel;
108
109 if (m_currVel > m_finalVel) {
110 m_currVel = m_finalVel;
111 m_motionState = MotionState::Cruising;
112 m_nextStateId = 2;
113 }
114 } else if (m_motionState == MotionState::Decelerating) {
115 // The cruising time might've had decimals and needed to end early.
116 // If we undershot it, keep a velocity of 0.01f so we can reach the end.
117 m_currVel = std::max(0.01f, m_currVel - m_accel);
118
119 if (m_changingDir) {
120 m_currVel = 0.0f;
121
122 if (m_railInterpolator->isMovementDirectionForward()) {
123 m_railInterpolator->init(0.0f, 0);
124 }
125
126 m_motionState = MotionState::Cruising;
127 m_nextStateId = 0;
128 }
129 }
130}
131
133void ObjectCarA::calcCruising() {
134 // We might've had decimals, better to undershoot the cruising time and handle it in decel
135 if (static_cast<f32>(m_currentFrame) > m_cruiseTime - 1.0f) {
136 m_motionState = MotionState::Decelerating;
137 m_nextStateId = 1;
138 }
139}
140
142void ObjectCarA::calcPos() {
143 m_currUp = Interpolate(0.1f, m_currUp, EGG::Vector3f::ey);
144 m_currUp.normalise2();
145
146 setMatrixTangentTo(m_currUp, m_currTangent);
147
148 m_pos = m_railInterpolator->curPos();
149 m_flags.setBit(eFlags::Position);
150}
151
152} // 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