예제 #1
0
        /// <summary>
        /// Splits node's primitives into 8 new children nodes.
        /// </summary>
        private void split()
        {
            if (boundingBox == null)
                throw new Exception("Cannot split null bounding box");

            try
            {
                this.childs = new OctreeNode[8];
                for (int i = 0; i < 8; i++)
                {
                    childs[i] = new OctreeNode();
                    childs[i].boundingBox = new BoundingBox(new Vector(), new Vector());
                }

                double dx2 = (boundingBox.RightBottomBack.X - boundingBox.LeftTopFront.X) / 2;
                double dy2 = (boundingBox.RightBottomBack.Y - boundingBox.LeftTopFront.Y) / 2;
                double dz2 = (boundingBox.RightBottomBack.Z - boundingBox.LeftTopFront.Z) / 2;
                childs[0].boundingBox.LeftTopFront = boundingBox.LeftTopFront;
                childs[1].boundingBox.LeftTopFront = boundingBox.LeftTopFront + new Vector(dx2, 0, 0);
                childs[2].boundingBox.LeftTopFront = boundingBox.LeftTopFront + new Vector(0, dy2, 0);
                childs[3].boundingBox.LeftTopFront = boundingBox.LeftTopFront + new Vector(dx2, dy2, 0);
                childs[4].boundingBox.LeftTopFront = boundingBox.LeftTopFront + new Vector(0, 0, dz2);
                childs[5].boundingBox.LeftTopFront = boundingBox.LeftTopFront + new Vector(dx2, 0, dz2);
                childs[6].boundingBox.LeftTopFront = boundingBox.LeftTopFront + new Vector(0, dy2, dz2);
                childs[7].boundingBox.LeftTopFront = boundingBox.LeftTopFront + new Vector(dx2, dy2, dz2);
                Vector sizeVector = new Vector(dx2, dy2, dz2);
                // all childs same size
                for (int i = 0; i < 8; i++)
                {
                    childs[i].boundingBox.RightBottomBack =
                        childs[i].boundingBox.LeftTopFront + sizeVector;
                }

                // distribute primitives into children
                foreach (Primitive primitive in primitives)
                {
                    // primitive may fall into multiple children at the same time
                    // ideally it will fall in only 1 child
                    for (int i = 0; i < 8; i++)
                    {
                        if (primitive.BoundingBox.Intersects(childs[i].boundingBox))
                        {
                            childs[i].Add(primitive);
                        }
                    }
                }
                primitives = null;
            }
            catch
            {
                // in case of exception clean up any inconsistencies
                this.childs = null;
                this.boundingBox = BoundingBox.Zero;
                throw;
            }
        }
예제 #2
0
 // checker. can be more than items inserted if some fall into multiple nodes
 private int totalPrimitivesIn(OctreeNode node)
 {
     int sum = node.PrimitiveCount;
     if (node.childs != null)
     {
         foreach (OctreeNode child in node.childs)
         {
             sum += totalPrimitivesIn(child);
         }
     }
     return sum;
 }
예제 #3
0
 // returns all leaf nodes hit by the ray
 private void traverse(OctreeNode node, Ray ray, LinkedList<OctreeNode> list)
 {
     if (node.primitives != null)
     {
         list.AddLast(node);
     }
     if (node.childs != null)
     {
         for (int i = 0; i < 8; i++)
         {
             if (node.childs[i].boundingBox.GetIntersection(ray) != Constants.Infinity)
             {
                 traverse(node.childs[i], ray, list);
             }
         }
     }
 }
예제 #4
0
 private void init()
 {
     compiled = false;
     root = new OctreeNode();
     bigObjects = new PrimitiveList();
 }