Skip to content

Commit

Permalink
Add ObjectDrivableDirector
Browse files Browse the repository at this point in the history
  • Loading branch information
malleoz authored and vabold committed Mar 4, 2025
1 parent bf0b5dc commit 1cce1cd
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 36 deletions.
7 changes: 7 additions & 0 deletions source/egg/core/BitFlag.hh
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ struct TBitFlag {
return (bits & mask) != 0;
}

/// @brief Checks if all bits are on in the specified mask.
/// @param mask The bit mask to check.
/// @return True if all bits in the mask are on, otherwise false.
[[nodiscard]] constexpr bool onAll(T mask) const {
return (bits | mask) == bits;
}

/// @brief Checks if all bits are off in the specified mask.
/// @param mask The bit mask to check.
/// @return True if all bits in the mask are off, otherwise false.
Expand Down
18 changes: 18 additions & 0 deletions source/game/field/BoxColManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,24 @@ void BoxColManager::search(BoxColUnit *unit, const BoxColFlag &flag) {
/// @addr{0x80786B14}
void BoxColManager::search(f32 radius, const EGG::Vector3f &pos, const BoxColFlag &flag) {
searchImpl(radius, pos, flag);
resetIterators();
}

/// @addr{0x80786E60}
bool BoxColManager::isSphereInSpatialCache(f32 radius, const EGG::Vector3f &pos,
const BoxColFlag &flag) const {
if (m_cacheRadius == -1.0f) {
return false;
}

if (!m_cacheFlag.onAll(flag)) {
return false;
}

f32 radiusDiff = m_cacheRadius - radius;
EGG::Vector3f posDiff = pos - m_cachePoint;

return EGG::Mathf::abs(posDiff.x) <= radiusDiff && EGG::Mathf::abs(posDiff.z) <= radiusDiff;
}

/// @addr{0x807855DC}
Expand Down
3 changes: 3 additions & 0 deletions source/game/field/BoxColManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ public:
void search(BoxColUnit *unit, const BoxColFlag &flag);
void search(f32 radius, const EGG::Vector3f &pos, const BoxColFlag &flag);

[[nodiscard]] bool isSphereInSpatialCache(f32 radius, const EGG::Vector3f &pos,
const BoxColFlag &flag) const;

static BoxColManager *CreateInstance();
static void DestroyInstance();
[[nodiscard]] static BoxColManager *Instance();
Expand Down
62 changes: 36 additions & 26 deletions source/game/field/CollisionDirector.cc
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
#include "CollisionDirector.hh"

#include "game/field/ObjectDrivableDirector.hh"

namespace Field {

/// @addr{0x8078E4F0}
void CollisionDirector::checkCourseColNarrScLocal(f32 radius, const EGG::Vector3f &pos,
KCLTypeMask mask, u32 /*timeOffset*/) {
KCLTypeMask mask, u32 timeOffset) {
CourseColMgr::Instance()->scaledNarrowScopeLocal(1.0f, radius, nullptr, pos, mask);
ObjectDrivableDirector::Instance()->colNarScLocal(radius, pos, mask, timeOffset);
}

/// @addr{0x8078F500}
bool CollisionDirector::checkSphereFull(f32 radius, const EGG::Vector3f &v0,
const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
u32 /*timeOffset*/) {
u32 timeOffset) {
if (pInfo) {
pInfo->bbox.min = EGG::Vector3f::zero;
pInfo->bbox.max = EGG::Vector3f::zero;
Expand All @@ -32,12 +35,11 @@ bool CollisionDirector::checkSphereFull(f32 radius, const EGG::Vector3f &v0,
noBounceInfo->dist = std::numeric_limits<f32>::min();
}

bool colliding = false;
bool colliding = flags &&
courseColMgr->checkSphereFull(1.0f, radius, nullptr, v0, v1, flags, pInfo, pFlagsOut);

if (flags &&
courseColMgr->checkSphereFull(1.0f, radius, nullptr, v0, v1, flags, pInfo, pFlagsOut)) {
colliding = true;
}
colliding |= ObjectDrivableDirector::Instance()->checkSphereFull(radius, v0, v1, flags, pInfo,
pFlagsOut, timeOffset);

if (colliding) {
if (pInfo) {
Expand All @@ -57,7 +59,7 @@ bool CollisionDirector::checkSphereFull(f32 radius, const EGG::Vector3f &v0,
/// @addr{0x8078F784}
bool CollisionDirector::checkSphereFullPush(f32 radius, const EGG::Vector3f &v0,
const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
u32 /*timeOffset*/) {
u32 timeOffset) {
if (pInfo) {
pInfo->bbox.setZero();
pInfo->_50 = -std::numeric_limits<f32>::min();
Expand All @@ -77,13 +79,12 @@ bool CollisionDirector::checkSphereFullPush(f32 radius, const EGG::Vector3f &v0,
noBounceInfo->dist = std::numeric_limits<f32>::min();
}

bool colliding = false;

if (flags &&
bool colliding = flags &&
courseColMgr->checkSphereFullPush(1.0f, radius, nullptr, v0, v1, flags, pInfo,
pFlagsOut)) {
colliding = true;
}
pFlagsOut);

colliding |= ObjectDrivableDirector::Instance()->checkSphereFullPush(radius, v0, v1, flags,
pInfo, pFlagsOut, timeOffset);

if (colliding) {
if (pInfo) {
Expand All @@ -103,7 +104,7 @@ bool CollisionDirector::checkSphereFullPush(f32 radius, const EGG::Vector3f &v0,
/// @addr{0x807901F0}
bool CollisionDirector::checkSphereCachedPartial(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
KCLTypeMask *typeMaskOut, u32 timeOffset) {
if (info) {
info->bbox.setZero();
}
Expand All @@ -119,10 +120,13 @@ bool CollisionDirector::checkSphereCachedPartial(f32 radius, const EGG::Vector3f
noBounceInfo->dist = std::numeric_limits<f32>::min();
}

bool hasCourseCol = courseColMgr->checkSphereCachedPartial(1.0f, radius, nullptr, pos, prevPos,
bool colliding = courseColMgr->checkSphereCachedPartial(1.0f, radius, nullptr, pos, prevPos,
typeMask, info, typeMaskOut);

if (hasCourseCol) {
colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartial(radius, pos, prevPos,
typeMask, info, typeMaskOut, timeOffset);

if (colliding) {
if (info) {
info->tangentOff = info->bbox.min + info->bbox.max;
}
Expand All @@ -134,13 +138,13 @@ bool CollisionDirector::checkSphereCachedPartial(f32 radius, const EGG::Vector3f

courseColMgr->clearNoBounceWallInfo();

return hasCourseCol;
return colliding;
}

/// @addr{0x807903BC}
bool CollisionDirector::checkSphereCachedPartialPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfoPartial *info,
KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
KCLTypeMask *typeMaskOut, u32 timeOffset) {
if (info) {
info->bbox.setZero();
}
Expand All @@ -156,18 +160,21 @@ bool CollisionDirector::checkSphereCachedPartialPush(f32 radius, const EGG::Vect
noBounceInfo->dist = std::numeric_limits<f32>::min();
}

bool hasCourseCol = courseColMgr->checkSphereCachedPartialPush(1.0f, radius, nullptr, pos,
prevPos, typeMask, info, typeMaskOut);
bool colliding = courseColMgr->checkSphereCachedPartialPush(1.0f, radius, nullptr, pos, prevPos,
typeMask, info, typeMaskOut);

colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedPartialPush(radius, pos,
prevPos, typeMask, info, typeMaskOut, timeOffset);

courseColMgr->clearNoBounceWallInfo();

return hasCourseCol;
return colliding;
}

/// @addr{0x807907F8}
bool CollisionDirector::checkSphereCachedFullPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfo *colInfo,
KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
KCLTypeMask *typeMaskOut, u32 timeOffset) {
if (colInfo) {
colInfo->bbox.min.setZero();
colInfo->bbox.max.setZero();
Expand All @@ -188,10 +195,13 @@ bool CollisionDirector::checkSphereCachedFullPush(f32 radius, const EGG::Vector3
info->dist = std::numeric_limits<f32>::min();
}

bool hasCourseCol = courseColMgr->checkSphereCachedFullPush(1.0f, radius, nullptr, pos, prevPos,
bool colliding = courseColMgr->checkSphereCachedFullPush(1.0f, radius, nullptr, pos, prevPos,
typeMask, colInfo, typeMaskOut);

if (hasCourseCol) {
colliding |= ObjectDrivableDirector::Instance()->checkSphereCachedFullPush(radius, pos, prevPos,
typeMask, colInfo, typeMaskOut, timeOffset);

if (colliding) {
if (colInfo) {
colInfo->tangentOff = colInfo->bbox.min + colInfo->bbox.max;
}
Expand All @@ -203,7 +213,7 @@ bool CollisionDirector::checkSphereCachedFullPush(f32 radius, const EGG::Vector3

courseColMgr->clearNoBounceWallInfo();

return hasCourseCol;
return colliding;
}

/// @addr{0x807BDA7C}
Expand Down
9 changes: 9 additions & 0 deletions source/game/field/ObjectDirector.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "ObjectDirector.hh"

#include "game/field/BoxColManager.hh"
#include "game/field/ObjectDrivableDirector.hh"
#include "game/field/obj/ObjectRegistry.hh"

#include "game/kart/KartObject.hh"
Expand All @@ -15,6 +16,8 @@ void ObjectDirector::init() {
obj->init();
obj->calcModel();
}

ObjectDrivableDirector::Instance()->init();
}

/// @addr{0x8082A8F4}
Expand All @@ -26,6 +29,8 @@ void ObjectDirector::calc() {
for (auto *&obj : m_calcObjects) {
obj->calcModel();
}

ObjectDrivableDirector::Instance()->calc();
}

/// @addr{0x8082B0E8}
Expand Down Expand Up @@ -100,6 +105,8 @@ ObjectDirector *ObjectDirector::CreateInstance() {
ASSERT(!s_instance);
s_instance = new ObjectDirector;

ObjectDrivableDirector::CreateInstance();

s_instance->createObjects();

return s_instance;
Expand All @@ -111,6 +118,8 @@ void ObjectDirector::DestroyInstance() {
auto *instance = s_instance;
s_instance = nullptr;
delete instance;

ObjectDrivableDirector::DestroyInstance();
}

/// @addr{0x8082A38C}
Expand Down
Loading

0 comments on commit 1cce1cd

Please sign in to comment.