Page 1 of 1

1-time Collision detection

Posted: Wed Apr 11, 2012 7:36 pm
by vToMy
Is it possible to run a collision detection for a given object and space?
Velocity is not important, all I want to is the answer if the given object in the given position intersects anything within the space (and of course get relevant info if it is...)

Note: The object is not in the space, and I don't want it to be (unless there's a way to enable/disable it, but didn't see one), it's just a '1-time' check that happens here and then.

Hope I managed to make myself clear? :S

Re: 1-time Collision detection

Posted: Wed Apr 11, 2012 8:05 pm
by Norbo
Is it possible to run a collision detection for a given object and space?
Yup, the process looks like this.

First, use the bounding box of the object in question to query the broad phase. The given list will be filled with any BroadPhaseEntry objects which have bounding boxes which overlap the bounding shape.
Space.BroadPhase.QueryAccelerator.GetEntries(boundingBox, entriesList);
Then, create pairs between those BroadPhaseEntry objects and your object's BroadPhaseEntry. If your object is an Entity, you can get its associated BroadPhaseEntry from the entity.CollisionInformation property (it is the collision proxy of the entity). StaticMeshes, Terrains, and InstancedMeshes all inherit from BroadPhaseEntry (through inherting Collidable). The NarrowPhaseHelper can help like so:

Code: Select all

var pair = NarrowPhaseHelper.GetPair(yourObjectEntry, entryFromBroadPhaseQuery);
The returned object is a NarrowPhasePair. The NarrowPhasePair has an UpdateCollision method. This will update the state of the pair. Any pair which has contacts is a CollidablePairHandler; you can try to cast the pair to a CollidablePairHandler to check the Contacts collection. If there exists a contact with nonnegative penetration depth, then the pair of objects is in collision. The contact data includes position, normal, depth, relative velocity and collision response impulses (unused if the pair's constraint isn't in a solver).

When a pair becomes irrelevant, its CleanUp method should be called and it should be given back to the factory that spawned it:

Code: Select all

pair.CleanUp();
pair.Factory.GiveBack(pair);
This whole process is a bit slower than what happens to objects actually in the simulation proper, but it's still very quick.

Re: 1-time Collision detection

Posted: Thu Apr 12, 2012 8:39 am
by vToMy
Hmm... can I use collision events with that? I can't seem to catch events that way. Maybe I'm doing something wrong?

Code: Select all

IList<BroadPhaseEntry> overlaps = new List<BroadPhaseEntry>();
space.BroadPhase.QueryAccelerator.GetEntries(Cylinder.CollisionInformation.BoundingBox, overlaps);

            foreach (var entry in overlaps)
            {
                var pair = NarrowPhaseHelper.GetPair(Cylinder.CollisionInformation, entry);

                pair.UpdateCollision(0);

                pair.CleanUp();
                pair.Factory.GiveBack(pair);
            }
I don't catch any events for the cylinder...
I tried doing it without events (as you explained), and It seems I catch collisions, but the number of collisions does not match the real one.

Code: Select all

//This goes inside the last loop
var collidablePair = pair as CollidablePairHandler;
                if (collidablePair != null)
                {
                    foreach (var contactInfo in collidablePair.Contacts)
                    {
                        var contact = contactInfo.Contact;
                        if (contact.PenetrationDepth >= 0f)
                        {
                            //Do something...
                        }
                    }
                }
I tried updating more than 0 (though I really don't need to) and it's the same.

BTW, I noticed there are two identical classes: Contact and ContactData (both in namespace BEPUphysics.CollisionTests).
You might wanna get rid of one of them...

As always, thanks for your help.

Re: 1-time Collision detection

Posted: Thu Apr 12, 2012 3:30 pm
by Norbo
Hmm... can I use collision events with that? I can't seem to catch events that way. Maybe I'm doing something wrong?
Deferred events cannot be used in such isolated queries. Any collision event which has a past tense name requires a deferred event dispatcher to be hooked up. You can, however, use present-tense collision events. Such 'immediate' events are called directly from inside the collision handler. More information can be found here: http://bepuphysics.codeplex.com/wikipag ... umentation

In this kind of use case, it's typically easier to analyze the contacts list directly rather than hooking up indirect contact events.
I tried doing it without events (as you explained), and It seems I catch collisions, but the number of collisions does not match the real one.
The contacts list is the 'real' representation of the collision state as far as the narrow phase collision detection system is concerned. What does not match?
BTW, I noticed there are two identical classes: Contact and ContactData (both in namespace BEPUphysics.CollisionTests).
You might wanna get rid of one of them...
While they have the same fields, they are not functionally identical. One is a class and is designed to persist. The other is a struct and is designed to be a snapshot of the state of a contact or a contact candidate not yet accepted into the main manifold.

Re: 1-time Collision detection

Posted: Sat Jun 09, 2012 6:30 pm
by vToMy
Hey, sorry for the late reply, been busy with some stuff...

Anyways, what I meant is that this method doesn't seem to take into account my static meshes...

But I think I'm over-doing things.... I don't want to write all that code myself, that's why I'm using your library! :)
Is there any way to insert a "ghost" shape (one that does not interact) into space and check for collisions?
This way, every time I need to check for collision I'll do this:

space.Add(myGhostShape)
//testForCollision???
space.Remove(myGhostShape)

I just wonder if I'll be able to test for collisions using events this way (since, for example, the object may be inserted inside another object, and the collision event won't fire since they didn't actually collided).
Otherwise, what other ways are there for checking collisions (except the already discussed one)?
Any thoughts?

Re: 1-time Collision detection

Posted: Sat Jun 09, 2012 6:50 pm
by Norbo
Anyways, what I meant is that this method doesn't seem to take into account my static meshes...
It should not miss anything; it's basically doing a query-formatted version of what the engine does internally.
But I think I'm over-doing things.... I don't want to write all that code myself, that's why I'm using your library!
Is there any way to insert a "ghost" shape (one that does not interact) into space and check for collisions?
This way, every time I need to check for collision I'll do this:

space.Add(myGhostShape)
//testForCollision???
space.Remove(myGhostShape)
A Space.Update() must occur between the Add and Remove in order for the collisions to be tested. So, if the ghost shape is kept within the Space rather than being added/removed around each individual query, it would work.
I just wonder if I'll be able to test for collisions using events this way
Yes. Immediate events would work with the other query method too. (Though again, it's often more convenient for queries to just look directly at the contact list instead of using events.)

CollisionRules can be used to turn off solving for the object (e.g. entity.CollisionInformation.CollisionRules.Personal = CollisionRules.NoSolver;).
Otherwise, what other ways are there for checking collisions (except the already discussed one)?
Any thoughts?
Any method which ends up creating or using pairs (internally or explicitly) can be used to check collisions.

For objects which perform frequent similar queries, keeping the detector 'ghost' object in the space is generally the easiest and individual queries are cheaper since they are performed as a natural part of the pipeline.

For objects which perform rare, individually unique queries, using a one-shot pair collection analysis like the character is a better fit and is a bit faster since it avoids keeping objects in the Space unnecessarily.