Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,14 @@
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.BiFunction;

public class InstancedGeometry extends Geometry {

private static final int INSTANCE_SIZE = 16;

private static BiFunction<Camera, Geometry, Boolean> instanceCullingFunction = new DefaultInstanceCullingFunction();

private VertexBuffer[] globalInstanceData;
private VertexBuffer transformInstanceData;
private Geometry[] geometries = new Geometry[1];
Expand Down Expand Up @@ -95,6 +98,22 @@ public InstancedGeometry(String name) {
setMaxNumInstances(1);
}

/**
* Set the function used for culling instances from being rendered.
* Default is {@link DefaultInstanceCullingFunction}.
*/
public static void setInstanceCullingFunction(BiFunction<Camera, Geometry, Boolean> instanceCullingFunction) {
InstancedGeometry.instanceCullingFunction = instanceCullingFunction;
}

/**
* @return The instance culling function or null if there isn't any.
* Default is {@link DefaultInstanceCullingFunction}.
*/
public static BiFunction<Camera, Geometry, Boolean> getInstanceCullingFunction() {
return instanceCullingFunction;
}

/**
* Global user specified per-instance data.
*
Expand Down Expand Up @@ -284,14 +303,9 @@ public void updateInstances() {
}
}

if (cam != null) {
BoundingVolume bv = geom.getWorldBound();
int save = cam.getPlaneState();
cam.setPlaneState(0);
FrustumIntersect intersect = cam.contains(bv);
cam.setPlaneState(save);

if (intersect == FrustumIntersect.Outside) {
if (cam != null && instanceCullingFunction != null) {
boolean culled = instanceCullingFunction.apply(cam, geom);
if (culled) {
numCulledGeometries++;
continue;
}
Expand Down Expand Up @@ -458,4 +472,22 @@ protected void cleanup() {
allInstanceData = null;
geometries = null;
}

/**
* By default, it checks if geometry is in camera frustum and culls it
* if it is outside camera view.
*/
public static class DefaultInstanceCullingFunction implements BiFunction<Camera, Geometry, Boolean> {

@Override
public Boolean apply(Camera cam, Geometry geom) {
BoundingVolume bv = geom.getWorldBound();
int save = cam.getPlaneState();
cam.setPlaneState(0);
FrustumIntersect intersect = cam.contains(bv);
cam.setPlaneState(save);

return intersect == FrustumIntersect.Outside;
}
}
}