A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectPropeller.cc
1#include "ObjectPropeller.hh"
2
3#include "game/field/ObjectDirector.hh"
4
5namespace Field {
6
8ObjectPropeller::ObjectPropeller(const System::MapdataGeoObj &params)
9 : ObjectCollidable(params), m_angle(0.0f) {
10 m_blades.fill(nullptr);
11}
12
14ObjectPropeller::~ObjectPropeller() {
15 for (auto *&blade : m_blades) {
16 delete blade;
17 }
18}
19
21void ObjectPropeller::init() {
22 ASSERT(m_mapObj);
23 m_angVel = static_cast<f32>(static_cast<s16>(m_mapObj->setting(0)));
24 if (m_mapObj->setting(1) == 1) {
25 m_angVel = -m_angVel;
26 }
27
28 m_rotMat.makeR(m_rot);
29 m_rotMat.setBase(3, m_pos);
30 m_axis = m_rotMat.base(2);
31}
32
34void ObjectPropeller::calc() {
35 m_angle += m_angVel * 0.5f;
36 m_curRot = EGG::Matrix34f::ident;
37 m_curRot.setAxisRotation(m_angle * DEG2RAD, m_axis);
38 m_transform = m_curRot.multiplyTo(m_rotMat);
39 m_flags.setBit(eFlags::Matrix);
40 m_transform.setBase(3, m_pos);
41}
42
44void ObjectPropeller::createCollision() {
45 ObjectCollidable::createCollision();
46
47 const auto &colCenter = collisionCenter();
48 const auto &flowTable = ObjectDirector::Instance()->flowTable();
49 const auto &params = flowTable.set(flowTable.slot(id()))->params.cylinder;
50 f32 radius = static_cast<f32>(parse<s16>(params.radius));
51 f32 height = static_cast<f32>(parse<s16>(params.height));
52
53 for (auto *&blade : m_blades) {
54 blade = new ObjectCollisionCylinder(radius, height, colCenter);
55 }
56}
57
59void ObjectPropeller::calcCollisionTransform() {
60 constexpr f32 BLADE_LENGTH = 250.0f;
61
62 for (u32 i = 0; i < m_blades.size(); ++i) {
64 mat.setBase(3, EGG::Vector3f::zero);
65 mat.setAxisRotation(static_cast<f32>(i * 120) * DEG2RAD, m_axis);
66 calcTransform();
67 mat = mat.multiplyTo(m_transform);
68 EGG::Vector3f dir = mat.base(1);
69 dir.normalise();
70 dir *= BLADE_LENGTH;
71 mat.setBase(3, m_pos + dir);
72
73 auto *&blade = m_blades[i];
74 blade->transform(mat, m_scale);
75 }
76}
77
79f32 ObjectPropeller::getCollisionRadius() const {
80 const auto &flowTable = ObjectDirector::Instance()->flowTable();
81 const auto &params = flowTable.set(flowTable.slot(id()))->params.box;
82 f32 z = m_scale.z * static_cast<f32>(parse<s16>(params.z));
83 f32 x = m_scale.x * static_cast<f32>(parse<s16>(params.x));
84
85 return 5.0f * std::max(z, x);
86}
87
89bool ObjectPropeller::checkCollision(ObjectCollisionBase *lhs, EGG::Vector3f &dist) {
90 EGG::Vector3f dist0 = EGG::Vector3f::zero;
91 EGG::Vector3f dist1 = EGG::Vector3f::zero;
92 EGG::Vector3f dist2 = EGG::Vector3f::zero;
93
94 bool hasCol = lhs->check(*m_blades[0], dist0);
95 hasCol = hasCol || lhs->check(*m_blades[1], dist1);
96 hasCol = hasCol || lhs->check(*m_blades[2], dist2);
97
98 dist = dist0 + dist1 + dist2;
99
100 return hasCol;
101}
102
103} // namespace Field
A 3 x 4 matrix.
Definition Matrix.hh:8
Matrix34f multiplyTo(const Matrix34f &rhs) const
Multiplies two matrices.
Definition Matrix.cc:202
void setBase(size_t col, const Vector3f &base)
Sets one column of a matrix.
Definition Matrix.cc:194
Vector3f base(size_t col) const
Get a particular column from a matrix.
Definition Matrix.hh:72
void setAxisRotation(f32 angle, const Vector3f &axis)
Rotates the matrix about an axis.
Definition Matrix.cc:180
The base class that all objects' collision inherits from.
Pertains to collision.
A 3D float vector.
Definition Vector.hh:88
f32 normalise()
Normalizes the vector and returns the original length.
Definition Vector.cc:52