A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
ObjectHwanwan.cc
1#include "ObjectHwanwan.hh"
2
3#include "game/field/CollisionDirector.hh"
4
5namespace Field {
6
8ObjectHwanwan::ObjectHwanwan(const System::MapdataGeoObj &params)
9 : ObjectCollidable(params), StateManager(this, STATE_ENTRIES), m_initPos(m_pos) {}
10
12ObjectHwanwan::~ObjectHwanwan() = default;
13
15void ObjectHwanwan::init() {
16 m_workPos = m_initPos + EGG::Vector3f::ey * DIAMETER;
17 m_extVel.setZero();
18 m_bounceVel.setZero();
19 m_tangent = EGG::Vector3f::ez;
20 m_up = EGG::Vector3f::ey;
21 m_targetUp = EGG::Vector3f::ey;
22 m_touchingGround = false;
23 m_initJumpVel = 0.0f;
24 m_targetY = m_workPos.y;
25
26 calcTransform();
27
28 m_nextStateId = 0;
29}
30
32void ObjectHwanwan::calc() {
33 StateManager::calc();
34
35 m_extVel += m_bounceVel - GRAVITY;
36 m_workPos += m_extVel;
37 m_bounceVel.setZero();
38
39 checkFloorCollision();
40
41 SetRotTangentHorizontal(m_transform, m_up, m_tangent);
42 m_transform.setBase(3, m_workPos);
43 m_pos = m_workPos;
44}
45
47void ObjectHwanwan::checkFloorCollision() {
48 constexpr f32 RADIUS = DIAMETER * 0.5f;
49
50 m_touchingGround = false;
51
52 CollisionInfo colInfo;
53 KCLTypeMask mask;
54 EGG::Vector3f pos = m_workPos + EGG::Vector3f(0.0f, -DIAMETER, 0.0f);
55
56 bool hasCol = CollisionDirector::Instance()->checkSphereFullPush(RADIUS, pos,
57 EGG::Vector3f::inf, KCL_TYPE_FLOOR, &colInfo, &mask, 0);
58
59 if (!hasCol || pos.y - m_targetY >= 300.0f) {
60 return;
61 }
62
63 m_touchingGround = true;
64
65 f32 len = colInfo.tangentOff.length();
66 m_workPos += EGG::Vector3f::ey * len;
67
68 if (colInfo.floorDist > -std::numeric_limits<f32>::min()) {
69 m_targetUp = colInfo.floorNrm;
70 }
71 m_extVel.y = 0.0f;
72}
73
75void ObjectHwanwan::calcUp() {
76 m_up = Interpolate(0.1f, m_up, m_targetUp);
77 if (m_up.squaredLength() > std::numeric_limits<f32>::epsilon()) {
78 m_up.normalise2();
79 } else {
80 m_up = EGG::Vector3f::ey;
81 }
82}
83
85ObjectHwanwanManager::ObjectHwanwanManager(const System::MapdataGeoObj &params)
86 : ObjectCollidable(params) {
87 m_hwanwan = new ObjectHwanwan(params);
88 m_hwanwan->setScale(EGG::Vector3f(2.0f, 2.0f, 2.0f));
89 m_hwanwan->load();
90}
91
93ObjectHwanwanManager::~ObjectHwanwanManager() = default;
94
96void ObjectHwanwanManager::init() {
97 m_railInterpolator->init(0.0f, 0);
98 m_hwanwan->m_tangent = m_railInterpolator->curTangentDir();
99 const auto &curPos = m_railInterpolator->curPos();
100 m_hwanwan->m_workPos.x = curPos.x;
101 m_hwanwan->m_workPos.z = curPos.z;
102 m_hwanwan->m_targetY = curPos.y;
103
104 m_hwanwan->calc();
105 m_hwanwan->calc();
106
107 ASSERT(m_mapObj);
108 m_railInterpolator->setCurrVel(static_cast<f32>(m_mapObj->setting(0)));
109}
110
112void ObjectHwanwanManager::calc() {
113 calcState();
114
115 const auto &curPos = m_railInterpolator->curPos();
116 m_hwanwan->m_workPos.x = curPos.x;
117 m_hwanwan->m_workPos.z = curPos.z;
118 m_hwanwan->m_targetY = curPos.y;
119 m_hwanwan->m_tangent = m_railInterpolator->curTangentDir();
120}
121
123void ObjectHwanwanManager::calcState() {
124 if (m_railInterpolator->calc() == RailInterpolator::Status::SegmentEnd &&
125 m_railInterpolator->curPoint().setting[1] == 1 && m_hwanwan->m_currentStateId != 2) {
126 m_hwanwan->m_nextStateId = 1;
127 }
128
129 if (m_hwanwan->m_currentStateId == 1 && m_hwanwan->m_currentFrame >= 60) {
130 m_hwanwan->m_nextStateId = 0;
131 }
132}
133
134} // namespace Field
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.
Pertains to collision.
A 3D float vector.
Definition Vector.hh:88