Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add instance culling function in InstancedGeometry #1865

Merged
merged 3 commits into from
Nov 18, 2022
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;
}
}
}