Original Post
Using DirectX 9 and c++ i am making a car game but my collision detection is playing up on me, I am using OBB collision and what is happening is when the car hits the wall it gets stuck and does not easily come away from the wall. Check out the exe at http://homepage.ntlworld.com/j.power40/html/zipfiles/CarExe.zip Bounding /Box Code collision code [Edited by - Prog101 on April 4, 2007 9:37:23 AM]
void CBoundingVolumes::BoundingVolumes_CreateBox(LPDIRECT3DDEVICE9 device, ID3DXMesh* mesh, float scale)
{
//******************** Compute Bounding Box
BoundingVolumes_Box_Compute(mesh, &s_BoundingBox);
s_BoundingBox.Scale = scale;
s_BoundingBox._max *= s_BoundingBox.Scale;
s_BoundingBox._min *= s_BoundingBox.Scale;
D3DXCreateBox(
device,
s_BoundingBox._max.x - s_BoundingBox._min.x,
s_BoundingBox._max.y - s_BoundingBox._min.y,
s_BoundingBox._max.z - s_BoundingBox._min.z,
&BoxMesh,
0);
}
bool CBoundingVolumes::BoundingVolumes_Box_Compute(ID3DXMesh* mesh, sBoundingBox* box)
{
HRESULT hr = 0;
BYTE* pVertices = NULL;
hr=mesh->LockVertexBuffer(0, (void**)&pVertices);
if (FAILED(hr))
return FALSE;
hr = D3DXComputeBoundingBox( //D3D Function that calc's the bounding box for a mesh
(D3DXVECTOR3*)pVertices, //Vertex position component is stored 1st in the vertex structure we are using
mesh->GetNumVertices(), //Get the number of vertices's in the mesh
D3DXGetFVFVertexSize(mesh->GetFVF()), //function how many bytes there are between each vertex
&box->_min, //Return the min and max points of the bounding box
&box->_max);
mesh->UnlockVertexBuffer();
if( FAILED(hr) )
return false;
return true;
}
sBoundingBox::sBoundingBox()
{
// infinite small
_min.x = INFINITY;
_min.y = INFINITY;
_min.z = INFINITY;
_max.x = -INFINITY;
_max.y = -INFINITY;
_max.z = -INFINITY;
}
void CBoundingVolumes::Update_OBB(D3DXMATRIX ObjectMatrix, D3DXVECTOR3 min, D3DXVECTOR3 max)
{
// We have min and max values, use these to get the 8 corners of the bounding box
m_objectBounds[0] = D3DXVECTOR3(min.x,min.y,min.z ); // XYZ
m_objectBounds[1] = D3DXVECTOR3(max.x,min.y,min.z ); // XYZ
m_objectBounds[2] = D3DXVECTOR3(min.x,max.y,min.z ); // XYZ
m_objectBounds[3] = D3DXVECTOR3(max.x,max.y,min.z ); // XYZ
m_objectBounds[4] = D3DXVECTOR3(min.x,min.y,max.z ); // XYZ
m_objectBounds[5] = D3DXVECTOR3(max.x,min.y,max.z ); // XYZ
m_objectBounds[6] = D3DXVECTOR3(min.x,max.y,max.z ); // XYZ
m_objectBounds[7] = D3DXVECTOR3(max.x,max.y,max.z ); // XYZ
for( int i = 0; i < 8; i++ )
D3DXVec3TransformCoord( &worldBounds, &m_objectBounds, &ObjectMatrix );
this->CalcAABBFromOBB(worldBounds,min,max);
}
/*********************************************************************************
Given the 8 corners of a OBB bounding box in world space, create a AABB bounding box in world space
*********************************************************************************/
void CBoundingVolumes::CalcAABBFromOBB(D3DXVECTOR3 *ObjectBounds,D3DXVECTOR3 min, D3DXVECTOR3 max)
{
min.x = max.x = ObjectBounds[0].x;
min.y = max.y = ObjectBounds[0].y;
min.z = max.z = ObjectBounds[0].z;
for (int i=1;i<8;i++)
{
if (ObjectBounds.x <min.x)min.x = ObjectBounds.x;
if (ObjectBounds.x >max.x)max.x = ObjectBounds.x;
if (ObjectBounds.y <min.y)min.y = ObjectBounds.y;
if (ObjectBounds.y >max.y)max.y = ObjectBounds.y;
if (ObjectBounds.z <min.z)min.z = ObjectBounds.z;
if (ObjectBounds.z >max.z)max.z = ObjectBounds.z;
}
s_BoundingBox.vMin = min;
s_BoundingBox.vMax = max;
}
int Game::update(void)
{
pCar->getPosition(LastPosition);
// UPDATE THE MOVEMENT AND PHYSICS HERE
// Update the oriented bounding box
pCar->pBoundingBox->Update_OBB(pCar->finalMatrix,pCar->pBoundingBox->s_BoundingBox._min,pCar->pBoundingBox->s_BoundingBox._max);
Collisions();
}
/********************************************************************
* collisions: this function handles all the collisions and responces
********************************************************************/
void Game::Collisions(void)
{
//* Perform a collision checks for the player and the walls
for (unsigned int i=0; i<pWall.size();i++)
{
pCar->get_BoundingBox(&playerBB);
pWall->get_BoundingBox(&wallBB);
if (Collision_BoxCheck(playerBB,wallBB))
{
pCar->setPosition(LastPosition);
break;
}
else bCollision = false;
}
}
bool Collision_BoxCheck(const sBoundingBox& pBox1, const sBoundingBox& pBox2)
{
/*If the max x position of 1 is less than the min x position of 2 they do not collide
If the min x position of 1 is greater than the max x position of 2 they do not collide
and the same goes for y and z */
if ( pBox1.vMax.x < pBox2.vMin.x || pBox1.vMin.x > pBox2.vMax.x
|| pBox1.vMax.y < pBox2.vMin.y || pBox1.vMin.y > pBox2.vMax.y
|| pBox1.vMax.z < pBox2.vMin.z || pBox1.vMin.z > pBox2.vMax.z)
return false;
else
return true;
}