A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
CollisionGroup.cc
Go to the documentation of this file.
1#include "CollisionGroup.hh"
2
3namespace Kinoko::Kart {
4
10 vel.setZero();
14 speedFactor = 1.0f;
15 rotFactor = 0.0f;
17 closestFloorSettings = 0xffffffff;
19 closestFloorSettings = 0xffffffff;
20 intensity = 0.0f;
22
23 bFloor = false;
24 bWall = false;
25 bInvisibleWall = false;
26 bTrickable = false;
28 bWall3 = false;
29 bInvisibleWallOnly = false;
31 bSoftWall = false;
34 bHasRoadVel = false;
35 bWallAtLeftCloser = false;
36 bWallAtRightCloser = false;
38}
39
41Hitbox::Hitbox() : m_bspHitbox(nullptr), m_ownsBSP(false) {}
42
49
52void Hitbox::calc(f32 totalScale, f32 sinkDepth, const EGG::Vector3f &scale, const EGG::Quatf &rot,
53 const EGG::Vector3f &pos) {
54 f32 fVar1 = 0.0f;
55 if (scale.y < totalScale) {
56 fVar1 = (totalScale - scale.y) * m_bspHitbox->radius;
57 }
58
59 EGG::Vector3f scaledPos = m_bspHitbox->position * scale;
60 scaledPos.y = (m_bspHitbox->position.y + sinkDepth) * scale.y + fVar1;
61
62 m_relPos = rot.rotateVector(scaledPos);
63 m_worldPos = m_relPos + pos;
64}
65
72
74void Hitbox::setLastPos(const EGG::Vector3f &scale, const EGG::Matrix34f &pose) {
75 f32 yScaleFactor = scale.y;
77 scaledPos.x *= scale.x;
78 scaledPos.z *= scale.z;
79
80 if (scale.y != scale.z && scale.y < 1.0f) {
81 scaledPos.y += (1.0f - scale.y) * m_radius;
82 yScaleFactor = scale.z;
83 }
84
85 scaledPos.y *= yScaleFactor;
86 m_lastPos = pose.ps_multVector(scaledPos);
87}
88
93
95
103f32 CollisionGroup::initHitboxes(const std::array<BSP::Hitbox, 16> &hitboxes) {
104 u16 bspHitboxCount = 0;
105
106 for (const auto &hitbox : hitboxes) {
107 if (parse<u16>(hitbox.enable)) {
108 ++bspHitboxCount;
109 }
110 }
111
112 m_hitboxes = owning_span<Hitbox>(bspHitboxCount);
113 u16 hitboxIdx = 0;
114
115 for (const auto &bspHitbox : hitboxes) {
116 if (parse<u16>(bspHitbox.enable)) {
117 m_hitboxes[hitboxIdx++].setBspHitbox(&bspHitbox);
118 }
119 }
120
121 return computeCollisionLimits();
122}
123
129
130 for (const auto &hitbox : m_hitboxes) {
131 const BSP::Hitbox *bspHitbox = hitbox.bspHitbox();
132
133 if (bspHitbox->enable == 0) {
134 continue;
135 }
136
137 max = max.maximize(bspHitbox->position.abs() + bspHitbox->radius);
138 }
139
140 // Get largest component of the vector
141 f32 maxComponent = max.z;
142
143 if (max.x <= max.y) {
144 if (max.z < max.y) {
145 maxComponent = max.y;
146 }
147 } else if (max.z < max.x) {
148 maxComponent = max.x;
149 }
150
151 m_boundingRadius = maxComponent;
152
153 return max.z * 0.5f;
154}
155
161
162 // TODO: Do we need for loop if this is just one?
163 // And how exactly will we identify to free the BSP::Hitbox on destruction?
164 for (auto &hitbox : m_hitboxes) {
165 hitbox.reset();
167 hitbox.setBspHitbox(bspHitbox, true);
168 bspHitbox->position = relPos;
169 bspHitbox->radius = radius;
170 hitbox.setRadius(radius);
171 }
172 m_boundingRadius = radius;
173}
174
178
179 for (auto &hitbox : m_hitboxes) {
180 hitbox.reset();
182 }
183}
184
188
191 m_hitboxScale = scale;
192
193 for (auto &hitbox : m_hitboxes) {
195 }
196}
197
198} // namespace Kinoko::Kart
A 3 x 4 matrix.
Definition Matrix.hh:10
constexpr Vector3f ps_multVector(const Vector3f &vec) const
Paired-singles impl. of multVector.
Definition Matrix.hh:273
void createSingleHitbox(f32 radius, const EGG::Vector3f &relPos)
Creates a hitbox to represent a tire.
Hitbox & hitbox(u16 hitboxIdx)
f32 computeCollisionLimits()
Sets the bounding radius.
owning_span< Hitbox > m_hitboxes
f32 initHitboxes(const std::array< BSP::Hitbox, 16 > &hitboxes)
Initializes the hitbox array based on the KartParam's BSP hitboxes.
void setRadius(f32 radius)
void calc(f32 totalScale, f32 sinkDepth, const EGG::Vector3f &scale, const EGG::Quatf &rot, const EGG::Vector3f &pos)
Calculates the position of a given hitbox, both relative to the player and world.
const BSP::Hitbox * m_bspHitbox
void setLastPos(const EGG::Vector3f &pos)
void setBspHitbox(const BSP::Hitbox *hitbox, bool owns=false)
const BSP::Hitbox * bspHitbox() const
owning_span()
Uninitialized buffer.
Definition Types.hh:35
void egg_delete(const T *ptr)
Definition Heap.hh:154
T * egg_new(Args &&...args)
Definition Heap.hh:148
Pertains to kart-related functionality.
float f32
Definition Memory.hh:21
uint16_t u16
Definition Memory.hh:17
A quaternion, used to represent 3D rotation.
Definition Quat.hh:12
constexpr Vector3f rotateVector(const Vector3f &vec) const
Rotates a vector based on the quat.
Definition Quat.hh:139
A 3D float vector.
Definition Vector.hh:108
constexpr Vector3f abs() const
Returns the absolute value of each element of the vector.
Definition Vector.hh:240
static const Vector3f zero
Definition Vector.hh:386
constexpr void setZero()
Definition Vector.hh:122
constexpr Vector3f maximize(const Vector3f &rhs) const
Returns a vector whose elements are the max of the elements of both vectors.
Definition Vector.hh:316
Represents one of the many hitboxes that make up a vehicle.
Definition KartParam.hh:10
EGG::Vector3f position
The relative position of the hitbox.
Definition KartParam.hh:12
u16 enable
Specifies if this is an active hitbox (since BSP always has 16).
Definition KartParam.hh:11
bool bMovingWaterDecaySpeed
Player speed will drop if not in mushroom.
u32 closestFloorSettings
The colliding floor KCL flag's "variant".
Field::KCLTypeMask closestFloorFlags
The colliding floor KCL flag's KColType.
bool bMovingWaterDisableAccel
KC last turn prevents mini-turbo acceleration.
bool bWall3
Set if colliding with COL_TYPE_WALL_2.
bool bMovingWaterStickyRoad
KC pipe vertical water section.
bool bWall
Set if colliding with KCL which satisfies KCL_TYPE_WALL.
s32 intensity
The KCL flag's "wheel depth".
bool bMovingWaterMomentum
Player will maintain speed for a bit after leaving KCL.
Field::KCLTypeMask closestWallFlags
The colliding wall KCL flag's KColType.
bool bFloor
Set if colliding with KCL which satisfies KCL_TYPE_FLOOR.
bool bMovingWaterVertical
KC last turn vertical water.