Collision between particles (Planes) and Box

Started by
16 comments, last by Medo Mex 10 years, 8 months ago

I'm trying to detect collision between planes (particles) and boxes (building bounding box) so I can prevent rain/snow particles from entering buildings.

Here is what I'm doing (not working though):


// q1, q2, q3, q4 = Particle plane verticesAABB aabb = GetBuildingBoundaryBox(); // *** The bounding box is calculated using D3DXComputeBoundingBox() ***
D3DXVECTOR3 boxPosition = GetBuildingPosition();
D3DXMATRIX matBox;
D3DXMatrixTranslation(&matBox, boxPosition.x, boxPosition.y, boxPosition.z);

D3DXVec3TransformCoord(&aabb.Min, &aabb.Min, &matBox);
D3DXVec3TransformCoord(&aabb.Max, &aabb.Max, &matBox);

Plane plane;
plane.normal = GetTriangleNormal(q1, q2, q3);
plane.offset = D3DXVec3Dot(&plane.normal, &q1);

if (TestBoxToPlaneCollision(plane, aabb))
{
    // Collision detected
} else {
    // Collision NOT detected
}

Is the above code valid? It's not working with me (It's detecting collision when there is no collision)

Advertisement

Collision is not the way to prevent snowflakes to enter the building! The reason is that the intersection detection will be extreamly slow!

The right way to do it is by using the Z-Depth test for the particles.

That topic is really advanced.

There are some cool workarounds:

1) Display the particles in only predefined shapes(like boxes). with that method you can control the particles. Pseudo code

CParticeEmiter snowEmiter(PARTICLE_SNOW, boundingBoxMin, boundingBoxMax); //boundingBoxMin & boundingBoxMax will defined there area where snowing is allowed

and later in your spawn method ....

void snowEmiter::spwanNewPartice()

{

const float newParticleXPox = lerp(boundingBoxMin.x, boundingBoxMax,y rndFloat(0.f, 1.f));//that line is a crap you've got the idea

.......
}

2) The second method is to move snowEmiter with the player. if the player enters a building then you will deatach the particle emitter and leave it in front of the building entrance.

There are a lot of different solutions but you've got the idea.

3) I need to make a picture for you

http://postimg.org/image/x4807pz0j/

Collision is not the way to prevent snowflakes to enter the building! The reason is that the intersection detection will be extreamly slow!

Doubt it, I have many snow rains per particle (not only one rain drop per particle)

The right way to do it is by using the Z-Depth test for the particles.

Z-Depth test? I don't know what the depth has to do with preventing particles from entering buildings

2) That's a good idea, but what if the player entered from the door and then went to look from a window upstairs? The rain/snow particles would be still infront of the door and he can't see it infront of the window.

Another problem is that the player could look at the building entrance from outside and see rain inside the building! blink.png

Ignoring the possibility of subtle math bugs you have a conceptual problem; you are treating the particle's as if they have infinite extent. A plane equation extends forever so it's not enough to simply test an AABB against a particle's plane equation. A particle is a polygon so there are bounds that must be considered.

While particles are usually rendered as 2d quads you rarely want to consider the topology of the rendered geometry while doing collision detection. Particles are typically stored as points with a radius, to render them you orient a quad towards the camera. This suggest that a particle's physical geometry is better represented with a sphere. I would switch approaches and use a sphere to AABB collision routine, it will make your life easier.

@nonoptimalrobot: I have the plane vertices v1, v2, v3, v4

How do I calculate the plane radius so I can do AABB to sphere collision test?

It should be noted that in the case of particles used for snow and rain this problem is solved differently in a number of commercial engines. The elementary solution is to not spawn particles indoors, this works okay but requires meta data to be attached to level geometry (indoor / outdoor bounding boxes) and doesn't extent well to cases where precipitation occluders are smaller than the actual particles (which happens if you have dozens/hundreds of rain or snow elements per particle).

A more elegant albeit complex solution is to use a form of shadow mapping. Precipitation particles are continuously generated in a volume that is moved around with the camera. A depth map is generated to correspond to this volume using an orthographic projection where the look direction is parallel to the direction of the precipitation. While rendering particles this depth map can be sampled and pixels with values that are occluded by the depth map are discarded. This is a flexible solution where all types of occluding geometry are accounted for and the occlusion is done on a per pixel basis so the size of your precipitation particles relative to the size of the blocking geometry is largely irrelevant.

@nonoptimalrobot: I have the plane vertices v1, v2, v3, v4

How do I calculate the plane radius so I can do AABB to sphere collision test?

Here's some extremely inefficient pseudo code:


void CalcBoundingSphere(const vector3& a_vVertexA,
                        const vector3& a_vVertexB,
                        const vector3& a_vVertexC,
                        const vector3& a_vVertexD,
                        vector3&       a_vCenter,
                        float&         a_fRadius)
{
   a_vCenter = (a_vVertexA + a_vVertexB + a_vVertexC + a_vVertexD) / 4;
   a_fRadius = vector3::Length(a_vCenter - a_vVertexA);
   a_fRadius = max(a_fRadius, vector3::Length(a_vCenter - a_vVertexB));
   a_fRadius = max(a_fRadius, vector3::Length(a_vCenter - a_vVertexC));
   a_fRadius = max(a_fRadius, vector3::Length(a_vCenter - a_vVertexD));
}

...although you are going about this from the wrong direction. Your particles should be stored CPU side as (position, radius) pairs and the quad vertices (v1, v2, v3, v4) should be generated from that prior to rendering. I suggest you check these links out: Math for Game Developers: Intro to Vectors, Math for Game Developers: Advanced Vectors

The right way to do it is by using the Z-Depth test for the particles.

Z-Depth test? I don't know what the depth has to do with preventing particles from entering buildings

Well the explanation really depends on your scene. In our game we are using simple depth test to discard some particle pixels. Note that that method depends on the rendering order(that's why it is scene dependable).

the only thing you need to know is 'is the player inside'

if the player is inside then:

Draw things that are outside (trees, birds stuff...)

turn off z-writing and change depth test to always succeed

draw the particles

turn z-depth buffer things back to normal

draw the building

and that is.

(in our game we have cars in tunnels ect);

@imoogiBG: I'm using soft particles, so I have to render the scene first and then the particles.

So how do I do that in soft particles? (Notice that I must render the particles AFTER the scene in soft particles)

@nonoptimalrobot: I'm already storing the particle size in the memory and then calculating the vertices prior rendering, but the size is not actually the radius.

Can someone point me to sphere/box collision detection sample? I have only implemented box/box collision detection.


Can someone point me to sphere/box collision detection sample?

http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/

This topic is closed to new replies.

Advertisement