A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectRock.cc
1#include "ObjectRock.hh"
2
3#include "game/field/CollisionDirector.hh"
4
5#include "game/kart/KartCollide.hh"
6
7namespace Field {
8
11
13ObjectRock::~ObjectRock() = default;
14
16void ObjectRock::init() {
17 m_railInterpolator->init(0.0f, 0);
18 m_railInterpolator->setCurrVel(static_cast<f32>(m_mapObj->setting(2)));
19 m_railInterpolator->calc();
20
21 m_state = State::Tangible;
22 m_flags.setBit(eFlags::Position);
23 m_pos.y = m_startYPos = m_railInterpolator->curPos().y;
24
25 EGG::Vector3f curTanDirNorm = m_railInterpolator->curTangentDir();
26 curTanDirNorm.normalise();
27 setMatrixTangentTo(EGG::Vector3f::ey, curTanDirNorm);
28 calcTransform();
29 m_angRad = 0.0f;
30 m_angSpd = INITIAL_ANGULAR_SPEED;
31 m_cooldownTimer = m_mapObj->setting(0);
32 m_colTranslate.x = 0.0f;
33 m_colTranslate.y = static_cast<f32>(m_mapObj->setting(3));
34 m_colTranslate.z = 0.0f;
35 calcTransform();
36}
37
39void ObjectRock::calc() {
40 switch (m_state) {
41 case State::Tangible:
42 calcTangible();
43 break;
44 case State::Intangible:
45 calcIntangible();
46 break;
47 }
48
49 --m_cooldownTimer;
50 EGG::Vector3f scaledTang =
51 m_railInterpolator->curTangentDir() * m_railInterpolator->getCurrVel();
52 m_colTranslate.x = scaledTang.x;
53 m_colTranslate.z = scaledTang.z;
54}
55
56// @addr{0x8076F768}
57void ObjectRock::calcTangible() {
58 auto railStatus = m_railInterpolator->calc();
59 if (railStatus == RailInterpolator::Status::ChangingDirection) {
60 breakRock();
61 }
62
63 m_flags.setBit(eFlags::Position);
64 m_pos.x = m_railInterpolator->curPos().x;
65 m_flags.setBit(eFlags::Position);
66 m_pos.z = m_railInterpolator->curPos().z;
67 m_colTranslate.y -= 2.0f;
68
69 m_flags.setBit(eFlags::Position);
70 m_pos += m_colTranslate;
71
72 checkSphereFull();
73 calcTangibleSub();
74}
75
77void ObjectRock::calcIntangible() {
78 if (m_cooldownTimer < 0) {
79 m_state = State::Tangible;
80 m_angSpd = INITIAL_ANGULAR_SPEED;
81 m_colTranslate.y = static_cast<f32>(m_mapObj->setting(3));
82 m_cooldownTimer = m_mapObj->setting(1);
83 enableCollision();
84 }
85}
86
88void ObjectRock::calcTangibleSub() {
89 EGG::Vector3f tangDir = m_railInterpolator->curTangentDir();
90 tangDir.y = 0.0f;
91 tangDir.normalise();
92 EGG::Matrix34f m = OrthonormalBasis(tangDir);
93 m_angRad += m_angSpd * DEG2RAD;
94
95 EGG::Matrix34f mat(EGG::Matrix34f::ident);
96 EGG::Vector3f vRot(m_angRad, 0.0f, 0.0f);
97 mat.makeR(vRot);
98 m_flags.setBit(eFlags::Matrix);
99 m_transform = m.multiplyTo(mat);
100 m_transform.setBase(3, m_pos);
101}
102
103// @addr {0x8076FA60}
104void ObjectRock::checkSphereFull() {
105 CollisionInfo info;
106
107 EGG::Vector3f offset(0.0f, -(m_scale.x * 240.0f - 50.0f), 0.0f);
108 EGG::Vector3f pos = m_pos + offset;
109
110 if (CollisionDirector::Instance()->checkSphereFull(50.0f, pos, EGG::Vector3f::inf,
111 KCL_TYPE_FLOOR, &info, nullptr, 0)) {
112 m_colTranslate.y *= -0.3f;
113 m_angSpd = std::max(360.0f * static_cast<f32>(m_mapObj->setting(2)) /
114 (480.0f * m_scale.x * F_PI),
115 m_angSpd + 1.0f);
116 m_flags.setBit(eFlags::Position);
117 m_pos += info.tangentOff;
118 }
119}
120
122void ObjectRock::breakRock() {
123 m_state = State::Intangible;
124 m_railInterpolator->init(0.0f, 0);
125 m_railInterpolator->setCurrVel(static_cast<f32>(m_mapObj->setting(2)));
126
127 m_flags.setBit(eFlags::Position);
128 m_pos.y = m_startYPos;
129 disableCollision();
130}
131
132// @addr{0x80770068}
133Kart::Reaction ObjectRock::onCollision(Kart::KartObject * /*kartObj*/,
134 Kart::Reaction reactionOnKart, Kart::Reaction /*reactionOnObj*/,
135 EGG::Vector3f & /*hitDepth*/) {
136 if (m_scale.x < 1.0f) {
137 breakRock();
138 return Kart::Reaction::None;
139 }
140 return reactionOnKart;
141}
142
143} // namespace Field
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.
A 3 x 4 matrix.
Definition Matrix.hh:8
Matrix34f multiplyTo(const Matrix34f &rhs) const
Multiplies two matrices.
Definition Matrix.cc:189
void setBase(size_t col, const Vector3f &base)
Sets one column of a matrix.
Definition Matrix.cc:181
ObjectRock(const System::MapdataGeoObj &params)
@addr {0x8076F2E0}
Definition ObjectRock.cc:10
The highest level abstraction for a kart.
Definition KartObject.hh:11
Pertains to collision.
constexpr TBitFlag< T, E > & setBit(Es... es)
Sets the corresponding bits for the provided enum values.
Definition BitFlag.hh:57
A 3D float vector.
Definition Vector.hh:88
f32 normalise()
Normalizes the vector and returns the original length.
Definition Vector.cc:52