New Rotate Animator

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
raven_coda
Posts: 89
Joined: Thu Aug 17, 2006 8:11 pm
Location: Salt Lake City, UT, USA
Contact:

New Rotate Animator

Post by raven_coda »

For one of my projects I made a new rotate animator that rotates a node from a to b over a set time. It's based off the flystraight animator.There is also a bool for repeat where it starts going back and forth from a and b. Works well for the camera in fly bys or whatever else. We are using it to animate a little security camera that scans back and forth on one of our maps. Let me know what you think and or what uses you have for it!

CSeneNodeAnimatorRotate.cpp

Code: Select all


#include "CSceneNodeAnimatorRotate.h"

namespace irr
{
namespace scene
{


//! constructor
CSceneNodeAnimatorRotate::CSceneNodeAnimatorRotate(const core::vector3df& startRotation,
							const core::vector3df& endRotation, u32 timeForWay,
							bool loop, u32 now)
: Start(startRotation), End(endRotation), StartTime(now), TimeForWay(timeForWay), Loop(loop)
{
	#ifdef _DEBUG
	setDebugName("CSceneNodeAnimatorRotate");
	#endif

	recalculateImidiateValues();
}


void CSceneNodeAnimatorRotate::recalculateImidiateValues()
{
	Vector = End - Start;
	WayLength = (f32)Vector.getLength();
	Vector.normalize();

	TimeFactor = WayLength / TimeForWay;
}



//! destructor
CSceneNodeAnimatorRotate::~CSceneNodeAnimatorRotate()
{
}



//! animates a scene node
void CSceneNodeAnimatorRotate::animateNode(ISceneNode* node, u32 timeMs)
{
	if (!node)
		return;

	u32 t = (timeMs-StartTime);

	core::vector3df pos = Start;

	if (!Loop && t >= TimeForWay)
		pos = End;
	else if (t > TimeForWay)
	{
		StartTime+=TimeForWay;
		t-=TimeForWay;
		core::vector3df tmp=Start;
		Start=End;
		End=tmp;
		recalculateImidiateValues();
		pos = Start;
		pos += Vector * (f32)t * TimeFactor;
	}
	else
		pos += Vector * (f32)t * TimeFactor;
	node->setRotation(pos);
}


//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorRotate::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options)
{
	out->addVector3d("Start", Start);
	out->addVector3d("End", End);
	out->addInt("TimeForWay", TimeForWay);
	out->addBool("Loop", Loop);
}


//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorRotate::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
	Start = in->getAttributeAsVector3d("Start");
	End = in->getAttributeAsVector3d("End");
	TimeForWay = in->getAttributeAsInt("TimeForWay");
	Loop = in->getAttributeAsBool("Loop");

	recalculateImidiateValues();
}


} // end namespace scene
} // end namespace irr

CSeneNodeAnimatorRotate.h

Code: Select all


#ifndef __C_SCENE_NODE_ANIMATOR_ROTATE_H_INCLUDED__
#define __C_SCENE_NODE_ANIMATOR_ROTATE_H_INCLUDED__

#include "ISceneNode.h"

namespace irr
{
namespace scene
{
	class CSceneNodeAnimatorRotate : public ISceneNodeAnimator
	{
	public:

		//! constructor
		CSceneNodeAnimatorRotate(const core::vector3df& startRotation, 
									  const core::vector3df& endRotation, u32 timeForWay,
									  bool loop, u32 now);

		//! destructor
		virtual ~CSceneNodeAnimatorRotate();

		//! animates a scene node
		virtual void animateNode(ISceneNode* node, u32 timeMs);

		//! Writes attributes of the scene node animator.
		virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0);

		//! Reads attributes of the scene node animator.
		virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);

		//! Returns type of the scene node animator
		virtual ESCENE_NODE_ANIMATOR_TYPE getType()	{ return ESNAT_ROTATE; }

	private:

		void recalculateImidiateValues();

		core::vector3df Start;
		core::vector3df End;
		core::vector3df Vector;
		f32 WayLength;
		f32 TimeFactor;
		u32 StartTime;
		u32 TimeForWay;
		bool Loop;
	};


} // end namespace scene
} // end namespace irr

#endif


add to ISceneManager.h

Code: Select all

	//! Creates a rotate animator, which lets the attached scene node change rotations smoothly.
		/** \param startRotation: Starting rotation.
		 \param endRotation: Ending rotation.
		 \param timeForWay: Time in milli seconds how long the node should need to
		 move from the start rotation to the end rotation.
		 \param loop: If set to false, the node stops when the end point is reached.
		 If loop is true, the node begins then starts heading back.
		 \return Returns the animator. Attach it to a scene node with ISceneNode::addAnimator()
		 and the animator will animate it.
		 If you no longer need the animator, you should call ISceneNodeAnimator::drop().
		 See IUnknown::drop() for more information. */
		virtual ISceneNodeAnimator* createRotateAnimator(const core::vector3df& startRotation,
			const core::vector3df& endRotation, u32 timeForWay, bool loop=false) = 0;
add to CSceneManager.h

Code: Select all



		//! Creates a rotate animator, which lets the attached scene node
		//! rotate from one rotation to the other smoothly.
		virtual ISceneNodeAnimator* createRotateAnimator(const core::vector3df& startRotation,
			const core::vector3df& endRotation, u32 timeForWay, bool loop=false);

add to CSceneManager.cpp

Code: Select all

#include "CSceneNodeAnimatorRotate.h"
and

Code: Select all


//! Creates a rotate animator, which lets the attached scene node
//! rotate from one rotation to the other smoothly.
ISceneNodeAnimator* CSceneManager::createRotateAnimator(const core::vector3df& startRotation,
					const core::vector3df& endRotation, u32 timeForWay, bool loop)
{
	ISceneNodeAnimator* anim = new CSceneNodeAnimatorRotate(startRotation,
		endRotation, timeForWay, loop, os::Timer::getTime());

	return anim;
}
Definition of an Upgrade: Take old bugs out, put new ones in.
radishlaw
Posts: 6
Joined: Tue Jan 16, 2007 2:25 pm

Post by radishlaw »

Thanks for sharing your code.
In my project I need to have a node constantly trying to face another moving node (think turret aiming at a ship)
Your animation code is potentially useful for this but it would be very troublesome to keep making new animators everytime the target moves.
Would it be too troublesome if you can give me a few pointers on converting it for such a use?
raven_coda
Posts: 89
Joined: Thu Aug 17, 2006 8:11 pm
Location: Salt Lake City, UT, USA
Contact:

Post by raven_coda »

hmm well, as long as you constantly follow your target then you could just update it every frame like this:

Code: Select all

core::vector3df direction = turret->getPosition() - ship->getPosition(); 
turret->setRotation(direction.getHorizontalAngle()); 
Definition of an Upgrade: Take old bugs out, put new ones in.
Post Reply