Problem with Compound Bodies intersection events

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
piotre_005
Posts: 7
Joined: Wed Nov 20, 2013 7:16 pm

Problem with Compound Bodies intersection events

Post by piotre_005 »

Hello,

if got a Problem by the interesection checking of compound bodies.....

If I specify Tags in coumpound body and in Ini like this:

ini.CollisionInformation.Tag = “ini_1”;
compoundBody.CollisionInformation.Tag = “compound_payload”;

and if I register event handling to ini like like we correctly do (i hope so):
ini.CollisionInformation.Events.EndOfCollision += Event_EndOfCollision; // or start

I get both A and B collidables correctly, but TAG of compound collidable is NULL, even if I set it correctly before.
Tag of ini collidable is OK.

I tried to solve it thousand ways, I tried even compound body demo in bepu. And still the same result. But:
Here here is an interesting thing – when I register collision event handler not to INI, but to Compound body thing, like:

compoundBody.CollisionInformation.Events.EndOfCollision += Event_EndOfCollision;

then on collision event I get correctly both of Tags…. And strings from them!

Here the CompundBodieDemo changed to Show the Problem....

Code: Select all

using BEPUphysics.Entities.Prefabs;
using BEPUphysics.CollisionShapes;
using BEPUphysics.CollisionShapes.ConvexShapes;
using System.Collections.Generic;
using System.Diagnostics;
using BEPUutilities;

namespace BEPUphysicsDemos.Demos
{
    /// <summary>
    /// Compound bodies are created from other entities to make concave shapes.
    /// </summary>
    public class CompoundBodiesDemo : StandardDemo
    {
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CompoundBodiesDemo(DemosGame game)
            : base(game)
        {

            //Build the first body
            var bodies = new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(0, 1, 0), 1),
                new CompoundShapeEntry(new ConeShape(2, .5f), new Vector3(1, 1, 0), 1),
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(-1, 1, 0), 1)
            };
            var cb1 = new CompoundBody(bodies, 45);



            //Build the second body
            bodies = new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(1,1,1), new Vector3(0, 3, 0), 1),
                new CompoundShapeEntry(new BoxShape(1,1,1), new Vector3(1, 3.5f, 0), 1),
            };
            var cb2 = new CompoundBody(bodies, 4);

            bodies = new List<CompoundShapeEntry>();
            //Build the third Braum's-fry style body
            for (int k = 0; k < 7; k++)
            {
                bodies.Add(new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-4 + k * .7f, 2 + .7f * k, 2 + k * .2f), 1));
            }
            var cb3 = new CompoundBody(bodies, 7);

            //Add them all to the space
            cb3.CollisionInformation.Tag = "cb";


            Space.Add(cb3);
            //  Space.Add(cb2);
            //   Space.Add(cb1);

            Box ground = new Box(new Vector3(0, -.5f, 0), 10, 1, 10);
            ground.CollisionInformation.Tag = "ground";


            ground.CollisionInformation.Events.InitialCollisionDetected += Events_InitialCollisionDetected;
        //    cb3.CollisionInformation.Events.InitialCollisionDetected += Events_InitialCollisionDetected;

            Space.Add(ground);
            game.Camera.Position = new Vector3(0, 3, 15);

        }

        void Events_InitialCollisionDetected(BEPUphysics.BroadPhaseEntries.MobileCollidables.EntityCollidable sender, BEPUphysics.BroadPhaseEntries.Collidable other, BEPUphysics.NarrowPhaseSystems.Pairs.CollidablePairHandler pair)
        {
            string a = ((string)pair.CollidableA.Tag);
            string b = ((string)pair.CollidableB.Tag);
        }

        /// <summary>
        /// Gets the name of the simulation.
        /// </summary>
        public override string Name
        {
            get { return "Compound Bodies"; }
        }
    }
}
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Problem with Compound Bodies intersection events

Post by Norbo »

Let me preface with: the implementation of collision events is a giant tangled mess, and I'd like to delete/redo it all. It took me a while to figure out if this was intended behavior :)

This issue is based on the event reporting the child collidable associated with the collision instead of the parent collidable. Since the child collidable was not given a tag, it shows up as null.

-When an event is hooked on the top-level compound, it should fire an event that reports the top-level compound collidable as the sender.
-When an event is hooked on another object which collides with a compound, the 'other' is reported as the involved child collidable instead of the top-level compound.

This is technically intended behavior, since reversing the choices causes issues:
-In the former case, reporting the child compound would be unexpected and redundant with hooking the event directly to the relevant child collidable.
-In the latter case, reporting the top-level compound would make it difficult (in the current implementation) to know which child was hit.

Here's a few solutions:
1) Put the tag on the child collidables. For example:

Code: Select all

            foreach (var child in cb3.CollisionInformation.Children)
            {
                child.CollisionInformation.Tag = "meow meow meow meow";
            }
The tag could be the same tag, or it could be child-specific, or it could just point to the parent compound.

2) Walk up the hierarchy of pairs. For example, insert this at the beginning of the event handler:

Code: Select all

            while (pair.Parent != null)
                pair = (CollidablePairHandler)pair.Parent;
That will get you the top-level pair, which contains the top-level compound.

3) Instead of using events, just query state. For example, to know if an object is currently in collision:

Code: Select all

            foreach (var pair in cb3.CollisionInformation.Pairs)
            {
                if (pair.Colliding)
                {
                    //This pair is colliding!
                    //[dosomething]
                }
            }
I find that these sorts of checks tend to fit into program flow more easily than events, and they don't have any hidden complexities.
piotre_005
Posts: 7
Joined: Wed Nov 20, 2013 7:16 pm

Re: Problem with Compound Bodies intersection events

Post by piotre_005 »

Norbo thx for you fast reply ...
I will use it in the way you wrote ...
so once again the problem is solved for me :)
YEHAAA weekend can come ... :)
Thanks and all a nice weekend ! ..
Post Reply