A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectCollidable.cc
1#include "ObjectCollidable.hh"
2
3#include "game/field/ObjectCollisionBox.hh"
4#include "game/field/ObjectCollisionCylinder.hh"
5#include "game/field/ObjectCollisionSphere.hh"
6#include "game/field/ObjectDirector.hh"
7
8#include "game/kart/KartObject.hh"
9
10namespace Field {
11
13ObjectCollidable::ObjectCollidable(const System::MapdataGeoObj &params) : ObjectBase(params) {}
14
16ObjectCollidable::~ObjectCollidable() {
17 delete m_collision;
18}
19
21void ObjectCollidable::load() {
22 createCollision();
23
24 if (m_collision) {
25 loadAABB(0.0f);
26 }
27
28 ObjectDirector::Instance()->addObject(this);
29}
30
32void ObjectCollidable::calcCollisionTransform() {
33 calcTransform();
34 m_collision->transform(m_transform, m_scale, getCollisionTranslation());
35}
36
41f32 ObjectCollidable::getCollisionRadius() const {
42 const auto &flowTable = ObjectDirector::Instance()->flowTable();
43 const auto *collisionSet = flowTable.set(flowTable.slot(m_id));
44
45 f32 zRadius = m_scale.z * static_cast<f32>(parse<s16>(collisionSet->params.box.z));
46 f32 xRadius = m_scale.x * static_cast<f32>(parse<s16>(collisionSet->params.box.x));
47
48 return std::max(xRadius, zRadius);
49}
50
52void ObjectCollidable::loadAABB(f32 maxSpeed) {
53 loadAABB(getCollisionRadius(), maxSpeed);
54}
55
57void ObjectCollidable::loadAABB(f32 radius, f32 maxSpeed) {
58 auto *boxColMgr = BoxColManager::Instance();
59 const EGG::Vector3f &pos = getPosition();
60 bool alwaysRecalc = loadFlags() & 0x5;
61 m_boxColUnit = boxColMgr->insertObject(radius, maxSpeed, &pos, alwaysRecalc, this);
62}
63
65void ObjectCollidable::processKartReactions(Kart::KartObject *kartObj,
66 Kart::Reaction &reactionOnKart, Kart::Reaction &reactionOnObj) {
67 // Process the reaction on kart
68 if (kartObj->speedRatioCapped() < 0.5f) {
69 if (reactionOnKart == Kart::Reaction::SpinSomeSpeed) {
70 reactionOnKart = Kart::Reaction::WallAllSpeed;
71 } else if (reactionOnKart == Kart::Reaction::SpinHitSomeSpeed) {
72 reactionOnKart = Kart::Reaction::None;
73 }
74 } else {
75 if (reactionOnKart == Kart::Reaction::SpinHitSomeSpeed) {
76 reactionOnKart = Kart::Reaction::SpinSomeSpeed;
77 }
78 }
79
80 // Process the reaction on object
81 if (reactionOnObj == Kart::Reaction::UNK_3 || reactionOnObj == Kart::Reaction::UNK_4) {
82 reactionOnObj = Kart::Reaction::None;
83 }
84}
85
87bool ObjectCollidable::checkCollision(ObjectCollisionBase *lhs, EGG::Vector3f &dist) {
88 return lhs->check(*collision(), dist);
89}
90
92void ObjectCollidable::createCollision() {
93 const auto &flowTable = ObjectDirector::Instance()->flowTable();
94 const auto *collisionSet = flowTable.set(flowTable.slot(m_id));
95
96 if (!collisionSet) {
97 PANIC("Invalid object ID when creating primitive collision! ID: %d",
98 static_cast<size_t>(m_id));
99 }
100
101 switch (static_cast<CollisionMode>(parse<s16>(collisionSet->mode))) {
102 case CollisionMode::Sphere:
103 m_collision = new ObjectCollisionSphere(parse<s16>(collisionSet->params.sphere.radius),
104 collisionCenter());
105 break;
106 case CollisionMode::Cylinder:
107 m_collision = new ObjectCollisionCylinder(parse<s16>(collisionSet->params.cylinder.radius),
108 parse<s16>(collisionSet->params.cylinder.height), collisionCenter());
109 break;
110 case CollisionMode::Box:
111 m_collision = new ObjectCollisionBox(parse<s16>(collisionSet->params.box.x),
112 parse<s16>(collisionSet->params.box.y), parse<s16>(collisionSet->params.box.z),
113 collisionCenter());
114 break;
115 default:
116 PANIC("Invalid collision mode when creating primitive collision! ID: %d; Mode: %d",
117 static_cast<size_t>(m_id), parse<s16>(collisionSet->mode));
118 break;
119 }
120}
121
122} // namespace Field
The highest level abstraction for a kart.
Definition KartObject.hh:11
Pertains to collision.
CollisionMode
Maps to SObjectCollisionSet::mode. Determines what type of collision an object has.
A 3D float vector.
Definition Vector.hh:83