Simple environment collision

Started by
2 comments, last by DragonL 17 years, 11 months ago
I have written a game in Direct X 9.0 involving many objects colliding on a fully rotatable environment. At the moment the environment is just one big mesh object being rendered using a vertex buffer. To perform the collision I need to know the triangle normals and the positions of the transformed vertices from the vertex buffer. My problem is I don;t know how to retrieve them from the buffer or even if this is possible. Can the transformed vertex data be pulled out of the vertex buffer after a render cycle, and if not what's the best way to perform collsion of this nature in Direct X9? Surely I don;t need to make a copy of the terrain data and transform it seperately just for collision? many thanks
Advertisement
One way I've been using is to compute both meshes centre points like this:

	void* vertices;	if(FAILED(		pMesh->LockVertexBuffer(0,(void**)&vertices)	)) return false;	D3DXComputeBoundingSphere(		(D3DXVECTOR3*) vertices,		pMesh->GetNumVertices(),		pMesh->GetNumBytesPerVertex(),		¢reNoTransforms,		&radius	);	pMesh->UnlockVertexBuffer();


The above code only needs to be used when you first load the mesh, just store centreNoTransforms and radius somewhere afterwards. Then apply the transform matrix to centreNoTransforms for both the meshes you want to collide and then just do a test to if the transformed centre points are at least the total of the radius' of both meshes apart. (For some reason "& centreNoTransforms" keeps showing up as ¢reNoTransforms in this message)

If you want to test for collision with terrain you can try something like I did for my camera:

Collide(LPD3DXMESH mesh, float maxDistance, bool forwards) {	BOOL hit = FALSE;	float distance = 0.0f;	D3DXVECTOR3 heading;	D3DXVec3Normalize(&heading, &(cameraTarget - cameraPosition));	if (!forwards) heading *= -1;	D3DXIntersect(		mesh, &cameraPosition, &heading,		&hit, NULL, NULL, NULL, &distance,		NULL, NULL	);	if (hit && (distance<maxDistance)) {		return true;	}	return false;}


You'd need to ignore the forwards variable, use the radius you get from D3DXComputeBoundingSphere as the maxDistance and have heading point straight down to the floor instead of calculating it from the target and position. The mesh would be the terrain and instead of cameraPosition you'd use the centreNoTransforms variable I passed to the D3DXComputeBoundingSphere function.

[Edited by - CodeReaver on June 9, 2006 6:19:46 PM]
thanks for that. the trouble is i need to know the surface normals of each triangle as the collision is between balls and i'm applying accurate dynamics to each ball.

the normal is required to i can calculate the direction a ball will travel in after collision.
Quote:Original post by maximum01
Can the transformed vertex data be pulled out of the vertex buffer after a render cycle (...)


No, that's not possible unfortunately. You'll have to implement the collision separately from the rendering, which probably means you'd need to transform a second "collision mesh". The upshot is that the collision mesh can be simpler than the original, much like CodeReaver's method of simply transforming a sphere. This does not seem like an option in your case however. Do you really need to transform the environment mesh though? How about transforming the balls into the environment's object space instead? That'd most likely be much less of an effort computationally.
"Morituri Nolumus Mori"

This topic is closed to new replies.

Advertisement