A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectDrivableDirector.cc
1#include "ObjectDrivableDirector.hh"
2
3namespace Field {
4
6void ObjectDrivableDirector::init() {
7 for (auto *&obj : m_objects) {
8 obj->init();
9 obj->calcModel();
10 }
11}
12
14void ObjectDrivableDirector::calc() {
15 for (auto *&obj : m_calcObjects) {
16 obj->calc();
17 }
18
19 for (auto *&obj : m_calcObjects) {
20 obj->calcModel();
21 }
22}
23
25void ObjectDrivableDirector::addObject(ObjectDrivable *obj) {
26 if (obj->loadFlags() & 1) {
27 m_calcObjects.push_back(obj);
28 }
29
30 m_objects.push_back(obj);
31}
32
39
41bool ObjectDrivableDirector::checkSpherePartial(f32 radius, const EGG::Vector3f &pos,
42 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
43 KCLTypeMask *maskOut, u32 timeOffset) {
44 if (m_objects.empty()) {
45 return false;
46 }
47
48 bool hasCollision = false;
49 auto *boxColMgr = BoxColManager::Instance();
50 boxColMgr->search(radius, pos, eBoxColFlag::Drivable);
51
52 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
53 hasCollision |=
54 obj->checkSpherePartial(radius, pos, prevPos, mask, info, maskOut, timeOffset);
55 }
56
57 return hasCollision;
58}
59
61bool ObjectDrivableDirector::checkSpherePartialPush(f32 radius, const EGG::Vector3f &pos,
62 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
63 KCLTypeMask *maskOut, u32 timeOffset) {
64 if (m_objects.empty()) {
65 return false;
66 }
67
68 bool hasCollision = false;
69 auto *boxColMgr = BoxColManager::Instance();
70 boxColMgr->search(radius, pos, eBoxColFlag::Drivable);
71
72 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
73 hasCollision |=
74 obj->checkSpherePartialPush(radius, pos, prevPos, mask, info, maskOut, timeOffset);
75 }
76
77 return hasCollision;
78}
79
81bool ObjectDrivableDirector::checkSphereFull(f32 radius, const EGG::Vector3f &pos,
82 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut,
83 u32 timeOffset) {
84 if (m_objects.empty()) {
85 return false;
86 }
87
88 bool hasCollision = false;
89 auto *boxColMgr = BoxColManager::Instance();
90 boxColMgr->search(radius, pos, eBoxColFlag::Drivable);
91
92 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
93 hasCollision |= obj->checkSphereFull(radius, pos, prevPos, mask, info, maskOut, timeOffset);
94 }
95
96 return hasCollision;
97}
98
100bool ObjectDrivableDirector::checkSphereFullPush(f32 radius, const EGG::Vector3f &pos,
101 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut,
102 u32 timeOffset) {
103 if (m_objects.empty()) {
104 return false;
105 }
106
107 bool hasCollision = false;
108 auto *boxColMgr = BoxColManager::Instance();
109 boxColMgr->search(radius, pos, eBoxColFlag::Drivable);
110
111 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
112 hasCollision |=
113 obj->checkSphereFullPush(radius, pos, prevPos, mask, info, maskOut, timeOffset);
114 }
115
116 return hasCollision;
117}
118
120bool ObjectDrivableDirector::checkSphereCachedPartial(f32 radius, const EGG::Vector3f &pos,
121 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
122 KCLTypeMask *maskOut, u32 timeOffset) {
123 if (m_objects.empty()) {
124 return false;
125 }
126
127 auto *boxColMgr = BoxColManager::Instance();
128
129 if (boxColMgr->isSphereInSpatialCache(radius, pos, eBoxColFlag::Drivable)) {
130 boxColMgr->resetIterators();
131
132 bool hasCollision = false;
133 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
134 hasCollision |= obj->checkSphereCachedPartial(radius, pos, prevPos, mask, info, maskOut,
135 timeOffset);
136 }
137
138 return hasCollision;
139 }
140
141 return checkSpherePartial(radius, pos, prevPos, mask, info, maskOut, timeOffset);
142}
143
145bool ObjectDrivableDirector::checkSphereCachedPartialPush(f32 radius, const EGG::Vector3f &pos,
146 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfoPartial *info,
147 KCLTypeMask *maskOut, u32 timeOffset) {
148 if (m_objects.empty()) {
149 return false;
150 }
151
152 auto *boxColMgr = BoxColManager::Instance();
153
154 if (boxColMgr->isSphereInSpatialCache(radius, pos, eBoxColFlag::Drivable)) {
155 boxColMgr->resetIterators();
156
157 bool hasCollision = false;
158 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
159 hasCollision |= obj->checkSphereCachedPartialPush(radius, pos, prevPos, mask, info,
160 maskOut, timeOffset);
161 }
162
163 return hasCollision;
164 }
165
166 return checkSpherePartialPush(radius, pos, prevPos, mask, info, maskOut, timeOffset);
167}
168
170bool ObjectDrivableDirector::checkSphereCachedFullPush(f32 radius, const EGG::Vector3f &pos,
171 const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info, KCLTypeMask *maskOut,
172 u32 timeOffset) {
173 if (m_objects.empty()) {
174 return false;
175 }
176
177 auto *boxColMgr = BoxColManager::Instance();
178
179 if (boxColMgr->isSphereInSpatialCache(radius, pos, eBoxColFlag::Drivable)) {
180 bool hasCollision = false;
181 boxColMgr->resetIterators();
182
183 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
184 hasCollision |= obj->checkSphereCachedFullPush(radius, pos, prevPos, mask, info,
185 maskOut, timeOffset);
186 }
187
188 return hasCollision;
189 }
190
191 return checkSphereFullPush(radius, pos, prevPos, mask, info, maskOut, timeOffset);
192}
193
195void ObjectDrivableDirector::colNarScLocal(f32 radius, const EGG::Vector3f &pos, KCLTypeMask mask,
196 u32 timeOffset) {
197 if (m_objects.empty()) {
198 return;
199 }
200
201 auto *boxColMgr = BoxColManager::Instance();
202 boxColMgr->search(radius, pos, eBoxColFlag::Drivable);
203
204 while (ObjectDrivable *obj = boxColMgr->getNextDrivable()) {
205 obj->narrScLocal(radius, pos, mask, timeOffset);
206 }
207}
208
210ObjectDrivableDirector *ObjectDrivableDirector::CreateInstance() {
211 ASSERT(!s_instance);
212 s_instance = new ObjectDrivableDirector;
213 return s_instance;
214}
215
217void ObjectDrivableDirector::DestroyInstance() {
218 ASSERT(s_instance);
219 auto *instance = s_instance;
220 s_instance = nullptr;
221 delete instance;
222}
223
225ObjectDrivableDirector::ObjectDrivableDirector() : m_obakeManager(nullptr) {}
226
228ObjectDrivableDirector::~ObjectDrivableDirector() {
229 if (s_instance) {
230 s_instance = nullptr;
231 WARN("ObjectDrivableDirector instance not explicitly handled!");
232 }
233
234 for (auto *&obj : m_objects) {
235 delete obj;
236 }
237}
238
239ObjectDrivableDirector *ObjectDrivableDirector::s_instance = nullptr;
240
241} // namespace Field
std::vector< ObjectDrivable * > m_objects
All objects live here.
ObjectObakeManager * m_obakeManager
Manages rGV2 blocks and spatial indexing.
void createObakeManager(const System::MapdataGeoObj &params)
Creates the rGV2 block manager. Also implicitly adds the block represented by params.
std::vector< ObjectDrivable * > m_calcObjects
Objects needing calc() live here too.
The manager class for SNES Ghost Valley 2 blocks.
Pertains to collision.
A 3D float vector.
Definition Vector.hh:87