18 for (
auto &link : m_links) {
27 ASSERT(idx < m_links.size());
28 m_links[idx].setPos(pos);
33 ASSERT(idx < m_links.size());
34 m_links[idx].setVel(v);
39 ASSERT(idx < m_links.size());
40 return m_links[idx].pos();
45 ASSERT(idx < m_links.size());
46 return m_links[idx].up();
51 ASSERT(idx < m_links.size());
52 m_links[idx].addSpringForce(v);
57 void calcConstraints() {
58 for (
size_t i = 1; i < m_links.size(); ++i) {
59 m_links[i].calcConstraints(1.0f);
63 std::span<SphereLink> m_links;
149 void init()
override;
152 void calc()
override {
154 StateManager::calc();
159 [[nodiscard]] u32 loadFlags()
const override {
164 void loadGraphics()
override {}
167 void createCollision()
override {}
170 enum class RailAlignment {
194 void calcSlowMotion() {
195 constexpr f32 PERIOD = 50.0f;
196 constexpr f32 WAVELENGTH = 4000.0f;
198 calcLateralMotion(
m_stillAngVel, PERIOD, WAVELENGTH, m_currentFrame);
202 void calcFastMotion(s32 frame) {
203 constexpr f32 AMPLITUDE = 25.0f;
204 constexpr f32 PERIOD = 300.0f;
205 constexpr f32 WAVELENGTH = 5500.0f;
207 calcLateralMotion(AMPLITUDE, PERIOD, WAVELENGTH,
static_cast<s16
>(frame));
210 void calcLateralMotion(f32 amplitude, f32 period, f32 wavelength, s16 frame);
211 [[nodiscard]] RailAlignment calcRailAlignment()
const;
214 [[nodiscard]]
bool shouldStartMoving()
const {
215 return m_currentFrame > m_stillDuration;
219 void setMovingVel() {
220 m_railInterpolator->setCurrVel(m_movingVel);
227 [[nodiscard]] std::span<ObjectHanachanPart *> bodyParts() {
228 return std::span(m_parts.begin() + 1, m_parts.size() - 1);
231 std::array<ObjectHanachanPart *, 7> m_parts;
233 const f32 m_movingVel;
241 RailAlignment m_prevRailAlignment;
253 static constexpr std::array<StateManagerEntry, 2> STATE_ENTRIES = {{
254 {StateEntry<ObjectHanachan, &ObjectHanachan::initWalk, &ObjectHanachan::calcWalk>(0)},
255 {StateEntry<ObjectHanachan, &ObjectHanachan::initWait, &ObjectHanachan::calcWait>(1)},