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); }
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); }
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()); }
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); }