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)
14 : ObjectBase(params), m_collision(nullptr) {}
15
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) {}
20
22ObjectCollidable::~ObjectCollidable() {
23 delete m_collision;
24}
25
27void ObjectCollidable::load() {
28 loadGraphics();
29 loadAnims();
30 createCollision();
31
32 if (m_collision) {
33 loadAABB(0.0f);
34 }
35
36 loadRail();
37
38 ObjectDirector::Instance()->addObject(this);
39}
40
42void ObjectCollidable::calcCollisionTransform() {
43 calcTransform();
44 m_collision->transform(m_transform, m_scale, getCollisionTranslation());
45}
46
51f32 ObjectCollidable::getCollisionRadius() const {
52 const auto &flowTable = ObjectDirector::Instance()->flowTable();
53 const auto *collisionSet = flowTable.set(flowTable.slot(id()));
54
55 f32 zRadius = m_scale.z * static_cast<f32>(parse<s16>(collisionSet->params.box.z));
56 f32 xRadius = m_scale.x * static_cast<f32>(parse<s16>(collisionSet->params.box.x));
57
58 return std::max(xRadius, zRadius);
59}
60
62void ObjectCollidable::loadAABB(f32 maxSpeed) {
63 loadAABB(getCollisionRadius(), maxSpeed);
64}
65
67void ObjectCollidable::loadAABB(f32 radius, f32 maxSpeed) {
68 auto *boxColMgr = BoxColManager::Instance();
69 const EGG::Vector3f &pos = getPosition();
70 bool alwaysRecalc = loadFlags() & 0x5;
71 m_boxColUnit = boxColMgr->insertObject(radius, maxSpeed, &pos, alwaysRecalc, this);
72}
73
75void ObjectCollidable::processKartReactions(Kart::KartObject *kartObj,
76 Kart::Reaction &reactionOnKart, Kart::Reaction &reactionOnObj) {
77 // Process the reaction on kart
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;
83 }
84 } else {
85 if (reactionOnKart == Kart::Reaction::SpinHitSomeSpeed) {
86 reactionOnKart = Kart::Reaction::SpinSomeSpeed;
87 }
88 }
89
90 // Process the reaction on object
91 if (reactionOnObj == Kart::Reaction::UNK_3 || reactionOnObj == Kart::Reaction::UNK_4) {
92 reactionOnObj = Kart::Reaction::None;
93 }
94}
95
97bool ObjectCollidable::checkCollision(ObjectCollisionBase *lhs, EGG::Vector3f &dist) {
98 return lhs->check(*collision(), dist);
99}
100
102void ObjectCollidable::createCollision() {
103 const auto &flowTable = ObjectDirector::Instance()->flowTable();
104 const auto *collisionSet = flowTable.set(flowTable.slot(id()));
105
106 if (!collisionSet) {
107 PANIC("Invalid object ID when creating primitive collision! ID: %d",
108 static_cast<size_t>(m_id));
109 }
110
111 switch (static_cast<CollisionMode>(parse<s16>(collisionSet->mode))) {
112 case CollisionMode::Sphere:
113 m_collision = new ObjectCollisionSphere(parse<s16>(collisionSet->params.sphere.radius),
114 collisionCenter());
115 break;
116 case CollisionMode::Cylinder:
117 m_collision = new ObjectCollisionCylinder(parse<s16>(collisionSet->params.cylinder.radius),
118 parse<s16>(collisionSet->params.cylinder.height), collisionCenter());
119 break;
120 case CollisionMode::Box:
121 m_collision = new ObjectCollisionBox(parse<s16>(collisionSet->params.box.x),
122 parse<s16>(collisionSet->params.box.y), parse<s16>(collisionSet->params.box.z),
123 collisionCenter());
124 break;
125 default:
126 PANIC("Invalid collision mode when creating primitive collision! ID: %d; Mode: %d",
127 static_cast<size_t>(m_id), parse<s16>(collisionSet->mode));
128 break;
129 }
130}
131
133void ObjectCollidable::registerManagedObject() {
134 ObjectDirector::Instance()->addManagedObject(this);
135}
136
137} // 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:87