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;
}
Problem with Rotation 3D (Solved)
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
[Edited by - Prog101 on October 19, 2006 6:21:06 AM]
Quote:Original post by Prog101Hehe, I love how gimbal lock has become the scapegoat for all rotation-related problems :-)
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?)
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 quarterionsBah. 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].
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 :)
Thank you guys, espically Zymph, 0xCHAOS and jyk it now works
i'll post the completed code for others to read for the future
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;}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement