Advertisement

Orienting objects in the direction of their velocity

Started by August 22, 2001 06:53 AM
1 comment, last by Zawar 23 years, 6 months ago
For a seemingly easy problem, I just can''t find the correct solution. I write this code: void Mmissile::Mmove (D3DVECTOR &v, float timediff ) { setVelocity (v); position.dvX += velocity.dvX * timediff * timespeed; position.dvY += velocity.dvY * timediff * timespeed; position.dvZ += velocity.dvZ * timediff * timespeed; orientation.dvY = -(FLOAT)atan2(velocity.dvX, velocity.dvZ) + g_PI; if (velocity.dvZ > 0.0f) orientation.dvY += 2.0f * (g_PI_DIV_2 - orientation.dvY); //problemo orientation.dvX = -(FLOAT)atan2(velocity.dvY, velocity.dvZ); } void Mmissile:repareforRendering(LPDIRECT3DDEVICE7 m_pd3dDevice) { D3DMATRIX matWorld, matTrans, matRotate, matTemp; D3DUtil_SetIdentityMatrix(matRotate); D3DUtil_SetIdentityMatrix(matTemp); D3DUtil_SetTranslateMatrix (matTrans, position.dvX, position.dvY, position.dvZ); D3DUtil_SetRotateYMatrix( matTemp, orientation.dvY ); D3DMath_MatrixMultiply(matRotate, matRotate, matTemp); D3DUtil_SetRotateXMatrix( matTemp, orientation.dvX ); D3DMath_MatrixMultiply(matRotate, matRotate, matTemp); D3DMath_MatrixMultiply( matWorld, matRotate, matTrans ); m_pd3dDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &matWorld); } The problem is that when the z-component of the velocity approches zero, the object seems to wobble to the extreme of its erraticity (it basically rotates out of alignment on the X-axis), and in between it smoothly comes back to position. It seems like a really tricky problem to fix, so if anyone happens to have any code that aligns the objects in the direction of their velocity, please oblige. Zawar Qayyum |IRR|
|IRR| -- The hungary Programmer - till yet.
Hi,

This problem is very similar to that of a Billboard, where you are attempting to keep the object facing the camera. In your case, however, you already have a vector defining the direction the object should be facing.

As an alternative approach to the one you are taking you could use the same code that is used for billboards and construct the world matrix for the object similar to that given below.

//***********************************************
//this routine does a full billboard implementation
//the object always faces the camera

BLook = Camera - Object1;

D3DXVec3Normalize(&BLook, &BLook);

Dot = D3DXVec3Dot(&BLook, &WorldUp);

BUp = WorldUp - Dot * BLook;

D3DXVec3Normalize(&BUp, &BUp);

D3DXVec3Cross(&BRight, &BUp, &BLook);

//************************************************************************

MatrixT1._11 = BRight.x; MatrixT1._21 = BUp.x; MatrixT1._31 = BLook.x;
MatrixT1._12 = BRight.y; MatrixT1._22 = BUp.y; MatrixT1._32 = BLook.y;
MatrixT1._13 = BRight.z; MatrixT1._23 = BUp.z; MatrixT1._33 = BLook.z;

MatrixT1._41=Object1.x;
MatrixT1._42=Object1.y;
MatrixT1._43=Object1.z;

MatrixT1._14=0.0f;
MatrixT1._24=0.0f;
MatrixT1._34=0.0f;
MatrixT1._44=1.0f;


in your case, BLook is already known and is the velocity vector for the object and the rest can be calculated as shown and the world matrix difined.

Another advantage of this method is that you don''t need any sin/cos/tan functions which are a bit slow.

I can send you more detail if needed.

Hope this helps

henry
HenryLecturer in Computer Games TechnologyUniversity of Abertay DundeeScotlandUK
Advertisement
I am sure it would have helped but I happen to have solved the problem somehow. Here is the revised code:

void Mmissile::Mmove (D3DVECTOR &v, float timediff )
{
setVelocity (v);
position.dvX += velocity.dvX * timediff * timespeed;
position.dvY += velocity.dvY * timediff * timespeed;
position.dvZ += velocity.dvZ * timediff * timespeed;

orientation.dvY = (FLOAT)atan2(velocity.dvX, velocity.dvZ);
if (velocity.dvZ > 0.0f)
orientation.dvY += 2.0f * (g_PI_DIV_2 - orientation.dvY);

float xzplane = sqrt(pow(velocity.dvZ, 2) + pow(velocity.dvX, 2));
orientation.dvX = -(FLOAT)atan2(velocity.dvY, xzplane);
}
As you may have figured out, it was because I was determining my rotation about the X-axis as the trignometric
tangent of the Y and Z velocity vectors. Now I am doing it by using the tangent of Y and the resultant
of Z and X velocity vectors.

Thanks a bundle friend for your intention to help.
|IRR| -- The hungary Programmer - till yet.

This topic is closed to new replies.

Advertisement