Kinoko
A reimplementation of Mario Kart Wii's physics engine in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
ObjectHanachan.hh
1
#pragma once
2
3
#include "game/field/ObjectCollisionSphere.hh"
4
#include "game/field/SphereLink.hh"
5
#include "game/field/StateManager.hh"
6
#include "game/field/obj/ObjectCollidable.hh"
7
8
namespace
Kinoko::Field
{
9
11
class
HanachanChainManager {
12
public
:
13
HanachanChainManager(
const
std::span<const f32> &linkDistances);
14
~HanachanChainManager();
15
17
void
init() {
18
for
(
auto
&link : m_links) {
19
link.init();
20
}
21
}
22
23
void
calc();
24
26
void
setPos(
size_t
idx,
const
EGG::Vector3f
&pos) {
27
ASSERT(idx < m_links.size());
28
m_links[idx].setPos(pos);
29
}
30
32
void
setVel(
size_t
idx,
const
EGG::Vector3f
&v) {
33
ASSERT(idx < m_links.size());
34
m_links[idx].setVel(v);
35
}
36
38
[[nodiscard]]
const
EGG::Vector3f
&pos(
size_t
idx)
const
{
39
ASSERT(idx < m_links.size());
40
return
m_links[idx].pos();
41
}
42
44
[[nodiscard]]
const
EGG::Vector3f
&up(
size_t
idx)
const
{
45
ASSERT(idx < m_links.size());
46
return
m_links[idx].up();
47
}
48
50
void
addSpringForce(
size_t
idx,
const
EGG::Vector3f
&v) {
51
ASSERT(idx < m_links.size());
52
m_links[idx].addSpringForce(v);
53
}
54
55
private
:
57
void
calcConstraints() {
58
for
(
size_t
i = 1; i < m_links.size(); ++i) {
59
m_links[i].calcConstraints(1.0f);
60
}
61
}
62
63
owning_span<SphereLink>
m_links;
64
};
65
66
class
ObjectHanachanPart :
public
ObjectCollidable {
67
friend
class
ObjectHanachan;
68
69
public
:
70
ObjectHanachanPart(
const
System::MapdataGeoObj
¶ms) : ObjectCollidable(params) {}
71
72
ObjectHanachanPart(
const
char
*name,
const
EGG::Vector3f
&pos,
const
EGG::Vector3f
&rot,
73
const
EGG::Vector3f
&scale)
74
: ObjectCollidable(name, pos, rot, scale) {}
75
77
~ObjectHanachanPart() =
default
;
78
80
[[nodiscard]] u32 loadFlags()
const override
{
81
return
1;
82
}
83
85
[[nodiscard]]
const
char
*getKclName()
const override
{
86
return
"hanachan"
;
87
}
88
90
void
loadRail()
override
{}
91
92
private
:
94
void
calcTransformFromUpAndTangent(
const
EGG::Vector3f
&pos,
const
EGG::Vector3f
&up,
95
const
EGG::Vector3f
&tangent) {
96
EGG::Matrix34f
mat;
97
SetRotTangentHorizontal(mat, up, tangent);
98
mat.
setBase
(3, pos);
99
setTransform(mat);
100
}
101
};
102
103
class
ObjectHanachanHead final :
public
ObjectHanachanPart {
104
public
:
105
ObjectHanachanHead(
const
char
*name,
const
EGG::Vector3f
&pos,
const
EGG::Vector3f
&rot,
106
const
EGG::Vector3f
&scale);
107
~ObjectHanachanHead()
override
;
108
110
void
createCollision()
override
{
111
m_collision = EGG::egg_new<ObjectCollisionSphere>(150.0f, collisionCenter());
112
}
113
114
void
calcCollisionTransform()
override
;
115
116
private
:
117
EGG::Vector3f
m_lastPos;
118
};
119
120
class
ObjectHanachanBody final :
public
ObjectHanachanPart {
121
friend
class
ObjectHanachan;
122
123
public
:
124
ObjectHanachanBody(
const
System::MapdataGeoObj
¶ms,
const
char
*mdlName);
125
ObjectHanachanBody(
const
char
*name,
const
EGG::Vector3f
&pos,
const
EGG::Vector3f
&rot,
126
const
EGG::Vector3f
&scale,
const
char
*mdlName);
127
~ObjectHanachanBody()
override
;
128
130
[[nodiscard]]
const
char
*getKclName()
const override
{
131
return
m_mdlName;
132
}
133
134
void
calcCollisionTransform()
override
;
135
136
protected
:
137
const
char
*m_mdlName;
138
bool
m_lastSegment;
139
EGG::Vector3f
m_lastPos;
140
141
private
:
142
static
constexpr
std::array<const char *, 4> MDL_NAMES = {
143
"hanachan_body1"
,
144
"hanachan_body2"
,
145
"hanachan_body3"
,
146
"hanachan_body4"
,
147
};
148
};
149
150
class
ObjectHanachan final :
public
ObjectCollidable,
public
StateManager {
151
public
:
152
ObjectHanachan(
const
System::MapdataGeoObj
¶ms);
153
~ObjectHanachan()
override
;
154
155
void
init()
override
;
156
158
void
calc()
override
{
159
calcRail();
160
StateManager::calc();
161
calcBody();
162
}
163
165
[[nodiscard]] u32 loadFlags()
const override
{
166
return
1;
167
}
168
170
void
loadGraphics()
override
{}
171
173
void
createCollision()
override
{}
174
175
private
:
176
enum class
RailAlignment {
177
Aligned = -1,
178
Unknown = 0,
179
MisalignedLeft = 1,
180
MisalignedRight = 2,
181
};
182
183
void
initWalk();
184
186
void
initWait() {}
187
188
void
calcWalk();
189
void
calcWait();
190
191
void
onSegmentEnd();
192
void
calcRail();
193
void
calcBody();
194
void
initBody();
195
void
initChain();
196
void
clearChain();
197
void
calcRailAlignmentMotion
();
198
200
void
calcSlowMotion() {
201
constexpr
f32 PERIOD = 50.0f;
202
constexpr
f32 WAVELENGTH = 4000.0f;
203
204
calcLateralMotion(
m_stillAngVel
, PERIOD, WAVELENGTH, m_currentFrame);
205
}
206
208
void
calcFastMotion(s32 frame) {
209
constexpr
f32 AMPLITUDE = 25.0f;
210
constexpr
f32 PERIOD = 300.0f;
211
constexpr
f32 WAVELENGTH = 5500.0f;
212
213
calcLateralMotion(AMPLITUDE, PERIOD, WAVELENGTH,
static_cast<
s16
>
(frame));
214
}
215
216
void
calcLateralMotion(f32 amplitude, f32 period, f32 wavelength, s16 frame);
217
[[nodiscard]] RailAlignment calcRailAlignment()
const
;
218
220
[[nodiscard]]
bool
shouldStartMoving()
const
{
221
return
m_currentFrame > m_stillDuration;
222
}
223
225
void
setMovingVel() {
226
m_railInterpolator->setCurrVel(m_movingVel);
227
}
228
229
[[nodiscard]]
ObjectHanachanHead
*&headPart() {
230
return
reinterpret_cast<
ObjectHanachanHead
*&
>
(m_parts[0]);
231
}
232
233
[[nodiscard]] std::span<ObjectHanachanPart *> bodyParts() {
234
return
std::span(m_parts.begin() + 1, m_parts.size() - 1);
235
}
236
237
std::array<ObjectHanachanPart *, 7> m_parts;
238
HanachanChainManager
m_chain;
239
const
f32 m_movingVel;
240
std::array<float, 7>
m_partDisplacement
;
241
u16 m_stillDuration;
242
f32
m_stillAngVel
;
243
bool
m_still;
244
u16
m_leftMisalignFrame
;
245
EGG::Vector3f
m_right;
246
RailAlignment
m_railAlignment
;
247
RailAlignment m_prevRailAlignment;
248
250
static
constexpr
std::array<f32, 6>
BODY_PART_DISTANCES
= {{
251
360.0f,
252
510.0f,
253
510.0f,
254
480.0f,
255
510.0f,
256
510.0f,
257
}};
258
259
static
constexpr
std::array<StateManagerEntry, 2> STATE_ENTRIES = {{
260
{StateEntry<ObjectHanachan, &ObjectHanachan::initWalk, &ObjectHanachan::calcWalk>(0)},
261
{StateEntry<ObjectHanachan, &ObjectHanachan::initWait, &ObjectHanachan::calcWait>(1)},
262
}};
263
};
264
265
}
// namespace Kinoko::Field
Kinoko::EGG::Matrix34f
A 3 x 4 matrix.
Definition
Matrix.hh:10
Kinoko::EGG::Matrix34f::setBase
constexpr void setBase(size_t col, const Vector3f &base)
Sets one column of a matrix.
Definition
Matrix.hh:230
Kinoko::Field::HanachanChainManager
Class that interfaces with the chain links corresponding to wiggler body parts.
Definition
ObjectHanachan.hh:11
Kinoko::Field::ObjectHanachanHead
Definition
ObjectHanachan.hh:103
Kinoko::Field::ObjectHanachan::m_stillAngVel
f32 m_stillAngVel
Affects body part swaying when coming to a standstill.
Definition
ObjectHanachan.hh:242
Kinoko::Field::ObjectHanachan::m_leftMisalignFrame
u16 m_leftMisalignFrame
Frame at which the wiggler became left-misaligned from the rail.
Definition
ObjectHanachan.hh:244
Kinoko::Field::ObjectHanachan::calcRailAlignmentMotion
void calcRailAlignmentMotion()
If the wiggler has moved out of alignment of the rail, then applies a lateral adjustment to the wiggl...
Definition
ObjectHanachan.cc:280
Kinoko::Field::ObjectHanachan::m_partDisplacement
std::array< float, 7 > m_partDisplacement
Total distance between a given part and the head.
Definition
ObjectHanachan.hh:240
Kinoko::Field::ObjectHanachan::m_railAlignment
RailAlignment m_railAlignment
Captures when the wiggle takes sharp turns.
Definition
ObjectHanachan.hh:246
Kinoko::Field::ObjectHanachan::BODY_PART_DISTANCES
static constexpr std::array< f32, 6 > BODY_PART_DISTANCES
The distance between each body part link in the chain.
Definition
ObjectHanachan.hh:250
Kinoko::System::MapdataGeoObj
Definition
MapdataGeoObj.hh:9
Kinoko::owning_span
A contiguous storage container that manages the lifecycle of a buffer of a given size.
Definition
Types.hh:31
Kinoko::Field
Pertains to collision.
Definition
BoxColManager.cc:10
Kinoko::EGG::Vector3f
A 3D float vector.
Definition
Vector.hh:107
game
field
obj
ObjectHanachan.hh
Made by
Malleo
. Logo by
vabold
. Website generated by
Doxygen
1.17.0