1#include "SphereLink.hh"
3#include "game/field/CollisionDirector.hh"
7SphereLink::SphereLink() : m_prev(nullptr), m_next(nullptr) {}
9SphereLink::~SphereLink() =
default;
12void SphereLink::initLinkLen(f32 length) {
17void SphereLink::init() {
20 m_springForce.setZero();
21 m_up = EGG::Vector3f::ey;
22 m_touchingGround =
true;
26void SphereLink::calcStiffness() {
27 constexpr f32 STIFFNESS = 0.15f;
35 if (dist < m_prev->m_linkLen) {
39 EGG::Vector3f springForce = dir * (STIFFNESS * (dist - m_prev->m_linkLen));
40 EGG::Vector3f velDamping = dir * (-STIFFNESS * (m_prev->m_vel - m_vel).dot(dir));
43 m_springForce += totalForce;
45 if (!m_prev->isLeader()) {
46 m_prev->m_springForce -= totalForce;
51void SphereLink::calc() {
60 if (dist > m_prev->m_linkLen) {
61 m_springForce += dir * 2.0f;
72void SphereLink::calcConstraints(f32 scale) {
73 constexpr f32 MIN_PITCH_ANGLE = DEG2FIDX * -75.0f;
74 STATIC_ASSERT(MIN_PITCH_ANGLE == -53.333336f);
80 f32 scaledLen = m_prev->m_linkLen * scale;
83 if (dist <= scaledLen) {
88 f32 minPitch = EGG::Mathf::SinFIdx(MIN_PITCH_ANGLE);
90 if (forward.y > minPitch && !m_touchingGround) {
92 if (forward.y >= 0.0f) {
104 newForward.normalise2();
107 m_pos = m_prev->m_pos + newForward * scaledLen;
111 m_pos += back * (dist - scaledLen);
116void SphereLink::checkCollision() {
117 constexpr f32 RADIUS = 55.0f;
125 auto *colDir = CollisionDirector::Instance();
126 m_touchingGround = colDir->checkSphereFullPush(RADIUS, pos, EGG::Vector3f::inf,
KCL_TYPE_FLOOR,
129 if (m_touchingGround) {
132 if (tangentOff.
squaredLength() > std::numeric_limits<f32>::epsilon()) {
133 tangentOff.normalise2();
136 if (EGG::Mathf::abs(tangentOff.y) > 0.7f) {
137 m_pos.y += info.tangentOff.y;
139 m_pos += info.tangentOff;
142 if (info.floorDist > -std::numeric_limits<f32>::min()) {
143 floorNrm = info.floorNrm;
146 m_vel = m_up * m_vel.
dot(m_up) * 0.5f;
147 m_springForce = GRAVITY;
150 m_up += (floorNrm - m_up) * 0.1f;
153void SphereLink::calcPos() {
154 m_vel += m_springForce - GRAVITY;
157 m_springForce.setZero();
161void SphereLink::calcSpring() {
162 ASSERT(m_prev && m_next);
167 if (dist > m_prev->m_linkLen) {
168 m_springForce += dir * 2.0f;
171 dir = m_next->m_pos - m_pos;
174 if (nextDist > m_linkLen) {
175 m_springForce += dir * 2.0f;
#define KCL_TYPE_FLOOR
0x20E80FFF - Any KCL that the player or items can drive/land on.
void setAxisRotation(f32 angle, const Vector3f &axis)
Rotates the matrix about an axis.
Vector3f ps_multVector(const Vector3f &vec) const
Paired-singles impl. of multVector.
f32 normalise()
Normalizes the vector and returns the original length.
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
f32 squaredLength() const
The dot product between the vector and itself.