Geom.IsSensor broken in 2.1?

Topics: Developer Forum
Oct 8, 2009 at 5:56 AM

I just wired up some code to IsSensor.  Unfortunately, setting IsSensor to false seems to overwrite the IsStatic value on Body.  The result is that setting IsSensor = false causes (previously static) objects to fall through the floor.

        public bool IsSensor
        {
            get { return _isSensor; }
            set
            {
                _isSensor = value;
                if (_isSensor)
                {
                    body.IsStatic = true;
                    CollisionResponseEnabled = false;
                }
                else
                {
                    body.IsStatic = false;
                    CollisionResponseEnabled = true;
                }
            }
        }

Oct 8, 2009 at 9:06 AM

It's because a sensor is just a geometry with static body and no collisionresponse, nothing else. If you want to only activate or deactivate the collision response, just change the CollisionResponseEnabled property, not the isSensor one.

Oct 8, 2009 at 3:54 PM
pnikosis wrote:

It's because a sensor is just a geometry with static body and no collisionresponse, nothing else. If you want to only activate or deactivate the collision response, just change the CollisionResponseEnabled property, not the isSensor one.

 I think the problem is a little more subtle.  The API surface is incorrect because of the side effects in the implementation of IsSensor.  The API should be idempotent and preferably have limited side effects.  So this should be OK, but it's broken:

body.IsStatic = true;
body.IsStatic = true; // should be idempotent
geom.IsSensor = true; // this sets body.IsStatic to true
body.IsStatic = false; // uh oh. we broke the implentation of IsSensor.  geom is now in unknown state
geom.IsSensor = true;// should be idempotent but it's not

 

Coordinator
Oct 8, 2009 at 4:03 PM

pnikosis is correct - and so are you.

The IsSensor property only sets collision response to false and IsStatic to true. A sensor is defined as non-reactionary to its surroundings and stationary.

However, as you write, the implementation is broken. It is broken in the sense that the state of the geometry changes because the IsSensor property changes two other properties. But then again, according to the definition, the implementation is correct because you can't suddenly change a sensor to a static geometry. So in the end it comes down to flexibility.

It was the easiest way of doing things and you have ways of doing it yourself. Instead of using the IsSensor property, you simply change the CollisionResponseEnabled and IsStatic properties manually. If you have a suggestion on how to improve the API, I would be more than happy to take a look at it.

Oct 8, 2009 at 5:16 PM

I'm not sure what the formal definitions of IsStatic and IsSensor are, but one should ask whether ALL of the following four states are allowable:

IsSensor = true, IsStatic = true

IsSensor = false, IsStatic = false

IsSensor = false, IsStatic = true

IsSensor = true, IsStatic = false

If they are not all valid (as I suspect is the case) then it would be clearer and more correct to create an enum that represents the allowable states (Normal, Sensor, Static), and block public access to the IsStatic and IsSensor members.

Can you explain the intent of IsSensor?

Coordinator
Oct 8, 2009 at 5:43 PM

You can't have a dynamic sensor, they must be static as they would just drift away into oblivion (gravity would affect dynamic sensors). Case 4 you mention is the only invalid once since it would create a dynamic sensor. The first 3 is perfectly fine (but might not make sense.)

I've done exactly that; I've implemented sensors as enums in my private build of 3.0. A geometry can have a lot more states in 3.0 and some can be combined. Some places I use normal enums, other places I use enum bitfields (combinable with binary operations).

The simple purpose of IsSensor is to make the geometry incapable of movement and reaction to the surroundings.