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
This commit is contained in:
cutealien 2021-08-20 16:39:37 +00:00
parent 54e10d0dbe
commit fab0c53b85
6 changed files with 29 additions and 12 deletions

@ -1,5 +1,7 @@
-------------------------- --------------------------
Changes in 1.9 (not yet released) 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. - 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. This was mentioned in bug #450 by vikaig.
The fix needs compiling with _IRR_LINUX_X11_XINPUT2_ enabled (so far disabled by default) The fix needs compiling with _IRR_LINUX_X11_XINPUT2_ enabled (so far disabled by default)

@ -1261,7 +1261,7 @@ namespace scene
See IReferenceCounted::drop() for more information. */ See IReferenceCounted::drop() for more information. */
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points, 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. //! Creates a simple ITriangleSelector, based on a mesh.
/** Triangle selectors /** Triangle selectors

@ -1872,10 +1872,10 @@ ISceneNodeAnimatorCollisionResponse* CSceneManager::createCollisionResponseAnima
//! Creates a follow spline animator. //! Creates a follow spline animator.
ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime, ISceneNodeAnimator* CSceneManager::createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points, 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, ISceneNodeAnimator* a = new CSceneNodeAnimatorFollowSpline(startTime, points,
speed, tightness, loop, pingpong); speed, tightness, loop, pingpong, steer);
return a; return a;
} }

@ -341,7 +341,7 @@ namespace scene
//! Creates a follow spline animator. //! Creates a follow spline animator.
virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime, virtual ISceneNodeAnimator* createFollowSplineAnimator(s32 startTime,
const core::array< core::vector3df >& points, 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. //! Creates a simple ITriangleSelector, based on a mesh.

@ -13,15 +13,17 @@ namespace scene
//! constructor //! constructor
CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time, CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time,
const core::array<core::vector3df>& points, f32 speed, const core::array<core::vector3df>& 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) : ISceneNodeAnimatorFinishing(0), Points(points), Speed(speed), Tightness(tightness)
, Loop(loop), PingPong(pingpong) , Loop(loop), PingPong(pingpong), Steer(steer)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSceneNodeAnimatorFollowSpline"); setDebugName("CSceneNodeAnimatorFollowSpline");
#endif #endif
StartTime = time; 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; const core::vector3df t2 = ( p3 - p1 ) * Tightness;
// interpolated point // 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->addFloat("Tightness", Tightness);
out->addBool("Loop", Loop); out->addBool("Loop", Loop);
out->addBool("PingPong", PingPong); out->addBool("PingPong", PingPong);
out->addBool("Steer", Steer);
u32 count = Points.size(); u32 count = Points.size();
@ -124,10 +137,11 @@ void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in,
{ {
ISceneNodeAnimatorFinishing::deserializeAttributes(in, options); ISceneNodeAnimatorFinishing::deserializeAttributes(in, options);
Speed = in->getAttributeAsFloat("Speed"); Speed = in->getAttributeAsFloat("Speed", Speed);
Tightness = in->getAttributeAsFloat("Tightness"); Tightness = in->getAttributeAsFloat("Tightness", Tightness);
Loop = in->getAttributeAsBool("Loop"); Loop = in->getAttributeAsBool("Loop", Loop);
PingPong = in->getAttributeAsBool("PingPong"); PingPong = in->getAttributeAsBool("PingPong", PingPong);
Steer = in->getAttributeAsBool("Steer", Steer);
Points.clear(); Points.clear();
for(u32 i=1; true; ++i) for(u32 i=1; true; ++i)

@ -22,7 +22,7 @@ namespace scene
//! constructor //! constructor
CSceneNodeAnimatorFollowSpline(u32 startTime, CSceneNodeAnimatorFollowSpline(u32 startTime,
const core::array< core::vector3df >& points, 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 //! animates a scene node
virtual void animateNode(ISceneNode* node, u32 timeMs) _IRR_OVERRIDE_; virtual void animateNode(ISceneNode* node, u32 timeMs) _IRR_OVERRIDE_;
@ -52,6 +52,7 @@ namespace scene
f32 Tightness; f32 Tightness;
bool Loop; bool Loop;
bool PingPong; bool PingPong;
bool Steer; // rotate depending on current movement
}; };