c# - 矩阵对象之间的距离,相对于 parent 的方向,使用 XNA?

标签 c# matrix xna

我想了解如何测量两个 3D 对象之间的距离,我们称它们为父对象和子对象。将 parent 想象成汽车的车身,将 child 想象成汽车的轮子。

我了解如何根据对象在世界空间中的位置来获得差异,但我想根据 parent 的相对对象空间来获得差异作为测量值。

例如,如果 parent 面向东方,而 child 与 parent 的距离为 2X、3Y,以相对方式测量。这样,如果父对象旋转 60 度,则子对象的相对位置在对象空间中保持 2x、3y 的距离。在世界空间中,作为 Vector3 的子对象测量会大不相同。

基本上我只是想要一种可预测的方法来获得差异,以便专利右侧的子对象始终保持在父对象的右侧。

这是父组件,每帧更新一次:

[Serializable]
    public class Component_Parent : BaseComponentAutoSerialization<ISceneEntity>
    {
        public override void OnUpdate(GameTime gameTime)
        {
            PassThrough.ParentMatrix = ParentObject.World;
            PassThrough.ParentTranslation = ParentObject.World.Translation;


        }
    }

下一部分是子组件:

[Serializable]
    public class Component_Child : BaseComponentAutoSerialization<ISceneEntity>
    {
        Vector3 _parentOffset;
        Quaternion _parentQuaternionOffset;

        public override void OnUpdate(GameTime gameTime)
        {
            // Get a sceneobject from the ParentObject
            SceneObject sceneobject = (SceneObject)ParentObject;

            // This relies on the position never being at 0,0,0 for setup, so please don't do that
            // or change it with more look ups so that you don't need to rely on a Zero Vector3 :-)
            if (PassThrough.GroupSetupMode || _parentOffset == Vector3.Zero)
            {
                if (PassThrough.ParentTranslation != Vector3.Zero)
                {
                    _parentOffset = sceneobject.World.Translation - PassThrough.ParentTranslation;

                    // Decompose World Matrix (Parent)
                    Quaternion parentQ = new Quaternion();
                    Vector3 parentSpot = new Vector3();
                    Vector3 parentScale = new Vector3();
                    PassThrough.ParentMatrix.Decompose(out parentScale, out parentQ, out parentSpot);

                    Matrix identity = Matrix.Identity;

                    // Decompose Identity Matrix (Parent)
                    Quaternion identityQ = new Quaternion();
                    Vector3 identitySpot = new Vector3();
                    Vector3 identityScale = new Vector3();
                    identity.Decompose(out identityScale, out identityQ, out identitySpot);

                    _parentQuaternionOffset = identityQ - parentQ;
                }
            }
            else
            {
                if (_parentOffset != Vector3.Zero)
                {

                    // Decompose World Matrix (Child)
                    Quaternion rotationQ = new Quaternion();
                    Vector3 spot = new Vector3();
                    Vector3 scale = new Vector3();
                    sceneobject.World.Decompose(out scale, out rotationQ, out spot);


                    // Decompose World Matrix (Parent)
                    Quaternion parentQ = new Quaternion();
                    Vector3 parentSpot = new Vector3();
                    Vector3 parentScale = new Vector3();
                    PassThrough.ParentMatrix.Decompose(out parentScale, out parentQ, out parentSpot);

                    Matrix location = Matrix.CreateTranslation(PassThrough.ParentTranslation);
                    Matrix rotation = Matrix.CreateFromQuaternion(parentQ);

                    Matrix rotation2 = Matrix.CreateFromQuaternion(_parentQuaternionOffset);

                    Matrix newWorld = rotation * location;

                    Vector3 testTranslation = newWorld.Translation + ((newWorld.Left * _parentOffset.X) + (newWorld.Up * _parentOffset.Y) + (newWorld.Forward * _parentOffset.Z));
                    Matrix scaleM = Matrix.CreateScale(scale);



                    //sceneobject.World = scaleM * (rotation * (Matrix.CreateTranslation(testTranslation)));
                    sceneobject.World = (Matrix.CreateTranslation(testTranslation));
                }
            }
        }
    }

我认为它与从单位矩阵跟踪偏移旋转有关,我已经开始尝试添加一些代码来实现这种效果,但现在真的不确定下一步是什么。

附加:

如果我让父对象面向世界空间的方向,一切正常,如果它面向不同的方向,那么它就是一个问题,当它们组合在一起时,子对象似乎旋转相同的量。

我已经上传了一个演示视频来尝试解释:

http://www.youtube.com/watch?v=BzAKW4WBWYs

我还粘贴了组件的完整代码、静态传递和场景实体。

http://pastebin.com/5hEmiVx9

谢谢

最佳答案

Think wheels on a car. I want the right wheel to always be in the same spot relative to the body of the car.

听起来您希望能够针对汽车的任何给定方向或位置定位车轮的位置。 XNA 在这里必须提供帮助的一种内置方法是 Model.CopyAbsoluteBoneTransformsTo(Matrix[]);但是,您的代码看起来像您想要手动处理父子关系。所以这是一种不使用内置方法的方法。它假定您在加载时确实有偏移信息:

在游戏循环开始之前(比如,在 LoadContent 方法中),加载汽车和车轮并假设它们加载到正确的位置之后,您可以创建偏移向量 (_parentOffset)

Vector3 _parentOffset = wheel.meshes[?].ParentBone.Transform.Translation - car.meshes[?].ParentBone.Transform.Translation;//where ? is the mesh index of the mesh you are setting up.

保存那个向量,不要修改它。

稍后,在汽车的矩阵发生旋转和/或位置位移后,设置车轮的矩阵如下:

Matrix wheelMatrix = carMatrix;
wheelMatrix.Translation += (wheelMatrix.Right * _parentOffset.X) +
                           (wheelMatrix.Up * _parentOffset.Y) +
                           (wheelMatrix.Backward * _parentOffset.Z);

这允许车轮矩阵从汽车继承任何旋转和平移信息,但无论汽车的方向/位置如何,都会适本地移动车轮的位置。

关于c# - 矩阵对象之间的距离,相对于 parent 的方向,使用 XNA?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6936126/

相关文章:

matrix - 莫林矩阵与 Google Drive 电子表格

C# - 如何访问仅给定类类型的静态类变量?

winforms - 在 XNA 中使用 system.windows.forms

xna - 在连续2D空间中避免障碍的基本寻路

c# - 将字符串从 C# 编码到 C++

c# - 如何在没有类实例的情况下访问类中的列表?

c++ - CUDA 卷积 - 不可分离内核

java - 原地旋转 NxN 矩阵 90 度时出现逻辑错误

c# -::在 C# 中的目的是什么?

C#调用native代码比native调用native快