Page 1 of 1

a b-spline animator

Posted: Tue Jul 03, 2007 5:31 am
by ikam
I'm working on a spline editor :
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=22559

But in some case I was not totally satisfied of the spline created with createFollowSplineAnimator because the start of the spline is influenced by the last point position :

Image

I created a new spline animator based on a b-spline, the difference are :
- the start is not influenced by the end
- the controls points are not on the spline but outside (easy to edit with my editor :P )
- the node doesn't slow on curve points
- at the end of the spline the node jump instantaneously at the start. (maybe it will be usefull to add an option to run only once and add a self removing animator with the vitek's functions )

i've add too a feature to rotate the node animated by this for always look forward facing the spline

Image


the code (based on the Rob Bateman opengl exemple of b-spline) :

Code: Select all

class CBSplineAnimator : public ISceneNodeAnimator
{
public: 
	CBSplineAnimator(u32 time, core::array<core::vector3df> points, f32 speed = 1.0f);
	virtual ~CBSplineAnimator ();
	virtual void animateNode (scene::ISceneNode *node, u32 timeMs);

protected:
	int clamp(s32 idx, u32 size);

	core::array<core::vector3df> mPoints;
	u32 mStartTime;
	f32 mSpeed;
};


CBSplineAnimator::CBSplineAnimator(u32 time, core::array<core::vector3df> points, f32 speed) 
{
	mStartTime = time;
	mPoints = points;
	mSpeed = speed;
}

CBSplineAnimator::~CBSplineAnimator ()
{
}


inline int CBSplineAnimator::clamp(s32 idx, u32 size) 
{
	return ( idx<0 ? 0 : ( idx>=size ? size-1 : idx ) );
}


void CBSplineAnimator::animateNode (scene::ISceneNode *node, u32 timeMs)
{ 
	u32 pSize = mPoints.size(); 	

	const f32 dt = ( (timeMs-mStartTime) * mSpeed * 0.001f );
	const f32 u = core::fract ( dt );
	s32 idx = core::floor32( dt ) % (pSize+1); 
	f32 iu = 1.0f-u;

	float b0 = iu * iu * iu / 6.0f;
	float b1 = ( 3 * u * u * u - 6 * u * u + 4 ) / 6.0f;
	float b2 = (-3 * u * u * u + 3 * u * u + 3* u + 1 ) /6.0f;
	float b3 = u * u * u /6.0f;     

	core::vector3df f, p0, p1, p2, p3;
	p0 = mPoints[ clamp( idx-2, pSize ) ];
	p1 = mPoints[ clamp( idx-1, pSize ) ];
	p2 = mPoints[ clamp( idx+0, pSize ) ];
	p3 = mPoints[ clamp( idx+1, pSize ) ]; 

	f = b0 * p0 + b1 * p1 + b2 * p2 + b3 * p3;        

	// set node orientation
	core::vector3df direction = node->getPosition() - f;
	node->setRotation(direction.getHorizontalAngle());

	// set node position
	node->setPosition(f);    
}
exmple for use :

Code: Select all

CBSplineAnimator *anim = new CBSplineAnimator(device->getTimer()->getTime(), points, 4.0f);
	cubeNode->addAnimator((scene::ISceneNodeAnimator*)anim);

Posted: Tue Jul 03, 2007 7:14 am
by Donner
Hey, great work!!!

I didn't test it, but it seems really great!

I think that could be useful to let the enemies, who are controlled by the computer, go more realistic ways!


Really good!

Posted: Tue Jul 03, 2007 8:45 pm
by bitplane
cool.. nice little snippet. would you mind if i added this to irrlicht plugins?

Posted: Tue Jul 03, 2007 9:52 pm
by ikam
no problem bitplane :wink:

Posted: Tue Aug 18, 2009 6:34 pm
by Holiday
i have a little problem.. it gives me cannot allocate an object of type `CBSplineAnimator' because following virtual functions are abstract: blah blah error;

its on this line
CBSplineAnimator *anim = new CBSplineAnimator(device->getTimer()->getTime(), points, 4.0f);

i'm don't know what im doing wrong, please help me :cry:

Posted: Tue Aug 18, 2009 6:56 pm
by FuzzYspo0N
Cool code snippet indeed! This is something we were discussing on irc, the spline animator.

Posted: Tue Aug 18, 2009 7:22 pm
by Holiday
please anybody? :oops:

Posted: Tue Aug 18, 2009 8:25 pm
by hybrid
you have to add the missing methods (those which are listed *after* the part of the error message that you showed us). Seems like there's some version changes that you have to fix.

Posted: Tue Aug 18, 2009 8:34 pm
by Holiday
how? where? what? please explain in a noob way

Posted: Wed Aug 19, 2009 7:04 am
by hybrid
Maybe buy a book on C++ and read about abstract classes (pure virtual methods). Usually, the problem is that a method was added or the signature of an existing method has changed. If the method cannot be overloaded, the remaining pure virtual method prevents creation of objects of that class.