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::checkSphereFull(f32 radius,
const EGG::Vector3f &v0,
16 const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
19 pInfo->bbox.min = EGG::Vector3f::zero;
20 pInfo->bbox.max = EGG::Vector3f::zero;
21 pInfo->_50 = -std::numeric_limits<f32>::min();
22 pInfo->wallDist = -std::numeric_limits<f32>::min();
23 pInfo->floorDist = -std::numeric_limits<f32>::min();
24 pInfo->perpendicularity = 0.0f;
28 *pFlagsOut = KCL_NONE;
31 auto *courseColMgr = CourseColMgr::Instance();
32 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
34 noBounceInfo->bbox.setZero();
35 noBounceInfo->dist = std::numeric_limits<f32>::min();
38 bool colliding = flags &&
39 courseColMgr->checkSphereFull(1.0f, radius,
nullptr, v0, v1, flags, pInfo, pFlagsOut);
41 colliding |= ObjectDrivableDirector::Instance()->checkSphereFull(radius, v0, v1, flags, pInfo,
42 pFlagsOut, timeOffset);
46 pInfo->tangentOff = pInfo->bbox.min + pInfo->bbox.max;
50 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
54 courseColMgr->clearNoBounceWallInfo();
60bool CollisionDirector::checkSphereFullPush(f32 radius,
const EGG::Vector3f &v0,
61 const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
64 pInfo->bbox.setZero();
65 pInfo->_50 = -std::numeric_limits<f32>::min();
66 pInfo->wallDist = -std::numeric_limits<f32>::min();
67 pInfo->floorDist = -std::numeric_limits<f32>::min();
68 pInfo->perpendicularity = 0.0f;
72 resetCollisionEntries(pFlagsOut);
75 auto *courseColMgr = CourseColMgr::Instance();
76 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
78 noBounceInfo->bbox.setZero();
79 noBounceInfo->dist = std::numeric_limits<f32>::min();
82 bool colliding = flags &&
83 courseColMgr->checkSphereFullPush(1.0f, radius,
nullptr, v0, v1, flags, pInfo,
86 colliding |= ObjectDrivableDirector::Instance()->checkSphereFullPush(radius, v0, v1, flags,
87 pInfo, pFlagsOut, timeOffset);
91 pInfo->tangentOff = pInfo->bbox.min + pInfo->bbox.max;
95 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
99 courseColMgr->clearNoBounceWallInfo();
105bool CollisionDirector::checkSphereCachedPartial(f32 radius,
const EGG::Vector3f &pos,
106 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
107 KCLTypeMask *typeMaskOut, u32 timeOffset) {
109 info->bbox.setZero();
113 *typeMaskOut = KCL_NONE;
116 auto *courseColMgr = CourseColMgr::Instance();
117 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
119 noBounceInfo->bbox.setZero();
120 noBounceInfo->dist = std::numeric_limits<f32>::min();
123 bool colliding = courseColMgr->checkSphereCachedPartial(1.0f, radius,
nullptr, pos, prevPos,
124 typeMask, info, typeMaskOut);
126 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartial(radius, pos, prevPos,
127 typeMask, info, typeMaskOut, timeOffset);
131 info->tangentOff = info->bbox.min + info->bbox.max;
135 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
139 courseColMgr->clearNoBounceWallInfo();
145bool CollisionDirector::checkSphereCachedPartialPush(f32 radius,
const EGG::Vector3f &pos,
146 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
147 KCLTypeMask *typeMaskOut, u32 timeOffset) {
149 info->bbox.setZero();
153 resetCollisionEntries(typeMaskOut);
156 auto *courseColMgr = CourseColMgr::Instance();
157 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
159 noBounceInfo->bbox.setZero();
160 noBounceInfo->dist = std::numeric_limits<f32>::min();
163 bool colliding = courseColMgr->checkSphereCachedPartialPush(1.0f, radius,
nullptr, pos, prevPos,
164 typeMask, info, typeMaskOut);
166 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartialPush(radius, pos,
167 prevPos, typeMask, info, typeMaskOut, timeOffset);
169 courseColMgr->clearNoBounceWallInfo();
175bool CollisionDirector::checkSphereCachedFullPush(f32 radius,
const EGG::Vector3f &pos,
176 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfo *colInfo,
177 KCLTypeMask *typeMaskOut, u32 timeOffset) {
179 colInfo->bbox.min.setZero();
180 colInfo->bbox.max.setZero();
181 colInfo->_50 = -std::numeric_limits<f32>::min();
182 colInfo->wallDist = -std::numeric_limits<f32>::min();
183 colInfo->floorDist = -std::numeric_limits<f32>::min();
184 colInfo->perpendicularity = 0.0f;
188 resetCollisionEntries(typeMaskOut);
191 auto *courseColMgr = CourseColMgr::Instance();
192 auto *info = courseColMgr->noBounceWallInfo();
194 info->bbox.setZero();
195 info->dist = std::numeric_limits<f32>::min();
198 bool colliding = courseColMgr->checkSphereCachedFullPush(1.0f, radius,
nullptr, pos, prevPos,
199 typeMask, colInfo, typeMaskOut);
201 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedFullPush(radius, pos, prevPos,
202 typeMask, colInfo, typeMaskOut, timeOffset);
206 colInfo->tangentOff = colInfo->bbox.min + colInfo->bbox.max;
210 info->tangentOff = info->bbox.min + info->bbox.max;
214 courseColMgr->clearNoBounceWallInfo();
220void CollisionDirector::resetCollisionEntries(KCLTypeMask *ptr) {
222 m_collisionEntryCount = 0;
223 m_closestCollisionEntry =
nullptr;
234 *typeMask = *typeMask | kclTypeBit;
235 if (m_collisionEntryCount >= m_entries.size()) {
236 m_collisionEntryCount = m_entries.size() - 1;
239 m_entries[m_collisionEntryCount++] =
CollisionEntry(kclTypeBit, attribute, dist);
247 m_closestCollisionEntry =
nullptr;
248 f32 minDist = -std::numeric_limits<f32>::min();
250 for (
size_t i = 0; i < m_collisionEntryCount; ++i) {
251 const auto &entry = m_entries[i];
252 u32 typeMask = entry.typeMask & type;
253 if (typeMask != 0 && entry.dist > minDist) {
254 minDist = entry.dist;
255 m_closestCollisionEntry = &entry;
259 return !!m_closestCollisionEntry;
270void CollisionDirector::DestroyInstance() {
272 auto *instance = s_instance;
273 s_instance =
nullptr;
278CollisionDirector::CollisionDirector() {
279 m_collisionEntryCount = 0;
280 m_closestCollisionEntry =
nullptr;
281 CourseColMgr::CreateInstance()->init();
285CollisionDirector::~CollisionDirector() {
287 s_instance =
nullptr;
288 WARN(
"CollisionDirector instance not explicitly handled!");
291 CourseColMgr::DestroyInstance();
294CollisionDirector *CollisionDirector::s_instance =
nullptr;
Manages the caching of colliding KCL triangles and exposes queries for collision checks.
void pushCollisionEntry(f32 dist, KCLTypeMask *typeMask, KCLTypeMask kclTypeBit, u16 attribute)
Called when we find a piece of collision we are touching and want to save it temporarily.
bool findClosestCollisionEntry(KCLTypeMask *typeMask, KCLTypeMask type)
Finds the closest KCL triangle out of the list of tris we are colliding with.