1#include "ObjectCollidable.hh"
3#include "game/field/ObjectCollisionBox.hh"
4#include "game/field/ObjectCollisionCylinder.hh"
5#include "game/field/ObjectCollisionSphere.hh"
6#include "game/field/ObjectDirector.hh"
8#include "game/kart/KartObject.hh"
13ObjectCollidable::ObjectCollidable(
const System::MapdataGeoObj ¶ms)
17ObjectCollidable::ObjectCollidable(
const char *name,
const EGG::Vector3f &pos,
18 const EGG::Vector3f &rot,
const EGG::Vector3f &scale)
19 : ObjectBase(name, pos, rot, scale), m_collision(nullptr) {}
22ObjectCollidable::~ObjectCollidable() {
23 EGG::egg_delete(m_collision);
27void ObjectCollidable::load() {
38 ObjectDirector::Instance()->addObject(
this);
42void ObjectCollidable::calcCollisionTransform() {
44 m_collision->transform(transform(), scale(), getCollisionTranslation());
52 const auto &flowTable = ObjectDirector::Instance()->flowTable();
53 const auto *collisionSet = flowTable.set(flowTable.slot(
id()));
55 f32 zRadius = scale().z *
static_cast<f32
>(parse<s16>(collisionSet->params.box.z));
56 f32 xRadius = scale().x *
static_cast<f32
>(parse<s16>(collisionSet->params.box.x));
58 return std::max(xRadius, zRadius);
62void ObjectCollidable::loadAABB(f32 maxSpeed) {
63 loadAABB(getCollisionRadius(), maxSpeed);
67void ObjectCollidable::loadAABB(f32 radius, f32 maxSpeed) {
68 auto *boxColMgr = BoxColManager::Instance();
70 bool alwaysRecalc = loadFlags() & 0x5;
71 m_boxColUnit = boxColMgr->insertObject(radius, maxSpeed, &pos, alwaysRecalc,
this);
75void ObjectCollidable::processKartReactions(Kart::KartObject *kartObj,
76 Kart::Reaction &reactionOnKart, Kart::Reaction &reactionOnObj) {
78 if (kartObj->speedRatioCapped() < 0.5f) {
79 if (reactionOnKart == Kart::Reaction::SpinSomeSpeed) {
80 reactionOnKart = Kart::Reaction::WallAllSpeed;
81 }
else if (reactionOnKart == Kart::Reaction::SpinHitSomeSpeed) {
82 reactionOnKart = Kart::Reaction::None;
85 if (reactionOnKart == Kart::Reaction::SpinHitSomeSpeed) {
86 reactionOnKart = Kart::Reaction::SpinSomeSpeed;
91 if (reactionOnObj == Kart::Reaction::UNK_3 || reactionOnObj == Kart::Reaction::UNK_4) {
92 reactionOnObj = Kart::Reaction::None;
97bool ObjectCollidable::checkCollision(ObjectCollisionBase *lhs, EGG::Vector3f &dist) {
98 return lhs->check(*collision(), dist);
102void ObjectCollidable::createCollision() {
103 const auto &flowTable = ObjectDirector::Instance()->flowTable();
104 const auto *collisionSet = flowTable.set(flowTable.slot(
id()));
107 PANIC(
"Invalid object ID when creating primitive collision! ID: %zu",
108 static_cast<size_t>(
id()));
111 switch (
static_cast<CollisionMode>(parse<s16>(collisionSet->mode))) {
112 case CollisionMode::Sphere:
113 m_collision = EGG::egg_new<ObjectCollisionSphere>(
114 parse<s16>(collisionSet->params.sphere.radius), collisionCenter());
116 case CollisionMode::Cylinder:
117 m_collision = EGG::egg_new<ObjectCollisionCylinder>(
118 parse<s16>(collisionSet->params.cylinder.radius),
119 parse<s16>(collisionSet->params.cylinder.height), collisionCenter());
121 case CollisionMode::Box:
122 m_collision = EGG::egg_new<ObjectCollisionBox>(parse<s16>(collisionSet->params.box.x),
123 parse<s16>(collisionSet->params.box.y), parse<s16>(collisionSet->params.box.z),
127 PANIC(
"Invalid collision mode when creating primitive collision! ID: %zu; Mode: %d",
128 static_cast<size_t>(
id()), parse<s16>(collisionSet->mode));
134void ObjectCollidable::registerManagedObject() {
135 ObjectDirector::Instance()->addManagedObject(
this);
f32 getCollisionRadius() const override
Finds the radius that fits fully in a BoxColUnit.
CollisionMode
Maps to SObjectCollisionSet::mode. Determines what type of collision an object has.