1#include "Library/Rail/RailPart.h"
2
3#include "Library/Math/MathUtil.h"
4#include "Project/Rail/BezierCurve.h"
5#include "Project/Rail/LinearCurve.h"
6
7namespace al {
8
9RailPart::RailPart() = default;
10
11void RailPart::init(const sead::Vector3f& start, const sead::Vector3f& startHandle,
12 const sead::Vector3f& endHandle, const sead::Vector3f& end) {
13 sead::Vector3f startDiff = start - startHandle;
14 sead::Vector3f endDiff = end - endHandle;
15 if (startDiff.equals(rhs: {0, 0, 0}, epsilon: 0.1) && endDiff.equals(rhs: {0, 0, 0}, epsilon: 0.1)) {
16 mLinearCurve = new LinearCurve();
17 mLinearCurve->set(start, end);
18 } else {
19 mBezierCurve = new BezierCurve();
20 mBezierCurve->set(start, startHandle, endHandle, end);
21 }
22}
23
24void RailPart::calcPos(sead::Vector3f* pos, f32 param) const {
25 return mBezierCurve ? mBezierCurve->calcPos(pos, param) : mLinearCurve->calcPos(pos, param);
26}
27
28void RailPart::calcVelocity(sead::Vector3f* vel, f32 param) const {
29 return mBezierCurve ? mBezierCurve->calcVelocity(vel, param) :
30 mLinearCurve->calcVelocity(vel, param);
31}
32
33void RailPart::calcDir(sead::Vector3f* dir, f32 param) const {
34 calcVelocity(vel: dir, param);
35 if (!isNearZero(vec: *dir, tolerance: 0.001)) {
36 normalize(vec: dir);
37 return;
38 }
39
40 sead::Vector3f startPos;
41 calcStartPos(&startPos);
42 sead::Vector3f endPos;
43 calcEndPos(&endPos);
44
45 dir->x = endPos.x - startPos.x;
46 dir->y = endPos.y - startPos.y;
47 dir->z = endPos.z - startPos.z;
48 if (isNearZero(vec: *dir, tolerance: 0.001))
49 *dir = {0, 0, 1};
50 else
51 normalize(vec: dir);
52}
53
54void RailPart::calcStartPos(sead::Vector3f* pos) const {
55 return mBezierCurve ? mBezierCurve->calcStartPos(pos) : mLinearCurve->calcStartPos(start: pos);
56}
57
58void RailPart::calcEndPos(sead::Vector3f* pos) const {
59 return mBezierCurve ? mBezierCurve->calcEndPos(pos) : mLinearCurve->calcEndPos(end: pos);
60}
61
62f32 RailPart::calcLength(f32 startParam, f32 endParam, s32 stepCount) const {
63 return mBezierCurve ? mBezierCurve->calcLength(startParam, endParam, stepCount) :
64 mLinearCurve->calcLength(param_start: startParam, param_end: endParam);
65}
66
67f32 RailPart::calcCurveParam(f32 param) const {
68 return mBezierCurve ? mBezierCurve->calcCurveParam(distance: param) : mLinearCurve->calcCurveParam(param);
69}
70
71f32 RailPart::calcNearestParam(const sead::Vector3f& pos, f32 interval) const {
72 return mBezierCurve ? mBezierCurve->calcNearestParam(pos, interval) :
73 mLinearCurve->calcNearestParam(pos);
74}
75
76void RailPart::calcNearestPos(sead::Vector3f* nearest, const sead::Vector3f& pos,
77 f32 interval) const {
78 return mBezierCurve ? mBezierCurve->calcNearestPos(nearest, pos, interval) :
79 mLinearCurve->calcNearestPos(nearest, pos);
80}
81
82f32 RailPart::calcNearestLength(f32* param, const sead::Vector3f& pos, f32 max,
83 f32 interval) const {
84 return mBezierCurve ? mBezierCurve->calcNearestLength(param, pos, max, interval) :
85 mLinearCurve->calcNearestLength(length: param, pos, param: max);
86}
87
88f32 RailPart::getPartLength() const {
89 return mBezierCurve ? mBezierCurve->getLength() : mLinearCurve->getLength();
90}
91
92} // namespace al
93