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.