Home | History | Annotate | Download | only in optimize
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 package jme3tools.optimize;
     34 
     35 import com.jme3.bounding.BoundingBox;
     36 import com.jme3.renderer.Camera;
     37 import com.jme3.scene.Geometry;
     38 import java.util.Set;
     39 
     40 public class FastOctnode {
     41 
     42     int offset;
     43     int length;
     44     FastOctnode child;
     45     FastOctnode next;
     46 
     47     private static final BoundingBox tempBox = new BoundingBox();
     48 
     49     public int getSide(){
     50         return ((offset & 0xE0000000) >> 29) & 0x7;
     51     }
     52 
     53     public void setSide(int side){
     54         offset &= 0x1FFFFFFF;
     55         offset |= (side << 29);
     56     }
     57 
     58     public void setOffset(int offset){
     59         if (offset < 0 || offset > 20000000){
     60             throw new IllegalArgumentException();
     61         }
     62 
     63         this.offset &= 0xE0000000;
     64         this.offset |= offset;
     65     }
     66 
     67     public int getOffset(){
     68         return this.offset & 0x1FFFFFFF;
     69     }
     70 
     71     private void generateRenderSetNoCheck(Geometry[] globalGeomList, Set<Geometry> renderSet, Camera cam){
     72         if (length != 0){
     73             int start = getOffset();
     74             int end   = start + length;
     75             for (int i = start; i < end; i++){
     76                 renderSet.add(globalGeomList[i]);
     77             }
     78         }
     79 
     80         if (child == null)
     81             return;
     82 
     83         FastOctnode node = child;
     84         while (node != null){
     85             node.generateRenderSetNoCheck(globalGeomList, renderSet, cam);
     86             node = node.next;
     87         }
     88     }
     89 
     90     private static void findChildBound(BoundingBox bbox, int side){
     91         float extent = bbox.getXExtent() * 0.5f;
     92         bbox.getCenter().set(bbox.getCenter().x + extent * Octnode.extentMult[side].x,
     93                              bbox.getCenter().y + extent * Octnode.extentMult[side].y,
     94                              bbox.getCenter().z + extent * Octnode.extentMult[side].z);
     95         bbox.setXExtent(extent);
     96         bbox.setYExtent(extent);
     97         bbox.setZExtent(extent);
     98     }
     99 
    100     public void generateRenderSet(Geometry[] globalGeomList, Set<Geometry> renderSet, Camera cam, BoundingBox parentBox, boolean isRoot){
    101         tempBox.setCenter(parentBox.getCenter());
    102         tempBox.setXExtent(parentBox.getXExtent());
    103         tempBox.setYExtent(parentBox.getYExtent());
    104         tempBox.setZExtent(parentBox.getZExtent());
    105 
    106         if (!isRoot){
    107             findChildBound(tempBox, getSide());
    108         }
    109 
    110         tempBox.setCheckPlane(0);
    111         cam.setPlaneState(0);
    112         Camera.FrustumIntersect result = cam.contains(tempBox);
    113         if (result != Camera.FrustumIntersect.Outside){
    114             if (length != 0){
    115                 int start = getOffset();
    116                 int end   = start + length;
    117                 for (int i = start; i < end; i++){
    118                     renderSet.add(globalGeomList[i]);
    119                 }
    120             }
    121 
    122             if (child == null)
    123                 return;
    124 
    125             FastOctnode node = child;
    126 
    127             float x = tempBox.getCenter().x;
    128             float y = tempBox.getCenter().y;
    129             float z = tempBox.getCenter().z;
    130             float ext = tempBox.getXExtent();
    131 
    132             while (node != null){
    133                 if (result == Camera.FrustumIntersect.Inside){
    134                     node.generateRenderSetNoCheck(globalGeomList, renderSet, cam);
    135                 }else{
    136                     node.generateRenderSet(globalGeomList, renderSet, cam, tempBox, false);
    137                 }
    138 
    139                 tempBox.getCenter().set(x,y,z);
    140                 tempBox.setXExtent(ext);
    141                 tempBox.setYExtent(ext);
    142                 tempBox.setZExtent(ext);
    143 
    144                 node = node.next;
    145             }
    146         }
    147     }
    148 
    149     @Override
    150     public String toString(){
    151         return "OCTNode[O=" + getOffset() + ", L=" + length +
    152                 ", S=" + getSide() + "]";
    153     }
    154 
    155     public String toStringVerbose(int indent){
    156         String str = "------------------".substring(0,indent) + toString() + "\n";
    157         if (child == null)
    158             return str;
    159 
    160         FastOctnode children = child;
    161         while (children != null){
    162             str += children.toStringVerbose(indent+1);
    163             children = children.next;
    164         }
    165 
    166         return str;
    167     }
    168 
    169 }
    170