0
votes

I want to write a Funktion where i can rotete a Mesh to a Point in 3D Space.

But i cant find any Examples for my Solution.

It should look like the following Code:

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

But i have no Idea how i can Rotate the MeshPos to TargetPos.

It would be nice if someone could explain it.

I think i need a Matrix as Return Value, because i need to add a Matrix to my draw Function for my SelectedPoint Matrix.

Draw Function:

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;
}

Well i tryed the following but somthing is already inverted..

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;

Well now i tryed something other.. but the mesh does rotate and deform! whats wrong?

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);
                }
            }

And what is the different between a Lefthand and Righthand Matrix? i think i have rigthhand.

Ok it wont work.. I should explain my programm.. there is a Sphere with the position "Vector3(0,0,0)"

If i click somewhere on the sphere.. a Castle will placed on the intersect coordinates.

the best solution at the moment is to create the LookAtL Matrix, but the Castle wont face the Vector(0,0,0) from the Intersect Vector.

Update 1.5.2013

Planet with Wire and the Castle on the Click position

Planet with Solid and the Castle on the Click position

Here is the current Function

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
Do you really mean rotate? Or do you want a mesh to face the target position? Therefore you can use a base transformation, which you can build of the vector between mesh and target as front, an up vector and the cross of both as left.Gnietschow
Hi Gnietschow, yes i mean to face the mesh to the target position. well du u mean with "the vector between mesh and taget as front and up vector" that i need the dotproduct from MeshVector.left and TargetVector.Left Cross MeshVector.Up and TargetVector.Up ?ZeraTFK
I mean Front = (target-position).Normalize; Left = Cross(Front,Vector3(0,1,0)).Normalize; Up = Cross(Left,Front).Normalize; and with this base you coult build a matrix for a base transformation, which maps your mesh in the right orientation.Gnietschow
Well i tryed something.. could u take a look on it? i edited my post.ZeraTFK
Try to work without the rotation, then it's easier to look for the error. I think your matrix-multiplication is in the wrong order, try SelectedPoint = Translation * Base * Rotation * Scaling. And the left up and front-vectors must be in the columns of the matrix.Gnietschow

2 Answers

0
votes

To make a object face a certain direction, use a camera view matrix. This matrix transforms the object from a space were it faces the look direction, to a space were it faces the z axis.

For your purposes you should invert this matrix, it will map the Z axis onto the lookdirection u use to create the view matrix.

pseudocode:

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

This will make the objects -z axis face in the direction in dir.

0
votes

Well i got it!

Thats my Solution:

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;
}

Thanks Gnietschow and MHGameWork