예제 #1
0
 public GlobalPhotonMap()
 {
     bounds = new BoundingBox();
     hasRadiance = false;
     maxPower = 0;
     maxRadius = 0;
 }
 public void build(PrimitiveList primitives)
 {
     this.primitives = primitives;
     int n = primitives.getNumPrimitives();
     UI.printDetailed(UI.Module.ACCEL, "Getting bounding box ...");
     bounds = primitives.getWorldBounds(null);
     objects = new int[n];
     for (int i = 0; i < n; i++)
         objects[i] = i;
     UI.printDetailed(UI.Module.ACCEL, "Creating tree ...");
     int initialSize = 3 * (2 * 6 * n + 1);
     List<int> tempTree = new List<int>((initialSize + 3) / 4);
     BuildStats stats = new BuildStats();
     Timer t = new Timer();
     t.start();
     buildHierarchy(tempTree, objects, stats);
     t.end();
     UI.printDetailed(UI.Module.ACCEL, "Trimming tree ...");
     tree = tempTree.ToArray();
     // display stats
     stats.printStats();
     UI.printDetailed(UI.Module.ACCEL, "  * Creation time:  %s", t);
     UI.printDetailed(UI.Module.ACCEL, "  * Usage of init:  %3d%%", 100 * tree.Length / initialSize);
     UI.printDetailed(UI.Module.ACCEL, "  * Tree memory:    %s", Memory.SizeOf(tree));
     UI.printDetailed(UI.Module.ACCEL, "  * Indices memory: %s", Memory.SizeOf(objects));
 }
예제 #3
0
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox(1.5f);
     if (o2w != null)
         bounds = o2w.transform(bounds);
     return bounds;
 }
예제 #4
0
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox();
     foreach (Instance i in instances)
         bounds.include(i.getBounds());
     return bounds;
 }
예제 #5
0
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox();
     if (o2w == null)
     {
         for (int i = 0; i < patches.Length; i++)
         {
             float[] patch = patches[i];
             for (int j = 0; j < patch.Length; j += 3)
                 bounds.include(patch[j], patch[j + 1], patch[j + 2]);
         }
     }
     else
     {
         // transform vertices first
         for (int i = 0; i < patches.Length; i++)
         {
             float[] patch = patches[i];
             for (int j = 0; j < patch.Length; j += 3)
             {
                 float x = patch[j];
                 float y = patch[j + 1];
                 float z = patch[j + 2];
                 float wx = o2w.transformPX(x, y, z);
                 float wy = o2w.transformPY(x, y, z);
                 float wz = o2w.transformPZ(x, y, z);
                 bounds.include(wx, wy, wz);
             }
         }
     }
     return bounds;
 }
예제 #6
0
 public UniformGrid()
 {
     nx = ny = nz = 0;
     bounds = null;
     cells = null;
     voxelwx = voxelwy = voxelwz = 0;
     invVoxelwx = invVoxelwy = invVoxelwz = 0;
 }
예제 #7
0
파일: Box.cs 프로젝트: rzel/sunflowsharp
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox(minX, minY, minZ);
     bounds.include(maxX, maxY, maxZ);
     if (o2w == null)
         return bounds;
     return o2w.transform(bounds);
 }
예제 #8
0
파일: Torus.cs 프로젝트: rzel/sunflowsharp
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox(-ro - ri, -ro - ri, -ri);
     bounds.include(ro + ri, ro + ri, ri);
     if (o2w != null)
         bounds = o2w.transform(bounds);
     return bounds;
 }
예제 #9
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);
 }
예제 #10
0
 public Instance()
 {
     o2w = new MovingMatrix4(null);
     w2o = new MovingMatrix4(null);
     bounds = null;
     geometry = null;
     shaders = null;
     modifiers = null;
 }
예제 #11
0
 public CausticPhotonMap(Options options)
 {
     _numEmit = options.getInt("caustics.emit", 10000);
     gatherNum = options.getInt("caustics.gather", 50);
     gatherRadius = options.getFloat("caustics.radius", 0.5f);
     filterValue = options.getFloat("caustics.filter", 1.1f);
     bounds = new BoundingBox();
     maxPower = 0;
     maxRadius = 0;
 }
예제 #12
0
 public GlobalPhotonMap(int numEmit, int numGather, float gatherRadius)
 {
     this._numEmit = numEmit;
     this.numGather = numGather;
     this.gatherRadius = gatherRadius;
     bounds = new BoundingBox();
     hasRadiance = false;
     maxPower = 0;
     maxRadius = 0;
 }
예제 #13
0
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox();
     if (o2w == null)
     {
         for (int i = 0; i < points.Length; i += 3)
             bounds.include(points[i], points[i + 1], points[i + 2]);
     }
     else
     {
         // transform vertices first
         for (int i = 0; i < points.Length; i += 3)
         {
             float x = points[i];
             float y = points[i + 1];
             float z = points[i + 2];
             float wx = o2w.transformPX(x, y, z);
             float wy = o2w.transformPY(x, y, z);
             float wz = o2w.transformPZ(x, y, z);
             bounds.include(wx, wy, wz);
         }
     }
     return bounds;
 }
예제 #14
0
 public void prepare(Options options, BoundingBox sceneBounds)
 {
     // get settings
     _numEmit = options.getInt("gi.irr-cache.gmap.emit", 100000);
     numGather = options.getInt("gi.irr-cache.gmap.gather", 50);
     gatherRadius = options.getFloat("gi.irr-cache.gmap.radius", 0.5f);
     // init
     bounds = new BoundingBox(sceneBounds);
     bounds.enlargeUlps();
     Vector3 w = bounds.getExtents();
     nx = (int)Math.Max(((w.x / gatherRadius) + 0.5f), 1);
     ny = (int)Math.Max(((w.y / gatherRadius) + 0.5f), 1);
     nz = (int)Math.Max(((w.z / gatherRadius) + 0.5f), 1);
     int numCells = nx * ny * nz;
     UI.printInfo(UI.Module.LIGHT, "Initializing grid photon map:");
     UI.printInfo(UI.Module.LIGHT, "  * Resolution:  {0}x{1}x{2}", nx, ny, nz);
     UI.printInfo(UI.Module.LIGHT, "  * Total cells: {0}", numCells);
     for (hashPrime = 0; hashPrime < PRIMES.Length; hashPrime++)
         if (PRIMES[hashPrime] > (numCells / 5))
             break;
     cellHash = new PhotonGroup[PRIMES[hashPrime]];
     UI.printInfo(UI.Module.LIGHT, "  * Initial hash size: {0}", cellHash.Length);
 }
예제 #15
0
 /**
  * Returns <code>true</code> if the specified bounding box intersects this
  * one. The boxes are treated as volumes, so a box inside another will
  * return true. Returns <code>false</code> if the parameter is
  * <code>null</code>.
  *
  * @param b box to be tested for intersection
  * @return <code>true</code> if the boxes overlap, <code>false</code>
  *         otherwise
  */
 public bool intersects(BoundingBox b)
 {
     return((b != null) && (minimum.x <= b.maximum.x) && (maximum.x >= b.minimum.x) && (minimum.y <= b.maximum.y) && (maximum.y >= b.minimum.y) && (minimum.z <= b.maximum.z) && (maximum.z >= b.minimum.z));
 }
예제 #16
0
 /**
  * Recompute world space bounding box of this instance.
  */
 public void updateBounds()
 {
     bounds = geometry.getWorldBounds(o2w.getData(0));
     for (int i = 1; i < o2w.numSegments(); i++)
         bounds.include(geometry.getWorldBounds(o2w.getData(i)));
 }
예제 #17
0
 /**
  * Creates a copy of the given box.
  *
  * @param b bounding box to copy
  */
 public BoundingBox(BoundingBox b)
 {
     minimum = new Point3(b.minimum);
     maximum = new Point3(b.maximum);
 }
예제 #18
0
 public void prepare(BoundingBox sceneBounds)
 {
     bounds = new BoundingBox(sceneBounds);
     bounds.enlargeUlps();
     Vector3 w = bounds.getExtents();
     nx = (int)Math.Max(((w.x / gatherRadius) + 0.5f), 1);
     ny = (int)Math.Max(((w.y / gatherRadius) + 0.5f), 1);
     nz = (int)Math.Max(((w.z / gatherRadius) + 0.5f), 1);
     int numCells = nx * ny * nz;
     UI.printInfo(UI.Module.LIGHT, "Initializing grid photon map:");
     UI.printInfo(UI.Module.LIGHT, "  * Resolution:  %dx%dx%d", nx, ny, nz);
     UI.printInfo(UI.Module.LIGHT, "  * Total cells: %d", numCells);
     for (hashPrime = 0; hashPrime < PRIMES.Length; hashPrime++)
         if (PRIMES[hashPrime] > (numCells / 5))
             break;
     cellHash = new PhotonGroup[PRIMES[hashPrime]];
     UI.printInfo(UI.Module.LIGHT, "  * Initial hash size: %d", cellHash.Length);
 }
예제 #19
0
 public void prepare(BoundingBox sceneBounds)
 {
     photonList = new List<Photon>();
     photonList.Add(null);
     photons = null;
     storedPhotons = halfStoredPhotons = 0;
 }
예제 #20
0
파일: Box.cs 프로젝트: rzel/sunflowsharp
 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;
 }
예제 #21
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;
     }
 }
예제 #22
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);
         }
     }
 }
예제 #23
0
 /**
  * Returns <code>true</code> if the specified bounding box intersects this
  * one. The boxes are treated as volumes, so a box inside another will
  * return true. Returns <code>false</code> if the parameter is
  * <code>null</code>.
  *
  * @param b box to be tested for intersection
  * @return <code>true</code> if the boxes overlap, <code>false</code>
  *         otherwise
  */
 public bool intersects(BoundingBox b)
 {
     return ((b != null) && (minimum.x <= b.maximum.x) && (maximum.x >= b.minimum.x) && (minimum.y <= b.maximum.y) && (maximum.y >= b.minimum.y) && (minimum.z <= b.maximum.z) && (maximum.z >= b.minimum.z));
 }
예제 #24
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);
        }
예제 #25
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;
 }
예제 #26
0
 /**
  * Creates a copy of the given box.
  *
  * @param b bounding box to copy
  */
 public BoundingBox(BoundingBox b)
 {
     minimum = new Point3(b.minimum);
     maximum = new Point3(b.maximum);
 }
예제 #27
0
 public CubeGrid()
 {
     nx = ny = nz = 1;
     bounds = new BoundingBox(1);
 }
예제 #28
0
 /**
  * Changes the extents of the box as needed to include the given box into
  * this box. Does nothing if the parameter is <code>null</code>.
  *
  * @param b box to be included
  */
 public void include(BoundingBox b)
 {
     if (b != null)
     {
         if (b.minimum.x < minimum.x)
             minimum.x = b.minimum.x;
         if (b.maximum.x > maximum.x)
             maximum.x = b.maximum.x;
         if (b.minimum.y < minimum.y)
             minimum.y = b.minimum.y;
         if (b.maximum.y > maximum.y)
             maximum.y = b.maximum.y;
         if (b.minimum.z < minimum.z)
             minimum.z = b.minimum.z;
         if (b.maximum.z > maximum.z)
             maximum.z = b.maximum.z;
     }
 }
예제 #29
0
 public void build(PrimitiveList primitives)
 {
     Timer t = new Timer();
     t.start();
     this.primitives = primitives;
     int n = primitives.getNumPrimitives();
     // compute bounds
     bounds = primitives.getWorldBounds(null);
     // create grid from number of objects
     bounds.enlargeUlps();
     Vector3 w = bounds.getExtents();
     double s = Math.Pow((w.x * w.y * w.z) / n, 1 / 3.0);
     nx = MathUtils.clamp((int)((w.x / s) + 0.5), 1, 128);
     ny = MathUtils.clamp((int)((w.y / s) + 0.5), 1, 128);
     nz = MathUtils.clamp((int)((w.z / s) + 0.5), 1, 128);
     voxelwx = w.x / nx;
     voxelwy = w.y / ny;
     voxelwz = w.z / nz;
     invVoxelwx = 1 / voxelwx;
     invVoxelwy = 1 / voxelwy;
     invVoxelwz = 1 / voxelwz;
     UI.printDetailed(UI.Module.ACCEL, "Creating grid: %dx%dx%d ...", nx, ny, nz);
     List<int>[] buildCells = new List<int>[nx * ny * nz];
     // add all objects into the grid cells they overlap
     int[] imin = new int[3];
     int[] imax = new int[3];
     int numCellsPerObject = 0;
     for (int i = 0; i < n; i++)
     {
         getGridIndex(primitives.getPrimitiveBound(i, 0), primitives.getPrimitiveBound(i, 2), primitives.getPrimitiveBound(i, 4), imin);
         getGridIndex(primitives.getPrimitiveBound(i, 1), primitives.getPrimitiveBound(i, 3), primitives.getPrimitiveBound(i, 5), imax);
         for (int ix = imin[0]; ix <= imax[0]; ix++)
         {
             for (int iy = imin[1]; iy <= imax[1]; iy++)
             {
                 for (int iz = imin[2]; iz <= imax[2]; iz++)
                 {
                     int idx = ix + (nx * iy) + (nx * ny * iz);
                     if (buildCells[idx] == null)
                         buildCells[idx] = new List<int>();
                     buildCells[idx].Add(i);
                     numCellsPerObject++;
                 }
             }
         }
     }
     UI.printDetailed(UI.Module.ACCEL, "Building cells ...");
     int numEmpty = 0;
     int numInFull = 0;
     cells = new int[nx * ny * nz][];
     //int i = 0;
     //foreach (List<int> cell in buildCells)
     for (int i = 0; i < buildCells.Length; i++)
     {
         if (buildCells[i] != null)
         {
             if (buildCells[i].Count == 0)
             {
                 numEmpty++;
                 buildCells[i] = null;
             }
             else
             {
                 cells[i] = buildCells[i].ToArray();
                 numInFull += buildCells[i].Count;
             }
         }
         else
             numEmpty++;
         //i++;
     }
     t.end();
     UI.printDetailed(UI.Module.ACCEL, "Uniform grid statistics:");
     UI.printDetailed(UI.Module.ACCEL, "  * Grid cells:          {0}", cells.Length);
     UI.printDetailed(UI.Module.ACCEL, "  * Used cells:          {0}", cells.Length - numEmpty);
     UI.printDetailed(UI.Module.ACCEL, "  * Empty cells:         {0}", numEmpty);
     UI.printDetailed(UI.Module.ACCEL, "  * Occupancy:           {0}", 100.0 * (cells.Length - numEmpty) / cells.Length);
     UI.printDetailed(UI.Module.ACCEL, "  * Objects/Cell:        {0}", (double)numInFull / (double)cells.Length);
     UI.printDetailed(UI.Module.ACCEL, "  * Objects/Used Cell:   {0}", (double)numInFull / (double)(cells.Length - numEmpty));
     UI.printDetailed(UI.Module.ACCEL, "  * Cells/Object:        {0}", (double)numCellsPerObject / (double)n);
     UI.printDetailed(UI.Module.ACCEL, "  * Build time:          {0}", t.ToString());
 }
예제 #30
0
 public void prepare(BoundingBox sceneBounds)
 {
 }
예제 #31
0
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox(getPrimitiveBound(0, 1));
     if (o2w != null)
         bounds = o2w.transform(bounds);
     return bounds;
 }
예제 #32
0
 public BoundingBox getWorldBounds(Matrix4 o2w)
 {
     BoundingBox bounds = new BoundingBox();
     if (o2w == null)
     {
         for (int i = 0; i < triangleMesh.uvs.data.Length; i += 2)
             bounds.include(triangleMesh.uvs.data[i], triangleMesh.uvs.data[i + 1], 0);
     }
     else
     {
         // transform vertices first
         for (int i = 0; i < triangleMesh.uvs.data.Length; i += 2)
         {
             float x = triangleMesh.uvs.data[i];
             float y = triangleMesh.uvs.data[i + 1];
             float wx = o2w.transformPX(x, y, 0);
             float wy = o2w.transformPY(x, y, 0);
             float wz = o2w.transformPZ(x, y, 0);
             bounds.include(wx, wy, wz);
         }
     }
     return bounds;
 }