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 m_pointers.body = body;
91 createTires();
92 for (u16 tireIdx = 0; tireIdx < m_pointers.param->tireCount(); ++tireIdx) {
93 m_pointers.tires[tireIdx]->init(tireIdx);
94 }
95 m_pointers.objectCollisionKart = EGG::egg_new<Field::ObjectCollisionKart>();
96}
97
99void KartObject::initImpl() {
100 sub()->initAABB(m_pointers, this);
101 sub()->init();
102 objectCollisionKart()->init(param()->playerIdx());
103}
104
108 EGG::Vector3f euler_angles_deg, position;
109
110 System::RaceManager::Instance()->findKartStartPoint(position, euler_angles_deg);
111 move()->setInitialPhysicsValues(position, euler_angles_deg);
112}
113
115void KartObject::prepareTiresAndSuspensions() {
116 constexpr u16 LOCAL_20[4] = {2, 1, 1, 1};
117 constexpr u16 LOCAL_28[4] = {2, 1, 1, 2};
118
119 const BSP &rBsp = m_pointers.param->bsp();
120 const KartParam::Stats::Body bodyWheels = m_pointers.param->stats().body;
121 u16 wheelCount = 0;
122
123 if (rBsp.wheels[0].enable != 0) {
124 wheelCount += LOCAL_20[static_cast<u16>(bodyWheels)];
125 }
126 if (rBsp.wheels[1].enable != 0) {
127 wheelCount += LOCAL_28[static_cast<u16>(bodyWheels)];
128 }
129 if (rBsp.wheels[2].enable != 0) {
130 wheelCount += LOCAL_20[static_cast<u16>(bodyWheels)];
131 }
132 if (rBsp.wheels[3].enable != 0) {
133 wheelCount += LOCAL_28[static_cast<u16>(bodyWheels)];
134 }
135
136 m_pointers.param->setTireCount(wheelCount);
137 m_pointers.param->setSuspCount(wheelCount);
138}
139
141void KartObject::createSub() {
142 m_pointers.sub = EGG::egg_new<KartSub>();
143 m_pointers.sub->createSubsystems(m_pointers.param->isBike(), m_pointers.param->stats());
144}
145
147void KartObject::createModel() {
148 s_proxyList.clear();
149
150 if (isBike()) {
151 m_pointers.model = EGG::egg_new<Render::KartModelBike>();
152 } else {
153 m_pointers.model = EGG::egg_new<Render::KartModelKart>();
154 }
155
156 ApplyAll(&m_pointers);
157
158 m_pointers.model->init();
159}
160
162void KartObject::calcSub() {
163 sub()->calcPass0();
164}
165
167void KartObject::calc() {
168 sub()->calcPass1();
169 model()->calc();
170}
171
172const KartAccessor *KartObject::accessor() const {
173 return &m_pointers;
174}
175
177KartObject *KartObject::Create(Character character, Vehicle vehicle, u8 playerIdx) {
178 s_proxyList.clear();
179
180 KartParam *param = EGG::egg_new<KartParam>(character, vehicle, playerIdx);
181
182 KartObject *object = nullptr;
183 if (vehicle < Vehicle::Standard_Bike_S) {
184 object = EGG::egg_new<KartObject>(param);
185 } else {
186 object = EGG::egg_new<KartObjectBike>(param);
187 }
188
189 object->init();
190 object->m_pointers.sub->copyPointers(object->m_pointers);
191
192 // Applies a valid pointer to all of the proxies we create
193 ApplyAll(&object->m_pointers);
194
195 for (u16 i = 0; i < object->suspCount(); ++i) {
196 object->suspension(i)->initPhysics();
197 }
198
199 for (u16 i = 0; i < object->tireCount(); ++i) {
200 object->tire(i)->initBsp();
201 }
202
203 return object;
204}
205
207KartObjectBike::KartObjectBike(KartParam *param) : KartObject(param) {}
208
210KartObjectBike::~KartObjectBike() = default;
211
213KartBody *KartObjectBike::createBody(KartPhysics *physics) {
214 if (m_pointers.param->isVehicleRelativeBike()) {
215 return EGG::egg_new<KartBodyQuacker>(physics);
216 } else {
217 return EGG::egg_new<KartBodyBike>(physics);
218 }
219}
220
222void KartObjectBike::createTires() {
223 for (u16 wheelIdx = 0; wheelIdx < m_pointers.param->suspCount(); ++wheelIdx) {
224 KartSuspension *sus = nullptr;
225 KartTire *tire = nullptr;
226
227 if (wheelIdx == 0 || wheelIdx == 2) {
228 sus = EGG::egg_new<KartSuspensionFrontBike>();
229 tire = EGG::egg_new<KartTireFrontBike>(KartSuspensionPhysics::TireType::Bike, 0);
230 } else {
231 sus = EGG::egg_new<KartSuspensionRearBike>();
232 tire = EGG::egg_new<KartTireRearBike>(KartSuspensionPhysics::TireType::Bike, 1);
233 }
234
235 m_pointers.suspensions.push_back(sus);
236 m_pointers.tires.push_back(tire);
237
238 sus->init(wheelIdx, KartSuspensionPhysics::TireType::Bike, wheelIdx);
239 }
240}
241} // 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