XNA Rotate a bone with an offset translation

送分小仙女□ 提交于 2019-12-12 02:16:09

问题


I have a model that has a bone which has a translated offset from the parent bone (it is not positioned at the tail of the parent bone). In Blender, where the model was made, I can rotate the bone and see the attached mesh rotate correctly. However, when I attempt to rotate the bone in my code, it seems to rotate it about the tail of the parent. I'm messing something up in the Matrix math (my worst enemy).

Update:

protected override void Update(GameTime gameTime)
    {
        bone.Transform =  Matrix.CreateFromYawPitchRoll(0f, 0.5f, 0f);

        base.Update(gameTime);
    }

Pretty standard, but if it matters, Draw:

private void DrawModel(Model model, GraphicsDevice graphics, Matrix viewMatrix, Matrix projectionMatrix)
    {
        Matrix[] boneTransforms = new Matrix[model.Bones.Count];
        model.CopyAbsoluteBoneTransformsTo(boneTransforms);

        Matrix worldMatrix = orientation * Matrix.CreateTranslation(position);

        foreach (ModelMesh mesh in model.Meshes)
        {
            foreach (BasicEffect effect in mesh.Effects)
            {
                effect.World = boneTransforms[mesh.ParentBone.Index] * worldMatrix;
                effect.View = viewMatrix;
                effect.Projection = projectionMatrix;

                effect.EnableDefaultLighting();
                effect.PreferPerPixelLighting = true;

                // Set the fog to match the black background color
                effect.FogEnabled = true;
                effect.FogColor = Vector3.Zero;
                effect.FogStart = 1000;
                effect.FogEnd = 3200;
            }
            mesh.Draw();
        }
    }

Here's screen shots to show the problem http://s1231.photobucket.com/albums/ee516/Neovivacity/?action=view&current=boneRotation.png


回答1:


Ok, this may not be the most straightforward way of solving this, but I have a fix for anyone who's also having a similar issue.

When loading the Model, store the original transform. Then you multiply the bone's transform like I did. Finally you get the original transforms Translation, oringalTranform.Translation for example, and get bone's new transform. To adjust for the offset, bone.Transform *= Matrix.CreateTranslation(originalTranslation - newTranslation).

Here's a code snippet from my solution:

public void LoadContent(ContentManager content)
    {
        Model = content.Load<Model>(ModelName);
        //Set the Bone pointers and transform matrices
        AileronLBone = Model.Bones["LAileron"];
        AileronRBone = Model.Bones["RAileron"];
        ElevatorBone = Model.Bones["Elevator"];
        RudderBone = Model.Bones["Rudder"];
        FlapsBone = Model.Bones["Flaps"];
        if (AileronLBone != null) AileronLTransform = AileronLBone.Transform;
        if (AileronRBone != null) AileronRTransform = AileronRBone.Transform;
        if (ElevatorBone != null) ElevatorTransform = ElevatorBone.Transform;
        if (RudderBone != null) RudderTransform = RudderBone.Transform;
        if (FlapsBone != null) FlapsTransform = FlapsBone.Transform;
    }

    public void Update(GameTime gameTime)
    {
        SetOffsetRotation(ElevatorBone, ElevatorTransform, ElevatorRotation);
    }

    public void SetOffsetRotation(ModelBone bone, Matrix transform, float rotation)
    {
        Vector3 oringalTrans = transform.Translation;
        bone.Transform *= Matrix.CreateRotationX(rotation);
        Vector3 newTrans = bone.Transform.Translation;
        bone.Transform *= Matrix.CreateTranslation(oringalTrans - newTrans);
    }


来源:https://stackoverflow.com/questions/8791845/xna-rotate-a-bone-with-an-offset-translation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!