1#include "KartPullPath.hh"
3#include "game/system/CourseMap.hh"
5#include <egg/geom/Plane.hh>
10KartPullPathTracker::KartPullPathTracker(KartPullPath *handle, Type type)
11 : m_type(type), m_currentIdx(0), m_pointInfo(nullptr), m_handle(handle) {}
14KartPullPathTracker::~KartPullPathTracker() =
default;
16void KartPullPathTracker::calc() {
19 if (m_type == Type::Global) {
21 }
else if (m_type == Type::Regional) {
22 calcTrackerRegional();
27void KartPullPathTracker::calcTrackerGlobal() {
30 if (search(SearchDirection::Current, idx, point, dir)) {
31 m_handle->changePoint(idx, getDistance(point, dir));
34 if (
static_cast<size_t>(++m_currentIdx) >= m_pointInfo->pointCount() - 1) {
40void KartPullPathTracker::calcTrackerRegional() {
41 if (m_handle->incomingIdx() < 0) {
48 if (search(SearchDirection::Current, idx, point, dir)) {
49 m_handle->changePoint(idx, getDistance(point, dir));
53 m_handle->resetDistance();
54 if (search(SearchDirection::Next, idx, point, dir)) {
55 m_handle->changePoint(idx, getDistance(point, dir));
59 if (search(SearchDirection::Previous, idx, point, dir)) {
60 m_handle->changePoint(idx, getDistance(point, dir));
71 f32 x = EGG::Mathf::abs(diff.
dot(dir));
72 return EGG::Mathf::sqrt(dist * dist - x * x);
76bool KartPullPathTracker::search(SearchDirection searchDirection, s16 &idx,
EGG::Vector3f &point,
81 switch (searchDirection) {
82 case SearchDirection::Current:
88 case SearchDirection::Next:
89 idx = m_currentIdx + 1;
94 case SearchDirection::Previous:
95 idx = m_currentIdx - 1;
101 PANIC(
"Invalid search direction!");
105 const auto &points = m_pointInfo->points();
108 if (m_currentIdx + c < 0 ||
static_cast<size_t>(m_currentIdx + c) >= points.size()) {
112 if (m_currentIdx + n < 0 ||
static_cast<size_t>(m_currentIdx + n) >= points.size()) {
116 const auto ¤tPos = points[m_currentIdx + c].pos;
117 const auto &nextPos = points[m_currentIdx + n].pos;
123 if (m_currentIdx + p >= 0 &&
static_cast<size_t>(m_currentIdx + p) < points.size()) {
124 const auto &prevPos = points[m_currentIdx + p].pos;
125 back = prevPos - currentPos;
132 if (backPlane.testPoint(pos()) && frontPlane.testPoint(pos())) {
142KartPullPath::KartPullPath()
143 : m_globalTracker(this, KartPullPathTracker::Type::Global),
144 m_regionalTracker(this, KartPullPathTracker::Type::Regional) {
149KartPullPath::~KartPullPath() =
default;
152void KartPullPath::init() {
155 m_roadSpeedDecay = 1.0f;
164 m_pointInfo =
nullptr;
165 m_pullDirection = EGG::Vector3f::zero;
167 m_maxPullSpeed = 0.0f;
171void KartPullPath::calc() {
177 if (m_pointInfo->pointCount() > 2) {
183void KartPullPath::changePoint(s16 idx, f32 distance) {
184 if ((m_distance >= 0.0f || distance >= 3000.0f) && distance >= m_distance) {
189 m_distance = distance;
190 m_regionalTracker.setCurrentIdx(idx);
195bool KartPullPath::calcArea() {
196 auto *courseMap = System::CourseMap::Instance();
198 s16 prevAreaId = m_areaId;
199 m_areaId = System::CourseMap::Instance()->getCurrentAreaID(m_areaId, pos(),
200 System::MapdataAreaBase::Type::MovingRoad);
203 if (prevAreaId < 0 || prevAreaId != m_areaId) {
205 auto *area = courseMap->getArea(m_areaId);
207 auto *pointInfo = area->getPointInfo();
209 m_pointInfo = pointInfo;
210 if (pointInfo->pointCount() > 2) {
211 setTrackerPointInfo(pointInfo);
216 m_roadSpeedDecay = 0.9f + 0.001f *
static_cast<f32
>(area->param(0));
217 m_maxPullSpeed =
static_cast<f32
>(area->param(1));
223 m_pullDirection = EGG::Vector3f::zero;
226 return m_areaId >= 0;
230void KartPullPath::calcPointChange() {
231 if (m_currentIdx == m_incomingIdx) {
235 const auto &points = m_pointInfo->points();
237 const auto ¤tPos = points[m_incomingIdx].pos;
238 const auto &nextPos = points[m_incomingIdx + 1].pos;
239 m_pullSpeed =
static_cast<f32
>(points[m_incomingIdx].setting[0]);
240 u16 pullInfluence = points[m_incomingIdx + 1].setting[1];
242 m_pullDirection = nextPos - currentPos;
247 if (pullInfluence == 1) {
252 else if (pullInfluence == 2) {
256 m_currentIdx = m_incomingIdx;
260void KartPullPath::calcTrackers() {
261 m_globalTracker.calc();
262 m_regionalTracker.calc();
270 if (EGG::Vector3f::ey.dot(m_pullDirection) == 1.0f) {
271 return EGG::Vector3f::zero;
274 EGG::Vector3f nrm = EGG::Vector3f::ey.cross(m_pullDirection);
281 m_globalTracker.setPointInfo(info);
282 m_regionalTracker.setPointInfo(info);
EGG::Vector3f getPullUnitNormal() const
Pertains to kart-related functionality.
Represents a plane in 3D space, expressed with n.dot(x) = d for point x on the plane.
f32 normalise()
Normalizes the vector and returns the original length.
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
f32 length() const
The square root of the vector's dot product.