diff --git a/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java b/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java index 2f76a01861..70266e401d 100644 --- a/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java +++ b/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedGeometry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022 jMonkeyEngine + * Copyright (c) 2009-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,7 +75,6 @@ public class InstancedGeometry extends Geometry { private int firstUnusedIndex = 0; private int numVisibleInstances = 0; - private Camera cam; public InstancedGeometry() { super(); @@ -276,7 +275,7 @@ private void swap(int idx1, int idx2) { } } - public void updateInstances() { + public void updateInstances(Camera cam) { FloatBuffer fb = (FloatBuffer) transformInstanceData.getData(); fb.limit(fb.capacity()); fb.position(0); @@ -416,12 +415,6 @@ private void updateAllInstanceData() { allInstanceData = allData.toArray(new VertexBuffer[allData.size()]); } - @Override - public boolean checkCulling(Camera cam) { - this.cam = cam; - return super.checkCulling(cam); - } - @Override public int collideWith(Collidable other, CollisionResults results) { return 0; // Ignore collision diff --git a/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java b/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java index ea5b576ed3..821264f9a6 100644 --- a/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java +++ b/jme3-core/src/main/java/com/jme3/scene/instancing/InstancedNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2021 jMonkeyEngine + * Copyright (c) 2014-2023 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +35,7 @@ import com.jme3.export.JmeImporter; import com.jme3.material.MatParam; import com.jme3.material.Material; +import com.jme3.renderer.Camera; import com.jme3.renderer.RenderManager; import com.jme3.renderer.ViewPort; import com.jme3.renderer.queue.RenderQueue; @@ -161,7 +162,7 @@ public void update(float tpf){ @Override public void render(RenderManager rm, ViewPort vp) { - node.renderFromControl(); + node.renderFromControl(vp.getCamera()); } @Override @@ -198,9 +199,9 @@ public InstancedNode(String name) { addControl(control); } - private void renderFromControl() { + private void renderFromControl(Camera cam) { for (InstancedGeometry ig : instancesMap.values()) { - ig.updateInstances(); + ig.updateInstances(cam); } } diff --git a/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java new file mode 100644 index 0000000000..f0fe8f6b7e --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/scene/instancing/TestInstancingWithWaterFilter.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2009-2023 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jme3test.scene.instancing; + +import com.jme3.app.SimpleApplication; +import com.jme3.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.scene.Geometry; +import com.jme3.scene.instancing.InstancedNode; +import com.jme3.scene.shape.Box; +import com.jme3.water.WaterFilter; + +/** + * A test case for using instancing with shadow filter. This is a test case + * for issue 2007 (Instanced objects are culled when using the WaterFilter). + * + * If test succeeds, all the boxes in the camera frustum will be rendered. If + * test fails, some of the boxes that are in the camera frustum will be culled. + * + * @author Ali-RS + */ +public class TestInstancingWithWaterFilter extends SimpleApplication { + public static void main(String[] args) { + TestInstancingWithWaterFilter test = new TestInstancingWithWaterFilter(); + test.start(); + } + + @Override + public void simpleInitApp() { + flyCam.setMoveSpeed(10); + + DirectionalLight light = new DirectionalLight(); + light.setDirection(new Vector3f(-1, -1, -1)); + rootNode.addLight(light); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + mat.setBoolean("UseInstancing", true); + + Box mesh = new Box(0.5f, 0.5f, 0.5f); + + InstancedNode instanceNode = new InstancedNode("TestInstancedNode"); + //instanceNode.setCullHint(Spatial.CullHint.Never); + rootNode.attachChild(instanceNode); + + for (int i = 0; i < 200; i++) { + Geometry obj = new Geometry("TestBox" + i, mesh); + obj.setMaterial(mat); + obj.setLocalTranslation(i, i, 0); + instanceNode.attachChild(obj); + } + instanceNode.instance(); + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + WaterFilter waterFilter = new WaterFilter(rootNode, light.getDirection()); + fpp.addFilter(waterFilter); + viewPort.addProcessor(fpp); + } +}