Buoyancy and active entities

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
trick
Posts: 6
Joined: Thu Apr 25, 2013 12:20 pm

Buoyancy and active entities

Post by trick »

hi,
i'm adding a buoyancy momentum to all my entities in their update method this way:

Code: Select all

            // add buoyancy momentum 
            if (buoyancy == true) // apply buoyancy force only to objects which are already moving to allow the entities to fall to sleep mode if they got to a rest
                if ((convexHull.AngularVelocity.LengthSquared() > 0.01f) || (convexHull.LinearVelocity.LengthSquared() > 0.01f))
                    convexHull.LinearMomentum += buoyancyMomentumVector;
i don't want to use the FluidVolume class, since my simulation is always completely beneath the water surface.
my approach works well together with the global gravity. i use the if statement to make sure, that the entities can fall to inactive mode to save (lots) of cpu time if they don't move anyway. if i would just add the buoyancy momentum every frame they would never get inactive and waste cpu cycles.
well, that's some kind of solution, but i'm not really happy with it. it would mean, that if an object gets stuck beneath another object due to buoyancy and the top object suddenly disappears, the object beneath would not feel a buoyancy force until it gets some momentum from somewhere else.
what would be great would be some kind of entity based gravity (so i could add together gravity and buoyancy force, which would also save cpu cycles since both work in the same dimension, just in opposite directions).
i use the framework for only two days now (and its great by the way), so i don't have that much experience with it yet.
how could i improve my approach?

thx
trick
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Buoyancy and active entities

Post by Norbo »

I would recommend doing what gravity does: check for activity. If the Entity.ActivityInformation.IsActive is true, apply the buoyancy force. If it's not, don't. You'll want to use the ApplyLinearImpulse method instead of the properties; the properties will wake the entity up, while ApplyLinearImpulse is designed to be a direct change to the momentum without interfering with deactivation.

Using this will solve the 'obstacle removed' issue. In order for the obstacle to be removed, the simulation islands associated with the obstacle must wake up, so buoyancy forces would once again be applied.
what would be great would be some kind of entity based gravity (so i could add together gravity and buoyancy force, which would also save cpu cycles since both work in the same dimension, just in opposite directions).
I wouldn't worry too much about that optimization- the rest of the engine is doing many orders of magnitude more work anyway :)
trick
Posts: 6
Joined: Thu Apr 25, 2013 12:20 pm

Re: Buoyancy and active entities

Post by trick »

works well! thank you.
where can i get more information about the properties and methods you've mentioned (concerning the momentum) and how they are supposed to be used?
is the activation thing the only difference? when should i usually use the waking up properties and when do i have to apply the momentum directly? i don't get the design point behind it yet.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Buoyancy and active entities

Post by Norbo »

The functional difference between velocity/momentum property setters and the functions is just the automatic activation. The ApplyLinearImpulse and ApplyAngularImpulse functions are also designed for performance; they only take ref parameters and do nothing except what is required. Those two functions are used internally in many places.

Also note that the ApplyImpulse function is distinct from the Linear/Angular variants; it is a convenience function like the property setters that applies an impulse with an offset. It activates the entity and has a non-ref option.
trick
Posts: 6
Joined: Thu Apr 25, 2013 12:20 pm

Re: Buoyancy and active entities

Post by trick »

i understand.
just another fundamental question which came to my mind when i saw the handover of the single Vector3 by reference: why do you think this increases performance? doesn't it involve boxing of the struct and therefor additional overhead also giving the GC additional work? wouldn't it be more performant to hand it over by value?
ah, probably you modify it internally and need the result in the calling place.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Buoyancy and active entities

Post by Norbo »

Passing by reference is not the same thing as passing a reference type variable; there is no boxing involved in the former when using value types. To help intuitively highlight the distinction, note that reference type variables can be passed by reference and that doing so is semantically different from just passing the reference type variable directly (by value).

It may help to just think of the ref parameter as a pointer to the passed in variable. So, for a value type variable passed by reference, you have a pointer pointing directly to where the values are. However, be careful to note what this means for a reference type parameter passed by reference: the ref parameter is not a pointer to the reference type object, it is a pointer to the reference type variable which itself contains a pointer to the reference type object. That's why you can change which object a reference type variable is pointing to using ref parameters.

Consider the 4x4 Matrix struct. It's 64 bytes. If it is passed by value, all of those values will be copied. If it's passed by reference, only a 4-8 byte (depending on target architecture) reference to the original matrix variable will be copied. Since there's so much less to copy, performance improves. The performance boost is also measurable when dealing with smaller value types, like Vector3 variables. However, it would be silly to pass a 4 byte parameter (like a float) by reference for performance reasons, since it doesn't reduce the parameter cost at all. Even sillier would be passing a reference type variable by reference for performance reasons: it just adds a layer of indirection while maintaining the exact same copy cost.

Most usages of ref parameters in the engine are solely for performance; very few actually need to modify the parameter value. The apply impulse methods do not modify the parameter value.
trick
Posts: 6
Joined: Thu Apr 25, 2013 12:20 pm

Re: Buoyancy and active entities

Post by trick »

indeed, also according to the msdn reference passing of value types doesn't include boxing. that's new to me, somehow i just assumed it. this opens new optimization potential to me :D
thx
Post Reply