Table of Contents

Class BepuEntityInstancing

Namespace
Stride.CommunityToolkit.Bepu
Assembly
Stride.CommunityToolkit.Bepu.dll

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

int

Methods

CanSkipUpdate()

Determines whether every registered body is asleep, in which case no transform can have changed.

protected override bool CanSkipUpdate()

Returns

bool

true when the previous frame's gather is still valid.

OnInstanceAdded(Entity)

Called after an instance is appended, for derived classes keeping parallel data.

protected override void OnInstanceAdded(Entity entity)

Parameters

entity Entity

The 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

index int

The index that was vacated and has just been overwritten.

lastIndex int

The 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()