Package jray.struct

Source Code of jray.struct.Octree

package jray.struct;

import java.util.List;

import jray.common.Object3D;
import jray.common.Sphere;
import jray.common.Vect3;
import jray.math.Vect;

/**
* A classic octree with some additional constraints:
*  - nodes are "complete" - they contain 0 or 8 child nodes.
*  - objects may be stored in every node (not leaf nodes only)
*  - some objects may be stored multiple times
*/
public class Octree{
  protected Node root;
 
  public Octree(Vect3 center, double width){
    root = new Node(center, null, width);
  }
 
  public void add(Object3D o){
    if(!root.insert(o, o.getBoundingSphere())){
      throw new RuntimeException("Could not insert: "+o);
    }
  }
 
  public Node getRoot(){
    return root;
  }
 
  public static Octree buildTree(Vect3 center, List<? extends Object3D> objects){
    double maxQuadDist=0, qdist;
    Vect3 dist=new Vect3();
   
    System.out.print("Building octree... ");
   
    for(Object3D o : objects){
      Sphere s = o.getBoundingSphere();
      if(s!=null){
        Vect.subtract(center, s.getPosition(), dist);
        qdist = s.getRadius();
        if(Double.isInfinite(qdist)||Double.isNaN(qdist))
          throw new RuntimeException("Invalid BoundingSphere: "+s+" from "+o);
        qdist = qdist*qdist + dist.quadLength();
        if(maxQuadDist < qdist)
          maxQuadDist = qdist;
      }
    }
   
    /**
     * Workaround: *2.1 instead of *2, because rays must always start inside an octree for RayPath.
     * To fix this problem, a RayPath should allow ray-origins outside the octree, but this would need
     * an additional ray-cube intersection test which is currently not implemented. Another downside of
     * this is that the camera must always be located inside the octree - it must not be moved outside.
     */
    double sizeHint = Math.sqrt(maxQuadDist)*2.1;
   
    long start=System.nanoTime();
    int resizeCount = 0;
    Octree t;
    outer:
    while(true){
      t = new Octree(center,sizeHint);
      for(Object3D o : objects){
        if(!t.root.insert(o, o.getBoundingSphere())){
          sizeHint *= 2;
          resizeCount++;
          System.out.println("Warning - resize needed!");
          continue outer;
        }
      }
     
      break;
    }
    t.getRoot().compress();
   
    System.out.printf(" %f seconds\n",(System.nanoTime()-start)*1e-9);
    System.out.println(" - contains "+t.getRoot().getSize()+" of "+objects.size()+" elements (x"+String.format("%.2f",t.getRoot().getSize()/(float)objects.size())+")");
        System.out.println(" - avg depth: "+t.getAverageObjectDepth());
        System.out.println(" - node count: "+t.getRoot().getNodeCount());
        System.out.println(" - objects per node: "+t.getRoot().getSize()/(float)t.getRoot().getNodeCount());
   
    return t;
  }
 
  @Override
  public String toString(){
    StringBuilder sb = new StringBuilder();
   
    root.addStringRep(sb, 0);
   
    return sb.toString();
  }
 
  public double getAverageObjectDepth(){
    return root.getContentDepthSum(0)/(double)root.getSize();
  }
}
TOP

Related Classes of jray.struct.Octree

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.