No collisions between two dynamic objects

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
jaja1
Posts: 43
Joined: Sat Nov 15, 2014 3:27 am

No collisions between two dynamic objects

Post by jaja1 »

I am trying to determine if a movable sphere and a bunch of fixed boxes ever overlap. I did not want the collisions to be resolved so I turned the solver off for the group pair of these objects. My space is being updated...I know this because the position of my sphere is being updated. Ideally I would keep the sphere kinematic but for debugging purposes I set both the boxes and the sphere to dynamic. I tried using both events and a "check loop" that runs after every update, but both methods failed. The pairs, overlappedentities and overlappedcollidables lists are all empty for the boxes. How can I resolve this?

Also, is it possible to detect whether one object is contained within another without their bounding shapes ever touching?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: No collisions between two dynamic objects

Post by Norbo »

Two entities configured to have a NoSolver rule with each other should still generate contacts. Is everything added to the Space? If it is, could you create a reproduction in the BEPUphysicsDemos for me to look at?
Also, is it possible to detect whether one object is contained within another without their bounding shapes ever touching?
I'm not sure what you mean.
jaja1
Posts: 43
Joined: Sat Nov 15, 2014 3:27 am

Re: No collisions between two dynamic objects

Post by jaja1 »

100% sure everything is in the space. I get update messages saying I have x entities in my space and I know the amount beforehand. I can definitely provide my code but I'm not sure if I will be able to create a similar copy in the Demos because of my implementation.

I'll try my best to explain every block:

This is how I create one of the fixed boxes (size of each box is 10x10x10):

Code: Select all

region_collider = new Box(position, width, height, length);
region_collider.CollisionInformation.CollisionRules.Group = regionsGroup;
region_collider.BecomeDynamic(1f);
mapSpace.Add(region_collider);
A timer calls an update method every 33 milliseconds (30 FPS) after the boxes are created:

Code: Select all

private static void Update()
        {
            lock (AllRunningMaps_lockObj)
            {
                foreach (GenericMap m in AllRunningMaps.Values)
                {
                    m.MapSpace.Update();//space is updated here
                    m.UpdateRegions();//collision check done here
                }
            }
       }
Here is the collision check:

Code: Select all

public void UpdateRegions()
        {
            for (int i = 0; i < regions.Length; i++)
            {
                for (int j = 0; j < Region.divisions; j++)
                {
                    for (int k = 0; k < Region.divisions; k++)
                    {
                        Region r = regions[i][j, k];

                        if (r.region_collider.CollisionInformation.OverlappedEntities.Count() > 0)
                        {
                            foreach (Entity e in r.region_collider.CollisionInformation.OverlappedEntities)
                            {
                                Player p = e.Tag as Player;
                                if (p != null)
                                {
                                    if (!r.entities.Contains(p))
                                    {
                                        r.entities.Add(p);
                                        _FormAccessor.OutputMessage = String.Format("Player is now in region ({0},{1})",
                                                                                   Array.IndexOf(regions[i], r), i);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
NB: I added a breakpoint at this line: if (r.region_collider.CollisionInformation.OverlappedEntities.Count() > 0)
and count is indeed zero, so the check is being done.

Adding the sphere is always done after the boxes are created and updates begin (radius of sphere is 20):

Code: Select all

player_region_collider = new Sphere(position, outerEntityRadius);
            player_region_collider.CollisionInformation.Tag = this;
            player_region_collider.BecomeDynamic(1f);
NB: the tag is my user specific class called "Player"


And suppose I add a box in my space....then I add a sphere in the same position whose diameter is larger than the box (so the edges of the box never touch the surface of the sphere). Is there a way to detect that the box is inside that sphere?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: No collisions between two dynamic objects

Post by Norbo »

While I see the box is having a collision group assigned to it, I don't see anything related to collision rules for the sphere, nor any collision rule relationships being defined. It's hard for me to say what might be happening.

I'd rather not get a full code dump, though- building a reproduction case in the demos (or another extremely stripped format) helps isolate the problem and generally lets me diagnose the problem immediately. Most likely, the problem will make itself obvious during the creation of the repro.
And suppose I add a box in my space....then I add a sphere in the same position whose diameter is larger than the box (so the edges of the box never touch the surface of the sphere). Is there a way to detect that the box is inside that sphere?
Convex shapes like the BoxShape and SphereShape are not hollow, so contacts will still be generated even if the surfaces do not intersect at all.

If you actually want to figure out if the box is fully contained as opposed to merely intersecting, things get trickier. Contacts between two convex shapes in isolation can't give you a complete and rigorously correct answer to that. You could approximate it by doing something like 'if any contact point has a penetration depth above X, it's contained'. Or, in the case of spheres, just using the distance of the box to the center of the sphere would often be sufficient. If you need a highly precise containment calculation for the box-sphere case, the computationally fastest thing to do would be to ignore the physics engine and just write a function that computes containment directly.
jaja1
Posts: 43
Joined: Sat Nov 15, 2014 3:27 am

Re: No collisions between two dynamic objects

Post by jaja1 »

Thanks for the feedback! I sent a PM so check it out when you get a chance.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: No collisions between two dynamic objects

Post by Norbo »

In the sample, the region boxes aren't positioned to overlap the sphere. When they are moved into position to overlap, it appears to work as expected, with overlaps and contacts being generated between the player sphere and boxes.

A few notes:
1) The repro case's timer-based updates run in parallel with the demo's own space updates which causes race conditions.
2) Since they are dynamic, gravity pulls all the regions out of position if not disabled (either globally or on a per entity basis).
3) The repro case's region boxes have zero extent.
jaja1
Posts: 43
Joined: Sat Nov 15, 2014 3:27 am

Re: No collisions between two dynamic objects

Post by jaja1 »

I indeed notes 2 and 3 were the problem and I can now detect collisions between the sphere and boxes.
1) The repro case's timer-based updates run in parallel with the demo's own space updates which causes race conditions.
How is this the case? Even if the system.threading.timer calls updates on threads in the threadpool, the space.update function will only be called once until that update is complete. Is the boolean synchronization parameter "enableUpdate" not enough? Unless space.update makes its own calls on a separate thread?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: No collisions between two dynamic objects

Post by Norbo »

The BEPUphysicsDemos StandardDemo, which your repro inherits, has a virtual Update function which calls Space.Update within it. Nothing in the repro case attempts to stop the StandardDemo-issued Space.Update calls from happening at the same time as the timer-issued updates.

This does not mean that your own application has a race condition- I only mentioned it in case you tried to fiddle with the repro case demo further and were wondering why it crashed randomly.
jaja1
Posts: 43
Joined: Sat Nov 15, 2014 3:27 am

Re: No collisions between two dynamic objects

Post by jaja1 »

Ahhh thank you! Makes sense. One side question...can you point me to any documentation on how to include a custom demo in the demo projects?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: No collisions between two dynamic objects

Post by Norbo »

The repro case you provided already does pretty much everything needed. If you want to be able to select it, toss the demo's type into the DemosGame.demoTypes array. If you want to just directly launch it without having to select it at runtime, in DemosGame change

Code: Select all

currentSimulation = (Demo)Activator.CreateInstance(demoType, new object[] { this });
to

Code: Select all

currentSimulation = new YourDemo(this);
Post Reply