Crash when calling OnCollisionGroupChanged

May 31, 2009 at 1:11 PM

Hi,

I just got a crash in SweepAndPruneCollisionSystem.cs Line 325, which getting lowerIndex = -1.

It appeared not so frequently, I am still trying to reproduce it again.

I will provide more information when I got it again.

Thanks.

Coordinator
Jun 1, 2009 at 8:00 PM

Hi

The sweep and prune collision system, at creation, adds a span of float.MinValue..float.MaxValue to each of the axes - x, y and z.  If everything is working correctly in the collision system, the only way you could get a lowerIndex of -1 is if CollisionGroup.AABB.Min has a float.MinValue component (x, y or z), meaning that at least on of the CollisionGroup's associated sweeps has a lower position of float.MinValue.

A CollisionGroup with zero associated CollisionShapes or a CollisionGroup with a CollisionPlane could cause this if the CollisionGroup's UpdateTransform is called directly or indirectly during integation of an associated RigidBody (i.e., RigidBody.IntegratePositions()). 

Any chance you have the situation above occurring?  I'm investigating to see if I can cause the same issue.

Jun 2, 2009 at 2:04 AM

Hi,

It seems that I got a CollisionGroup with empty CollisionShapes, and that RigidBody is not Static.

Thanks for your detailed reply!

Coordinator
Jun 3, 2009 at 6:52 PM

I'll look into it soon and see if I can prevent the issue even with the situations above.  You should be allowed to have those situations.  Thanks for the info.

Jun 23, 2009 at 6:00 AM

Hi, I just got this crash again.

 

Here is the detailed info:

Exception was caused at the line 326:

float upperDifference = newUpper - this.sweepMarkers[axis][upperIndex].Position;

where upperIndex = 134

sweepMarkers has 3 items, each with 134 items inside

 

Call Stack:

Oops.Xna.Framework.dll!Oops.Xna.Framework.Physics.CollisionSystems.SweepAndPruneCollisionSystem.OnCollisionGroupChanged(Oops.Xna.Framework.Physics.CollisionGroup collisionGroup = {Oops.Xna.Framework.Physics.CollisionGroup}) Line 326    C#
Oops.Xna.Framework.dll!Oops.Xna.Framework.Physics.CollisionGroup.UpdateTransform(ref Microsoft.Xna.Framework.Vector3 position = {X:145.3258 Y:15.86317 Z:270.4535}, ref Microsoft.Xna.Framework.Matrix orientation = { {M11:1 M12:0 M13:0 M14:0} {M21:0 M22:1 M23:0 M24:0} {M31:0 M32:0 M33:1 M34:0} {M41:0 M42:0 M43:0 M44:1} }) Line 365 + 0xe bytes    C#
Oops.Xna.Framework.dll!Oops.Xna.Framework.Physics.RigidBody.IntegratePosition(float elapsed = 0.022) Line 565 + 0x2f bytes    C#
Oops.Xna.Framework.dll!Oops.Xna.Framework.Physics.PhysicsComponent.Update(Oops.Xna.Framework.AsyncGameComponent.AsyncGameTime gameTime = {Oops.Xna.Framework.AsyncGameComponent.AsyncGameTime}) Line 526 + 0xd bytes    C#
Oops.Xna.Framework.dll!Oops.Xna.Framework.AsyncGameComponent.Update(Microsoft.Xna.Framework.GameTime gameTime = {Microsoft.Xna.Framework.GameTime}) Line 192 + 0x11 bytes    C#
Test.exe!TOopsWorldManager.Update(float dt = 0.022) Line 72 + 0x24 bytes    C#

 

CollisionGroup:    AABB    {Min:{X:144.3258 Y:14.86317 Z:269.4535} Max:{X:146.3258 Y:16.86317 Z:271.4535}}    Microsoft.Xna.Framework.BoundingBox
    CategoryFlags    2147483647    int
    CollisionFlags    2147483647    int
    collisions    Count = 0    Oops.Xna.Framework.Physics.CollisionGroup.CollisionCollection
    Collisions    Count = 0    Oops.Xna.Framework.Physics.CollisionGroup.CollisionCollection
    CollisionShapes    Count = 1    Oops.Xna.Framework.Physics.CollisionGroup.CollisionShapeCollection
    collisionShapes    Count = 1    Oops.Xna.Framework.Physics.CollisionGroup.CollisionShapeCollection
    CollisionSystem    {Oops.Xna.Framework.Physics.CollisionSystems.SweepAndPruneCollisionSystem}    Oops.Xna.Framework.Physics.CollisionSystem {Oops.Xna.Framework.Physics.CollisionSystems.SweepAndPruneCollisionSystem}
    collisionSystem    {Oops.Xna.Framework.Physics.CollisionSystems.SweepAndPruneCollisionSystem}    Oops.Xna.Framework.Physics.CollisionSystem {Oops.Xna.Framework.Physics.CollisionSystems.SweepAndPruneCollisionSystem}
    Flags    None    Oops.Xna.Framework.Physics.CollisionGroupFlags
    id    155    int
    Id    155    int
    internalTag    {Oops.Xna.Framework.Physics.CollisionSystems.SweepAndPruneCollisionSystem.SweepAndPruneNode}    object {Oops.Xna.Framework.Physics.CollisionSystems.SweepAndPruneCollisionSystem.SweepAndPruneNode}
    Orientation    { {M11:1 M12:0 M13:0 M14:0} {M21:0 M22:1 M23:0 M24:0} {M31:0 M32:0 M33:1 M34:0} {M41:0 M42:0 M43:0 M44:1} }    Microsoft.Xna.Framework.Matrix
    Position    {X:145.3258 Y:15.86317 Z:270.4535}    Microsoft.Xna.Framework.Vector3
    rigidBody    {Oops.Xna.Framework.Physics.RigidBody}    Oops.Xna.Framework.Physics.RigidBody
    RigidBody    {Oops.Xna.Framework.Physics.RigidBody}    Oops.Xna.Framework.Physics.RigidBody
    Tag    null    object
    UserIndex    7    int

 

There is 1 CollisionSphere in CollisionShape

    AABB    {Min:{X:144.3258 Y:14.86317 Z:269.4535} Max:{X:146.3258 Y:16.86317 Z:271.4535}}    Microsoft.Xna.Framework.BoundingBox
    CategoryFlags    2147483647    int
    CollisionFlags    2147483647    int
    collisionGroup    {Oops.Xna.Framework.Physics.CollisionGroup}    Oops.Xna.Framework.Physics.CollisionGroup
    CollisionGroup    {Oops.Xna.Framework.Physics.CollisionGroup}    Oops.Xna.Framework.Physics.CollisionGroup
    DynamicFriction    0.5    float
    Friction    0.5    float
    Id    153    int
    id    153    int
    Offset    { {M11:1 M12:0 M13:0 M14:0} {M21:0 M22:1 M23:0 M24:0} {M31:0 M32:0 M33:1 M34:0} {M41:0 M42:0 M43:0 M44:1} }    Microsoft.Xna.Framework.Matrix
    OffsetOrientation    { {M11:1 M12:0 M13:0 M14:0} {M21:0 M22:1 M23:0 M24:0} {M31:0 M32:0 M33:1 M34:0} {M41:0 M42:0 M43:0 M44:1} }    Microsoft.Xna.Framework.Matrix
    OffsetPosition    {X:0 Y:0 Z:0}    Microsoft.Xna.Framework.Vector3
    Orientation    { {M11:1 M12:0 M13:0 M14:0} {M21:0 M22:1 M23:0 M24:0} {M31:0 M32:0 M33:1 M34:0} {M41:0 M42:0 M43:0 M44:1} }    Microsoft.Xna.Framework.Matrix
    Position    {X:145.3258 Y:15.86317 Z:270.4535}    Microsoft.Xna.Framework.Vector3
    Restitution    0.5    float
    RigidBody    {Oops.Xna.Framework.Physics.RigidBody}    Oops.Xna.Framework.Physics.RigidBody
    StaticFriction    0.5    float
    Tag    null    object
    typeId    2    int
    Radius    1.0    float

Coordinator
Jun 24, 2009 at 4:45 AM

I'm looking into this right now.  I think I see what's going on but want to try and reproduce it consistently.  Are you adding/removing rigid bodies to/from the IPhysicsService.RigidBodies/PhysicsComponent.RigidBodies collection.  It okay that you are I just think might be where the problem is occurring. 

Jun 24, 2009 at 2:57 PM

I am using PhysicsComponent.

I found that the following case may reproduce a crash/abnormal collision behaviour, especially on Xbox360.

1.  Setup a Static RigidBody with some boxes to form a table (a box with 4 boxes as legs)

2. Create a RigidBody (AutoDiable Flag) with a box and sphere at the bottom under the table (no intersection with table, but inside the AABB of the table)

Sometimes when the scene has too few rigid bodies, no problem will occur.

In my test case, around 60 bounding boxes and 20 Rigid Bodies.

However I cannot find the number of bodies that invoke the problem.

Coordinator
Jul 12, 2009 at 6:32 PM

Hey Percy, I had been looking to this problem for a while.  I came up another possible reason why this might be occurring for you.  The physics all run in a separate thread, and if you add/remove/chage shapes during the processing that occurs in that separate thread, there is a possibility that the issues described above would happen (i.e., exceptions).  The only place that you can safely add and remove shapes or change some of the shape properties are between the PhysicsComponent.EndUpdate() and PhysicsComponent.BeginUpdate() calls.

Any chance you are add/remove/changing RigidBodies/CollisionGroups/CollisionShapes/etc outside of this area?

Jul 15, 2009 at 2:32 AM

Hi,

Currently I only call PhysicsComponent.Update(GameTime) to update physics with asyncEnabled = false

That should not have any thread issue?

Dec 15, 2010 at 9:47 PM

Hi,

I have similar problems like discussed above. I too am calling PhysicsComponent.Update(GameTime). So I'm pretty sure it's not a threading issue. I'm also using the OnCollide event with the callback but I'm very sure there are no CollisionShapes or groups added during these events.

Which leaves only the first 2 options mentioned: one of my AABB x y or z is float.minvalue. by the look of it, this is very unlikely (though I have't checked it by means of iterating all objects, so I might miss something), or UpdateTransform is called at the same time when RigidBody.IntegratePositions() is called. But I'm not really sure what the latter means. How does it occur, and how can I check if it occurs?

I do have this issue very frequently. So frequently even, I can't even seem to keep the game running for over a minute.

I also encounter a null-reference exception quite often. Not as often as the other exception but still a significant ammount. This happens in CollisionSystem.cs in the method 'CanCompare'. Collisiongroup1 is null when this happens.

I check if my rigidbodies have an empty collisiongroup just before calling PhysicsComponent.Update(gameTime). This is never the case however. Which is odd seeing there's a nullreference exception about it every so often.

Have you got any more advice on the matter?

Dec 18, 2010 at 4:23 PM

I found the cause of the problem for me, but I think it something that shouldn't happen.

The playerobject is a rigidbody which get forces applied based on playerinput. The Orientation of the playerobject is set based on it's current velocity so the front is always facing the direction it is moving. If I don;t set the orientation then the crashes don't occur. But the orientation is set as it should be, by means of UpdateTransform(ref Matrix) between physicsupdates.

To make things more odd. There are also AIControlled enemies. They're the same type of object, so they too use a rigibody for physics. This rigidbody is also subject to force based on the outcome of the AIController. And they too get an Orientation update based on current velocity to face the direction it is moving. But these guys don't cause crashes!

Of course there are small differences of how the rigidbody is set up. The ammount of force applied for instance, enemies are a bit slower. But I don't see how that could be the cause. I'll keep looking in hopes the explain this. But if you have an idea based on this information on where to look I'd love to know!

Cheers, Koen

Coordinator
Dec 19, 2010 at 12:51 AM

Hey Koen, It'll be difficult to determine the issue without the code but you could try something a little different to get away from modifying the "physics" orientation. You can keep a "facing" orientation Matrix with your player/enemie classes.  When the physics are done updating, update the "facing" matrix from the RigidBody.Velocity.  Then use the "facing" orientation for drawing/gameplay. 

If you set the RigidBody.InertiaTensor to all zeros, the RigidBody.Orientation will remain unmodified during physics updates...that may help.

Dec 19, 2010 at 10:05 AM

Hi, thanks for your reply. I was going to try to apply torque if I couldn't fix this. But you're idea is pretty smart to :)

Fortunatly I did find the problem now. And how silly it is. I check for zero movement, but afterwards I filter the 'Y' movement out of it, because I want the orientation only to happen on a 2D plane. Of course this change could still make the movement zero. Since you can't make a valid orientation out of a vector with zero length the game crashes shortly after.