Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


RigidBody "LookAt" Rotation


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 Medo3337   Members   -  Reputation: 680

Like
0Likes
Like

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

Edited by Medo3337, 30 November 2012 - 05:10 AM.


Sponsor:

#2 rocklobster   Members   -  Reputation: 415

Like
0Likes
Like

Posted 30 November 2012 - 10:49 AM

Look into slerp for quaternions, it's basically interpolating rotations.

#3 Medo3337   Members   -  Reputation: 680

Like
0Likes
Like

Posted 30 November 2012 - 11:30 AM

Thanks very much you really helped me! Two things that I'm concerned about:

1. How can I know that the mesh has finished rotating? (I want to know this so the tank mesh should fire after finishing rotation)

2. I can notice that the rotation speed slow down when the mesh is almost done rotating, I want it to be the same speed all the time.

Here is the code that I wrote:
if (?) // Expression to check if the rotation is completed or still in progress
{
// Not completed
btQuaternion currentQuat;
orn.getRotation(currentQuat);
float speed = 0.001f;
currentQuat = currentQuat.slerp(FinalQuat, timeElapsed * speed);
orn = btMatrix3x3(currentQuat);
body->getWorldTransform().setBasis(orn);
// You still need to call this method more to finish the rotation
return false; // RETURN FALSE
} else {
// Rotation completed, you don't need to call this method anymore, the tank mesh should fire now.
return true; // RETURN TRUE
}





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS