math & physics
I'm currently trying to solve the problem of creating a bounding volume (OBB or capsule) in the middle of my bone for ragdoll creation. I suppose it's really just a general maths problem, that my paltry maths skills can't overcome. I have a position (the head of the bone), a rotation (quaternion decomposed from the head's transformation matrix) and a bone length (a scalar).
So what is the maths for finding a position given a starting position, rotation and scalar length? Or in terms of this problem, how do I find the midpoint of a bone?
I'm using C++ and XNAMath by the way.
Searching on the internet, I can see that every sample I've seen just uses either the parent transformation of the current bone, or the first child transformation of the current bone, to calculate the midpoint. I could go that route too, but then there are going to be bones missing out from being in the ragdoll - either the root bone (because it has no parent) or every bone at an extremity (because they have no children). I'm thinking there must be a way to calculate the midpoint of a bone without using it's parent or child???
Thanks in advance,
Assuming that the bone extends along the X axis in its local space, couldn't you just create the vector (0.5 * bone_length, 0, 0) and transform to world space using the bone matrix?
Thats what I was thinking... isnt this really easy? I would have said that exact thing myself but I thought the solution couldnt be that simple...
Yes, I sometimes get stuck on the easy stuff. Here's my code, if anyone is as inept at maths as me and needs it:
// Decompose the bone head world matrix.
XMVECTOR boneHeadScale, boneHeadRotation, boneHeadPosition;
if (!XMMatrixDecompose(&boneHeadScale, &boneHeadRotation, &boneHeadPosition, worldMatrix))
Log::Warn(L"Failed to decompose bone world matrix.");
// Create the mid-point in local space.
XMVECTOR midPoint = XMVectorSet(0.0f, m_Bones[i].HalfLength, 0.0f, 0.0f);
// Transform the mid-point to world space.
midPoint = XMVector3TransformNormal(midPoint, worldMatrix) + boneHeadPosition;
// Construct the bounding volume world matrix.
worldMatrix = XMMatrixTransformation(XMVectorZero(), XMQuaternionIdentity(), boneHeadScale,
XMVectorZero(), boneHeadRotation, midPoint);
The ragdoll currently looks like this:
I was thinking of letting the artist define the bone volume "width" and "height" in the 3d editor, however I'm now thinking I should be able to automate this too - I should be able to just to min/max calculations on all of the vertices in each bone's vertex group to calculate the volume. Anyone tried this before, or should I just let the artist define the rest?
What are you using the bone width and height for? Collision volumes? Calculating the bounding box of the vertices skinned to the bone should give a reasonable result, but it may be slightly too large; character physics can look better if the characters are allowed to interpenetrate just a little, since flesh isn't totally rigid. You might try scaling the generated box down to 90% of its original size, or something like that.
Ah funny! Im doing something almost exactly the same as you are in my engine, and yes, I use my ragdolls for collision detection too.