[Share] Animation System

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
salival
Gnoblar
Posts: 9
Joined: Wed Nov 07, 2012 9:36 am
x 3

[Share] Animation System

Post by salival »

Hello everyone, I'm doing a game that needed multiple animation blending, so I created a simple system for this. Maybe someone else has use for it. Oh, and feel free to come with ideas or improvements :)

Have a good day.

Usage:

Code: Select all

//animation id's
enum AnimationID
{
	ANIM_IDLE,
	ANIM_RUN
};

//pseudo code
class MyEntity : public Animations
{
	public:
		/**
		 * Get entity reference
		 * @return				Entity reference.
		 */
		Ogre::Entity& getEntity() const {
			return *mEntity;
		}

	private:
		
		Ogre::Entity* mEntity;
};

void test()
{
	MyEntity entity;

	entity.registerAnimation(entity.getEntity(), 1.0f, 7.5, 4.5, true, ANIM_IDLE, "Idle");
	entity.registerAnimation(entity.getEntity(), 1.0f, 7.5, 4.5, true, ANIM_RUN, "Run");

	//set idle as default
	entity.setAnimation( ANIM_IDLE, Animations::eInstant );

	//switch using blending
	entity.setAnimation( ANIM_RUN );

	//update each frame
	entity.updateAnimations( timestep );
}
src:

Code: Select all

#include <animations.h>
#include <ogre/OgreEntity.h>
#include <ogre/OgreAnimationState.h>

//constructor
Animations::Animations() :	mActiveStatePtr( nullptr )
{
}

//registerAnimation
void Animations::registerAnimation(Ogre::Entity& entity, float speed, float blend_in, float blend_out, bool looping, AnimationID animationId, std::string const& name)
{
	if( entity.hasAnimationState(name) )
	{
		auto* statePtr = entity.getAnimationState(name);
		if( statePtr )
		{
			statePtr->setLoop(looping);
			statePtr->setEnabled(0);
			statePtr->setWeight(0);
			statePtr->setTimePosition(0);
			mAnimationSet[animationId] = AnimationData(statePtr, speed, blend_in, blend_out);
		}
	}
}

//setAnimation
void Animations::setAnimation(AnimationID animationId, SwitchStates state)
{
	auto it = mAnimationSet.find(animationId);
	if( it != std::end(mAnimationSet) ) {
		setAnimation(it->second, state);
	}
}

//setAnimation
void Animations::setAnimation(AnimationData& animation, SwitchStates state)
{
	switch( state )
	{
		case eInstant:
		{
			if( mActiveStatePtr ) {
				mActiveStatePtr->mStatePtr->setWeight(0);
				mActiveStatePtr->mStatePtr->setEnabled(0);
			}
			mActiveStatePtr = &animation;
			mActiveStatePtr->mStatePtr->setEnabled(1);
			mActiveStatePtr->mStatePtr->setTimePosition(0);
			mActiveStatePtr->mStatePtr->setWeight(1);
			break;
		}
		case eBlending:
		{
			//blending.
			if( mActiveStatePtr && mActiveStatePtr != &animation ) {
				mDeadList.push_back( mActiveStatePtr );
			}

			//activate new animation state.
			mActiveStatePtr = &animation;
			mActiveStatePtr->mStatePtr->setEnabled(1);
			break;
		}
	}
}

// Update the animation states.
void Animations::updateAnimations(float timestep)
{
	//blend in the new active animation.
	if( mActiveStatePtr )
	{
		Ogre::Real weight = mActiveStatePtr->mStatePtr->getWeight();
		if( weight < 1 ) {
			weight = std::min<float>( weight + (timestep * mActiveStatePtr->mBlendIn), 1.0f );
			mActiveStatePtr->mStatePtr->setWeight(weight);
		}
		mActiveStatePtr->mStatePtr->addTime(timestep * mActiveStatePtr->mSpeed);
	}

	//blend out / remove the "dead" animations.
	std::for_each( std::begin(mDeadList), std::end(mDeadList), [&]( AnimationData* dataPtr ) {
		dataPtr->mStatePtr->setWeight( std::max<float>( dataPtr->mStatePtr->getWeight() - (timestep * dataPtr->mBlendOut), 0.0f ) );
	});
	mDeadList.remove_if( [&]( AnimationData* dataPtr ) { return (dataPtr->mStatePtr->getWeight() == 0.0f || dataPtr == mActiveStatePtr); } );
}

//setAnimationSpeed
void Animations::setAnimationSpeed(AnimationID animationId, float speed)
{
	auto it = mAnimationSet.find( animationId );
	if( it != std::end(mAnimationSet) ) {
		it->second.mSpeed = speed;
	}
}

//clearAnimations
void Animations::clearAnimations()
{
	mAnimationSet.clear();
	mActiveStatePtr = nullptr;
}
header:

Code: Select all

#include <list>
#include <map>

//forward declaration.
namespace Ogre {
	class Entity;
	class AnimationState;
}

class Animations
{
	public:

		/**
		 * Constructor
		 */
		Animations();

		//typedefs
		typedef std::list<AnimationData*> DeadList;
		typedef std::map<AnimationID, AnimationData> MAnimationSet;

		//animation switch states
		enum SwitchStates
		{
			eBlending,
			eInstant
		};

		/**
		* Register new animation state.
		* @param	entity				Entity reference.
		* @param	speed				Animation speed.
		* @param	blend_in			Animation blend in speed.
		* @param	blend_out			Animation blend in speed.
		* @param	looping				Animation loop state.
		* @param	animationId			Animation id.
		* @param	name				Skeleton animation name.
		*/
		void registerAnimation(Ogre::Entity& entity, float speed, float blend_in, float blend_out, bool looping, AnimationID animationId, std::string const& name);

		/**
		* Set new animation state.
		* @param			Animation id.
		* @param			Current animation state.
		*/
		void setAnimation(AnimationID animationId, SwitchStates state = eBlending);

		/**
		 * Set new animation state.
		 * @param			AnimationData reference.
		 * @param			Current animation state.
		 */
		void setAnimation(AnimationData& animation, SwitchStates state = eBlending);

		/**
		 * Set new animation speed.
		 * @param	animationId			Animation id.
		 * @param	speed				New animation speed.
		 */
		void setAnimationSpeed(AnimationID animationId, float speed);

		/**
		 * Update the animation states.
		 * @param	timestep			Current timestep.
		 */
		void updateAnimations(float timestep);

		/**
		* clear animations.
		*/
		void clearAnimations();

		/**
		 * Get current active animation.
		 * @return				Current active animation state.
		 */
		inline AnimationData* getActiveState() {
			return mActiveStatePtr;
		}

	private:

		// animation states.
		MAnimationSet mAnimationSet;

		// storage of dead states.
		DeadList mDeadList;

		// current active animation state.
		AnimationData* mActiveStatePtr;
};
nickG
Greenskin
Posts: 122
Joined: Fri Jan 20, 2012 6:44 pm
Location: Russia,Moscow
x 1

Re: [Share] Animation System

Post by nickG »

subscribed for integration in my code
thanks
RigoCL
Greenskin
Posts: 114
Joined: Mon Oct 14, 2013 1:41 am
Location: Chile
x 3

Re: [Share] Animation System

Post by RigoCL »

Thanks for sharing.

I started to implement my own Animation Manager some months ago, considering that most of the Ogre examples use one, and only one, global variable for keep tracking and updating only one animation at any time, the problem is that in most cases you need to deal with several animations at any time, some meshes already come with a skeleton file, some others don't but you still need to animate them.

This blending algorithm is very handy to improve my own animation manager.
Integrated: Ogre3D + dotScene (Blender loader) + MyGUI (UI) + RakNet (Client/Server) + Leap Motion (The future is here!) + StereoManager (3D Anaglyph red-cyan)
WIP: StereoManager (Real 3D) + CCS (Camera Control System) + Sound, experimenting with Android.
User avatar
Thyrion
Goblin
Posts: 224
Joined: Wed Jul 31, 2013 1:58 pm
Location: germany
x 8

Re: [Share] Animation System

Post by Thyrion »

just to be sure you don't missed this thread
http://www.ogre3d.org/forums/viewtopic.php?f=11&t=45260
RigoCL
Greenskin
Posts: 114
Joined: Mon Oct 14, 2013 1:41 am
Location: Chile
x 3

Re: [Share] Animation System

Post by RigoCL »

I did, old post btw, hope it still woks, thanks anyway.
Integrated: Ogre3D + dotScene (Blender loader) + MyGUI (UI) + RakNet (Client/Server) + Leap Motion (The future is here!) + StereoManager (3D Anaglyph red-cyan)
WIP: StereoManager (Real 3D) + CCS (Camera Control System) + Sound, experimenting with Android.
User avatar
Zonder
Ogre Magi
Posts: 1168
Joined: Mon Aug 04, 2008 7:51 pm
Location: Manchester - England
x 73

Re: [Share] Animation System

Post by Zonder »

There are 10 types of people in the world: Those who understand binary, and those who don't...
User avatar
Thyrion
Goblin
Posts: 224
Joined: Wed Jul 31, 2013 1:58 pm
Location: germany
x 8

Re: [Share] Animation System

Post by Thyrion »

but no sourcecode? and
I decided to try to make a more
"professional" one (maintained, with regular releases,...etc)
could hold this for a year? XD
User avatar
Zonder
Ogre Magi
Posts: 1168
Joined: Mon Aug 04, 2008 7:51 pm
Location: Manchester - England
x 73

Re: [Share] Animation System

Post by Zonder »

Thyrion wrote:but no sourcecode? and
I decided to try to make a more
"professional" one (maintained, with regular releases,...etc)
could hold this for a year? XD
I wasn't endorsing it but just pointing out there was also another project eithen though it's commercial.
There are 10 types of people in the world: Those who understand binary, and those who don't...
frostbyte
Orc Shaman
Posts: 737
Joined: Fri May 31, 2013 2:28 am
x 65

Re: [Share] Animation System

Post by frostbyte »

Dont waste your time...
AFAICSee the commercial project is dead ...havn't been been updated since 2009 and the link to the free-tryout is broken...
NEVER the less - payment option still seems to be availble - with an outrageous price range( can buy unity pro for that price...but i would'nt :roll: )
TechnoFreak's project still works, looks preety, nice , FREE...and OpenSource!!!
best thing is to write your own blending - so this code snipplet can become quite handy - thanks for sharing... 8)
the woods are lovely dark and deep
but i have promises to keep
and miles to code before i sleep
and miles to code before i sleep..

coolest videos link( two minutes paper )...
https://www.youtube.com/user/keeroyz/videos
RigoCL
Greenskin
Posts: 114
Joined: Mon Oct 14, 2013 1:41 am
Location: Chile
x 3

Re: [Share] Animation System

Post by RigoCL »

I do agree that TechnoFreak's project is the one and only option, but writing your own code would be a waste of time either, unless you have plenty of spare time.
Integrated: Ogre3D + dotScene (Blender loader) + MyGUI (UI) + RakNet (Client/Server) + Leap Motion (The future is here!) + StereoManager (3D Anaglyph red-cyan)
WIP: StereoManager (Real 3D) + CCS (Camera Control System) + Sound, experimenting with Android.
Post Reply