Class BepuEntityInstancing
An EntityInstancing for Bepu physics bodies that stops working entirely once the bodies fall asleep.
public class BepuEntityInstancing : EntityInstancing, IInstancing
- Inheritance
-
BepuEntityInstancing
- Implements
- Inherited Members
Examples
game.AddInstancingSupport();
var instancing = new BepuEntityInstancing();
var master = new Entity("Master") { new ModelComponent(model), new InstancingComponent { Type = instancing } };
master.Scene = scene;
// Instances carry a body but no ModelComponent - the master draws them
foreach (var cube in cubes) instancing.AddInstance(cube);
Remarks
Bepu puts bodies to sleep when they come to rest, and a sleeping body's transform cannot change. That makes re-reading every transform, re-inverting every matrix and re-computing the bounding box pure waste, which is what the engine does forever once a pile settles. This class checks the bodies instead and reuses the previous frame's results while they are all asleep.
Measured on 20,000 settled cubes, this took the per-frame instancing update from 1.94 ms to zero. Pair it with BufferedEntityInstancing to stop the redundant GPU upload as well.
The check is a scan over the registered bodies, so it costs a little while things are moving - it gives up at the first awake body - and pays for itself many times over when they are not. Instances registered without a BodyComponent (a static or kinematic entity moved by script, say) disable skipping altogether, since nothing indicates when they move.
Properties
InstancesWithoutBody
Gets the number of registered instances that have no BodyComponent, and so prevent the sleep skip.
public int InstancesWithoutBody { get; }
Property Value
Methods
CanSkipUpdate()
Determines whether every registered body is asleep, in which case no transform can have changed.
protected override bool CanSkipUpdate()
Returns
OnInstanceAdded(Entity)
Called after an instance is appended, for derived classes keeping parallel data.
protected override void OnInstanceAdded(Entity entity)
Parameters
entityEntityThe newly registered entity, now at index RegisteredInstanceCount - 1.
OnInstanceRemoved(int, int)
Called after an instance is removed by swapping the last one into its place, for derived classes keeping parallel data.
protected override void OnInstanceRemoved(int index, int lastIndex)
Parameters
indexintThe index that was vacated and has just been overwritten.
lastIndexintThe index the surviving instance came from, now past the end.
Remarks
Derived data must mirror this exactly: copy lastIndex to
index when they differ, then drop lastIndex.
OnInstancesCleared()
Called after every instance is unregistered, for derived classes keeping parallel data.
protected override void OnInstancesCleared()