Sign in to follow this  

3D BoundingBox collision detection

This topic is 4016 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 does anyone know of any good tutorials or example code for 3D collision detection i'm using DX9 and C++ i would really appriciate it [Edited by - Prog101 on December 13, 2006 6:26:13 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Prog101
Hi guys does anyone know of any good tutorials or example code for 3D collision detection i'm using DX9 and C++ i would really appriciate it
Check the articles section here on gdnet - there are at least a couple of articles that discuss collision detection algos for AABBs and OBBs.

Share this post


Link to post
Share on other sites
i have my bounding boxes working now, I used the following code: -

boundingVolumes.h

#ifndef _BOUNDING_VOLUMES_
#define _BOUNDING_VOLUMES_

#include <d3dx9.h>
#include <string>
#include <limits>

// Colors
const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) );
const D3DXCOLOR BLUE( D3DCOLOR_XRGB( 0, 0, 255) );

class CBoundingVolumes
{
public:
CBoundingVolumes(void);
virtual ~CBoundingVolumes(void);

//////////////////
// Struct
/////////////////
struct BoundingBox
{
BoundingBox();
D3DXVECTOR3 _min;
D3DXVECTOR3 _max;
};

D3DMATERIAL9 WHITE_MTRL;
D3DMATERIAL9 RED_MTRL;
D3DMATERIAL9 GREEN_MTRL;
D3DMATERIAL9 BLUE_MTRL;
D3DMATERIAL9 YELLOW_MTRL;

LPD3DXMESH BoxMesh;

/////////////////////
// Functions
////////////////////
D3DMATERIAL9 BoundingVolumes_InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);

void BoundingVolumes_CreateBox(LPDIRECT3DDEVICE9 device, ID3DXMesh* mesh);
void BoundingVolumes_RenderBox(LPDIRECT3DDEVICE9 device);

bool BoundingVolumes_Box_Compute(ID3DXMesh* mesh, BoundingBox* box);

private:

};
#endif // _BOUNDING_VOLUMES_








boundingVolumes.cpp


#include "boundingvolumes.h"
#include <vector>

CBoundingVolumes::CBoundingVolumes(void)
{
BLUE_MTRL = BoundingVolumes_InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
BoxMesh = 0;
}
CBoundingVolumes::~CBoundingVolumes(void)
{
BoxMesh->Release();
}
D3DMATERIAL9 CBoundingVolumes::BoundingVolumes_InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
{
D3DMATERIAL9 mtrl;
mtrl.Ambient = a;
mtrl.Diffuse = d;
mtrl.Specular = s;
mtrl.Emissive = e;
mtrl.Power = p;
return mtrl;
}
CBoundingVolumes::BoundingBox::BoundingBox()
{
// infinite small
_min.x = INFINITY;
_min.y = INFINITY;
_min.z = INFINITY;

_max.x = -INFINITY;
_max.y = -INFINITY;
_max.z = -INFINITY;
}
void CBoundingVolumes::BoundingVolumes_RenderBox(LPDIRECT3DDEVICE9 device)
{
// Draw bounding volume in Blue
D3DMATERIAL9 color = BLUE_MTRL;
color.Diffuse.a = 0.10f; // 10% opacity

device->SetMaterial(&color);
device->SetTexture(0, 0); // disable texture

device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

BoxMesh->DrawSubset(0);
}
bool CBoundingVolumes::BoundingVolumes_Box_Compute(ID3DXMesh* mesh, BoundingBox* 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;
}
void CBoundingVolumes::BoundingVolumes_CreateBox(LPDIRECT3DDEVICE9 device, ID3DXMesh* mesh)
{
//******************** Compute Bounding Box.
BoundingBox boundingBox;

BoundingVolumes_Box_Compute(mesh, &boundingBox);

D3DXCreateBox(
device,
boundingBox._max.x - boundingBox._min.x,
boundingBox._max.y - boundingBox._min.y,
boundingBox._max.z - boundingBox._min.z,
&BoxMesh,
0);
}







[Edited by - Prog101 on December 14, 2006 2:17:28 PM]

Share this post


Link to post
Share on other sites
so using the above BoundingVolumes class i have now got all the objects that i need with a BoundingBox.

i do this by calling:

#include 
//Header
"../BoundingVolume/boundingvolumes.h"
//Create a pointer objects
CBoundingVolumes *pPacManBoundingBox;
// In the constructor and destructure
pPacManBoundingBox = NULL;
//In the Init
pPacManBoundingBox = new CBoundingVolumes();
pPacManBoundingBox->BoundingVolumes_CreateBox(device,PacManModel->mesh);
// In the Render
pPacManBoundingBox->BoundingVolumes_RenderBox(device);




you can see how it works with Rendered Bounding Boxes now by running my exe
http://homepage.ntlworld.com/j.power40/html/zipfiles/exe.zip

what i would like to know now is how do i detect if a collision has occured between 2 objects?

[Edited by - Prog101 on December 14, 2006 11:26:07 AM]

Share this post


Link to post
Share on other sites
If your bounding boxes are overlapped you can perform a more accurate test.

The "more accurate test" depends by the structures you used to store your models: for example you could use a series of sub-bounding boxes in which you can insert parts of your model (a leg, an arm, ...)(keyword: Hierarchical Bounding Volumes).
If your models are not static you could create the sub-bounding volumes on the fly because they are cheap to build and to test (simply "inflate" the bounding volume with each vertex in the mesh).

If you need the perfect collision test you have to test each polygon of one set against each polygon of the second set. Since this operation is expensive in term of computational time ( O(N*N) ) you have to use bounding volumes to reduce these sets to a "decent" size.

Now your question could be: how to see if a polygon intersects another? :-D

Before try this method you should ask yourself if you really need this precision.

Share this post


Link to post
Share on other sites
so is this correct?

if (Check_For_Collisions(pPacman->pPacManBoundingBox->BoundingBox,
pPill->pPillBoundingBox->BoundingBox)== true)
{
//do something as a responce
}

i dont think it is , i want to call this in the main.cpp do how do i declare the pBox1 and pBox2 from the BoundingBox struct in the BoundingVolumes class?



bool Check_For_Collisions(pBox1,pBox2)
{
if ( pBox1._min.x > pBox2._max.x || pBox2._min.x > pBox1._max.x
||pBox1._min.y > pBox2._max.y || pBox2._min.y > pBox1._max.y
||pBox1._min.z > pBox2._max.z || pBox2._min.z > pBox1._max.z )
{
return false;
}

return true;
}




[Edited by - Prog101 on December 15, 2006 4:29:22 AM]

Share this post


Link to post
Share on other sites
Proq101:

your box collision test make sense for me.
When the function returns true, the two volumes are intersecting.

In this case you could backtrack the scene in the previous (non colliding) state (if you want avoid penetration) or do something else (for example "kill" the eaten pill).

However if your problem is only to eat a pill the problem is much simpler!
I would only check the distance from the center of the pill and some pac-man hotspots (for example the "feet" if your pacman is a 3D model or simply its center).
If the distance is less than a threshold, pac eats the pill :P

I dont know how many pills do you have but you can perform thousands of these tests without the need of octree/bsp...

Share this post


Link to post
Share on other sites

This topic is 4016 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this