C# Управляемый DirectX - Как я могу повернуть сетку к любому вектору?
Я хочу написать Функцию, где я могу повернуть Сетка в Точку в 3D Пространстве.
Но я не могу найти какие-либо примеры для моего решения.
Он должен выглядеть следующим образом:
public void RotateMesh(Vector3 MeshPos, Vector3 TargedPos)
{
... Do something
}
Но я понятия не имею, как я могу повернуть MeshPos в TargetPos.
Было бы хорошо, если бы кто-то мог это объяснить.
Я думаю, что мне нужна Матрица как Возвращаемое значение, потому что мне нужно добавить Матрицу в мою функцию рисования для моей SelectedPoint Matrix.
Функция Draw:
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
Планета с проволокой и замком в позиции Click
Планета с Телом и Замок на позиции Клик
Вот текущая функция
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;
2 ответа
Ну, я понял!
Вот мое решение:
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
Чтобы сделать объект лицом в определенном направлении, используйте матрицу вида камеры. Эта матрица преобразует объект из пространства, в котором он обращен к направлению взгляда, в пространство, в котором он обращен к оси z.
Для ваших целей вы должны инвертировать эту матрицу, она отобразит ось Z на направление взгляда, которое вы используете для создания матрицы вида.
псевдокод:
ObjectMatrix = Matrix.Invert(Matrix.CreateLookAtLH(dir,up,right));
Это сделает объекты -z осью в направлении в направлении dir.