From fab0c53b85de559b16dfb5a1c91123e6019cc737 Mon Sep 17 00:00:00 2001 From: cutealien Date: Fri, 20 Aug 2021 16:39:37 +0000 Subject: [PATCH] Add steer parameter to CSceneNodeAnimatorFollowSpline which allows rotating node toward direction of movement. Thanks @ Bate for the patch (patch #175 with minor changes). git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6234 dfc29bdd-3216-0410-991c-e03cc46cb475 --- changes.txt | 2 ++ include/ISceneManager.h | 2 +- source/Irrlicht/CSceneManager.cpp | 4 +-- source/Irrlicht/CSceneManager.h | 2 +- .../CSceneNodeAnimatorFollowSpline.cpp | 28 ++++++++++++++----- .../Irrlicht/CSceneNodeAnimatorFollowSpline.h | 3 +- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/changes.txt b/changes.txt index 9c27ea15..f6d11bb1 100644 --- a/changes.txt +++ b/changes.txt @@ -1,5 +1,7 @@ -------------------------- Changes in 1.9 (not yet released) +- Add steer parameter to CSceneNodeAnimatorFollowSpline which allows rotating node toward direction of movement. + Thanks @ Bate for the patch (patch #175) - Add a workaround for XWarpPointer bug that causes mouse to jump when users have set a Coordinate Transformation Matrix for their mouse on X11. This was mentioned in bug #450 by vikaig. The fix needs compiling with _IRR_LINUX_X11_XINPUT2_ enabled (so far disabled by default) diff --git a/include/ISceneManager.h b/include/ISceneManager.h index 65e81c3d..e0733b19 100644 --- a/include/ISceneManager.h +++ b/include/ISceneManager.h @@ -1261,7 +1261,7 @@ namespace scene See IReferenceCounted::drop() for more information. */ virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, const core::array< core::vector3df >& points, - f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false) = 0; + f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false, bool steer=false) = 0; //! Creates a simple ITriangleSelector, based on a mesh. /** Triangle selectors diff --git a/source/Irrlicht/CSceneManager.cpp b/source/Irrlicht/CSceneManager.cpp index e49e0a93..7d6de532 100644 --- a/source/Irrlicht/CSceneManager.cpp +++ b/source/Irrlicht/CSceneManager.cpp @@ -1872,10 +1872,10 @@ ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnima //! Creates a follow spline animator. ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime, const core::array< core::vector3df >& points, - f32 speed, f32 tightness, bool loop, bool pingpong) + f32 speed, f32 tightness, bool loop, bool pingpong, bool steer) { ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points, - speed, tightness, loop, pingpong); + speed, tightness, loop, pingpong, steer); return a; } diff --git a/source/Irrlicht/CSceneManager.h b/source/Irrlicht/CSceneManager.h index 7340c954..5f0daf33 100644 --- a/source/Irrlicht/CSceneManager.h +++ b/source/Irrlicht/CSceneManager.h @@ -341,7 +341,7 @@ namespace scene //! Creates a follow spline animator. virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, const core::array< core::vector3df >& points, - f32 speed, f32 tightness, bool loop, bool pingpong) _IRR_OVERRIDE_; + f32 speed, f32 tightness, bool loop, bool pingpong, bool steer) _IRR_OVERRIDE_; //! Creates a simple ITriangleSelector, based on a mesh. diff --git a/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp b/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp index 6bbf20c3..ac38549f 100644 --- a/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorFollowSpline.cpp @@ -13,15 +13,17 @@ namespace scene //! constructor CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time, const core::array& points, f32 speed, - f32 tightness, bool loop, bool pingpong) + f32 tightness, bool loop, bool pingpong, bool steer) : ISceneNodeAnimatorFinishing(0), Points(points), Speed(speed), Tightness(tightness) -, Loop(loop), PingPong(pingpong) +, Loop(loop), PingPong(pingpong), Steer(steer) { #ifdef _DEBUG setDebugName("CSceneNodeAnimatorFollowSpline"); #endif StartTime = time; + //if (points.size() != 0) + // LastPos = points[0]; } @@ -86,7 +88,17 @@ void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs) const core::vector3df t2 = ( p3 - p1 ) * Tightness; // interpolated point - node->setPosition(p1 * h1 + p2 * h2 + t1 * h3 + t2 * h4); + const core::vector3df lastPos(node->getPosition()); + const core::vector3df pos(p1 * h1 + p2 * h2 + t1 * h3 + t2 * h4); + node->setPosition(pos); + + // steering (rotate in direction of movement) + if (Steer && !pos.equals(lastPos)) // equality check fixes glitches due to very high frame rates + { + const core::vector3df toTarget(pos - lastPos); + const core::vector3df requiredRotation = toTarget.getHorizontalAngle(); + node->setRotation(requiredRotation); + } } @@ -99,6 +111,7 @@ void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, i out->addFloat("Tightness", Tightness); out->addBool("Loop", Loop); out->addBool("PingPong", PingPong); + out->addBool("Steer", Steer); u32 count = Points.size(); @@ -124,10 +137,11 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in, { ISceneNodeAnimatorFinishing::deserializeAttributes(in, options); - Speed = in->getAttributeAsFloat("Speed"); - Tightness = in->getAttributeAsFloat("Tightness"); - Loop = in->getAttributeAsBool("Loop"); - PingPong = in->getAttributeAsBool("PingPong"); + Speed = in->getAttributeAsFloat("Speed", Speed); + Tightness = in->getAttributeAsFloat("Tightness", Tightness); + Loop = in->getAttributeAsBool("Loop", Loop); + PingPong = in->getAttributeAsBool("PingPong", PingPong); + Steer = in->getAttributeAsBool("Steer", Steer); Points.clear(); for(u32 i=1; true; ++i) diff --git a/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h b/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h index b0eec698..c2864d23 100644 --- a/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h +++ b/source/Irrlicht/CSceneNodeAnimatorFollowSpline.h @@ -22,7 +22,7 @@ namespace scene //! constructor CSceneNodeAnimatorFollowSpline(u32 startTime, const core::array< core::vector3df >& points, - f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false); + f32 speed = 1.0f, f32 tightness = 0.5f, bool loop=true, bool pingpong=false, bool steer=false); //! animates a scene node virtual void animateNode(ISceneNode* node, u32 timeMs) _IRR_OVERRIDE_; @@ -52,6 +52,7 @@ namespace scene f32 Tightness; bool Loop; bool PingPong; + bool Steer; // rotate depending on current movement };