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,
23 *pFlagsOut = 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->checkSphereFull(1.0f, radius,
nullptr, v0, v1, flags, pInfo, pFlagsOut);
36 colliding |= ObjectDrivableDirector::Instance()->checkSphereFull(radius, v0, v1, flags, pInfo,
37 pFlagsOut, timeOffset);
41 pInfo->tangentOff = pInfo->bbox.min + pInfo->bbox.max;
45 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
49 courseColMgr->clearNoBounceWallInfo();
55bool CollisionDirector::checkSphereFullPush(f32 radius,
const EGG::Vector3f &v0,
56 const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
63 resetCollisionEntries(pFlagsOut);
66 auto *courseColMgr = CourseColMgr::Instance();
67 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
69 noBounceInfo->bbox.setZero();
70 noBounceInfo->dist = std::numeric_limits<f32>::min();
73 bool colliding = flags &&
74 courseColMgr->checkSphereFullPush(1.0f, radius,
nullptr, v0, v1, flags, pInfo,
77 colliding |= ObjectDrivableDirector::Instance()->checkSphereFullPush(radius, v0, v1, flags,
78 pInfo, 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::checkSphereCachedPartial(f32 radius,
const EGG::Vector3f &pos,
97 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
98 KCLTypeMask *typeMaskOut,
u32 timeOffset) {
100 info->bbox.setZero();
104 *typeMaskOut = KCL_NONE;
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 = courseColMgr->checkSphereCachedPartial(1.0f, radius,
nullptr, pos, prevPos,
115 typeMask, info, typeMaskOut);
117 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartial(radius, pos, prevPos,
118 typeMask, info, typeMaskOut, timeOffset);
122 info->tangentOff = info->bbox.min + info->bbox.max;
126 noBounceInfo->tangentOff = noBounceInfo->bbox.min + noBounceInfo->bbox.max;
130 courseColMgr->clearNoBounceWallInfo();
136bool CollisionDirector::checkSphereCachedPartialPush(f32 radius,
const EGG::Vector3f &pos,
137 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
138 KCLTypeMask *typeMaskOut,
u32 timeOffset) {
140 info->bbox.setZero();
144 resetCollisionEntries(typeMaskOut);
147 auto *courseColMgr = CourseColMgr::Instance();
148 auto *noBounceInfo = courseColMgr->noBounceWallInfo();
150 noBounceInfo->bbox.setZero();
151 noBounceInfo->dist = std::numeric_limits<f32>::min();
154 bool colliding = courseColMgr->checkSphereCachedPartialPush(1.0f, radius,
nullptr, pos, prevPos,
155 typeMask, info, typeMaskOut);
157 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartialPush(radius, pos,
158 prevPos, typeMask, info, typeMaskOut, timeOffset);
160 courseColMgr->clearNoBounceWallInfo();
166bool CollisionDirector::checkSphereCachedFullPush(f32 radius,
const EGG::Vector3f &pos,
167 const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfo *colInfo,
168 KCLTypeMask *typeMaskOut,
u32 timeOffset) {
174 resetCollisionEntries(typeMaskOut);
177 auto *courseColMgr = CourseColMgr::Instance();
178 auto *info = courseColMgr->noBounceWallInfo();
180 info->bbox.setZero();
181 info->dist = std::numeric_limits<f32>::min();
184 bool colliding = courseColMgr->checkSphereCachedFullPush(1.0f, radius,
nullptr, pos, prevPos,
185 typeMask, colInfo, typeMaskOut);
187 colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedFullPush(radius, pos, prevPos,
188 typeMask, colInfo, typeMaskOut, timeOffset);
192 colInfo->tangentOff = colInfo->bbox.min + colInfo->bbox.max;
196 info->tangentOff = info->bbox.min + info->bbox.max;
200 courseColMgr->clearNoBounceWallInfo();
206void CollisionDirector::resetCollisionEntries(KCLTypeMask *ptr) {
208 m_collisionEntryCount = 0;
209 m_closestCollisionEntry =
nullptr;
220 *typeMask = *typeMask | kclTypeBit;
221 if (m_collisionEntryCount >= m_entries.size()) {
222 m_collisionEntryCount = m_entries.size() - 1;
225 m_entries[m_collisionEntryCount++] =
CollisionEntry(kclTypeBit, attribute, dist);
233 m_closestCollisionEntry =
nullptr;
234 f32 minDist = -std::numeric_limits<f32>::min();
236 for (
size_t i = 0; i < m_collisionEntryCount; ++i) {
237 const auto &entry = m_entries[i];
238 u32 typeMask = entry.typeMask & type;
239 if (typeMask != 0 && entry.dist > minDist) {
240 minDist = entry.dist;
241 m_closestCollisionEntry = &entry;
245 return !!m_closestCollisionEntry;
256void CollisionDirector::DestroyInstance() {
258 auto *instance = s_instance;
259 s_instance =
nullptr;
264CollisionDirector::CollisionDirector() {
265 m_collisionEntryCount = 0;
266 m_closestCollisionEntry =
nullptr;
267 CourseColMgr::CreateInstance()->init();
271CollisionDirector::~CollisionDirector() {
273 s_instance =
nullptr;
274 WARN(
"CollisionDirector instance not explicitly handled!");
277 CourseColMgr::DestroyInstance();
280CollisionDirector *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.