Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualMedo3337

Posted 30 November 2012 - 05:10 AM

Hello everyone,

I'm trying to make a mesh look at another mesh so I will be having two methods:
1. This method will make the mesh look at x, y ,z point instantly when called:
void Mesh::LookAtInstantly(float x, float y, float z);

2. This method will make the mesh move slightly till it look at the point, the method will be called several times to make the mesh look at another mesh, this method should return true when the it's actually looking at another mesh, otherwise it should return false when it's not yet looking at the other mesh (I will use this method to make a tank mesh look at another area, a tank can't just rotate to another area suddenly, it must rotate gradually):
bool Mesh::LookAtGradually(float x, float y, float z);

The following code is getting a valid Quaternion rotation to make the mesh1 look at mesh2, but I'm able to make it look at the other mesh instantly only, I want to be able to make it look at the other mesh gradually as well.
D3DXMATRIX rotation;
// World space position of the 1st, watching mesh.
D3DXVECTOR3 mesh1Pos_World(X, Y, Z);
// World space position of the 2nd, watched mesh.
D3DXVECTOR3 mesh2Pos_World;
if (boolOnYAxis)
  mesh2Pos_World = D3DXVECTOR3(x, y, z);
else
  mesh2Pos_World = D3DXVECTOR3(x, Y, z);
// mesh2Pos_World.y = 0; // Will NOT rotate on Y axis (UP), should be applied to tank cannon
// Object space direction of the 1st mesh; in other
// words it says where your mesh is looking at prior
// to any transformation. Your mesh is assumed to be
// at the origin.
D3DXVECTOR3 mesh1Dir_Object(0, 0, -1);
// This is the vector that goes from the watching mesh
// to the watched mesh.
D3DXVECTOR3 direction_World = mesh2Pos_World - mesh1Pos_World;
D3DXMATRIX finalCannonRot;
if (direction_World.x != 0 || direction_World.y != 0 || direction_World.z != 0)
{
  // Normalize the two directions.
  D3DXVec3Normalize(&mesh1Dir_Object, &mesh1Dir_Object);
  D3DXVec3Normalize(&direction_World, &direction_World);
  // The acos of the dot product between the two directions is
  // the rotation angle in world space.
  FLOAT angle_World = std::acos(D3DXVec3Dot(&mesh1Dir_Object, &direction_World));
  // The normalized cross product between the two directions is
  // the rotation axis in world space.
  D3DXVECTOR3 axis_World;
  D3DXVec3Cross(&axis_World, &mesh1Dir_Object, &direction_World);
  D3DXVec3Normalize(&axis_World, &axis_World);
  // This is the rotation matrix; this should be set as the
  // world matrix for the 1st mesh.
  D3DXMatrixRotationAxis(&rotation, &axis_World, angle_World);
  // -- Get rotation quaternion
  D3DXQUATERNION rotQuaternion;
  D3DXQuaternionRotationAxis(&rotQuaternion, &axis_World, angle_World);
  
  btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
  btRigidBody* body = btRigidBody::upcast(obj);
  if (body && body->getMotionState())
  {
	body->activate(true);
	btMatrix3x3 orn = body->getWorldTransform().getBasis();
	btQuaternion quat = btQuaternion(rotQuaternion.x, rotQuaternion.y, rotQuaternion.z, rotQuaternion.w);
    // *********************************************************************************************
    orn.setEulerYPR(???); // I want set this value to rotate the mesh gradually
    // *********************************************************************************************
	body->getWorldTransform().setBasis(orn);
  }
}

#4Medo3337

Posted 30 November 2012 - 05:07 AM

Hello everyone,

I'm trying to make a mesh look at another mesh so I will be having two methods:
1. This method will make the mesh look at x, y ,z point instantly when called:
void Mesh::LookAtInstantly(float x, float y, float z);

2. This method will make the mesh move slightly till it look at the point, the method will be called several times to make the mesh look at another mesh, this method should return true when the it's actually looking at another mesh, otherwise it should return false when it's not yet looking at the other mesh:
bool Mesh::LookAtGradually(float x, float y, float z);

The following code is getting a valid Quaternion rotation to make the mesh1 look at mesh2, but I'm able to make it look at the other mesh instantly only, I want to be able to make it look at the other mesh gradually as well.
D3DXMATRIX rotation;
// World space position of the 1st, watching mesh.
D3DXVECTOR3 mesh1Pos_World(X, Y, Z);
// World space position of the 2nd, watched mesh.
D3DXVECTOR3 mesh2Pos_World;
if (boolOnYAxis)
  mesh2Pos_World = D3DXVECTOR3(x, y, z);
else
  mesh2Pos_World = D3DXVECTOR3(x, Y, z);
// mesh2Pos_World.y = 0; // Will NOT rotate on Y axis (UP), should be applied to tank cannon
// Object space direction of the 1st mesh; in other
// words it says where your mesh is looking at prior
// to any transformation. Your mesh is assumed to be
// at the origin.
D3DXVECTOR3 mesh1Dir_Object(0, 0, -1);
// This is the vector that goes from the watching mesh
// to the watched mesh.
D3DXVECTOR3 direction_World = mesh2Pos_World - mesh1Pos_World;
D3DXMATRIX finalCannonRot;
if (direction_World.x != 0 || direction_World.y != 0 || direction_World.z != 0)
{
  // Normalize the two directions.
  D3DXVec3Normalize(&mesh1Dir_Object, &mesh1Dir_Object);
  D3DXVec3Normalize(&direction_World, &direction_World);
  // The acos of the dot product between the two directions is
  // the rotation angle in world space.
  FLOAT angle_World = std::acos(D3DXVec3Dot(&mesh1Dir_Object, &direction_World));
  // The normalized cross product between the two directions is
  // the rotation axis in world space.
  D3DXVECTOR3 axis_World;
  D3DXVec3Cross(&axis_World, &mesh1Dir_Object, &direction_World);
  D3DXVec3Normalize(&axis_World, &axis_World);
  // This is the rotation matrix; this should be set as the
  // world matrix for the 1st mesh.
  D3DXMatrixRotationAxis(&rotation, &axis_World, angle_World);
  // -- Get rotation quaternion
  D3DXQUATERNION rotQuaternion;
  D3DXQuaternionRotationAxis(&rotQuaternion, &axis_World, angle_World);
  
  btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
  btRigidBody* body = btRigidBody::upcast(obj);
  if (body && body->getMotionState())
  {
	body->activate(true);
	btMatrix3x3 orn = body->getWorldTransform().getBasis();
	btQuaternion quat = btQuaternion(rotQuaternion.x, rotQuaternion.y, rotQuaternion.z, rotQuaternion.w);
	orn.setEulerYPR(???); // I want set this value to rotate the mesh gradually
	body->getWorldTransform().setBasis(orn);
  }
}

#3Medo3337

Posted 30 November 2012 - 04:04 AM

Hello everyone,
I'm trying to make a mesh look at another mesh so I will be having two methods:
1. This method will make the mesh look at x, y ,z point instantly when called:
void Mesh::LookAtInstantly(float x, float y, float z);
2. This method will make the mesh move slightly till it look at the point, the method will be called several times to make the mesh look at another mesh, this method should return true when the it's actually looking at another mesh, otherwise it should return false when it's not yet looking at the other mesh:
bool Mesh::LookAtGradually(float x, float y, float z);
Here is the code that I'm using to make the mesh look at another, it's not working as expected.
D3DXMATRIX rotation;
// World space position of the 1st, watching mesh.
D3DXVECTOR3 mesh1Pos_World(X, Y, Z);
// World space position of the 2nd, watched mesh.
D3DXVECTOR3 mesh2Pos_World;
if (boolOnYAxis)
  mesh2Pos_World = D3DXVECTOR3(x, y, z);
else
  mesh2Pos_World = D3DXVECTOR3(x, Y, z);
// mesh2Pos_World.y = 0; // Will NOT rotate on Y axis (UP), should be applied to tank cannon
// Object space direction of the 1st mesh; in other
// words it says where your mesh is looking at prior
// to any transformation. Your mesh is assumed to be
// at the origin.
D3DXVECTOR3 mesh1Dir_Object(0, 0, -1);
// This is the vector that goes from the watching mesh
// to the watched mesh.
D3DXVECTOR3 direction_World = mesh2Pos_World - mesh1Pos_World;
D3DXMATRIX finalCannonRot;
if (direction_World.x != 0 || direction_World.y != 0 || direction_World.z != 0)
{
  // Normalize the two directions.
  D3DXVec3Normalize(&mesh1Dir_Object, &mesh1Dir_Object);
  D3DXVec3Normalize(&direction_World, &direction_World);
  // The acos of the dot product between the two directions is
  // the rotation angle in world space.
  FLOAT angle_World = std::acos(D3DXVec3Dot(&mesh1Dir_Object, &direction_World));
  // The normalized cross product between the two directions is
  // the rotation axis in world space.
  D3DXVECTOR3 axis_World;
  D3DXVec3Cross(&axis_World, &mesh1Dir_Object, &direction_World);
  D3DXVec3Normalize(&axis_World, &axis_World);
  // This is the rotation matrix; this should be set as the
  // world matrix for the 1st mesh.
  D3DXMatrixRotationAxis(&rotation, &axis_World, angle_World);
  // -- Get rotation quaternion
  D3DXQUATERNION rotQuaternion;
  D3DXQuaternionRotationAxis(&rotQuaternion, &axis_World, angle_World);
  // -- Convert quaternion to Yaw Pitch Roll
  D3DXVECTOR3 rotXYZ;
  rotXYZ = QuaternionToVector3(rotQuaternion);
  btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
  btRigidBody* body = btRigidBody::upcast(obj);
  if (body && body->getMotionState())
  {
   body->activate(true);
   // -- Set new transform
   btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
   btRigidBody* body = btRigidBody::upcast(obj);
   if (body && body->getMotionState())
   {
    body->activate(true);
    // ********* THE FOLLOWING IS NOT WORKING AS EXPECTED *********
    btMatrix3x3 orn = body->getWorldTransform().getBasis(); //get basis of world transformation
    btQuaternion quat = btQuaternion(rotQuaternion.x, rotQuaternion.y, rotQuaternion.z, rotQuaternion.w);
    D3DXQUATERNION *dxQuat = new D3DXQUATERNION(quat.getX(), quat.getY(), quat.getZ(), quat.getW());
    D3DXVECTOR3 rotVector3 = QuaternionToVector3(*dxQuat);
    orn.setEulerYPR(rotVector3.x, rotVector3.y, rotVector3.z);
    body->getWorldTransform().setBasis(orn);
   }
}

Here is QuaternionToVector3():
D3DXVECTOR3 QuaternionToVector3(D3DXQUATERNION q)
{
    D3DXVECTOR3 euler;
    float sqx = q.x * q.x;
    float sqy = q.y * q.y;
    float sqz = q.z * q.z;
    float sqw = q.w * q.w;
    float unit = sqx + sqy + sqz + sqw;
    float test = (q.x * q.w - q.y * q.z);
    // Handle singularity
    if (test > 0.4999999f * unit)
    {
	    euler.x = D3DX_PI / 2;
	    euler.y = 2.0f * (float)atan2(q.y, q.w);
	    euler.z = 0;
    }
    else if (test < -0.4999999f * unit)
    {
	    euler.x = -D3DX_PI / 2;
	    euler.y = 2.0f * (float)atan2(q.y, q.w);
	    euler.z = 0;
    }
    else
    {
	    float ey_Y = 2 * (q.x * q.z + q.y * q.w);
	    float ey_X = 1 - 2 * (sqy + sqx);
	    float ez_Y = 2 * (q.x * q.y + q.z * q.w);
	    float ez_X = 1 - 2 * (sqx + sqz);
	    euler.y = (float)asin(2 * test);
	    euler.x = (float)atan2(ey_Y, ey_X);
	    euler.z = (float)atan2(ez_Y, ez_X);
    }
    // Convert to degrees
    euler.x = D3DXToDegree(euler.x);
    euler.y = D3DXToDegree(euler.y);
    euler.z = D3DXToDegree(euler.z);
    return euler;
}

#2Medo3337

Posted 30 November 2012 - 04:01 AM

Hello everyone,

I'm trying to make a mesh look at another mesh so I will be having two methods:

1. This method will make the mesh look at x, y ,z point instantly when called:
void Mesh::LookAtInstantly(float x, float y, float z);

2. This method will make the mesh move slightly till it look at the point, the method will be called several times to make the mesh look at another mesh, this method should return true when the it's actually looking at another mesh, otherwise it should return false when it's not yet looking at the other mesh:
bool Mesh::LookAtGradually(float x, float y, float z);

Here is the code that I'm using to make the mesh look at another, it's not working as expected.
D3DXMATRIX rotation;
// World space position of the 1st, watching mesh.
D3DXVECTOR3 mesh1Pos_World(X, Y, Z);
// World space position of the 2nd, watched mesh.
D3DXVECTOR3 mesh2Pos_World;
if (boolOnYAxis)
  mesh2Pos_World = D3DXVECTOR3(x, y, z);
else
  mesh2Pos_World = D3DXVECTOR3(x, Y, z);
// mesh2Pos_World.y = 0; // Will NOT rotate on Y axis (UP), should be applied to tank cannon
// Object space direction of the 1st mesh; in other
// words it says where your mesh is looking at prior
// to any transformation. Your mesh is assumed to be
// at the origin.
D3DXVECTOR3 mesh1Dir_Object(0, 0, -1);
// This is the vector that goes from the watching mesh
// to the watched mesh.
D3DXVECTOR3 direction_World = mesh2Pos_World - mesh1Pos_World;
D3DXMATRIX finalCannonRot;
if (direction_World.x != 0 || direction_World.y != 0 || direction_World.z != 0)
{
  // Normalize the two directions.
  D3DXVec3Normalize(&amp;mesh1Dir_Object, &amp;mesh1Dir_Object);
  D3DXVec3Normalize(&amp;direction_World, &amp;direction_World);
  // The acos of the dot product between the two directions is
  // the rotation angle in world space.
  FLOAT angle_World = std::acos(D3DXVec3Dot(&amp;mesh1Dir_Object, &amp;direction_World));
  // The normalized cross product between the two directions is
  // the rotation axis in world space.
  D3DXVECTOR3 axis_World;
  D3DXVec3Cross(&amp;axis_World, &amp;mesh1Dir_Object, &amp;direction_World);
  D3DXVec3Normalize(&amp;axis_World, &amp;axis_World);
  // This is the rotation matrix; this should be set as the
  // world matrix for the 1st mesh.
  D3DXMatrixRotationAxis(&amp;rotation, &amp;axis_World, angle_World);

  // -- Get rotation quaternion
  D3DXQUATERNION rotQuaternion;
  D3DXQuaternionRotationAxis(&amp;rotQuaternion, &amp;axis_World, angle_World);
  // -- Convert quaternion to Yaw Pitch Roll
  D3DXVECTOR3 rotXYZ;
  rotXYZ = QuaternionToVector3(rotQuaternion);

  btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
  btRigidBody* body = btRigidBody::upcast(obj);
  if (body &amp;&amp; body->getMotionState())
  {
   body->activate(true);
   // -- Set new transform
   btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
   btRigidBody* body = btRigidBody::upcast(obj);
   if (body &amp;&amp; body->getMotionState())
   {
    body->activate(true);
    // ********* THE FOLLOWING IS NOT WORKING AS EXPECTED *********
    btMatrix3x3 orn = body->getWorldTransform().getBasis(); //get basis of world transformation
    btQuaternion quat = btQuaternion(rotQuaternion.x, rotQuaternion.y, rotQuaternion.z, rotQuaternion.w);
    D3DXQUATERNION *dxQuat = new D3DXQUATERNION(quat.getX(), quat.getY(), quat.getZ(), quat.getW());
    D3DXVECTOR3 rotVector3 = QuaternionToVector3(*dxQuat);
    orn.setEulerYPR(rotVector3.x, rotVector3.y, rotVector3.z);
    body->getWorldTransform().setBasis(orn);
   }
}


Here is QuaternionToVector3():
D3DXVECTOR3 QuaternionToVector3(D3DXQUATERNION q)
{
    D3DXVECTOR3 euler;

    float sqx = q.x * q.x;
    float sqy = q.y * q.y;
    float sqz = q.z * q.z;
    float sqw = q.w * q.w;

    float unit = sqx + sqy + sqz + sqw;
    float test = (q.x * q.w - q.y * q.z);

    // Handle singularity
    if (test > 0.4999999f * unit)
    {
        euler.x = D3DX_PI / 2;
        euler.y = 2.0f * (float)atan2(q.y, q.w);
        euler.z = 0;
    }
    else if (test < -0.4999999f * unit)
    {
        euler.x = -D3DX_PI / 2;
        euler.y = 2.0f * (float)atan2(q.y, q.w);
        euler.z = 0;
    }
    else
    {
        float ey_Y = 2 * (q.x * q.z + q.y * q.w);
        float ey_X = 1 - 2 * (sqy + sqx);
        float ez_Y = 2 * (q.x * q.y + q.z * q.w);
        float ez_X = 1 - 2 * (sqx + sqz);

        euler.y = (float)asin(2 * test);
        euler.x = (float)atan2(ey_Y, ey_X);
        euler.z = (float)atan2(ez_Y, ez_X);
    }

    // Convert to degrees
    euler.x = D3DXToDegree(euler.x);
    euler.y = D3DXToDegree(euler.y);
    euler.z = D3DXToDegree(euler.z);

    return euler;
}

#1Medo3337

Posted 30 November 2012 - 03:18 AM

Hello everyone,

I'm trying to make a mesh look at another mesh so I will be having two methods:

1. This method will make the mesh look at x, y ,z point instantly when called:
void Mesh::LookAtInstantly(float x, float y, float z);

2. This method will make the mesh move slightly till it look at the point, the method will be called several times to make the mesh look at another mesh, this method should return true when the it's actually looking at another mesh, otherwise it should return false when it's not yet looking at the other mesh:
bool Mesh::LookAtGradually(float x, float y, float z);

Here is the code that I'm using to make the mesh look at another, it's not working as expected.
D3DXMATRIX rotation;
// World space position of the 1st, watching mesh.
D3DXVECTOR3 mesh1Pos_World(X, Y, Z);
// World space position of the 2nd, watched mesh.
D3DXVECTOR3 mesh2Pos_World;
if (boolOnYAxis)
  mesh2Pos_World = D3DXVECTOR3(x, y, z);
else
  mesh2Pos_World = D3DXVECTOR3(x, Y, z);
// mesh2Pos_World.y = 0; // Will NOT rotate on Y axis (UP), should be applied to tank cannon
// Object space direction of the 1st mesh; in other
// words it says where your mesh is looking at prior
// to any transformation. Your mesh is assumed to be
// at the origin.
D3DXVECTOR3 mesh1Dir_Object(0, 0, -1);
// This is the vector that goes from the watching mesh
// to the watched mesh.
D3DXVECTOR3 direction_World = mesh2Pos_World - mesh1Pos_World;
D3DXMATRIX finalCannonRot;
if (direction_World.x != 0 || direction_World.y != 0 || direction_World.z != 0)
{
  // Normalize the two directions.
  D3DXVec3Normalize(&mesh1Dir_Object, &mesh1Dir_Object);
  D3DXVec3Normalize(&direction_World, &direction_World);
  // The acos of the dot product between the two directions is
  // the rotation angle in world space.
  FLOAT angle_World = std::acos(D3DXVec3Dot(&mesh1Dir_Object, &direction_World));
  // The normalized cross product between the two directions is
  // the rotation axis in world space.
  D3DXVECTOR3 axis_World;
  D3DXVec3Cross(&axis_World, &mesh1Dir_Object, &direction_World);
  D3DXVec3Normalize(&axis_World, &axis_World);
  // This is the rotation matrix; this should be set as the
  // world matrix for the 1st mesh.
  D3DXMatrixRotationAxis(&rotation, &axis_World, angle_World);
 
  // -- Get rotation quaternion
  D3DXQUATERNION rotQuaternion;
  D3DXQuaternionRotationAxis(&rotQuaternion, &axis_World, angle_World);
  // -- Convert quaternion to Yaw Pitch Roll
  D3DXVECTOR3 rotXYZ;
  rotXYZ = QuaternionToVector3(rotQuaternion);

  btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
  btRigidBody* body = btRigidBody::upcast(obj);
  if (body && body->getMotionState())
  {
   body->activate(true);
   // -- Set new transform
   btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[ID];
   btRigidBody* body = btRigidBody::upcast(obj);
   if (body && body->getMotionState())
   {
    body->activate(true);
    btMatrix3x3 orn = body->getWorldTransform().getBasis();
    btMatrix3x3 ypr;
    // ********* THE FOLLOWING IS NOT WORKING AS EXPECTED *********
    orn.setEulerYPR(rotXYZ.x, rotXYZ.y, rotXYZ.z);
    // ypr.setEulerYPR(0.0f,rotXYZ.y,0.0f);
    // orn *= ypr;
    body->getWorldTransform().setBasis(orn);
   }

}

PARTNERS