
Orienting objects in the direction of their velocity
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
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
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.
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
Popular Topics
Advertisement
Recommended Tutorials
Advertisement