Collision Testing physics elements against non-physics elements

Oct 7, 2009 at 8:22 PM
Edited Oct 7, 2009 at 8:23 PM

I'm trying to make a feature where the designer can create regions on the canvas that, when the player's object is inside the region, cause various events to happen (imagine having a trapdoor open when the player steps on an invisible trigger). 

I have pretty much everything set up the way I need, save one thing.  It appears that the coordinate system for objects that have a PhysicsObjectBehavior isn't the same as objects that don't.  For example, if I place two rectangles in a scene so they overlap, then give one a PhysicsObjectBehavior, a simple bounding box test will result in "false"-- they don't overlap.

This seems to be resultant from whatever happens to a Shape object when it's processed by the AddPhysicsBody function.

So-- question is how can I get at point information for a physics object that is suitable for collision testing with non-physics objects? 

 

Coordinator
Oct 7, 2009 at 9:00 PM

Yeah the position of an element in the physics engine (Farseer) is based on the location x,y being at the center of the object.

You could get at the UI Element of the physics object and get its position instead:

Ellipse ball = _physicsController.PhysicsObjects["ball"].uiElement as Ellipse;

(there is an example of this on the main wiki page if you need more info)

But I think what would be best for that is to add a property to the Physics Object Behavior that wraps a Sensor in the Farseer Physics Engine.

Farseer supports Sensors, and I think its actually simple - you just set the IsSensor property on the Geometry object to true, and then that object will fire collisions, but does not move or have impulse, etc.

You could try to do this manually, again by going through the PhysicsObjects collection and getting the Geometry object, and setting IsSensor (sorry I haven't tested this, might be wrong!)

_physicsController.PhysicsObjects["ball"].GeometryObject.IsSensor = true;

 

Oct 8, 2009 at 4:19 AM

I did what you suggested and exposed IsSensor through PhysicsHelper.  Everything works brilliantly, except... IsStatic is now broken.  When I rebuild your samples and run them (without any changes to the samples) everything which is supposed to be pinned by IsStatic falls through the floor. 

I suspect this might have something to do with the way DependencyProperties work, but I'm new to Silverlight so I don't have any real leads beyond that.

Here is the patch from 3.0.0.3:

Index: PhysicsHelper.3.0.0.3/Common/PhysicsBehaviors/PhysicsObjectBehavior.cs
===================================================================
--- PhysicsHelper.3.0.0.3/Common/PhysicsBehaviors/PhysicsObjectBehavior.cs	(revision 51)
+++ PhysicsHelper.3.0.0.3/Common/PhysicsBehaviors/PhysicsObjectBehavior.cs	(working copy)
@@ -41,6 +41,7 @@
             PhysicsObjectMain.SetPhysicsObject(this.AssociatedObject, _physicsObjectMain);
 
             this.AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
+
         }
 
         private PhysicsControllerMain _controller = null;
@@ -83,6 +84,17 @@
         }
 
         [Category("Physics")]
+        [Description("If true, then the element is a sensor and will fire events but not move or block other objects")]
+        public bool IsSensor
+        {
+            get { return _physicsObjectMain.IsSensor; }
+            set
+            {
+                _physicsObjectMain.IsSensor = value;
+            }
+        }
+
+        [Category("Physics")]
 		[Description("Objects collide with other objects that have different Collision Groups.")]
         public int CollisionGroup
         {
Index: PhysicsHelper.3.0.0.3/Common/PhysicsHelper/PhysicsControllerMain.cs
===================================================================
--- PhysicsHelper.3.0.0.3/Common/PhysicsHelper/PhysicsControllerMain.cs	(revision 51)
+++ PhysicsHelper.3.0.0.3/Common/PhysicsHelper/PhysicsControllerMain.cs	(working copy)
@@ -545,6 +545,7 @@
 
             sprite.GeometryObject.CollisionGroup = physObject.CollisionGroup;
             sprite.BodyObject.IsStatic = physObject.IsStatic;
+            sprite.GeometryObject.IsSensor = physObject.IsSensor;
 
             if (physObject.RestitutionCoefficient != 0)
                 sprite.GeometryObject.RestitutionCoefficient = (float)physObject.RestitutionCoefficient;
Index: PhysicsHelper.3.0.0.3/Common/PhysicsHelper/PhysicsObjectMain.cs
===================================================================
--- PhysicsHelper.3.0.0.3/Common/PhysicsHelper/PhysicsObjectMain.cs	(revision 51)
+++ PhysicsHelper.3.0.0.3/Common/PhysicsHelper/PhysicsObjectMain.cs	(working copy)
@@ -73,6 +73,13 @@
             set { _isStatic = value; }
         }
 
+        private bool _isSensor = false;
+        public bool IsSensor
+        {
+            get { return _isSensor; }
+            set { _isSensor = value; }
+        }
+        
         private double _restitutionCoefficient;
         public double RestitutionCoefficient
         {
Oct 8, 2009 at 5:00 AM

I believe I found a bug in Farseer 2.1 that is causing the problem.  See my comments here.