Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

ID3DXAnimationController Problem

Started by rKallmeyer Feb 27, 2005 at 1:38 PM 4 replies 3.6k views
Original Post
rKallmeyer
rKallmeyer
I am having a problem with the ID3DXAnimationController Class. My goal is to seperate the AnimationController from the mesh class in the same way that the MultiAnimation sample from the SDK does. I load the mesh from a D3D9Mesh class, which contains the root frame and the first AnimationController. To create animation entities, I clone the animation controller from the D3D9Mesh, and create a new array of bone transformation matricies. When it's time to render an entity, I call AnimationController->AdvanceTime() and then apply of the transformations to the root frame contained in the D3D9Mesh class. Right aftward, I use the the transformed frame hierarchy to transform the skin mesh contained in the entity class, and everything should be fine. Here is the problem I'm getting: I can make one mesh + entity pair (clone the D3D9Mesh AnimationController once) with no problem, everything works great. But if I make another mesh + entity pair (with the same or different mesh), the program hangs when I call AnimationController->AdvanceTime() for the second entity. I've been trying to figure this out for a couple of days with no luck, so if you think you can help me, let me know what else you need to know, or what parts of the source code I should post.
peter_b
peter_b
Since its AdvanceTime that hangs it probebly has something to do with the transformation matrices. You say that you create a new array of bone transformation matrices? Im not sure why/what you are doing here?

Are you aware of that all animation controllers share the same transformation hierarchy of the original mesh? That means that everytime you call AdvanceTime it overwrites what the previus AdvanceTime wrote in the matrices. But maybe you have already figured that out. Its not documented.

This has the effect that when several animation controllers share the same hierarchy, and overwrite the matrix hierarchy all the time. Animations that only updates parts of a mesh, for instance tiny_4anim.x's "Wave" animation. Which only updates the matrices associated with tiny's arm, will not work. (if you dont belive me try playing "wave" in the multianim sdk sample)

If this is the reason you create new transformation matrices, then you are probebly doing someting similiar what i do. So il post my code here for cloning the transformation matrix hierarchy, and maybe it can help you.

[Source]//-----------------------------------------------------------------------------	// Name: clone_mesh_container	// Desc: clones a mesh container	//-----------------------------------------------------------------------------	void animation_instance_d3d_t::clone_mesh_container(D3DXMESHCONTAINER* mesh_container_src, D3DXMESHCONTAINER** mesh_container_dest)	{		if(mesh_container_src)		{			(*mesh_container_dest) = new D3DXMESHCONTAINER_EX;			*(D3DXMESHCONTAINER_EX*)(*mesh_container_dest) = *(D3DXMESHCONTAINER_EX*)mesh_container_src;			if(mesh_container_src->pNextMeshContainer)				clone_mesh_container(mesh_container_src, mesh_container_dest);			else				(*mesh_container_dest)->pNextMeshContainer = 0;		}		else			(*mesh_container_dest) = 0;	}	//-----------------------------------------------------------------------------	// Name: clone_frame_hierarchy	// Desc: clones a frame hierarchy	//-----------------------------------------------------------------------------	void animation_instance_d3d_t::clone_frame_hierarchy(D3DXFRAME* frame_src, D3DXFRAME** frame_dest)	{		if(frame_src)		{			(*frame_dest) = new D3DXFRAME_EX;			*(D3DXFRAME_EX*)(*frame_dest) = *(D3DXFRAME_EX*)frame_src;			clone_mesh_container(frame_src->pMeshContainer, &(*frame_dest)->pMeshContainer);			if(frame_src->pFrameSibling)				clone_frame_hierarchy(frame_src->pFrameSibling, &(*frame_dest)->pFrameSibling);			else				(*frame_dest)->pFrameSibling = 0;			if(frame_src->pFrameFirstChild)				clone_frame_hierarchy(frame_src->pFrameFirstChild, &(*frame_dest)->pFrameFirstChild);				else				(*frame_dest)->pFrameFirstChild = 0;		}		else			(*frame_dest) = 0;			}
Shields up! Rrrrred alert!
rKallmeyer
rKallmeyer
Peter,

Thanks for the explanation, I think I understand what I doing better know. I have another question. If I duplicate the mesh container and frame hierarchy, how do I set the Animation Controller to output to them? Maybe I am not understanding this correctly.

Thanks,
Ray
peter_b
peter_b
There is a function for that, D3DXFrameRegisterNamedMatrices(). In fact the existance of that function, altough not documented, implies that microsoft have probebly intended for this approach. So its strange why the multianim sample isnt using it.

This is how i have done it, i never use the original controller and frame hierarchy, i just keep them around to make clones of, because you need them unspoiled.


//-----------------------------------------------------------------------------	// Name: create_animation_instance	// Desc: clones the animation controller	//-----------------------------------------------------------------------------	void skinned_mesh_d3d_t::create_animation_instance(animation_instance_interface_t* animation_instance)	{		// Clone the original AC.  This clone is what we will use to animate		// this mesh; the original never gets used except to clone, since we		// always need to be able to add another instance at any time.			HRESULT hr = 0;		animation_instance_d3d_t* animation_instance_d3d = static_cast<animation_instance_d3d_t*>(animation_instance);				// save device		animation_instance_d3d->m_d3d_device = m_d3d_device;				// the following steps only needs to be preformed on meshes that have animation data		// if the mesh is a static mesh, the animation controller will be null.		if(m_d3dx_animation_controller)		{			// clone the frame hierarchy so the animation instances dont mess with the original matrices.			// the instances still share the mesh data.			animation_instance_d3d->clone_frame_hierarchy(m_frame_root, &animation_instance_d3d->m_frame_root);			// do the cloneing						if(FAILED(hr = m_d3dx_animation_controller->CloneAnimationController( m_d3dx_animation_controller->GetMaxNumAnimationOutputs(),				m_d3dx_animation_controller->GetMaxNumAnimationSets(),				m_d3dx_animation_controller->GetMaxNumTracks(),				m_d3dx_animation_controller->GetMaxNumEvents(),				&animation_instance_d3d->m_d3dx_animation_controller)))				debug_assert(false, DXGetErrorString9(hr));			// switch frame hierarchy to work on for the new controller			if(FAILED(hr = D3DXFrameRegisterNamedMatrices(animation_instance_d3d->m_frame_root, animation_instance_d3d->m_d3dx_animation_controller)))				debug_assert(false, DXGetErrorString9(hr));				// setup matrices			if(FAILED(hr = animation_instance_d3d->setup_bone_matrix_pointers(animation_instance_d3d->m_frame_root)))				debug_assert(false, DXGetErrorString9(hr));			// save bone pointer			animation_instance_d3d->m_bone_matrices = m_bone_matrices;		}		else			// static meshes don't need their own set of transformation matrices, just save			// a reference to the original			animation_instance_d3d->m_frame_root = m_frame_root;	}


Good luck with getting this beast to work properly, i sat with it for a long long time before i got it work in all cases, and i still make improvements sometimes.
Shields up! Rrrrred alert!
rKallmeyer
rKallmeyer
Peter,

Thanks for your explanation and source examples, I wish the documentation on these functions and interfaces was alittle bit more complete. I'll let you know if every thing works in a little bit.

Also - It seems like you have a really good understanding of the animation. Have you thought of posting a simple tutorial on the subject? The sample that comes with directx is horrible in my opinion - you'd wonder if they understood the principles behind object oriented programming - because everything is so dependent on everything else. Trying to rap my head around the animation interface is hard enough without having to learn the vertex shaders at the same time as well.

Thanks again,
Ray
rKallmeyer
rKallmeyer
Okay, I've got a seperate frame heirarchy and mesh container created in my Entity class. But I don't think that my Bone pointers are being set up correctly, and I think that might have been why I was getting my original problem.

I am now getting the same problem (hanging at AdvanceTime()) but now, it happens to any entity when I give it an animation to play.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.