MD5 Animation. Performance issues

It’s not completely clear what you’re doing. But as always, if your performance is sufficient, it’s only an academic exercise to optimize further.

I see you loading matrices in your game loop, and that tells me that you haven’t uploaded your full joint transform palette to the GPU (one transform per animation/keyframe/joint) as a preprocess, and pushed “game time” transform sampling and keyframe interpolation to the GPU. That’s just fine if you don’t need more speed.

Re your comment about the animation rendering very quickly and having to “slow it down”. What you’re doing works but is fragile. If your rendered frame rate changes, you’ve got to go tweak all those delays (expressed as “number of frames”).

I suggest you instead use wall clock time as a global clock to gate the playback speed of your animations. Basically, there is a global time (wall clock time) measured in seconds. Your animation has a specified start time which is given in global time. Based on the current time you can compute how long the animation has been running (seconds). Your skeletal animation has a specified play speed (keyframes per second). So with a simple product you can compute which keyframe you should be on “this frame” (mod this product by the number of keyframes in the animation if this is a looping animation). Use this to determine which two keyframes you need to interpolate between to get a pose which is “in between” the poses specified (the fractional part of this keyframe gives you the blend percentage).

If you use this method, then your animation always updates at the appropriate “real-world” rate, regardless of whether your renderer is rendering frames at 1000Hz, 60Hz, 30Hz, or some other random frame rate – even a variable one.

If you have Jason Gregory’s “Game Engine Architecture” book, read up on the global clock animation method there (see time or clock in the index).

E ended up doing something like this , just to test how would it act if i use current time elapsed etc.
Also Restricted Uploading to shader if the matrix is the same as previous one. This gave me huge boost. Animation does not feel or play choppy , it’s pretty smooth. The interpolation you are talking about is happening during the caching of the matrices before the main game loop which i have not included here. It is a part of ogl’s code.


rtime += DisplayManager::getElapsedTime();
		float TimeInTicks = rtime * 25.0f;
		float AnimationTime = fmod(TimeInTicks, MAX_MAT - 1);
		buffer_index = index;
		index = (int)AnimationTime;
		
		if (buffer_index != index)
		{
			ShdrSimple->StartShader();
			for (uint i = 0; i < Transformations[index].size(); i++)
			{
				glm::mat4 out;
				memcpy(&out, &Transformations[index][i], sizeof(Transformations[index][0]));
				ShdrSimple->loadUniform4fvTransposed(&out[0][0], ShdrSimple->getVariableID("gBones[" + to_string(i) + "]"));
			}
			ShdrSimple->StopShader();
		}
		md5Renderer->Render(Mesh);


Got it Working, using the clock. Now the animation runs smooth and equally fast anywhere, very nice ,thanks again for the information. In your post you mentioned “… if this is a looping animation”, it is indeed looping animation , but is it possible to apply a simple walk animation to play continuously when i press some key. At the moment i managed to make the animation play when i press a key , but when it reaches the end of the walk animation it loops back to the beginning and the model translates back (takes back several steps). Basically the idea is to make him walk indefinitely while a key is pressed without looping to its starting position

I assume you’re talking about the character’s pose, and not just the position at which the character is centered (its object space) as you can keep track of the accumulated position internal to your animation state.

Yeah, in the general case, one animation track isn’t sufficient. You need feathered blending between animation tracks to do the start and stop smoothly (legs winding up and winding down). Once you’re ready for this added realism, read up on Animation State Machines (aka Action State Machines), or ASMs. These let your friendly content modeler build these so your program can just read it an use it to generate smoothly-varying animation states.

I don’t think we are talking about the same thing here. I think you are talking about smooth transitioning between different animations.Idle/Walk/Attack etc. Which is in my TODO list, as well. But I am talking about something else.
Lets take my Walk Animation for example , it has certain number of matrices generated and the vertex shader interpolates, and does the skinning process. Lets assume that the model starts at point A ,when the whole walk animation is played the model now resides at point B. Now the animation Loops and the model translates back to starting point A repeating the process over and over. My Question was how would i make the model advance in translation( in other words make it walk not just return to its starting position). I assume that after 1 animation cycle is played i should translate the model to the furthest location in space that the animation can get to (position B) Then when the walk start again the model will be at position B and when the animation finishes it will be translated to position C , then i can simply repeat the process and the model will actually walk ahead ??
Am i right or horribly wrong ?

Ah, I see! You have root motion baked into your animation track. You need to extract that and use it to move your character’s object space around (i.e. use this to update the character’s modeling transform).

(Sorry, I did misunderstand what you were describing.)

That’s Right! Can you explain more in depth with some example steps ? What does root motion baking stands for ? Not very familiar with all graphics terms yet , thanks

If you want a good, coherent write-up of this and many other skeletal concepts, I highly recommend you pick up a copy of:

It’s worth your time and money. There’s a 2nd edition; it’ll probably work too; but I don’t have it.

Or for starters, just websearch it (e.g. root motion, root bone motion, motion extraction, etc.) Combine with the names of various skeletal tools/exporters to get targeted hits (Granny3D, Havok Behavior, Unity3D, Blender, etc.) Or do a targetted search on gamdev.net (site:gamedev.net). You’ll find hits in many places. Any decent skeletal animation publishing tool will describe this.

But briefly, root motion is where the motion of the character through the world (translation, turning, rise-and-fall, etc.) is “baked” (pre-encoded) into the skeletal joint transform data somehow. Sometimes this is placed on the root joint. But depending the DCC (3D modeling/animation) tools used, a child joint which encodes the “local origin” of the entity might be used instead. In any case, the animation has some joint through which you can determine how the character needs to move (translate+rotate) through the world as time progresses.

Good God , i am so frustrated. I have been looking for some good md5 import/export for more recent versions of blender but i can not find any working. I found a working md5 mesh/anim importer but for blender 2.49b.I can import animation and mesh but i have no idea where the dope sheet is (if it even exists in 2.49b ?) Here is the solution on how to remove the root motion in animations but it is for recent versions of blender 2.7+: Removing Root Motion on Blender: https://www.youtube.com/watch?v=WXw73tBd1PM.

PS: I found a very nice Simple Model Loading Tool. But i get strange results when i try to import the md5mesh. (the tool is based on assimp)[ATTACH=CONFIG]1051[/ATTACH]

PS2: Managed to find a workaround using 3DS Max and importing/exporting the models from there. Still Trying to figure out how to extract the root motion , tho !

Perhaps you should take that as a sign about how widely used MD5 is as a model format.

Yea i realize that, long before i started doing the implementation of the Loader in my Engine. But i find it somewhat easy to understand and i found really nice tutorial about how to implement animation. In future i plan to have Collada (.dae) as main animated models file format . Other cool thing is that you can find tons of test assets of MD5 in Doom3

UPDATE: Ditched the MD5 files from Doom 3, and tried to use other models. Since i have LoL on my PC i exported a model converted it to FBX and from FBX to MD5. It’s working fantastic , animation and mesh look fine but there is a small hitch. The Picture below shows the model , the model is supposed be holding the axe with it’s right hand, but the axe appears to be drawn at origin space (at the center of the model). The picture below is from 3DS Max (i tried to load the model in my engine , same exact problem appears) My Guess is that this is happening during conversion from FBX to MD5 (i do this convertion in blender)
[ATTACH=CONFIG]1052[/ATTACH]
PS: Model Looks fine in FBX, model and animations are fine

Unless you’re on a tight budget, you might consider purchasing Granny3D and use its GR2 format for skeletal assets (and GState for Animation State Machines). If you needs are similar (and its sounding like they are), it’ll save you a lot of trouble publishing and loading skeletal assets.

Well i have seen it but never really considered the idea. Thanks.
Any suggestions why the axe mesh would appear in origin space (e.g. local space 0,0,0)

Just a semi-random guess: could be the axe is built to be a skeletal attachment. That is, it could be you’re supposed to decide when the axe is rendered with the character, and when it is, position it at the appropriate attachment joint in the character model (e.g. hand, chest mount, back mount, etc.).

I was wondering if someone here could offer me a nice working Converter from .dae to md5 ? I tried to use the blender converter (to md5) in blender 2.73 but i get some errors during conversion (however using the same blender converter i can convert .fbx to .md5 without any problems, except the axe problem). Also i CAN convert .fbx to md5 but as stated in my other post character’s axe is miss placed. Assuming that the problem occurs while converting to md5. The Axe Problem however is not present in the .dae or .fbx files.

PS: I think i have figured out why the axe is miss places. The reason is that the Model has Root bone and The Axe has Root Bone aswell , and we cannot have 2 root bones in an MD5

PS2: Confirmed 1 Root Bone Models Work Fine. I will try to stick to 1 Root Bone Models , until i find out a workaround or i implement a collada loader

PS3: I just tried to load a .dae file to my MD5 loader and it loaded perfectly , with all animations working. No asserts , no exceptions, dead on loaded two different .dae models