1#include "CollisionDirector.hh"
3#include "game/field/ObjectDrivableDirector.hh"
8void CollisionDirector::checkCourseColNarrScLocal(f32 radius,
const EGG::Vector3f &pos,
9 KCLTypeMask mask, u32 timeOffset) {
10 CourseColMgr::Instance()->scaledNarrowScopeLocal(1.0f, radius,
nullptr, pos, mask);
11 ObjectDrivableDirector::Instance()->colNarScLocal(radius, pos, mask, timeOffset);
15bool CollisionDirector::checkSpherePartialPush(f32 radius,
const EGG::Vector3f &pos,
16 const EGG::Vector3f &prevPos, KCLTypeMask flags, CollisionInfoPartial *info,
17 KCLTypeMask *typeMaskOut, u32 timeOffset) {
23 *typeMaskOut = KCL_NONE;
26 auto *courseColMgr = CourseColMgr::Instance();
27 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
29 noBounceInfo->bbox.setZero();
30 noBounceInfo->dist = std::numeric_limits<f32>::min();
33 bool colliding = flags &&
34 courseColMgr->checkSpherePartialPush(1.0f, radius,
nullptr, pos, prevPos, flags, info,
37 colliding |= ObjectDrivableDirector::Instance()->checkSpherePartialPush(radius, pos, prevPos,
38 flags, info, typeMaskOut, timeOffset);
42 info->tangentOff = info->bbox.min + info->bbox.max;
46 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
50 courseColMgr->clearNoBounceWallInfo();
56bool CollisionDirector::checkSphereFull(f32 radius,
const EGG::Vector3f &v0,
57 const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
64 *pFlagsOut = KCL_NONE;
67 auto *courseColMgr = CourseColMgr::Instance();
68 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
70 noBounceInfo->bbox.setZero();
71 noBounceInfo->dist = std::numeric_limits<f32>::min();
74 bool colliding = flags &&
75 courseColMgr->checkSphereFull(1.0f, radius,
nullptr, v0, v1, flags, pInfo, pFlagsOut);
77 colliding |= ObjectDrivableDirector::Instance()->checkSphereFull(radius, v0, v1, flags, pInfo,
78 pFlagsOut, timeOffset);
82 pInfo->tangentOff = pInfo->bbox.min + pInfo->bbox.max;
86 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
90 courseColMgr->clearNoBounceWallInfo();
96bool CollisionDirector::checkSphereFullPush(f32 radius,
const EGG::Vector3f &v0,
97 const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
104 resetCollisionEntries(pFlagsOut);
107 auto *courseColMgr = CourseColMgr::Instance();
108 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
110 noBounceInfo->bbox.setZero();
111 noBounceInfo->dist = std::numeric_limits<f32>::min();
114 bool colliding = flags &&
115 courseColMgr->checkSphereFullPush(1.0f, radius,
nullptr, v0, v1, flags, pInfo,
118 colliding |= ObjectDrivableDirector::Instance()->checkSphereFullPush(radius, v0, v1, flags,
119 pInfo, pFlagsOut, timeOffset);
123 pInfo->tangentOff = pInfo->bbox.min + pInfo->bbox.max;
127 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
131 courseColMgr->clearNoBounceWallInfo();
137bool CollisionDirector::checkSphereCachedPartial(f32 radius,
const EGG::Vector3f &pos,
138 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
139 KCLTypeMask *typeMaskOut, u32 timeOffset) {
141 info->bbox.setZero();
145 *typeMaskOut = KCL_NONE;
148 auto *courseColMgr = CourseColMgr::Instance();
149 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
151 noBounceInfo->bbox.setZero();
152 noBounceInfo->dist = std::numeric_limits<f32>::min();
155 bool colliding = courseColMgr->checkSphereCachedPartial(1.0f, radius,
nullptr, pos, prevPos,
156 typeMask, info, typeMaskOut);
158 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartial(radius, pos, prevPos,
159 typeMask, info, typeMaskOut, timeOffset);
163 info->tangentOff = info->bbox.min + info->bbox.max;
167 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
171 courseColMgr->clearNoBounceWallInfo();
177bool CollisionDirector::checkSphereCachedPartialPush(f32 radius,
const EGG::Vector3f &pos,
178 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
179 KCLTypeMask *typeMaskOut, u32 timeOffset) {
181 info->bbox.setZero();
185 resetCollisionEntries(typeMaskOut);
188 auto *courseColMgr = CourseColMgr::Instance();
189 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
191 noBounceInfo->bbox.setZero();
192 noBounceInfo->dist = std::numeric_limits<f32>::min();
195 bool colliding = courseColMgr->checkSphereCachedPartialPush(1.0f, radius,
nullptr, pos, prevPos,
196 typeMask, info, typeMaskOut);
198 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartialPush(radius, pos,
199 prevPos, typeMask, info, typeMaskOut, timeOffset);
201 courseColMgr->clearNoBounceWallInfo();
207bool CollisionDirector::checkSphereCachedFullPush(f32 radius,
const EGG::Vector3f &pos,
208 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfo *colInfo,
209 KCLTypeMask *typeMaskOut, u32 timeOffset) {
215 resetCollisionEntries(typeMaskOut);
218 auto *courseColMgr = CourseColMgr::Instance();
219 auto *info = courseColMgr->noBounceWallInfo();
221 info->bbox.setZero();
222 info->dist = std::numeric_limits<f32>::min();
225 bool colliding = courseColMgr->checkSphereCachedFullPush(1.0f, radius,
nullptr, pos, prevPos,
226 typeMask, colInfo, typeMaskOut);
228 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedFullPush(radius, pos, prevPos,
229 typeMask, colInfo, typeMaskOut, timeOffset);
233 colInfo->tangentOff = colInfo->bbox.min + colInfo->bbox.max;
237 info->tangentOff = info->bbox.min + info->bbox.max;
241 courseColMgr->clearNoBounceWallInfo();
247void CollisionDirector::resetCollisionEntries(KCLTypeMask *ptr) {
249 m_collisionEntryCount = 0;
250 m_closestCollisionEntry =
nullptr;
261 *typeMask = *typeMask | kclTypeBit;
262 if (m_collisionEntryCount >= m_entries.size()) {
263 m_collisionEntryCount = m_entries.size() - 1;
266 m_entries[m_collisionEntryCount++] =
CollisionEntry(kclTypeBit, attribute, dist);
274 m_closestCollisionEntry =
nullptr;
275 f32 minDist = -std::numeric_limits<f32>::min();
277 for (
size_t i = 0; i < m_collisionEntryCount; ++i) {
278 const auto &entry = m_entries[i];
279 u32 typeMask = entry.typeMask & type;
280 if (typeMask != 0 && entry.dist > minDist) {
281 minDist = entry.dist;
282 m_closestCollisionEntry = &entry;
286 return !!m_closestCollisionEntry;
297void CollisionDirector::DestroyInstance() {
299 auto *instance = s_instance;
300 s_instance =
nullptr;
305CollisionDirector::CollisionDirector() {
306 m_collisionEntryCount = 0;
307 m_closestCollisionEntry =
nullptr;
308 CourseColMgr::CreateInstance()->init();
312CollisionDirector::~CollisionDirector() {
314 s_instance =
nullptr;
315 WARN(
"CollisionDirector instance not explicitly handled!");
318 CourseColMgr::DestroyInstance();
321CollisionDirector *CollisionDirector::s_instance =
nullptr;
Manages the caching of colliding KCL triangles and exposes queries for collision checks.
bool findClosestCollisionEntry(KCLTypeMask *typeMask, KCLTypeMask type)
Finds the closest KCL triangle out of the list of tris we are colliding with.
void pushCollisionEntry(f32 dist, KCLTypeMask *typeMask, KCLTypeMask kclTypeBit, CollisionAttribute attribute)
Called when we find a piece of collision we are touching and want to save it temporarily.