# Collision Detection Problems

• 12-11-2006
Dark_Phoenix
Collision Detection Problems
I'm working on a simple breakout clone. I have the board set up an a ball moving across it. But I have two (related?) problems :
(1) Instead of bouncing off the walls, the ball goes right through them.
(2) The ball should start off moving at an angle to the back left side but instead goes straight left. It acts like it is bouncing off of walls directly in front and behind, so that it can only move left to right.

This should create a bounding box for the floor/walls and one for the ball. before rendering each frame I check to see if the bounding box for the ball is still inside the bounding box for the floor/walls. If not then I change directions. Then I calculate the new bounding box for the ball and render the frame.

I have a mesh that is loaded for the ball and the floor / walls in seperate cMeshInstace objects and each one is attached to a seperate cMeshBoundingBox object.

Any Ideas? I have been messing with this most of the day and cannot figure it out.
Code:

bool cMeshBoundingBox::FindBounds(LPD3DXMESH Mesh) {
// First get the min and max bounds for the object
BYTE* pVertices = NULL;
HRESULT hr;
(LPVOID*)&pVertices) ) ) {
SHOWERROR("Could not lock Vertex Buffer", __FILE__, __LINE__);
return FALSE;
}
D3DXComputeBoundingBox( (D3DXVECTOR3*)pVertices,
Mesh->GetNumVertices(),
D3DXGetFVFVertexSize(Mesh->GetFVF() ),
&m_MinBounds, &m_MaxBounds);
Mesh->UnlockVertexBuffer();
// Next get the 8 corners of the bounding box
m_ObjectBounds[0] = D3DXVECTOR3(m_MinBounds.x, m_MinBounds.y, m_MinBounds.z);
m_ObjectBounds[1] = D3DXVECTOR3(m_MaxBounds.x, m_MinBounds.y, m_MinBounds.z);
m_ObjectBounds[2] = D3DXVECTOR3(m_MinBounds.x, m_MaxBounds.y, m_MinBounds.z);
m_ObjectBounds[3] = D3DXVECTOR3(m_MaxBounds.x, m_MaxBounds.y, m_MinBounds.z);
m_ObjectBounds[4] = D3DXVECTOR3(m_MinBounds.x, m_MinBounds.y, m_MaxBounds.z);
m_ObjectBounds[5] = D3DXVECTOR3(m_MaxBounds.x, m_MinBounds.y, m_MaxBounds.z);
m_ObjectBounds[6] = D3DXVECTOR3(m_MinBounds.x, m_MaxBounds.y, m_MaxBounds.z);
m_ObjectBounds[7] = D3DXVECTOR3(m_MaxBounds.x, m_MaxBounds.y, m_MaxBounds.z);
return true;
}

Code:

void cGameApp::UpdateFrame(LPDIRECT3DDEVICE9 pDevice, float ElapsedTime) {
m_pBall->TranslateRel(m_xDirection * ElapsedTime, 0.0f,
m_zDirection * ElapsedTime);
m_pBall->UpdateBounds();
// do collision checking
int collision = 0;
// Collect the Bounding Boxes
D3DXVECTOR3 bBallMin,  bBallMax,
bFloorMin,  bFloorMax;
m_pBall->GetBounds(&bBallMin, &bBallMax);
m_pFloor->GetBounds(&bFloorMin, &bFloorMax);

// check for Collision
if (bBallMax.x > bFloorMax.x || bBallMin.x > bFloorMin.x)
collision = 1;  // collision on x axis
if (bBallMax.z > bFloorMax.z || bBallMin.z > bFloorMin.z)
collision = 2;  // collision on z axis

if (collision != 0) {
if (collision == 1)
m_xDirection *= -1;
if (collision == 2)
m_zDirection *= -1;
m_pBall->TranslateRel(m_xDirection * ElapsedTime, 0.0f,
m_zDirection * ElapsedTime);
m_pBall->UpdateBounds();
}
return;
}

Code:

void cMeshBoundingBox::UpdateBounds() {
// get the world position of the bounding box
D3DXVECTOR3 WorldBounds[8];
for (int i = 0; i < 8; i++)
D3DXVec3TransformCoord(&WorldBounds[i],
&m_ObjectBounds[i],
GetWorldMatrix() );

//  find the min and max bounds for the box
m_MinBounds.x = m_MaxBounds.x = WorldBounds[0].x;
m_MinBounds.y = m_MaxBounds.y = WorldBounds[0].y;
m_MinBounds.z = m_MaxBounds.z = WorldBounds[0].z;
for (int i=1;i<8;i++) {
if (WorldBounds[i].x < m_MinBounds.x)  m_MinBounds.x = WorldBounds[i].x;
if (WorldBounds[i].x > m_MaxBounds.x)  m_MaxBounds.x = WorldBounds[i].x;
if (WorldBounds[i].y < m_MinBounds.y)  m_MinBounds.y = WorldBounds[i].y;
if (WorldBounds[i].y > m_MaxBounds.y)  m_MaxBounds.y = WorldBounds[i].y;
if (WorldBounds[i].z < m_MinBounds.z)  m_MinBounds.z = WorldBounds[i].z;
if (WorldBounds[i].z > m_MaxBounds.z)  m_MaxBounds.z = WorldBounds[i].z;
}
return;
}

• 12-17-2006
skorman00
Code:

// check for Collision
if (bBallMax.x > bFloorMax.x || bBallMin.x > bFloorMin.x)
collision = 1;  // collision on x axis
if (bBallMax.z > bFloorMax.z || bBallMin.z > bFloorMin.z)
collision = 2;  // collision on z axis

I think the conditions are incorrect, both of them on the right of the or
Code:

// check for Collision
if (bBallMax.x > bFloorMax.x || bBallMin.x < bFloorMin.x)
collision = 1;  // collision on x axis
if (bBallMax.z > bFloorMax.z || bBallMin.z < bFloorMin.z)
collision = 2;  // collision on z axis

You also don't need to keep all 8 points for the bounding box. 1 min and 1 max would do just as well, and would make the logic in UpdateBounds() easier to follow.