Small issue with Kinematic CompoundBody ctor

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
ecosky
Posts: 69
Joined: Fri Nov 04, 2011 7:13 am
Contact:

Small issue with Kinematic CompoundBody ctor

Post by ecosky »

I was providing a list of zero mass shapes to a CompoundBody ctor and the ComputeCenter failed validation because of the zero mass total of all shapes caused a divide by zero. Note that I am using the CompoundBody ctor that doesn't take mass, which the XML docs say is the way to create a kinematic CompoundBody.

Code: Select all

 	SMW.exe!BEPUphysics.MathExtensions.MathChecker.Validate(Microsoft.Xna.Framework.Vector3 v) Line 47	C#
 	SMW.exe!BEPUphysics.CollisionShapes.CompoundShape.ComputeCenter(System.Collections.Generic.IList<BEPUphysics.CollisionShapes.CompoundShapeEntry> childData) Line 271 + 0x17 bytes	C#
 	SMW.exe!BEPUphysics.CollisionShapes.CompoundShape.CompoundShape(System.Collections.Generic.IList<BEPUphysics.CollisionShapes.CompoundShapeEntry> shapes, out Microsoft.Xna.Framework.Vector3 center) Line 171 + 0x11 bytes	C#
>	SMW.exe!BEPUphysics.Entities.Prefabs.CompoundBody.CompoundBody(System.Collections.Generic.IList<BEPUphysics.CollisionShapes.CompoundShapeEntry> bodies) Line 37 + 0x1c bytes	C#
I worked around it by providing dummy weights for each CompoundShapeEntry in the bodies list but I just thought I should point this out since it doesn't seem to be intended behavior. Then again, I could just be using it wrong. Anyway, it seemed worth mentioning.
Thanks
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Small issue with Kinematic CompoundBody ctor

Post by Norbo »

That is intended behavior; the 'weight' associated with the individual subshapes affects the compound shape's local origin regardless of what kind of object is using it. If all weights are zero, then the shape's center is undefined.

I've thought about allowing zero weights to mean 'just use 0,0,0 as the local origin; do not recenter any of the subshapes', but dynamic entities suffer from a second layer of undefined behavior with the inertia tensors. Another option would be to redo the computation using volumes if the weight calculation fails, but this probably would not be the most obvious result and is functionally redundant with just directly assigning the weights according to volume. The simplest and most intuitive solution to these problems is just to disallow such singularities.

I went ahead and introduced some intent-clarifying exceptions to the relevant methods for nonpositive total weights.
ecosky
Posts: 69
Joined: Fri Nov 04, 2011 7:13 am
Contact:

Re: Small issue with Kinematic CompoundBody ctor

Post by ecosky »

Interesting, thanks for the explanation.

If I understand correctly, it seems like it might be preferred for kinematic CompoundBody objects to use a separate CompoundShape ctor that didn't need to ComputeCenter or adjust the local position? Not that it's a big deal but I'm always looking for ways to speed up the preparation of rigid bodies. I reuse/cache as much as possible but when new instances have to be prepared the game is already taking a big hit getting everything set up so any CPU time I can save helps to reduce the load spike. The kinematic bodies are expected to be used more often, and with more complex compound shapes, than the dynamic objects (generally environmental) so speeding this up even a small amount seems useful, so long as it's a near-trivial change which it seems like it might be. Is the concern about having a valid inertia tensor primarily to support the case where a kinematic might become dynamic some time later? If so, given the choice I'd prefer to ComputeCenter when it does become dynamic (assuming that's possible).

Thanks again,
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Small issue with Kinematic CompoundBody ctor

Post by Norbo »

If I understand correctly, it seems like it might be preferred for kinematic CompoundBody objects to use a separate CompoundShape ctor that didn't need to ComputeCenter or adjust the local position?
Whether the user is kinematic or dynamic (or even something else, like a StaticGroup) does not change what the shape itself must do. The shape itself has a contract to satisfy; if it violates that contract, it becomes inconsistent with the other shapes' standard behavior. While this violation could be technically dealt with for the CompoundShape specifically, it would not produce particularly intuitive results because the expectations associated with other shapes would not apply.
Is the concern about having a valid inertia tensor primarily to support the case where a kinematic might become dynamic some time later?
Partially, but my main concern is losing consistency. There is quite a lot of value in a kinematic and dynamic entity, constructed from the shape, behaving in an intuitive way- having the same center of rotation, for example.

Then, there's the issue of consistency within dynamics in conceptual isolation; there isn't a particularly great result for a 0 weight shape for both the center and inertia tensor together. Choosing a particular center constrains the choices for the inertia tensor. For example, if 0,0,0 was arbitrarily picked for the center, it is possible that there does not exist a 'valid' inertia tensor for some shapes. An arbitrarily chosen distribution method, like 'assume all shapes have equal weight', would have to be used instead. That would cause a unintuitive behavioral inconsistency. If 'assume all shapes have equal weight' is used for both the center and distribution, it would be internally consistent, but you'd gain nothing performance wise and it would be functionally redundant with using appropriate weights.

Dynamics could simply not support 0 weight, leaving kinematics with a hidden special feature, but this would be a fiddly little inconsistency that I'd prefer to avoid.
I reuse/cache as much as possible but when new instances have to be prepared the game is already taking a big hit getting everything set up so any CPU time I can save helps to reduce the load spike.
Performance wise, I would expect the ComputeCenter method to be fairly trivial compared to the other costs associated with creating a new entity. In particular, a new CompoundCollidable requires a new hierarchy.

In addition, if a CompoundBody prefab type is being created directly, you could improve performance by initializing the entity directly instead of using a prefab entity type. For example, modifying an example from the EntityConstructionDemo:

Code: Select all

new Entity(compoundShape, mass, localInertiaTensor, volume)
If you are creating multiple compounds which can share the same shape, then this will be a significant win. If they aren't shared but you can still load the physical properties like mass/inertia/volume from a cache, then this will still help a lot. The above prevents any extra computations from occurring for inertia or volume. This is most helpful for dynamic entities since the inertia tensor is a bit expensive to compute every time, but the lack of a volume computation can help kinematics too. (To get the benefit for kinematics, you'll have to grab the version I just uploaded which allows zero/negative masses to be passed into the Entity constructor to signify a kinematic.)

To cut the initialization cost down further, you'll need to 'cache' the CompoundCollidable itself. Chances are it would be easier and more effective to perform external optimizations like deferring the constructions over multiple frames or using asynchronous computation.
ecosky
Posts: 69
Joined: Fri Nov 04, 2011 7:13 am
Contact:

Re: Small issue with Kinematic CompoundBody ctor

Post by ecosky »

Thanks very much for the detailed & helpful reply, as usual. I'll look into initializing the entity directly, that seems most likely to help performance based on your comments.
Post Reply