| 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 | |
| 7 | namespace al { |
| 8 | |
| 9 | RailPart::RailPart() = default; |
| 10 | |
| 11 | void 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 | |
| 24 | void RailPart::calcPos(sead::Vector3f* pos, f32 param) const { |
| 25 | return mBezierCurve ? mBezierCurve->calcPos(pos, param) : mLinearCurve->calcPos(pos, param); |
| 26 | } |
| 27 | |
| 28 | void RailPart::calcVelocity(sead::Vector3f* vel, f32 param) const { |
| 29 | return mBezierCurve ? mBezierCurve->calcVelocity(vel, param) : |
| 30 | mLinearCurve->calcVelocity(vel, param); |
| 31 | } |
| 32 | |
| 33 | void 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 | |
| 54 | void RailPart::calcStartPos(sead::Vector3f* pos) const { |
| 55 | return mBezierCurve ? mBezierCurve->calcStartPos(pos) : mLinearCurve->calcStartPos(start: pos); |
| 56 | } |
| 57 | |
| 58 | void RailPart::calcEndPos(sead::Vector3f* pos) const { |
| 59 | return mBezierCurve ? mBezierCurve->calcEndPos(pos) : mLinearCurve->calcEndPos(end: pos); |
| 60 | } |
| 61 | |
| 62 | f32 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 | |
| 67 | f32 RailPart::calcCurveParam(f32 param) const { |
| 68 | return mBezierCurve ? mBezierCurve->calcCurveParam(distance: param) : mLinearCurve->calcCurveParam(param); |
| 69 | } |
| 70 | |
| 71 | f32 RailPart::calcNearestParam(const sead::Vector3f& pos, f32 interval) const { |
| 72 | return mBezierCurve ? mBezierCurve->calcNearestParam(pos, interval) : |
| 73 | mLinearCurve->calcNearestParam(pos); |
| 74 | } |
| 75 | |
| 76 | void 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 | |
| 82 | f32 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 | |
| 88 | f32 RailPart::getPartLength() const { |
| 89 | return mBezierCurve ? mBezierCurve->getLength() : mLinearCurve->getLength(); |
| 90 | } |
| 91 | |
| 92 | } // namespace al |
| 93 | |