C # Managed DirectX - как повернуть сетку на любой вектор?

Я хочу написать Funktion, в котором я могу перенести сетку в точку в трехмерном пространстве.

Но я не могу найти никаких примеров для своего решения.

Он должен выглядеть следующим образом:

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;

person ZeraTFK    schedule 29.04.2013    source источник
comment
Вы действительно имеете в виду поворот? Или вы хотите, чтобы сетка была обращена в целевую позицию? Следовательно, вы можете использовать базовое преобразование, которое вы можете построить из вектора между сеткой и целью как спереди, вектора вверх и пересечения обоих как слева.   -  person Gnietschow    schedule 30.04.2013
comment
Привет, Gnietschow, да, я имею в виду повернуть сетку лицом к целевой позиции. Что ж, если вектор между сеткой и тегом в качестве переднего и верхнего вектора, мне нужен точечный продукт из MeshVector.left и TargetVector.Left Cross MeshVector.Up и TargetVector.Up?   -  person ZeraTFK    schedule 30.04.2013
comment
Я имею в виду Front = (target-position).Normalize; Left = Cross(Front,Vector3(0,1,0)).Normalize; Up = Cross(Left,Front).Normalize;, и с этой базой вы можете построить матрицу для базового преобразования, которая отображает вашу сетку в правильной ориентации.   -  person Gnietschow    schedule 30.04.2013
comment
Ну, я кое-что пробовал ... не могли бы вы взглянуть на это? я отредактировал свой пост.   -  person ZeraTFK    schedule 30.04.2013
comment
Попробуйте поработать без ротации, тогда проще поискать ошибку. Я думаю, что ваше умножение матриц находится в неправильном порядке, попробуйте SelectedPoint = Translation * Base * Rotation * Scaling. И левый верхний и передний векторы должны быть в столбцах матрицы.   -  person Gnietschow    schedule 30.04.2013
comment
Эй, это уже не сработает ... Я редактирую свой главный пост ... не могли бы вы взглянуть на это? Или можно добавить u в скайп или еще что-нибудь на будущее?   -  person ZeraTFK    schedule 02.05.2013
comment
Вы хотите разместить сетки ортонормированными на сфере, с этой информацией ясно, почему мой предлагаемый подход бесполезен;) Вам нужно построить базовую матрицу, чтобы вектор вверх был нормалью сферы в данной позиции. Если центр вашей сферы находится в точке (0,0,0), это должно быть: Up = IntersectVector.Normalize; Front = ross (Up, Vector3 (0,1,0)). Normalize; Left = Cross (Up, Front) .Normalize; `Для общности вы должны предотвратить ситуацию, когда Up = (0,1,0).   -  person Gnietschow    schedule 03.05.2013


Ответы (2)


Чтобы объект смотрел в определенном направлении, используйте матрицу обзора камеры. Эта матрица преобразует объект из пространства, если он обращен к направлению взгляда, в пространство, если он обращен к оси z.

Для ваших целей вы должны инвертировать эту матрицу, она отобразит ось Z на направление взгляда, которое вы используете для создания матрицы просмотра.

псевдокод:

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

Это заставит объекты ось -z смотреть в направлении dir.

person MHGameWork    schedule 30.04.2013
comment
Итак, сетка повернется, но не лицом к вектору (0,0,0). И мой объект должен быть обращен к оси Y. Я не уверен, как создать вектор dir, up и right. Я редактирую свой главный пост ... не могли бы вы взглянуть на него? Или можно добавить u в скайп или еще что-нибудь на будущее? - person ZeraTFK; 02.05.2013

Хорошо, я понял!

Это мое решение:

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

person ZeraTFK    schedule 04.05.2013