From dab8d7c6f6153e5797c418fc9a9a5289096835ab Mon Sep 17 00:00:00 2001 From: sogladev Date: Fri, 30 Jan 2026 14:13:53 +0100 Subject: [PATCH] fix(Core/Movement): fix calculation first Catmull-Rom spline point (#24449) Co-authored-by: DanVS <33371360+DanVS@users.noreply.github.com> Co-authored-by: Ryan Turner <16946913+TheSCREWEDSoftware@users.noreply.github.com> --- src/server/game/Movement/Spline/MoveSpline.cpp | 4 ++-- src/server/game/Movement/Spline/Spline.cpp | 14 ++++++++++---- src/server/game/Movement/Spline/Spline.h | 9 +++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index 513a789ef..0d9581a2e 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -128,11 +128,11 @@ namespace Movement // MoveSplineFlag::Enter_Cycle support dropped //if (splineflags & SPLINEFLAG_ENTER_CYCLE) //cyclic_point = 1; // shouldn't be modified, came from client - spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point); + spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point, args.initialOrientation); } else { - spline.init_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()]); + spline.init_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], args.initialOrientation); } // init spline timestamps diff --git a/src/server/game/Movement/Spline/Spline.cpp b/src/server/game/Movement/Spline/Spline.cpp index 9c65619b5..5baf32027 100644 --- a/src/server/game/Movement/Spline/Spline.cpp +++ b/src/server/game/Movement/Spline/Spline.cpp @@ -199,18 +199,20 @@ namespace Movement return length; } - void SplineBase::init_spline(const Vector3* controls, index_type count, EvaluationMode m) + void SplineBase::init_spline(const Vector3* controls, index_type count, EvaluationMode m, float orientation) { m_mode = m; cyclic = false; + initialOrientation = orientation; (this->*initializers[m_mode])(controls, count, cyclic, 0); } - void SplineBase::init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point) + void SplineBase::init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point, float orientation) { m_mode = m; cyclic = true; + initialOrientation = orientation; (this->*initializers[m_mode])(controls, count, cyclic, cyclic_point); } @@ -253,14 +255,18 @@ namespace Movement if (cyclic_point == 0) points[0] = controls[count - 1]; else - points[0] = controls[0].lerp(controls[1], -1); + points[0] = controls[0] - G3D::Vector3{ std::cos(initialOrientation), std::sin(initialOrientation), 0.0f }; points[high_index + 1] = controls[cyclic_point]; points[high_index + 2] = controls[cyclic_point + 1]; } else { - points[0] = controls[0].lerp(controls[1], -1); + if (m_mode == ModeCatmullrom) + points[0] = controls[0] - G3D::Vector3{ std::cos(initialOrientation), std::sin(initialOrientation), 0.0f }; + else + points[0] = controls[0].lerp(controls[1], -1); + points[high_index + 1] = controls[count - 1]; } diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h index 9645eb607..ef0b6aee5 100644 --- a/src/server/game/Movement/Spline/Spline.h +++ b/src/server/game/Movement/Spline/Spline.h @@ -48,6 +48,7 @@ namespace Movement uint8 m_mode{UninitializedMode}; bool cyclic{false}; + float initialOrientation{0}; enum { @@ -116,8 +117,8 @@ namespace Movement [[nodiscard]] const Vector3& getPoint(index_type i) const { return points[i];} /** Initializes spline. Don't call other methods while spline not initialized. */ - void init_spline(const Vector3* controls, index_type count, EvaluationMode m); - void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point); + void init_spline(const Vector3* controls, index_type count, EvaluationMode m, float orientation); + void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point, float orientation); /** As i can see there are a lot of ways how spline can be initialized would be no harm to have some custom initializers. */ @@ -170,8 +171,8 @@ namespace Movement void computeIndex(float t, index_type& out_idx, float& out_u) const; /** Initializes spline. Don't call other methods while spline not initialized. */ - void init_spline(const Vector3* controls, index_type count, EvaluationMode m) { SplineBase::init_spline(controls, count, m);} - void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point) { SplineBase::init_cyclic_spline(controls, count, m, cyclic_point);} + void init_spline(const Vector3* controls, index_type count, EvaluationMode m, float orientation = 0) { SplineBase::init_spline(controls, count, m, orientation);} + void init_cyclic_spline(const Vector3* controls, index_type count, EvaluationMode m, index_type cyclic_point, float orientation = 0) { SplineBase::init_cyclic_spline(controls, count, m, cyclic_point, orientation);} /** Initializes lengths with SplineBase::SegLength method. */ void initLengths();