# Problem with Rotation 3D (Solved)

This topic is 4476 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi guys i am having a problem trying to rotate my mesh smoothly, when i try to rotate the mesh the car just disapears at one point and when i rotate it further it appears again (some one said its Gimble lock?) but i'm only rotating around 1 Axis, anyhow i was thinking i would like to use quarterions but have never implemented them before i have read up all about them but would like some assistence to get me started? so basically i want to know how to change this to rotate it by quarterions or be pointed in the right direction to figure this out car.cpp
bool CCar::create(LPDIRECT3DDEVICE9 device)
{
//Setup the cars physics 1st
car_initPhysics();
Model = new CModel();
// Create a color for the text - in this case Blue
d3dBlue1 = D3DCOLOR_ARGB(255,0,0,255);
}
void CCar::car_initPhysics(void)
{
accelerationVector.x = 0.0f;
accelerationVector.y = 0.0f;
accelerationVector.z = 0.0f;
positionVector.x = 0.0f;
positionVector.y = 0.0f;
positionVector.z = 0.0f;
VelocityVector.x = 0.0f;
VelocityVector.y = 0.0f;
VelocityVector.z = 0.0f;
directionVector.x = 0.0f;
directionVector.y = 0.0f;
directionVector.z = 1.0f;
referenceVector.x = 0.0f;
referenceVector.y = 0.0f;
referenceVector.z = 1.0f;
directionVectorTemp.x = 0.0f;
directionVectorTemp.y = 0.0f;
directionVectorTemp.z = 0.0f;
ACCELERATION_RATE	=  5.0;
BRAKING_RATE		= -20.0;
FRICTION_RATE		= -1.0;
STOP_RATE			=  0.0;
STEERING_RATE		=  5.0;
MAX_SPEED			=  5.0f;
}
void CCar::car_setPosition(D3DXVECTOR3 newPosition)
{
positionVector = newPosition;
}
void CCar::getPosition(D3DXVECTOR3 &carPosition)
{
carPosition = positionVector;
}
void CCar::getCarDirection(D3DXVECTOR3 &carDirection)
{
D3DXVec3Normalize(& tempCarDirection, & directionVector);
carDirection = tempCarDirection;
}
void CCar::car_updatePhysics(float dtime)
{
VelocityVector = VelocityVector + accelerationVector * dtime; /*Update the VelocityVector*/
positionVector = positionVector + VelocityVector;/*Update the positionVector*/
/*Get the magnitude of the cars velocity*/
magnitude = (sqrt)((VelocityVector.x * VelocityVector.x) +
(VelocityVector.y * VelocityVector.y) +
(VelocityVector.z * VelocityVector.z));

speed = magnitude;/*speed = magnitude of the cars vectors*/

/*Update the angle for the car to turn by getting the dot
product between the direction and a reference in radians*/
fDot = acos(D3DXVec3Dot(&directionVector,&referenceVector));

/* check if the directionVector has a -ve X, which means it is pointing towards -ve X
in this case, the angle should be 360 - angle,360 in radians is 2*pi */
if(directionVector.x < 0)
{
fDot = 2*D3DX_PI - fDot;
}
car_updateCar();
}

void CCar::car_updateCar()
{
if (bAccelerationKeyPressed == true)/*ACCELERATE THE CAR*/
{
if (speed <= MAX_SPEED) //Cap the speed
{
accelerationVector = directionVector * ACCELERATION_RATE;
}
}
if (bLeftKeyPressed == true)/*TURN CAR LEFT*/
{
if (speed >= 0.5f)/*only rotate if speed is above*/
{
directionVectorTemp.x = directionVector.x;
directionVectorTemp.z = directionVector.z;
//Rotate  the direction vector by an angle
}
}
if (bRightKeyPressed == true)/*TURN CAR LEFT*/
{
if (speed >= 0.5f)/*only rotate if speed is above*/
{
directionVectorTemp.x = directionVector.x;
directionVectorTemp.z = directionVector.z;
//Rotate the direction vector by an angle
}
}
if (bBreakingKeyPressed == true)/*BRAKE THE CAR*/
{
accelerationVector = directionVector * BRAKING_RATE;
}

if (bAccelerationKeyPressed == false && speed != 0)/*Set the friction rate on the car*/
{
accelerationVector = directionVector * FRICTION_RATE;
}

VelocityVector = directionVector * speed;
}

void CCar::render(LPDIRECT3DDEVICE9 device)
{

// Display the Speed
RECT rSpeed;
rSpeed.top = 100;
rSpeed.bottom = 600;
rSpeed.left = 5;
rSpeed.right = 640;
std::stringstream ss; ss <<"Speed "<<  speed/100;
dxMgr.pFont->DrawText(NULL, ss.str().c_str(), -1, &rSpeed, DT_TOP | DT_LEFT, d3dBlue1);

D3DXMATRIX transMatrix;				// the translation matrix
D3DXMATRIX rotMatrix;				// the rotation matrix
D3DXMATRIX scaleMatrix;				// the scale matrix

// create the translation matrix
D3DXMatrixTranslation(&transMatrix, positionVector.x, positionVector.y, positionVector.z);

// create the rotation matrix for the object
D3DXMatrixRotationY(&rotMatrix,fDot);

// Scale the Car by the size amount
D3DXMatrixScaling(&scaleMatrix, size, size, size);

// Multiply the translation matrix by the rotation matrix
// The resulting matrix is stored in the transMatrix
D3DXMatrixMultiply(&transMatrix, &rotMatrix, &transMatrix);

// Multiply the translation matrix by the scale
D3DXMatrixMultiply(&transMatrix, &scaleMatrix, &transMatrix);

// Transform the object into world space
device->SetTransform(D3DTS_WORLD, &transMatrix);

// render the model for this car
Model->render(device);
}
void CCar::car_setSize(float carSize)
{
size = carSize;
}

[Edited by - Prog101 on October 19, 2006 6:21:06 AM]

##### Share on other sites
Quote:
 Original post by Prog101Hi guys i am having a problem trying to rotate my mesh smoothly, when i try to rotate the mesh the car just disapears at one point and when i rotate it further it appears again (Gimble lock?)
Hehe, I love how gimbal lock has become the scapegoat for all rotation-related problems :-)

Anyway, it looks to me like you're only performing a single rotation (about the y axis), in which case no, gimbal lock is not the problem. Also, the behavior you describe is not a typical symptom of gimbal lock.
Quote:
 so basically i want to know how to change this to rotate it by quarterions
Bah. You don't need quaternions to fix this problem, and in fact you'd be doing yourself a disservice by bailing on your current implementation without figuring out why it doesn't work.

As for the problem, it looks to me like you're concatenating the matrices in the correct order. A possible culprit might be the value of 'fDot' and the acos() call, so I would start by adding some debug output to confirm that fDot and the matrix created from it are valid.

Whether or not this turns out to be the problem, you should always clamp the input to acos() to the range [-1,1].

##### Share on other sites
I can testify to that... I ran into a similar problem a couple of weeks ago. At certain orientations some of my models were not being drawn, and the problem turned out to be that I was calling an inverse trig function with a value slightly bigger than one (hence filling the transformation matrix with NaNs). The number being passed to the inverse trig function came from the length of the cross product of two unit vectors, which I assumed could be no greater than one. Mathematically it can't be, but hey, gotta love floating point errors :)

##### Share on other sites
Thank you guys, espically Zymph, 0xCHAOS and jyk it now works

i'll post the completed code for others to read for the future

CCar::CCar(void)
{

}
CCar::~CCar(void)
{

}
bool CCar::create(LPDIRECT3DDEVICE9 device)
{
//Setup the cars physics 1st
car_initPhysics();
Model = new CModel();
// Create a color for the text - in this case Blue
d3dBlue1 = D3DCOLOR_ARGB(255,0,0,255);
}
void CCar::car_initPhysics(void)
{
accelerationVector.x = 0.0f;
accelerationVector.y = 0.0f;
accelerationVector.z = 0.0f;
positionVector.x = 0.0f;
positionVector.y = 0.0f;
positionVector.z = 0.0f;
VelocityVector.x = 0.0f;
VelocityVector.y = 0.0f;
VelocityVector.z = 0.0f;
directionVector.x = 0.0f;
directionVector.y = 0.0f;
directionVector.z = 1.0f;
referenceVector.x = 0.0f;
referenceVector.y = 0.0f;
referenceVector.z = 1.0f;
directionVectorTemp.x = 0.0f;
directionVectorTemp.y = 0.0f;
directionVectorTemp.z = 0.0f;
ACCELERATION_RATE = 5.0;
BRAKING_RATE = -20.0;
FRICTION_RATE = -1.0;
STOP_RATE = 0.0;
STEERING_RATE = 5.0;
MAX_SPEED = 0.5f;
}
void CCar::car_setPosition(D3DXVECTOR3 newPosition)
{
positionVector = newPosition;
}
void CCar::getPosition(D3DXVECTOR3 &carPosition)
{
carPosition = positionVector;
}
void CCar::getCarDirection(D3DXVECTOR3 &carDirection)
{
D3DXVec3Normalize(& tempCarDirection, & directionVector);
carDirection = tempCarDirection;
}
void CCar::car_updatePhysics(float dtime)
{
VelocityVector = VelocityVector + accelerationVector * dtime; /*Update the VelocityVector*/
positionVector = positionVector + VelocityVector;/*Update the positionVector*/
/*Get the magnitude of the cars velocity*/
magnitude = (sqrt)((VelocityVector.x * VelocityVector.x) +
(VelocityVector.y * VelocityVector.y) +
(VelocityVector.z * VelocityVector.z));

speed = magnitude;/*speed = magnitude of the cars vectors*/

/*Update the angle for the car to turn by getting the dot
product between the direction and a reference in radians, and then clamp it to stop floating point errors*/

temp1 = D3DXVec3Dot(&directionVector,&referenceVector);
if (temp1 < -1)
{
temp1 = -1;
}
else if (temp1 > 1)
{
temp1 = 1;
}
fDot = acos(temp1);
/* check if the directionVector has a -ve X, which means it is pointing towards -ve X
in this case, the angle should be 360 - angle,360 in radians is 2*pi */

if(directionVector.x < 0)
{
fDot = 2*D3DX_PI - fDot;
}

car_updateCar();
}

void CCar::car_updateCar()
{
if (bAccelerationKeyPressed == true)/*ACCELERATE THE CAR*/
{
if (speed <= MAX_SPEED) //Cap the speed
{
accelerationVector = directionVector * ACCELERATION_RATE;
}
}
if (bLeftKeyPressed == true)/*TURN CAR LEFT*/
{
if (speed >= 0.5f)/*only rotate if speed is above*/
{
directionVectorTemp.x = directionVector.x;
directionVectorTemp.z = directionVector.z;
//Rotate the direction vector by an angle
}
}
if (bRightKeyPressed == true)/*TURN CAR LEFT*/
{
if (speed >= 0.5f)/*only rotate if speed is above*/
{
directionVectorTemp.x = directionVector.x;
directionVectorTemp.z = directionVector.z;
//Rotate the direction vector by an angle
}
}
if (bBreakingKeyPressed == true)/*BRAKE THE CAR*/
{
accelerationVector = directionVector * BRAKING_RATE;
}

if (bAccelerationKeyPressed == false && speed != 0)/*Set the friction rate on the car*/
{
accelerationVector = directionVector * FRICTION_RATE;
}

VelocityVector = directionVector * speed;

WheelFL->WheelFL_updatePosition(positionVector);
}

void CCar::render(LPDIRECT3DDEVICE9 device)
{

// Display the Speed
RECT rSpeed;
rSpeed.top = 100;
rSpeed.bottom = 600;
rSpeed.left = 5;
rSpeed.right = 640;
std::stringstream ss; ss <<"Speed "<< speed/100;
dxMgr.pFont->DrawText(NULL, ss.str().c_str(), -1, &rSpeed, DT_TOP | DT_LEFT, d3dBlue1);

D3DXMATRIX transMatrix; // the translation matrix
D3DXMATRIX rotMatrix; // the rotation matrix
D3DXMATRIX scaleMatrix; // the scale matrix

// create the translation matrix
D3DXMatrixTranslation(&transMatrix, positionVector.x, positionVector.y, positionVector.z);

// create the rotation matrix for the object
D3DXMatrixRotationY(&rotMatrix,fDot);

// Scale the Car by the size amount
D3DXMatrixScaling(&scaleMatrix, size, size, size);

// Multiply the translation matrix by the rotation matrix
// The resulting matrix is stored in the transMatrix
D3DXMatrixMultiply(&transMatrix, &rotMatrix, &transMatrix);

// Multiply the translation matrix by the scale
D3DXMatrixMultiply(&transMatrix, &scaleMatrix, &transMatrix);

// Transform the object into world space
device->SetTransform(D3DTS_WORLD, &transMatrix);

// render the model for this car
Model->render(device);

}
void CCar::car_setSize(float carSize)
{
size = carSize;
}

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 17
• 14
• 10
• 9
• 11
• ### Forum Statistics

• Total Topics
634095
• Total Posts
3015501
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!