use of org.sunflow.math.BoundingBox in project joons-renderer by joonhyublee.
the class GridPhotonMap method prepare.
@Override
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);
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(Module.LIGHT, "Initializing grid photon map:");
UI.printInfo(Module.LIGHT, " * Resolution: %dx%dx%d", nx, ny, nz);
UI.printInfo(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(Module.LIGHT, " * Initial hash size: %d", cellHash.length);
}
use of org.sunflow.math.BoundingBox in project joons-renderer by joonhyublee.
the class CornellBox method intersects.
public boolean 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;
}
use of org.sunflow.math.BoundingBox in project joons-renderer by joonhyublee.
the class CornellBox method getWorldBounds.
@Override
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);
}
use of org.sunflow.math.BoundingBox in project joons-renderer by joonhyublee.
the class KDTree method build.
@Override
public void build(PrimitiveList primitives) {
UI.printDetailed(Module.ACCEL, "KDTree settings");
UI.printDetailed(Module.ACCEL, " * Max Leaf Size: %d", maxPrims);
UI.printDetailed(Module.ACCEL, " * Max Depth: %d", MAX_DEPTH);
UI.printDetailed(Module.ACCEL, " * Traversal cost: %.2f", TRAVERSAL_COST);
UI.printDetailed(Module.ACCEL, " * Intersect cost: %.2f", INTERSECT_COST);
UI.printDetailed(Module.ACCEL, " * Empty bonus: %.2f", EMPTY_BONUS);
UI.printDetailed(Module.ACCEL, " * Dump leaves: %s", 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();
IntArray tempTree = new IntArray();
IntArray tempList = new IntArray();
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 final arrays
// free some memory
task = null;
tree = tempTree.trim();
tempTree = null;
this.primitives = tempList.trim();
tempList = null;
total.end();
// display some extra info
stats.printStats();
UI.printDetailed(Module.ACCEL, " * Node memory: %s", Memory.sizeof(tree));
UI.printDetailed(Module.ACCEL, " * Object memory: %s", Memory.sizeof(this.primitives));
UI.printDetailed(Module.ACCEL, " * Prepare time: %s", prepare);
UI.printDetailed(Module.ACCEL, " * Sorting time: %s", sorting);
UI.printDetailed(Module.ACCEL, " * Tree creation: %s", t);
UI.printDetailed(Module.ACCEL, " * Build time: %s", total);
if (dump) {
try {
UI.printInfo(Module.ACCEL, "Dumping mtls to %s.mtl ...", dumpPrefix);
FileWriter mtlFile = new FileWriter(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.write(String.format("newmtl mtl%d\n", n));
float[] rgb = nc.getRGB();
mtlFile.write("Ka 0.1 0.1 0.1\n");
mtlFile.write(String.format("Kd %.12g %.12g %.12g\n", rgb[0], rgb[1], rgb[2]));
mtlFile.write("illum 1\n\n");
}
FileWriter objFile = new FileWriter(dumpPrefix + ".obj");
UI.printInfo(Module.ACCEL, "Dumping tree to %s.obj ...", dumpPrefix);
dumpObj(0, 0, maxN, new BoundingBox(bounds), objFile, mtlFile);
objFile.close();
mtlFile.close();
} catch (IOException e) {
Logger.getLogger(KDTree.class.getName()).log(Level.SEVERE, null, e);
}
}
}
Aggregations