Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a class which will draw cylinders with deformer's index in the FBX file.

The deformer which was in the 3ds max's biped.

ex: If I have 22 bones in the deformer's structure, I will draw 22 cylinders.

But I was in trouble that I want to let these cylinders in the model.

And then I refer to the example (XNA Club Simple Animation 4.0) for my program.

But these cylinders are not in correct positions with the model.

How do I make these cylinders in correct positions with the model?

share|improve this question
3  
This question is not very clear. I don't understand what you mean by "let these cylinders in the model". Can you edit the question to explain more, perhaps add a screenshot of the problem? –  Nathan Reed Nov 12 '11 at 22:34

1 Answer 1

I'm not sure exactly what you're asking, but if you are trying to orient cylinders so that they align with the bones of a skeleton, here's a little code I wrote that will do this. It's using SlimDX, but porting it to XNA should be trivial.

for(int i = 1; i < nBones; i++)
{
    // get positions of bone and parent
    int p = hierarchy[i];
    Vector3 a = new Vector3(transforms[i].M41, transforms[i].M42, transforms[i].M43);
    Vector3 b = new Vector3(transforms[p].M41, transforms[p].M42, transforms[p].M43);

    // get bone length and scale the cylinder by that much
    float boneLength = Vector3.Distance(a, b);
    Matrix scale = Matrix.Scaling(boneLength, 1, 1);

    // get bone direction and create matrix to rotate towards that direction
    Vector3 dir = Vector3.Normalize(b - a);
    Vector3 axis = Vector3.Cross(Vector3.UnitX, dir);
    float cosine = Vector3.Dot(dir, Vector3.UnitX);
    float angle = (float) Math.Acos(cosine);
    Matrix rot = Matrix.RotationAxis(axis, angle);

    // declare sexy variables
    Matrix world;
    Matrix.Multiply(ref scale, ref rot, out world);
    DxUtils.translate(ref world, ref a);

    // do sexy stuff
    fx.world = world;
    fx.beginPass(0);
    _cylinder.draw();
    fx.endPass();
}

NOTE: It requires a cylinder of length 1 starting at the origin and going in the positive X direction... Just replace "UnitX" with "UnitY" if the cylinder is going up. This code assumes that the bone matrices are absolute transforms, not absolute inverses (which is what you would pass in for a skinned character)... so you might need to invert them all.

share|improve this answer
    
Thanks buddy! Your code is so great for me. But I try to modify my code. And then I finished it. Thanks my buddy! –  Stanley Chiu Nov 15 '11 at 7:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.