0

我想写一个Funktion,我可以在其中将网格旋转到3D空间中的一个点。

但我找不到我的解决方案的任何示例。

它应该类似于以下代码:

public void RotateMesh(Vector3 MeshPos, Vector3 TargedPos)
{
   ... Do something
}

但我不知道如何将 MeshPos 旋转到 TargetPos。

如果有人能解释一下就好了。

我想我需要一个矩阵作为返回值,因为我需要为我的 SelectedPoint 矩阵添加一个矩阵到我的绘图函数中。

绘图功能:

Matrix SelectedPoint = Matrix.Scaling(0.1f, 0.1f, 0.1f) * Matrix.Translation(IntersectVector) * OldMatrix;
                gameengine.m_Device.Transform.World = SelectedPoint;
                for (int i = 0; i < Burg.MeshObject.NumberAttributes; i++)
                {
                    gameengine.m_Device.Material = Burg.material[i];
                    gameengine.m_Device.SetTexture(0, Burg.texture[i]);
                    Burg.MeshObject.DrawSubset(0);
                }


public Matrix RotateMesh(Vector3 MeshPos, Vector3 TargedPos)
{
   ... Do something
   return AMatrix;
}

好吧,我尝试了以下方法,但有些东西已经倒置了..

Vector3 target =new Vector3(0.0001f, 0.0001f, 0.0001f);
            Vector3 vFront = target - IntersectVector;
            vFront.Normalize();

            Vector3 vLeft = Vector3.Cross(vFront, new Vector3(0, 1, 0));
            vLeft.Normalize(); 
            Vector3 vUp = Vector3.Cross(vLeft, vFront);
            vUp.Normalize();

            Matrix mBase = Matrix.Identity;
            mBase.M11 = vLeft.X;
            mBase.M21 = vLeft.Y;
            mBase.M31 = vLeft.Z;
            mBase.M12 = vUp.X;
            mBase.M22 = vUp.Y;
            mBase.M32 = vUp.Z;
            mBase.M13 = vFront.X;
            mBase.M23 = vFront.Y;
            mBase.M33 = vFront.Z;

            Matrix TestMatrix = gameengine.camera._viewMatrix;
            TestMatrix.Invert();

            gameengine.m_Device.RenderState.DitherEnable = true;
            gameengine.m_Device.RenderState.ZBufferEnable = true;
            gameengine.m_Device.VertexFormat = SEarth.MeshObject.VertexFormat;
            gameengine.m_Device.RenderState.CullMode = Cull.None;


            if (IntersectVector != Vector3.Empty)
            {
                Matrix SelectedPoint = Matrix.Scaling(0.1f, 0.1f, 0.1f) * mBase * Matrix.Translation(IntersectVector) * OldMatrix;

好吧,现在我尝试了其他东西..但是网格确实会旋转和变形!怎么了?

OldMatrix *= Matrix.RotationX(CubeRotX) * Matrix.RotationY(CubeRotY);


            Vector3 target =new Vector3(0.0001f, 0.0001f, 0.0001f);
            Vector3 vFront = target - IntersectVector;
            vFront.Normalize();

            Vector3 vLeft = Vector3.Cross(vFront, new Vector3(0, 1, 0));
            vLeft.Normalize(); 
            Vector3 vUp = Vector3.Cross(vLeft, vFront);
            vUp.Normalize();

            Matrix mBase = Matrix.Identity;
            mBase.M11 = vLeft.X;
            mBase.M12 = vUp.X;
            mBase.M13 = vFront.X;
            mBase.M14 = 0.0f;
            mBase.M21 = vLeft.Y;
            mBase.M22 = vUp.Y;
            mBase.M23 = vFront.Z;
            mBase.M24 = 0.0f;
            mBase.M31 = vLeft.Z;
            mBase.M32 = vUp.Z;
            mBase.M33 = vFront.Z;
            mBase.M34 = 0.0f;
            //mBase.M41 = IntersectVector.X;
            //mBase.M42 = IntersectVector.Y;
            //mBase.M43 = IntersectVector.Z;
            mBase.M41 = 0;
            mBase.M42 = 0;
            mBase.M43 = 0;
            mBase.M44 = 1.0f;

            if (IntersectVector != Vector3.Empty)
            {
                Matrix SelectedPoint = Matrix.Scaling(0.1f, 0.1f, 0.1f) * mBase * Matrix.Translation(IntersectVector) * OldMatrix;
                gameengine.m_Device.Transform.World = SelectedPoint;
                for (int i = 0; i < Burg.MeshObject.NumberAttributes; i++)
                {
                    gameengine.m_Device.Material = Burg.material[i];
                    gameengine.m_Device.SetTexture(0, Burg.texture[i]);
                    Burg.MeshObject.DrawSubset(0);
                }
            }

左手矩阵和右手矩阵有什么区别?我想我有权利。

好的,它不起作用..我应该解释我的程序..有一个位置为“Vector3(0,0,0)”的球体

如果我单击球体上的某个位置.. 一个城堡将放置在相交坐标上。

目前最好的解决方案是创建 LookAtL 矩阵,但城堡不会面对相交向量中的向量(0,0,0)。

更新 1.5.2013

带有电线的星球和点击位置上的城堡

星球与固体和城堡在点击位置

这是当前的功能

gameengine.m_Device.RenderState.FillMode = FillMode.Solid;
            OldMatrix *= Matrix.RotationX(CubeRotX) * Matrix.RotationY(CubeRotY);


            Vector3 target =new Vector3(0.0001f, 0.0001f, 0.0001f);
            Vector3 vFront = target - IntersectVector;
            vFront.Normalize();

            Vector3 vLeft = Vector3.Cross(vFront, new Vector3(0, 1, 0));
            vLeft.Normalize(); 
            Vector3 vUp = Vector3.Cross(vLeft, vFront);
            vUp.Normalize();

            Vector3 vRigth = Vector3.Cross(vUp, vFront);


            Matrix mBase = Matrix.Identity;
            mBase.M11 = vLeft.X;
            mBase.M12 = vUp.X;
            mBase.M13 = vFront.X;
            mBase.M21 = vLeft.Y;
            mBase.M22 = vUp.Y;
            mBase.M23 = vFront.Z;
            mBase.M31 = vLeft.Z;
            mBase.M32 = vUp.Z;
            mBase.M33 = vFront.Z;

            //Matrix ObjectMatrix = Matrix.LookAtLH(IntersectVector, new Vector3(0, 0, 0), new Vector3(0, 1, 0));
            Matrix ObjectMatrix = Matrix.LookAtLH(vFront, vUp, vLeft);

            if (IntersectVector != Vector3.Empty)
            {
                // Translation * Base * Rotation * Scaling
                Matrix SelectedPoint = Matrix.Identity * ObjectMatrix *Matrix.Scaling(0.3f, 0.3f, 0.3f) * Matrix.Translation(IntersectVector) *OldMatrix;
                //SelectedPoint.M41 = IntersectVector.X;
                //SelectedPoint.M42 = IntersectVector.Y;
                //SelectedPoint.M43 = IntersectVector.Z;
                //SelectedPoint *= OldMatrix;

                gameengine.m_Device.Transform.World = SelectedPoint;
                for (int i = 0; i < Burg.MeshObject.NumberAttributes; i++)
                {
                    gameengine.m_Device.Material = Burg.material[i];
                    gameengine.m_Device.SetTexture(0, Burg.texture[i]);
                    Burg.MeshObject.DrawSubset(0);
                }
            }
            Material deviceMat = gameengine.m_Device.Material;
            //gameengine.m_Device.Material.AmbientColor = ColorValue.FromArgb(161613);


            //testsphere.DrawSubset(0);
            gameengine.m_Device.Material = deviceMat;
//gameengine.m_Device.RenderState.FillMode = FillMode.WireFrame;
4

2 回答 2

0

要使对象面向某个方向,请使用相机视图矩阵。该矩阵将对象从面向观察方向的空间转换为面向 z 轴的空间。

出于您的目的,您应该反转此矩阵,它将 Z 轴映射到您用来创建视图矩阵的外观方向。

伪代码:

ObjectMatrix = Matrix.Invert(Matrix.CreateLookAtLH(dir,up,right));

这将使对象 -z 轴面向 dir 中的方向。

于 2013-04-30T21:18:04.213 回答
0

好吧,我明白了!

这就是我的解决方案:

public Matrix GetRotateToTargetMatrix(Vector3 TargetVector)
{
            Matrix mBase = Matrix.Invert(Matrix.LookAtLH(new Vector3(0, 0, 0),     TargetVector, new Vector3(0, 1, 0)));
            mBase.M44 = 1;
            mBase.M14 = 0;
            mBase.M24 = 0;
            mBase.M34 = 0;
            mBase.M41 = 0;
            mBase.M42 = 0;
            mBase.M43 = 0;

            return = mBase;
}

感谢 Gnietschow 和 MHGameWork

于 2013-05-04T14:18:53.607 回答