| /* |
| * Copyright (c) 2009-2010 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 jme3tools.optimize; |
| |
| import com.jme3.bounding.BoundingBox; |
| import com.jme3.renderer.Camera; |
| import com.jme3.scene.Geometry; |
| import java.util.Set; |
| |
| public class FastOctnode { |
| |
| int offset; |
| int length; |
| FastOctnode child; |
| FastOctnode next; |
| |
| private static final BoundingBox tempBox = new BoundingBox(); |
| |
| public int getSide(){ |
| return ((offset & 0xE0000000) >> 29) & 0x7; |
| } |
| |
| public void setSide(int side){ |
| offset &= 0x1FFFFFFF; |
| offset |= (side << 29); |
| } |
| |
| public void setOffset(int offset){ |
| if (offset < 0 || offset > 20000000){ |
| throw new IllegalArgumentException(); |
| } |
| |
| this.offset &= 0xE0000000; |
| this.offset |= offset; |
| } |
| |
| public int getOffset(){ |
| return this.offset & 0x1FFFFFFF; |
| } |
| |
| private void generateRenderSetNoCheck(Geometry[] globalGeomList, Set<Geometry> renderSet, Camera cam){ |
| if (length != 0){ |
| int start = getOffset(); |
| int end = start + length; |
| for (int i = start; i < end; i++){ |
| renderSet.add(globalGeomList[i]); |
| } |
| } |
| |
| if (child == null) |
| return; |
| |
| FastOctnode node = child; |
| while (node != null){ |
| node.generateRenderSetNoCheck(globalGeomList, renderSet, cam); |
| node = node.next; |
| } |
| } |
| |
| private static void findChildBound(BoundingBox bbox, int side){ |
| float extent = bbox.getXExtent() * 0.5f; |
| bbox.getCenter().set(bbox.getCenter().x + extent * Octnode.extentMult[side].x, |
| bbox.getCenter().y + extent * Octnode.extentMult[side].y, |
| bbox.getCenter().z + extent * Octnode.extentMult[side].z); |
| bbox.setXExtent(extent); |
| bbox.setYExtent(extent); |
| bbox.setZExtent(extent); |
| } |
| |
| public void generateRenderSet(Geometry[] globalGeomList, Set<Geometry> renderSet, Camera cam, BoundingBox parentBox, boolean isRoot){ |
| tempBox.setCenter(parentBox.getCenter()); |
| tempBox.setXExtent(parentBox.getXExtent()); |
| tempBox.setYExtent(parentBox.getYExtent()); |
| tempBox.setZExtent(parentBox.getZExtent()); |
| |
| if (!isRoot){ |
| findChildBound(tempBox, getSide()); |
| } |
| |
| tempBox.setCheckPlane(0); |
| cam.setPlaneState(0); |
| Camera.FrustumIntersect result = cam.contains(tempBox); |
| if (result != Camera.FrustumIntersect.Outside){ |
| if (length != 0){ |
| int start = getOffset(); |
| int end = start + length; |
| for (int i = start; i < end; i++){ |
| renderSet.add(globalGeomList[i]); |
| } |
| } |
| |
| if (child == null) |
| return; |
| |
| FastOctnode node = child; |
| |
| float x = tempBox.getCenter().x; |
| float y = tempBox.getCenter().y; |
| float z = tempBox.getCenter().z; |
| float ext = tempBox.getXExtent(); |
| |
| while (node != null){ |
| if (result == Camera.FrustumIntersect.Inside){ |
| node.generateRenderSetNoCheck(globalGeomList, renderSet, cam); |
| }else{ |
| node.generateRenderSet(globalGeomList, renderSet, cam, tempBox, false); |
| } |
| |
| tempBox.getCenter().set(x,y,z); |
| tempBox.setXExtent(ext); |
| tempBox.setYExtent(ext); |
| tempBox.setZExtent(ext); |
| |
| node = node.next; |
| } |
| } |
| } |
| |
| @Override |
| public String toString(){ |
| return "OCTNode[O=" + getOffset() + ", L=" + length + |
| ", S=" + getSide() + "]"; |
| } |
| |
| public String toStringVerbose(int indent){ |
| String str = "------------------".substring(0,indent) + toString() + "\n"; |
| if (child == null) |
| return str; |
| |
| FastOctnode children = child; |
| while (children != null){ |
| str += children.toStringVerbose(indent+1); |
| children = children.next; |
| } |
| |
| return str; |
| } |
| |
| } |