• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

矩阵对象之间的距离,相对于父母定位,使用XNA?

c/c++ 来源:Sebastian Gray 3次浏览

我想了解如何测量两个3D对象之间的距离,我们称它们为父对象和子对象。将父母视为汽车的车身,将孩子视为汽车的车轮。矩阵对象之间的距离,相对于父母定位,使用XNA?

我明白如何让基于在世界空间中的物体位置的不同,但我想获得的测量依据的父母相对对象空间上的差异。

E.g如果父面向东和孩子是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://pastebin.com/5hEmiVx9

由于


===========解决方案如下:

问题是我试图使用世界空间的偏移量的方式。 感谢从EFnet上#XNA闪现,此代码完美工作:

[Serializable] 
    public class Component_Child_fromxna : BaseComponentAutoSerialization<ISceneEntity> 
    { 
     Vector3 _parentOffset; 
     Matrix _ParentMatrixOffset; 


     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) 
       { 
        // The old offset - This is just in world space though... 
        _parentOffset = sceneObject.World.Translation - PassThrough.ParentTranslation; 

        // Get the distance between the child and the parent which we keep as the offset 
        // Inversing the ParentMatrix and multiplying it by the childs matrix gives an offset 
        // The offset is stored as a relative xyz, based on the parents object space 
        _ParentMatrixOffset = sceneObject.World * Matrix.Invert(PassThrough.ParentMatrix); 
       } 
      } 
      else 
      { 
       if (_parentOffset != Vector3.Zero) 
       { 

        //Matrix pLocation = Matrix.CreateTranslation(_parentOffset); 
        //sceneObject.World = Matrix.Multiply(pLocation, PassThrough.ParentMatrix); 

        sceneObject.World = Matrix.Multiply(_ParentMatrixOffset, PassThrough.ParentMatrix); 
       } 
      } 
     } 
    } 

版权声明:本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。
喜欢 (0)