Browse Source

Check culling on the instanced geometries. (#1315)

Ali-RS 5 years ago
parent
commit
0c6f240222

+ 26 - 2
jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java

@@ -40,6 +40,8 @@ import com.jme3.export.Savable;
 import com.jme3.math.Matrix3f;
 import com.jme3.math.Matrix4f;
 import com.jme3.math.Quaternion;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.Camera.FrustumIntersect;
 import com.jme3.scene.Geometry;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.VertexBuffer;
@@ -63,6 +65,8 @@ public class InstancedGeometry extends Geometry {
     private Geometry[] geometries = new Geometry[1];
 
     private int firstUnusedIndex = 0;
+    private int numCulledGeometries = 0;
+    private Camera cam;
 
     public InstancedGeometry() {
         super();
@@ -208,7 +212,7 @@ public class InstancedGeometry extends Geometry {
     }
 
     public int getActualNumInstances() {
-        return firstUnusedIndex;
+        return firstUnusedIndex - numCulledGeometries;
     }
 
     private void swap(int idx1, int idx2) {
@@ -250,6 +254,7 @@ public class InstancedGeometry extends Geometry {
         fb.limit(fb.capacity());
         fb.position(0);
 
+        numCulledGeometries = 0;
         TempVars vars = TempVars.get();
         {
             float[] temp = vars.matrixWrite;
@@ -271,6 +276,19 @@ public class InstancedGeometry extends Geometry {
                     }
                 }
 
+                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) {
+                        numCulledGeometries++;
+                        continue;
+                    }
+                }
+
                 Matrix4f worldMatrix = geom.getWorldMatrix();
                 updateInstance(worldMatrix, temp, 0, vars.tempMat3, vars.quat1);
                 fb.put(temp);
@@ -280,7 +298,7 @@ public class InstancedGeometry extends Geometry {
 
         fb.flip();
 
-        if (fb.limit() / INSTANCE_SIZE != firstUnusedIndex) {
+        if (fb.limit() / INSTANCE_SIZE != (firstUnusedIndex - numCulledGeometries)) {
             throw new AssertionError();
         }
 
@@ -368,6 +386,12 @@ public class InstancedGeometry extends Geometry {
         return allData.toArray(new VertexBuffer[allData.size()]);
     }
 
+    @Override
+    public boolean checkCulling(Camera cam) {
+        this.cam = cam;
+        return super.checkCulling(cam);
+    }
+
     /**
      *  Called internally by com.jme3.util.clone.Cloner.  Do not call directly.
      */