#include "Library/Rail/RailPart.h" #include "Library/Math/MathUtil.h" #include "Project/Rail/BezierCurve.h" #include "Project/Rail/LinearCurve.h" namespace al { RailPart::RailPart() = default; void RailPart::init(const sead::Vector3f& start, const sead::Vector3f& startHandle, const sead::Vector3f& endHandle, const sead::Vector3f& end) { sead::Vector3f startDiff = start - startHandle; sead::Vector3f endDiff = end - endHandle; if (startDiff.equals({0, 0, 0}, 0.1) && endDiff.equals({0, 0, 0}, 0.1)) { mLinearCurve = new LinearCurve(); mLinearCurve->set(start, end); } else { mBezierCurve = new BezierCurve(); mBezierCurve->set(start, startHandle, endHandle, end); } } void RailPart::calcPos(sead::Vector3f* pos, f32 param) const { return mBezierCurve ? mBezierCurve->calcPos(pos, param) : mLinearCurve->calcPos(pos, param); } void RailPart::calcVelocity(sead::Vector3f* vel, f32 param) const { return mBezierCurve ? mBezierCurve->calcVelocity(vel, param) : mLinearCurve->calcVelocity(vel, param); } void RailPart::calcDir(sead::Vector3f* dir, f32 param) const { calcVelocity(dir, param); if (!isNearZero(*dir, 0.001)) { normalize(dir); return; } sead::Vector3f startPos; calcStartPos(&startPos); sead::Vector3f endPos; calcEndPos(&endPos); dir->x = endPos.x - startPos.x; dir->y = endPos.y - startPos.y; dir->z = endPos.z - startPos.z; if (isNearZero(*dir, 0.001)) *dir = {0, 0, 1}; else normalize(dir); } void RailPart::calcStartPos(sead::Vector3f* pos) const { return mBezierCurve ? mBezierCurve->calcStartPos(pos) : mLinearCurve->calcStartPos(pos); } void RailPart::calcEndPos(sead::Vector3f* pos) const { return mBezierCurve ? mBezierCurve->calcEndPos(pos) : mLinearCurve->calcEndPos(pos); } f32 RailPart::calcLength(f32 startParam, f32 endParam, s32 stepCount) const { return mBezierCurve ? mBezierCurve->calcLength(startParam, endParam, stepCount) : mLinearCurve->calcLength(startParam, endParam); } f32 RailPart::calcCurveParam(f32 param) const { return mBezierCurve ? mBezierCurve->calcCurveParam(param) : mLinearCurve->calcCurveParam(param); } f32 RailPart::calcNearestParam(const sead::Vector3f& pos, f32 interval) const { return mBezierCurve ? mBezierCurve->calcNearestParam(pos, interval) : mLinearCurve->calcNearestParam(pos); } void RailPart::calcNearestPos(sead::Vector3f* nearest, const sead::Vector3f& pos, f32 interval) const { return mBezierCurve ? mBezierCurve->calcNearestPos(nearest, pos, interval) : mLinearCurve->calcNearestPos(nearest, pos); } f32 RailPart::calcNearestLength(f32* param, const sead::Vector3f& pos, f32 max, f32 interval) const { return mBezierCurve ? mBezierCurve->calcNearestLength(param, pos, max, interval) : mLinearCurve->calcNearestLength(param, pos, max); } f32 RailPart::getPartLength() const { return mBezierCurve ? mBezierCurve->getLength() : mLinearCurve->getLength(); } } // namespace al