Пример #1
0
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox();
     for (int i = 0, i3 = 0; i < n; i++, i3 += 3)
         bounds.include(particles[i3], particles[i3 + 1], particles[i3 + 2]);
     bounds.include(bounds.getMinimum().x - r, bounds.getMinimum().y - r, bounds.getMinimum().z - r);
     bounds.include(bounds.getMaximum().x + r, bounds.getMaximum().y + r, bounds.getMaximum().z + r);
     return o2w == null ? bounds : o2w.transform(bounds);
 }
Пример #2
0
        /**
         * Transforms each corner of the specified axis-aligned bounding box and
         * returns a new bounding box which incloses the transformed corners.
         *
         * @param b original bounding box
         * @return a new BoundingBox object which encloses the transform version of
         *         b
         */
        public BoundingBox transform(BoundingBox b)
        {
            if (b.isEmpty())
            {
                return(new BoundingBox());
            }
            // special case extreme corners
            BoundingBox rb = new BoundingBox(transformP(b.getMinimum()));

            rb.include(transformP(b.getMaximum()));
            // do internal corners
            for (int i = 1; i < 7; i++)
            {
                rb.include(transformP(b.getCorner(i)));
            }
            return(rb);
        }
Пример #3
0
 public bool update(ParameterList pl, SunflowAPI api)
 {
     ParameterList.FloatParameter pts = pl.getPointArray("points");
     if (pts != null)
     {
         BoundingBox bounds = new BoundingBox();
         for (int i = 0; i < pts.data.Length; i += 3)
             bounds.include(pts.data[i], pts.data[i + 1], pts.data[i + 2]);
         // cube extents
         minX = bounds.getMinimum().x;
         minY = bounds.getMinimum().y;
         minZ = bounds.getMinimum().z;
         maxX = bounds.getMaximum().x;
         maxY = bounds.getMaximum().y;
         maxZ = bounds.getMaximum().z;
     }
     return true;
 }
Пример #4
0
 private int dumpObj(int offset, int vertOffset, int maxN, BoundingBox bounds, StreamWriter file, StreamWriter mtlFile)
 {
     if (offset == 0)
         file.WriteLine(string.Format("mtllib {0}.mtl", dumpPrefix));
     int nextOffset = tree[offset];
     if ((nextOffset & (3 << 30)) == (3 << 30))
     {
         // leaf
         int n = tree[offset + 1];
         if (n > 0)
         {
             // output the current voxel to the file
             Point3 min = bounds.getMinimum();
             Point3 max = bounds.getMaximum();
             file.WriteLine(string.Format("o node{0}", offset));
             file.WriteLine(string.Format("v {0} {1} {2}", max.x, max.y, min.z));
             file.WriteLine(string.Format("v {0} {1} {2}", max.x, min.y, min.z));
             file.WriteLine(string.Format("v {0} {1} {2}", min.x, min.y, min.z));
             file.WriteLine(string.Format("v {0} {1} {2}", min.x, max.y, min.z));
             file.WriteLine(string.Format("v {0} {1} {2}", max.x, max.y, max.z));
             file.WriteLine(string.Format("v {0} {1} {2}", max.x, min.y, max.z));
             file.WriteLine(string.Format("v {0} {1} {2}", min.x, min.y, max.z));
             file.WriteLine(string.Format("v {0} {1} {2}", min.x, max.y, max.z));
             int v0 = vertOffset;
             file.WriteLine(string.Format("usemtl mtl{0}", n));
             file.WriteLine("s off");
             file.WriteLine(string.Format("f {0} {1} {2} {3}", v0 + 1, v0 + 2, v0 + 3, v0 + 4));
             file.WriteLine(string.Format("f {0} {1} {2} {3}", v0 + 5, v0 + 8, v0 + 7, v0 + 6));
             file.WriteLine(string.Format("f {0} {1} {2} {3}", v0 + 1, v0 + 5, v0 + 6, v0 + 2));
             file.WriteLine(string.Format("f {0} {1} {2} {3}", v0 + 2, v0 + 6, v0 + 7, v0 + 3));
             file.WriteLine(string.Format("f {0} {1} {2} {3}", v0 + 3, v0 + 7, v0 + 8, v0 + 4));
             file.WriteLine(string.Format("f {0} {1} {2} {3}", v0 + 5, v0 + 1, v0 + 4, v0 + 8));
             vertOffset += 8;
         }
         return vertOffset;
     }
     else
     {
         // node, recurse
         int axis = nextOffset & (3 << 30), v0;
         float split = ByteUtil.intBitsToFloat(tree[offset + 1]), min, max;
         nextOffset &= ~(3 << 30);
         switch (axis)
         {
             case 0:
                 max = bounds.getMaximum().x;
                 bounds.getMaximum().x = split;
                 v0 = dumpObj(nextOffset, vertOffset, maxN, bounds, file, mtlFile);
                 // restore and go to other side
                 bounds.getMaximum().x = max;
                 min = bounds.getMinimum().x;
                 bounds.getMinimum().x = split;
                 v0 = dumpObj(nextOffset + 2, v0, maxN, bounds, file, mtlFile);
                 bounds.getMinimum().x = min;
                 break;
             case 1 << 30:
                 max = bounds.getMaximum().y;
                 bounds.getMaximum().y = split;
                 v0 = dumpObj(nextOffset, vertOffset, maxN, bounds, file, mtlFile);
                 // restore and go to other side
                 bounds.getMaximum().y = max;
                 min = bounds.getMinimum().y;
                 bounds.getMinimum().y = split;
                 v0 = dumpObj(nextOffset + 2, v0, maxN, bounds, file, mtlFile);
                 bounds.getMinimum().y = min;
                 break;
             case 2 << 30:
                 max = bounds.getMaximum().z;
                 bounds.getMaximum().z = split;
                 v0 = dumpObj(nextOffset, vertOffset, maxN, bounds, file, mtlFile);
                 // restore and go to other side
                 bounds.getMaximum().z = max;
                 min = bounds.getMinimum().z;
                 bounds.getMinimum().z = split;
                 v0 = dumpObj(nextOffset + 2, v0, maxN, bounds, file, mtlFile);
                 // restore and go to other side
                 bounds.getMinimum().z = min;
                 break;
             default:
                 v0 = vertOffset;
                 break;
         }
         return v0;
     }
 }
Пример #5
0
 public void build(PrimitiveList primitives)
 {
     UI.printDetailed(UI.Module.ACCEL, "KDTree settings");
     UI.printDetailed(UI.Module.ACCEL, "  * Max Leaf Size:  {0}", maxPrims);
     UI.printDetailed(UI.Module.ACCEL, "  * Max Depth:      {0}", MAX_DEPTH);
     UI.printDetailed(UI.Module.ACCEL, "  * Traversal cost: {0}", TRAVERSAL_COST);
     UI.printDetailed(UI.Module.ACCEL, "  * Intersect cost: {0}", INTERSECT_COST);
     UI.printDetailed(UI.Module.ACCEL, "  * Empty bonus:    {0}", EMPTY_BONUS);
     UI.printDetailed(UI.Module.ACCEL, "  * Dump leaves:    {0}", dump ? "enabled" : "disabled");
     Timer total = new Timer();
     total.start();
     primitiveList = primitives;
     // get the object space bounds
     bounds = primitives.getWorldBounds(null);
     int nPrim = primitiveList.getNumPrimitives(), nSplits = 0;
     BuildTask task = new BuildTask(nPrim);
     Timer prepare = new Timer();
     prepare.start();
     for (int i = 0; i < nPrim; i++)
     {
         for (int axis = 0; axis < 3; axis++)
         {
             float ls = primitiveList.getPrimitiveBound(i, 2 * axis + 0);
             float rs = primitiveList.getPrimitiveBound(i, 2 * axis + 1);
             if (ls == rs)
             {
                 // flat in this dimension
                 task.splits[nSplits] = pack(ls, PLANAR, axis, i);
                 nSplits++;
             }
             else
             {
                 task.splits[nSplits + 0] = pack(ls, OPENED, axis, i);
                 task.splits[nSplits + 1] = pack(rs, CLOSED, axis, i);
                 nSplits += 2;
             }
         }
     }
     task.n = nSplits;
     prepare.end();
     Timer t = new Timer();
     List<int> tempTree = new List<int>();
     List<int> tempList = new List<int>();
     tempTree.Add(0);
     tempTree.Add(1);
     t.start();
     // sort it
     Timer sorting = new Timer();
     sorting.start();
     radix12(task.splits, task.n);
     sorting.end();
     // build the actual tree
     BuildStats stats = new BuildStats();
     buildTree(bounds.getMinimum().x, bounds.getMaximum().x, bounds.getMinimum().y, bounds.getMaximum().y, bounds.getMinimum().z, bounds.getMaximum().z, task, 1, tempTree, 0, tempList, stats);
     t.end();
     // write out arrays
     // free some memory
     task = null;
     tree = tempTree.ToArray();
     tempTree = null;
     this.primitives = tempList.ToArray();
     tempList = null;
     total.end();
     // display some extra info
     stats.printStats();
     UI.printDetailed(UI.Module.ACCEL, "  * Node memory:    {0}", Memory.SizeOf(tree));
     UI.printDetailed(UI.Module.ACCEL, "  * Object memory:  {0}", Memory.SizeOf(this.primitives));
     UI.printDetailed(UI.Module.ACCEL, "  * Prepare time:   {0}", prepare);
     UI.printDetailed(UI.Module.ACCEL, "  * Sorting time:   {0}", sorting);
     UI.printDetailed(UI.Module.ACCEL, "  * Tree creation:  {0}", t);
     UI.printDetailed(UI.Module.ACCEL, "  * Build time:     {0}", total);
     if (dump)
     {
         try
         {
             UI.printInfo(UI.Module.ACCEL, "Dumping mtls to {0}.mtl ...", dumpPrefix);
             StreamWriter mtlFile = new StreamWriter(dumpPrefix + ".mtl");
             int maxN = stats.maxObjects;
             for (int n = 0; n <= maxN; n++)
             {
                 float blend = (float)n / (float)maxN;
                 Color nc;
                 if (blend < 0.25)
                     nc = Color.blend(Color.BLUE, Color.GREEN, blend / 0.25f);
                 else if (blend < 0.5)
                     nc = Color.blend(Color.GREEN, Color.YELLOW, (blend - 0.25f) / 0.25f);
                 else if (blend < 0.75)
                     nc = Color.blend(Color.YELLOW, Color.RED, (blend - 0.50f) / 0.25f);
                 else
                     nc = Color.MAGENTA;
                 mtlFile.WriteLine(string.Format("newmtl mtl{0}", n));
                 float[] rgb = nc.getRGB();
                 mtlFile.WriteLine("Ka 0.1 0.1 0.1");
                 mtlFile.WriteLine(string.Format("Kd {0}g {1}g {2}g", rgb[0], rgb[1], rgb[2]));
                 mtlFile.WriteLine("illum 1\n");
             }
             StreamWriter objFile = new StreamWriter(dumpPrefix + ".obj");
             UI.printInfo(UI.Module.ACCEL, "Dumping tree to {0}.obj ...", dumpPrefix);
             dumpObj(0, 0, maxN, new BoundingBox(bounds), objFile, mtlFile);
             objFile.Close();
             mtlFile.Close();
         }
         catch (Exception e)
         {
             Console.WriteLine(e);
         }
     }
 }
Пример #6
0
        private void updateGeometry(Point3 c0, Point3 c1)
        {
            // figure out cube extents
            lightBounds = new BoundingBox(c0);
            lightBounds.include(c1);

            // cube extents
            minX = lightBounds.getMinimum().x;
            minY = lightBounds.getMinimum().y;
            minZ = lightBounds.getMinimum().z;
            maxX = lightBounds.getMaximum().x;
            maxY = lightBounds.getMaximum().y;
            maxZ = lightBounds.getMaximum().z;

            // work around epsilon problems for light test
            lightBounds.enlargeUlps();

            // light source geometry
            lxmin = maxX / 3 + 2 * minX / 3;
            lxmax = minX / 3 + 2 * maxX / 3;
            lymin = maxY / 3 + 2 * minY / 3;
            lymax = minY / 3 + 2 * maxY / 3;
            area = (lxmax - lxmin) * (lymax - lymin);
        }
Пример #7
0
 public bool intersects(BoundingBox box)
 {
     // this could be optimized
     BoundingBox b = new BoundingBox();
     b.include(new Point3(minX, minY, minZ));
     b.include(new Point3(maxX, maxY, maxZ));
     if (b.intersects(box))
     {
         // the box is overlapping or enclosed
         if (!b.contains(new Point3(box.getMinimum().x, box.getMinimum().y, box.getMinimum().z)))
             return true;
         if (!b.contains(new Point3(box.getMinimum().x, box.getMinimum().y, box.getMaximum().z)))
             return true;
         if (!b.contains(new Point3(box.getMinimum().x, box.getMaximum().y, box.getMinimum().z)))
             return true;
         if (!b.contains(new Point3(box.getMinimum().x, box.getMaximum().y, box.getMaximum().z)))
             return true;
         if (!b.contains(new Point3(box.getMaximum().x, box.getMinimum().y, box.getMinimum().z)))
             return true;
         if (!b.contains(new Point3(box.getMaximum().x, box.getMinimum().y, box.getMaximum().z)))
             return true;
         if (!b.contains(new Point3(box.getMaximum().x, box.getMaximum().y, box.getMinimum().z)))
             return true;
         if (!b.contains(new Point3(box.getMaximum().x, box.getMaximum().y, box.getMaximum().z)))
             return true;
         // all vertices of the box are inside - the surface of the box is
         // not intersected
     }
     return false;
 }
Пример #8
0
 /**
  * Transforms each corner of the specified axis-aligned bounding box and
  * returns a new bounding box which incloses the transformed corners.
  *
  * @param b original bounding box
  * @return a new BoundingBox object which encloses the transform version of
  *         b
  */
 public BoundingBox transform(BoundingBox b)
 {
     if (b.isEmpty())
         return new BoundingBox();
     // special case extreme corners
     BoundingBox rb = new BoundingBox(transformP(b.getMinimum()));
     rb.include(transformP(b.getMaximum()));
     // do internal corners
     for (int i = 1; i < 7; i++)
         rb.include(transformP(b.getCorner(i)));
     return rb;
 }