collision detection on a skinned animated mesh

Started by
8 comments, last by Stowelly 17 years, 8 months ago
ok i have a mesh hierarchy using bones, exported from max in the .x format and am loading it into an extended hieracrhy function which handles the bones and anim of the skinned mesh now ive opted to create a bounding volume for each bone of the mesh by getting the index of every vertex affected by each bone and calculating the bounds based on the resultant vertex data ok, the volumes appear to be the correct size, although im not 100% sure as im not able to get them transformed correctly (in order to draw the bounds and physically debug it), im pretty sure that as i obtain the vertex data required from the basic mesh before any blending and skinning info has been applied that the bounds would infact change size and direction? (obviously the transforms would be different). so this bound data will probably be almost useless to me (except the vertex indices gained from calculating the bones which they affect), my rendering method calls a function to apply the world transforms i.e the bone offset matrix and the parent frame in order to correctly transform each element of the bone. ive been planning to use this vertex data in order to calculate my bounding volumes for each bone and have very accurate collision on the mesh (can be tweaked later by adding key values to meshes i want info from). im worried that this will be very resource hungry and believe that theres a better method to do this sorry for such a long post, hope someone can help thanks
http://stowelly.co.uk/
Advertisement
Quote:Original post by Stowelly
ok, the volumes appear to be the correct size, although im not 100% sure as im not able to get them transformed correctly (in order to draw the bounds and physically debug it), im pretty sure that as i obtain the vertex data required from the basic mesh before any blending and skinning info has been applied that the bounds would infact change size and direction? (obviously the transforms would be different).

What you can do is transform the vertices of this bounding volume in the same manner that you would skin a vertex. However, it is a bit simpler in this case, since you only have one bone influence. So just transform each bounding vertex by the world transform of the bone (and inv. base pose if you need to). At that point, you should be good to test your collisions.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
You could clone the mesh and use the UpdateSkinnedMesh() function to apply the current transformations in the heirarchy. Then create a separater vertex buffer containing only the vertices that influence a bone, and calculate the bounding volume from that. Then just apply the world matrix to each bounding volume as you do intersect tests.

If you want to keep track of exactly where each limb is during the animation, you could save the to-root-transformation matrix of the bone when you create the bounding volumes, then during the animation get the difference between the current one and the one you saved to transform the bounding volume into the current space of the bone, and then apply the world matrix.

--------------------------Most of what I know came from Frank D. Luna's DirectX books
thanks for your replys

right my update skinned mesh function happens every frame (doesnt use the inverse param) and takes an array of bone matrices called m_boneMatrices which defines the offset for each bone

ive tried to use the destination vertex buffer to iterate through each vertex and calculate the bounding volume based on the vertex data but like i thought it gives me an EXTREMELY slow game, am i doing this the correct way?

for( UINT j = 0; j < numvertices; j++ )					{						DWORD position = pMesh->bones.indecies[j] * stride;						D3DXVECTOR3 *temp = (D3DXVECTOR3*)&destPtr[position];                 		pMesh->bones.centre.x = pMesh->bones.centre.x + temp->x; 						pMesh->bones.centre.y = pMesh->bones.centre.y + temp->y; 						pMesh->bones.centre.z = pMesh->bones.centre.z + temp->z; 						if(j==0){							Min = D3DXVECTOR3(temp->x,temp->y,temp->z);							Max = D3DXVECTOR3(temp->x,temp->y,temp->z);						}else{							Min.x = min(Min.x, temp->x);							Min.y = min(Min.y, temp->y);							Min.z = min(Min.z, temp->z);							Max.x = max(Max.x, temp->x);							Max.y = max(Max.y, temp->y);							Max.z = max(Max.z, temp->z);													}


again thanks alot
http://stowelly.co.uk/
Why not use the DX function D3DXComputeBoundingBox? This is the DirectX forum, so you might as well use DirectX functions to do the work for you.

However, as I tried to say it would be expensive to this every frame. You should do it once at the beginning, and then transform the bounding box values for each bone by the world matrix (and optionally the difference between the to-root matrix at the time the box was created and what it is now, now - first).
--------------------------Most of what I know came from Frank D. Luna's DirectX books
i thought as much, (am using compute bound box for my overall bounds, just wanted to work out how it was implemented manually)

im sorry im abit of a beginner but was wondering how i would go about getting the difference between where it is created and where it is now? isnt the bone hierarchy a linked list of pointers to the next bone? its hard to determin where in the chain each bone is, i.e the to-root matrix

[Edited by - Stowelly on July 29, 2006 4:42:17 PM]
http://stowelly.co.uk/
You can also take a different approach by using collision meshes.
Simply link each collision mesh to a given bone. These are non-skinned objects. You could use parametric objects such as capsules, spheres and boxes and/or triangle primitives (so regular low detail meshes, depending on the accuracy you need).

If you would want to detect for example a bullet hit with the character, you can transform the ray of the bullet into space of the collision object. This way you don't need to transform any vertices at all to check for collision.

Another option is to auto-generate the bounds. I would probably use capsules simply based on the bone transforms. Put a capsule/cylinder/box between all the bones. You could estimate the radius/diameter/thickness of them by using the length of the bone, or better by precalculating a the maximum distance from bone to a given vertex that this bone uses.
yeh bounding meshes sounds like a nice option, would be alot mroe work for my artists though and would be nice after having spent so much time on this to be able to finally do it

i just dont understand how i determin the transform from the parent to the actual bone as there doesnt seem a path from the current bone to the parent of that bone
http://stowelly.co.uk/
The transform, you can calculate it manually based on the position and parent.
That gives you a direction vector. Then you can take some up vector and calculate the right vector from that as well. That gives you a transform matrix for the current volume of the bone.

Another option is just to take the transform of the bone itself. Possibly multiply it with the inverse bind pose matrix of the bone. Then you know the "relative" rotation of the bone compared to bind pose as where you calculated the initial box from. It all depends a bit on in what space you want to work.

Hope that gives some ideas.
ok i think im finally there, the boxes are redered in there corect places, although for some reason the legs seem to be rotated 90 degrees off where as the hands and shoulders etc seem ok, (although the head seems abit off)

is there any kind of rotational matrice i should be applying to this? im surely just missing one transform

any ideas

http://img322.imageshack.us/img322/6893/collision3jx3.jpg
http://stowelly.co.uk/

This topic is closed to new replies.

Advertisement