A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
KartObject.cc
1#include "KartObject.hh"
2
3#include "game/kart/KartParam.hh"
4#include "game/kart/KartSub.hh"
5#include "game/kart/KartSuspension.hh"
6#include "game/kart/KartTire.hh"
7
8#include "game/field/ObjectCollisionKart.hh"
9
10#include "game/render/KartModel.hh"
11
12#include "game/system/RaceConfig.hh"
13#include "game/system/RaceManager.hh"
14
15namespace Kinoko::Kart {
16
18KartObject::KartObject(KartParam *param) {
19 m_pointers.param = param;
20}
21
23KartObject::~KartObject() {
24 EGG::egg_delete(m_pointers.param);
25 EGG::egg_delete(m_pointers.body);
26 EGG::egg_delete(m_pointers.sub);
27 EGG::egg_delete(m_pointers.model);
28 EGG::egg_delete(m_pointers.objectCollisionKart);
29
30 for (auto *susp : m_pointers.suspensions) {
31 EGG::egg_delete(susp);
32 }
33
34 for (auto *tire : m_pointers.tires) {
35 EGG::egg_delete(tire);
36 }
37}
38
40void KartObject::createTires() {
41 constexpr u16 BSP_WHEEL_INDICES[8] = {0, 0, 1, 1, 2, 2, 3, 3};
42 constexpr KartSuspensionPhysics::TireType X_MIRRORED_TIRE[8] = {
43 KartSuspensionPhysics::TireType::Kart,
44 KartSuspensionPhysics::TireType::KartReflected,
45 KartSuspensionPhysics::TireType::Kart,
46 KartSuspensionPhysics::TireType::KartReflected,
47 KartSuspensionPhysics::TireType::Kart,
48 KartSuspensionPhysics::TireType::KartReflected,
49 KartSuspensionPhysics::TireType::Kart,
50 KartSuspensionPhysics::TireType::KartReflected,
51 };
52
53 auto bodyType = m_pointers.param->stats().body;
54 u32 tireCount = m_pointers.param->tireCount();
55
57 tireCount = 4;
58 }
59
60 for (u16 wheelIdx = 0, i = 0; i < tireCount; ++i) {
61 if (bodyType == KartParam::Stats::Body::Three_Wheel_Kart && i == 0) {
62 continue;
63 }
64
65 u16 bspWheelIdx = BSP_WHEEL_INDICES[i];
66 KartSuspensionPhysics::TireType tireType = X_MIRRORED_TIRE[i];
67
68 KartSuspension *sus = EGG::egg_new<KartSuspension>();
69 KartTire *tire = (bspWheelIdx == 0) ? EGG::egg_new<KartTireFront>(tireType, bspWheelIdx) :
70 EGG::egg_new<KartTire>(tireType, bspWheelIdx);
71
72 m_pointers.suspensions.push_back(sus);
73 m_pointers.tires.push_back(tire);
74
75 sus->init(wheelIdx++, tireType, bspWheelIdx);
76 }
77}
78
80KartBody *KartObject::createBody(KartPhysics *physics) {
81 return EGG::egg_new<KartBodyKart>(physics);
82}
83
85void KartObject::init() {
86 prepareTiresAndSuspensions();
87 createSub();
88 auto *physics = KartPhysics::Create(*m_pointers.param);
89 auto *body = createBody(physics);
90 body->init(m_pointers.param->kartDisp(), m_pointers.param->bikeDisp());
91 m_pointers.body = body;
92 createTires();
93 for (u16 tireIdx = 0; tireIdx < m_pointers.param->tireCount(); ++tireIdx) {
94 m_pointers.tires[tireIdx]->init(tireIdx);
95 }
96 m_pointers.objectCollisionKart = EGG::egg_new<Field::ObjectCollisionKart>();
97}
98
100void KartObject::initImpl() {
101 sub()->initAABB(m_pointers, this);
102 sub()->init();
103 objectCollisionKart()->init(param()->playerIdx());
104}
105
109 EGG::Vector3f euler_angles_deg, position;
110
111 System::RaceManager::Instance()->findKartStartPoint(position, euler_angles_deg);
112 move()->setInitialPhysicsValues(position, euler_angles_deg);
113}
114
116void KartObject::prepareTiresAndSuspensions() {
117 constexpr u16 LOCAL_20[4] = {2, 1, 1, 1};
118 constexpr u16 LOCAL_28[4] = {2, 1, 1, 2};
119
120 const BSP &rBsp = m_pointers.param->bsp();
121 const KartParam::Stats::Body bodyWheels = m_pointers.param->stats().body;
122 u16 wheelCount = 0;
123
124 if (rBsp.wheels[0].enable != 0) {
125 wheelCount += LOCAL_20[static_cast<u16>(bodyWheels)];
126 }
127 if (rBsp.wheels[1].enable != 0) {
128 wheelCount += LOCAL_28[static_cast<u16>(bodyWheels)];
129 }
130 if (rBsp.wheels[2].enable != 0) {
131 wheelCount += LOCAL_20[static_cast<u16>(bodyWheels)];
132 }
133 if (rBsp.wheels[3].enable != 0) {
134 wheelCount += LOCAL_28[static_cast<u16>(bodyWheels)];
135 }
136
137 m_pointers.param->setTireCount(wheelCount);
138 m_pointers.param->setSuspCount(wheelCount);
139
140 m_pointers.tires.reserve(wheelCount);
141 m_pointers.suspensions.reserve(wheelCount);
142}
143
145void KartObject::createSub() {
146 m_pointers.sub = EGG::egg_new<KartSub>();
147 m_pointers.sub->createSubsystems(m_pointers.param->isBike(), m_pointers.param->stats());
148}
149
151void KartObject::createModel() {
152 s_proxyList.clear();
153
154 if (isBike()) {
155 m_pointers.model = EGG::egg_new<Render::KartModelBike>();
156 } else {
157 m_pointers.model = EGG::egg_new<Render::KartModelKart>();
158 }
159
160 ApplyAll(&m_pointers);
161
162 m_pointers.model->init();
163}
164
166void KartObject::calcSub() {
167 sub()->calcPass0();
168}
169
171void KartObject::calc() {
172 sub()->calcPass1();
173 model()->calc();
174}
175
176const KartAccessor *KartObject::accessor() const {
177 return &m_pointers;
178}
179
181KartObject *KartObject::Create(Character character, Vehicle vehicle, u8 playerIdx) {
182 s_proxyList.clear();
183
184 KartParam *param = EGG::egg_new<KartParam>(character, vehicle, playerIdx);
185
186 KartObject *object = nullptr;
187 if (vehicle < Vehicle::Standard_Bike_S) {
188 object = EGG::egg_new<KartObject>(param);
189 } else {
190 object = EGG::egg_new<KartObjectBike>(param);
191 }
192
193 object->init();
194 object->m_pointers.sub->copyPointers(object->m_pointers);
195
196 // Applies a valid pointer to all of the proxies we create
197 ApplyAll(&object->m_pointers);
198
199 for (u16 i = 0; i < object->suspCount(); ++i) {
200 object->suspension(i)->initPhysics();
201 }
202
203 for (u16 i = 0; i < object->tireCount(); ++i) {
204 object->tire(i)->initBsp();
205 }
206
207 return object;
208}
209
211KartObjectBike::KartObjectBike(KartParam *param) : KartObject(param) {}
212
214KartObjectBike::~KartObjectBike() = default;
215
217KartBody *KartObjectBike::createBody(KartPhysics *physics) {
218 if (m_pointers.param->isVehicleRelativeBike()) {
219 return EGG::egg_new<KartBodyQuacker>(physics);
220 } else {
221 return EGG::egg_new<KartBodyBike>(physics);
222 }
223}
224
226void KartObjectBike::createTires() {
227 for (u16 wheelIdx = 0; wheelIdx < m_pointers.param->suspCount(); ++wheelIdx) {
228 KartSuspension *sus = nullptr;
229 KartTire *tire = nullptr;
230
231 if (wheelIdx == 0 || wheelIdx == 2) {
232 sus = EGG::egg_new<KartSuspensionFrontBike>();
233 tire = EGG::egg_new<KartTireFrontBike>(KartSuspensionPhysics::TireType::Bike, 0);
234 } else {
235 sus = EGG::egg_new<KartSuspensionRearBike>();
236 tire = EGG::egg_new<KartTireRearBike>(KartSuspensionPhysics::TireType::Bike, 1);
237 }
238
239 m_pointers.suspensions.push_back(sus);
240 m_pointers.tires.push_back(tire);
241
242 sus->init(wheelIdx, KartSuspensionPhysics::TireType::Bike, wheelIdx);
243 }
244}
245} // namespace Kinoko::Kart
static std::list< KartObjectProxy *, EGG::Allocator< KartObjectProxy * > > s_proxyList
List of all KartObjectProxy children.
static void ApplyAll(const KartAccessor *pointers)
For all proxies in the static list, synchronizes all pointers to the KartAccessor.
The highest level abstraction for a kart.
Definition KartObject.hh:11
void prepare()
Sets the initial position and rotation of the kart based off the current track.
Houses stats regarding a given character/vehicle combo.
Definition KartParam.hh:51
Manages the lifecycle of KartDynamics, handles moving floors and trick rotation.
TireType
Every other kart tire is a mirror of the first. Bikes do not leverage this.
Pertains to kart-related functionality.
A 3D float vector.
Definition Vector.hh:107
Shared between classes who inherit KartObjectProxy so they can access one another.
Body
The body style of the vehicle. Basically the number of wheels.
Definition KartParam.hh:81
@ Three_Wheel_Kart
Used by Blue Falcon.
Definition KartParam.hh:85