Animator design (a simple proposal)

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Animator design (a simple proposal)

Post by powerpop »

Seems like my game is pushing hard on Animators and other modifiers of SceneNodes - after going around in design circles and trying different patterns out i think i found a simple way out of the box ...

As I wrote in a different thread, there are three kinds of animators - but i want to update that to be four types:

1. Every frame they want to be called - this is the best for things that change the rendering of an object

2. On a timer - this is best for character animation and other motion based things that dont require every frame updates

3. Called from outside - not timer or frame based - some outside object is determining when to update these

4. Data updating - want to be called whenever something in the scenenode changes (rotation, position, etc.)

If each scenenode could keep a list of each of these it would be AMAZING - and if an animator could be added to multiple lists that would be great too - so for physics i could make an animator that would be added to #3 and #4 lists - the animation framework would have callbacks for each type

and #2 would save the framerate! - the scenenode could organize the list to be in the order of fastest to slowest timer - so one object might want an update every 10 milliseconds while another wants it only once a minute

what do people think? - so the current one stays the same - we just add a timer list, static list and data updating list

with this kind of framework our animators would be incredibly powerful for games!!!
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Post by powerpop »

niko - if you dont want to do the above then there are two additions to the current API that would make it possible for me to build a game object above IRR that does this (currently i cant because scenenodes are a blackbox)

- add a userdata pointer to scenenode

- add a flag that gets set when a node gets modified, and cleared during a render loop (after animators are called of course)
powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Post by powerpop »

here is the ISceneNode.h file with the proposed additions:

all the lists work on the Animator class, we would just add two calls - UpdateData and TimerAnimate to the class

Animators would work as they always have (per Frame)

DataUpdaters would get called each frame only if the IsChanged bool i true (if data has been modified in this scenenode)

TimerAnimators would be called each frame with an elapsed time variable - the scenenode should keep the list organized from faster to slower updaters so only those that need to get triggered are during a frame gap.

Code: Select all

	protected:

		//! updates the absolute position based on the relative and the parents position
		void updateAbsolutePosition()
		{
			if (Parent)
				AbsoluteTransformation =
					Parent->getAbsoluteTransformation() * getRelativeTransformation();
			else
				AbsoluteTransformation = getRelativeTransformation();
		}

		//! name of the scene node.
		core::stringw Name;

		//! absolute transformation of the node.
		core::matrix4 AbsoluteTransformation;

		//! relative translation of the scene node.
		core::vector3df RelativeTranslation;

		//! relative rotation of the scene node.
		core::vector3df RelativeRotation;

		//! relative scale of the scene node.
		core::vector3df RelativeScale;

		//! Pointer to the parent
		ISceneNode* Parent;

		//! List of all children of this node
		core::list<ISceneNode*> Children;

		//! List of all Animators
		core::list<ISceneNodeAnimator*> Animators;

		//! List of all DataUpdaters
		core::list<ISceneNodeAnimator*> DataUpdators;

		//! List of all TimeAnimators
		core::list<ISceneNodeAnimator*> TimeAnimators;

		//! User data pointer
		u32 *UserData;

		//! id of the node.
		s32 ID;

		//! pointer to the scene manager
		ISceneManager* SceneManager;

		//! pointer to the triangleselector
		ITriangleSelector* TriangleSelector;

		//! automatic culling
		bool AutomaticCullingEnabled;

		//! flag if debug data should be drawed, like Bounding Boxes.
		bool DebugDataVisible;

		//! is the node visible?
		bool IsVisible;

		//! did data get modified in between frames?
		bool IsChanged;
	};

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

#endif

powerpop
Posts: 171
Joined: Thu Jan 08, 2004 1:39 am
Location: san francisco

Post by powerpop »

and here is the OnPostRender

i havent figured out how to do the timerAnimators since the elapsed time is not sent into OnPostRender - seems like each scenenode would have to hold into the aggregate time elapsed until it made it through its list of timers - for instance there might be three .10, .30 and .40 - if each elapsed time is coming in around 3 milliseconds it will take a while until the .40 one is triggered

hmmm, this is a tough one - its nice to have animators inside scenenodes but having high gap timers (.40 for instance) means that a ton of performance gets killed if the animators gets called every frame - right now in my game i keep these kinds of animators completely separate from the scenenode they effect

Code: Select all

		virtual void OnPostRender(u32 timeMs)
		{
			if (IsVisible)
			{
				// animate this node with all dataupdators if changed
				if (IsChanged)
				{
					core::list<ISceneNodeAnimator*>::Iterator ait = DataUpdaters.begin();
					for (; ait != DataUpdaters.end(); ++ait)
						(*ait)->dataUpdateNode(this, timeMs);
				}

				IsChanged = false;

				// animate this node with all animators

				core::list<ISceneNodeAnimator*>::Iterator ait = Animators.begin();
				for (; ait != Animators.end(); ++ait)
					(*ait)->animateNode(this, timeMs);

				// update absolute position
				updateAbsolutePosition();

				// perform the post render process on all children

				core::list<ISceneNode*>::Iterator it = Children.begin();
				for (; it != Children.end(); ++it)
					(*it)->OnPostRender(timeMs);
			}
		}

keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

i think these are definately reasonable requests, with not much impact on regular IrrLicht
a screen cap is worth 0x100000 DWORDS
Post Reply