Skip to content

Commit

Permalink
Add ObjectDrivable
Browse files Browse the repository at this point in the history
  • Loading branch information
malleoz authored and vabold committed Mar 1, 2025
1 parent ece0c03 commit a254940
Show file tree
Hide file tree
Showing 20 changed files with 201 additions and 88 deletions.
5 changes: 3 additions & 2 deletions source/game/field/BoxColManager.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "BoxColManager.hh"

#include "game/field/obj/ObjectCollidable.hh"
#include "game/field/obj/ObjectDrivable.hh"

#include <numeric>

Expand Down Expand Up @@ -184,8 +185,8 @@ ObjectCollidable *BoxColManager::getNextObject() {
}

/// @addr{0x80785EC4}
void *BoxColManager::getNextDrivable() {
return getNextImpl(m_nextDrivableID, eBoxColFlag::Drivable);
ObjectDrivable *BoxColManager::getNextDrivable() {
return reinterpret_cast<ObjectDrivable *>(getNextImpl(m_nextDrivableID, eBoxColFlag::Drivable));
}

/// @addr{0x80785F2C}
Expand Down
3 changes: 2 additions & 1 deletion source/game/field/BoxColManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class KartObject;
namespace Field {

class ObjectCollidable;
class ObjectDrivable;

/// @brief A bitfield that represents the state and type of a given BoxColUnit.
/// @details The lower 8 bits represent the type, while the remaining bits represent the state.
Expand Down Expand Up @@ -72,7 +73,7 @@ public:
void calc();

[[nodiscard]] ObjectCollidable *getNextObject();
[[nodiscard]] void *getNextDrivable();
[[nodiscard]] ObjectDrivable *getNextDrivable();

void resetIterators();

Expand Down
10 changes: 5 additions & 5 deletions source/game/field/CollisionDirector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void CollisionDirector::checkCourseColNarrScLocal(f32 radius, const EGG::Vector3

/// @addr{0x8078F500}
bool CollisionDirector::checkSphereFull(f32 radius, const EGG::Vector3f &v0,
const EGG::Vector3f &v1, KCLTypeMask flags, CourseColMgr::CollisionInfo *pInfo,
const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo,
KCLTypeMask *pFlagsOut, u32 /*timeOffset*/) {
if (pInfo) {
pInfo->bbox.min = EGG::Vector3f::zero;
Expand Down Expand Up @@ -56,7 +56,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, CourseColMgr::CollisionInfo *pInfo,
const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo,
KCLTypeMask *pFlagsOut, u32 /*timeOffset*/) {
if (pInfo) {
pInfo->bbox.setZero();
Expand Down Expand Up @@ -103,7 +103,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,
CourseColMgr::CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
if (info) {
info->bbox.setZero();
}
Expand Down Expand Up @@ -140,7 +140,7 @@ bool CollisionDirector::checkSphereCachedPartial(f32 radius, const EGG::Vector3f
/// @addr{0x807903BC}
bool CollisionDirector::checkSphereCachedPartialPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask,
CourseColMgr::CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
if (info) {
info->bbox.setZero();
}
Expand All @@ -166,7 +166,7 @@ bool CollisionDirector::checkSphereCachedPartialPush(f32 radius, const EGG::Vect

/// @addr{0x807907F8}
bool CollisionDirector::checkSphereCachedFullPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CourseColMgr::CollisionInfo *colInfo,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfo *colInfo,
KCLTypeMask *typeMaskOut, u32 /*timeOffset*/) {
if (colInfo) {
colInfo->bbox.min.setZero();
Expand Down
10 changes: 5 additions & 5 deletions source/game/field/CollisionDirector.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ public:
u32 timeOffset);

[[nodiscard]] bool checkSphereFull(f32 radius, const EGG::Vector3f &v0, const EGG::Vector3f &v1,
KCLTypeMask flags, CourseColMgr::CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
KCLTypeMask flags, CollisionInfo *pInfo, KCLTypeMask *pFlagsOut,
u32 timeOffset);
[[nodiscard]] bool checkSphereFullPush(f32 radius, const EGG::Vector3f &v0,
const EGG::Vector3f &v1, KCLTypeMask flags, CourseColMgr::CollisionInfo *pInfo,
const EGG::Vector3f &v1, KCLTypeMask flags, CollisionInfo *pInfo,
KCLTypeMask *pFlagsOut, u32 timeOffset);

[[nodiscard]] bool checkSphereCachedPartial(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask,
CourseColMgr::CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 timeOffset);
CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 timeOffset);
[[nodiscard]] bool checkSphereCachedPartialPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask,
CourseColMgr::CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 timeOffset);
CollisionInfoPartial *info, KCLTypeMask *typeMaskOut, u32 timeOffset);
[[nodiscard]] bool checkSphereCachedFullPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CourseColMgr::CollisionInfo *info,
const EGG::Vector3f &prevPos, KCLTypeMask typeMask, CollisionInfo *info,
KCLTypeMask *typeMaskOut, u32 timeOffset);

void resetCollisionEntries(KCLTypeMask *ptr);
Expand Down
19 changes: 0 additions & 19 deletions source/game/field/CourseColMgr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -574,25 +574,6 @@ bool CourseColMgr::doCheckMaskOnlyPush(KColData *data, CollisionCheckFunc collis
return hasCol;
}

void CourseColMgr::CollisionInfo::update(f32 now_dist, const EGG::Vector3f &offset,
const EGG::Vector3f &fnrm, u32 kclAttributeTypeBit) {
bbox.min = bbox.min.minimize(offset);
bbox.max = bbox.max.maximize(offset);

if (kclAttributeTypeBit & KCL_TYPE_FLOOR) {
updateFloor(now_dist, fnrm);
} else if (kclAttributeTypeBit & KCL_TYPE_WALL) {
if (wallDist > -std::numeric_limits<f32>::min()) {
f32 dot = 1.0f - wallNrm.ps_dot(fnrm);
if (dot > perpendicularity) {
perpendicularity = std::min(dot, 1.0f);
}
}

updateWall(now_dist, fnrm);
}
}

CourseColMgr *CourseColMgr::s_instance = nullptr; ///< @addr{0x809C3C10}

} // namespace Field
34 changes: 0 additions & 34 deletions source/game/field/CourseColMgr.hh
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,6 @@ typedef bool (
/// @nosubgrouping
class CourseColMgr : EGG::Disposer {
public:
struct CollisionInfoPartial {
EGG::BoundBox3f bbox;
EGG::Vector3f tangentOff;
};

struct CollisionInfo {
EGG::BoundBox3f bbox;
EGG::Vector3f tangentOff;
EGG::Vector3f floorNrm;
EGG::Vector3f wallNrm;
EGG::Vector3f _3c;
f32 floorDist;
f32 wallDist;
f32 _50;
f32 perpendicularity;

void updateFloor(f32 dist, const EGG::Vector3f &fnrm) {
if (dist > floorDist) {
floorDist = dist;
floorNrm = fnrm;
}
}

void updateWall(f32 dist, const EGG::Vector3f &fnrm) {
if (dist > wallDist) {
wallDist = dist;
wallNrm = fnrm;
}
}

void update(f32 now_dist, const EGG::Vector3f &offset, const EGG::Vector3f &fnrm,
u32 kclAttributeTypeBit);
};

struct NoBounceWallColInfo {
EGG::BoundBox3f bbox;
EGG::Vector3f tangentOff;
Expand Down
19 changes: 19 additions & 0 deletions source/game/field/KColData.cc
Original file line number Diff line number Diff line change
Expand Up @@ -682,4 +682,23 @@ KColData::KCollisionPrism::KCollisionPrism(f32 height, u16 posIndex, u16 faceNor
: height(height), pos_i(posIndex), fnrm_i(faceNormIndex), enrm1_i(edge1NormIndex),
enrm2_i(edge2NormIndex), enrm3_i(edge3NormIndex), attribute(attribute) {}

void CollisionInfo::update(f32 now_dist, const EGG::Vector3f &offset, const EGG::Vector3f &fnrm,
u32 kclAttributeTypeBit) {
bbox.min = bbox.min.minimize(offset);
bbox.max = bbox.max.maximize(offset);

if (kclAttributeTypeBit & KCL_TYPE_FLOOR) {
updateFloor(now_dist, fnrm);
} else if (kclAttributeTypeBit & KCL_TYPE_WALL) {
if (wallDist > -std::numeric_limits<f32>::min()) {
f32 dot = 1.0f - wallNrm.ps_dot(fnrm);
if (dot > perpendicularity) {
perpendicularity = std::min(dot, 1.0f);
}
}

updateWall(now_dist, fnrm);
}
}

} // namespace Field
34 changes: 34 additions & 0 deletions source/game/field/KColData.hh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,40 @@

namespace Field {

struct CollisionInfoPartial {
EGG::BoundBox3f bbox;
EGG::Vector3f tangentOff;
};

struct CollisionInfo {
EGG::BoundBox3f bbox;
EGG::Vector3f tangentOff;
EGG::Vector3f floorNrm;
EGG::Vector3f wallNrm;
EGG::Vector3f _3c;
f32 floorDist;
f32 wallDist;
f32 _50;
f32 perpendicularity;

void updateFloor(f32 dist, const EGG::Vector3f &fnrm) {
if (dist > floorDist) {
floorDist = dist;
floorNrm = fnrm;
}
}

void updateWall(f32 dist, const EGG::Vector3f &fnrm) {
if (dist > wallDist) {
wallDist = dist;
wallNrm = fnrm;
}
}

void update(f32 now_dist, const EGG::Vector3f &offset, const EGG::Vector3f &fnrm,
u32 kclAttributeTypeBit);
};

/// @brief Performs lookups for KCL triangles
/// @nosubgrouping
class KColData {
Expand Down
1 change: 1 addition & 0 deletions source/game/field/obj/ObjectBase.hh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public:
virtual void calc() {}
virtual void calcModel();
virtual void load() = 0;
virtual void createCollision() = 0;
virtual void calcCollisionTransform() = 0;

/// @addr{0x806BF434}
Expand Down
2 changes: 1 addition & 1 deletion source/game/field/obj/ObjectCollidable.hh
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public:
}

protected:
virtual void createCollision();
void createCollision() override;

/// @addr{0x806816B8}
virtual const EGG::Vector3f &collisionCenter() const {
Expand Down
2 changes: 1 addition & 1 deletion source/game/field/obj/ObjectDokan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void ObjectDokan::calcFloor() {
constexpr f32 PIPE_SQRT_RADIUS = 10.0f;
constexpr f32 ACCELERATION = 0.2f;

CourseColMgr::CollisionInfo colInfo;
CollisionInfo colInfo;
EGG::Vector3f pos = m_pos;
pos.y += PIPE_RADIUS;
KCLTypeMask typeMask;
Expand Down
32 changes: 32 additions & 0 deletions source/game/field/obj/ObjectDrivable.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "game/field/obj/ObjectDrivable.hh"

namespace Field {

/// @addr{0x8081A6D0}
ObjectDrivable::ObjectDrivable(const System::MapdataGeoObj &params) : ObjectBase(params) {}

/// @addr{0x8067EB3C}
ObjectDrivable::~ObjectDrivable() = default;

/// @addr{0x8081A79C}
void ObjectDrivable::load() {
createCollision();
initCollision();
loadAABB(getCollisionRadius());

// ObjectDrivableDirector::Instance()->addObject(this);
}

/// @addr{0x80682918}
f32 ObjectDrivable::getCollisionRadius() const {
return 5000.0f;
}

/// @addr{0x8081A85C}
void ObjectDrivable::loadAABB(f32 radius) {
auto *boxColMgr = BoxColManager::Instance();
const EGG::Vector3f &pos = getPosition();
m_boxColUnit = boxColMgr->insertDrivable(radius, 0.0f, &pos, false, this);
}

} // namespace Field
77 changes: 77 additions & 0 deletions source/game/field/obj/ObjectDrivable.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#pragma once

#include "game/field/CourseColMgr.hh"
#include "game/field/KCollisionTypes.hh"
#include "game/field/ObjectCollisionBase.hh"
#include "game/field/obj/ObjectBase.hh"

namespace Field {

class ObjectDrivable : public ObjectBase {
public:
ObjectDrivable(const System::MapdataGeoObj &params);
~ObjectDrivable() override;

void load() override;
[[nodiscard]] f32 getCollisionRadius() const override;

virtual void initCollision() {}
virtual void loadAABB(f32 radius);

[[nodiscard]] virtual bool checkPointPartial(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask,
CollisionInfoPartial *info, KCLTypeMask *maskOut) = 0;
[[nodiscard]] virtual bool checkPointPartialPush(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask flags,
CollisionInfoPartial *info, KCLTypeMask *maskOut) = 0;
[[nodiscard]] virtual bool checkPointFull(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut) = 0;
[[nodiscard]] virtual bool checkPointFullPush(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut) = 0;

[[nodiscard]] virtual bool checkSpherePartial(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask,
CollisionInfoPartial *info, KCLTypeMask *maskOut, u32 timeOffset) = 0;
[[nodiscard]] virtual bool checkSpherePartialPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask,
CollisionInfoPartial *info, KCLTypeMask *maskOut, u32 timeOffset) = 0;
[[nodiscard]] virtual bool checkSphereFull(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut, u32 timeOffset) = 0;
[[nodiscard]] virtual bool checkSphereFullPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut, u32 timeOffset) = 0;

virtual void narrScLocal(f32 radius, const EGG::Vector3f &pos, KCLTypeMask mask,
u32 timeOffset) {}

[[nodiscard]] virtual bool checkPointCachedPartial(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask,
CollisionInfoPartial *info, KCLTypeMask *maskOut) = 0;
[[nodiscard]] virtual bool checkPointCachedPartialPush(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask,
CollisionInfoPartial *info, KCLTypeMask *maskOut) = 0;
[[nodiscard]] virtual bool checkPointCachedFull(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut) = 0;
[[nodiscard]] virtual bool checkPointCachedFullPush(const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut) = 0;

[[nodiscard]] virtual bool checkSphereCachedPartial(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask,
CollisionInfoPartial *info, KCLTypeMask *maskOut, u32 timeOffset) = 0;
[[nodiscard]] virtual bool checkSphereCachedPartialPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask,
CollisionInfoPartial *info, KCLTypeMask *maskOut, u32 timeOffset) = 0;
[[nodiscard]] virtual bool checkSphereCachedFull(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut, u32 timeOffset) = 0;
[[nodiscard]] virtual bool checkSphereCachedFullPush(f32 radius, const EGG::Vector3f &pos,
const EGG::Vector3f &prevPos, KCLTypeMask mask, CollisionInfo *info,
KCLTypeMask *maskOut, u32 timeOffset) = 0;
};

} // namespace Field
1 change: 1 addition & 0 deletions source/game/field/obj/ObjectNoImpl.hh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public:
~ObjectNoImpl() override;

void load() override;
void createCollision() override {}
void calcCollisionTransform() override {}
};

Expand Down
Loading

0 comments on commit a254940

Please sign in to comment.