XNA使用偏移平移旋转骨骼

时间:2012-01-09 16:38:17

标签: matrix xna rotation xna-4.0

我的模型有一个骨骼,它与父骨骼有一个平移的偏移(它不位于父骨骼的尾部)。在模型制作的Blender中,我可以旋转骨骼,看到连接的网格正确旋转。但是,当我尝试在我的代码中旋转骨骼时,它似乎围绕父级的尾部旋转它。我在Matrix数学(我最大的敌人)中搞砸了什么。

更新

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

        base.Update(gameTime);
    }

非常标准,但如果重要,请绘制:

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();
        }
    }

这是显示问题的屏幕截图 http://s1231.photobucket.com/albums/ee516/Neovivacity/?action=view&current=boneRotation.png

1 个答案:

答案 0 :(得分:1)

好吧,这可能不是解决这个问题最直接的方法,但是对于那些也遇到类似问题的人我有一个解决办法。

加载模型时,存储原始变换。然后你像我一样乘以骨骼的变换。最后,您将获得原始变换Translation,oringalTranform.Translation,并获得骨骼的新变换。要调整偏移量,骨骼.Transform * = Matrix.CreateTranslation(originalTranslation - newTranslation)。

以下是我的解决方案中的代码段:

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);
    }