Jump to content
  • Advertisement
Sign in to follow this  
Prog101

Problem with Rotation 3D (Solved)

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

If you intended to correct an error in the post then please contact us.

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);
	return Model->loadModel(device, "./models/lambo.x");
}
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
			directionVector.x = directionVectorTemp.x*cos(D3DXToRadian(STEERING_RATE))
				- directionVectorTemp.z*sin(D3DXToRadian(STEERING_RATE));
			directionVector.z = directionVectorTemp.x*sin(D3DXToRadian(STEERING_RATE))
				+ directionVectorTemp.z*cos(D3DXToRadian(STEERING_RATE));
		}
	}
	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
			directionVector.x = directionVectorTemp.x*cos(D3DXToRadian(- STEERING_RATE))
				- directionVectorTemp.z*sin(D3DXToRadian(- STEERING_RATE));
			directionVector.z = directionVectorTemp.x*sin(D3DXToRadian(- STEERING_RATE))
				+ directionVectorTemp.z*cos(D3DXToRadian(- STEERING_RATE));
		}
	}
	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,D3DXToRadian(rotation));
	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 this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Prog101
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 (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 this post


Link to post
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 this post


Link to post
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);
return Model->loadModel(device, "./models/lamboChas.x");
}
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
directionVector.x = directionVectorTemp.x*cos(D3DXToRadian(STEERING_RATE))
- directionVectorTemp.z*sin(D3DXToRadian(STEERING_RATE));
directionVector.z = directionVectorTemp.x*sin(D3DXToRadian(STEERING_RATE))
+ directionVectorTemp.z*cos(D3DXToRadian(STEERING_RATE));
}
}
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
directionVector.x = directionVectorTemp.x*cos(D3DXToRadian(- STEERING_RATE))
- directionVectorTemp.z*sin(D3DXToRadian(- STEERING_RATE));
directionVector.z = directionVectorTemp.x*sin(D3DXToRadian(- STEERING_RATE))
+ directionVectorTemp.z*cos(D3DXToRadian(- STEERING_RATE));
}
}
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,D3DXToRadian(rotation));
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;
}


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!