private void build() { lock (lockObj) { // double check flag if (builtAccel != 0) { return; } if (primitives != null) { int n = primitives.getNumPrimitives(); if (n >= 1000) { UI.printInfo(UI.Module.GEOM, "Building acceleration structure for {0} primitives ...", n); } accel = AccelerationStructureFactory.create(acceltype, n, true); accel.build(primitives); } else { // create an empty accelerator to avoid having to check for null // pointers in the intersect method accel = new NullAccelerator(); } builtAccel = 1; } }
/** * Render the scene using the specified options, image sampler and display. * * @param options rendering options object * @param sampler image sampler * @param display display to send the image to, a default display will * be created if <code>null</code> */ public void render(Options options, ImageSampler sampler, IDisplay display) { stats.reset(); if (display == null) { display = null;// new FrameDisplay(); } if (bakingInstance != null) { UI.printDetailed(UI.Module.SCENE, "Creating primitives for lightmapping ..."); bakingPrimitives = bakingInstance.getBakingPrimitives(); if (bakingPrimitives == null) { UI.printError(UI.Module.SCENE, "Lightmap baking is not supported for the given instance."); return; } int n = bakingPrimitives.getNumPrimitives(); UI.printInfo(UI.Module.SCENE, "Building acceleration structure for lightmapping ({0} num primitives) ...", n); bakingAccel = AccelerationStructureFactory.create("auto", n, true); bakingAccel.build(bakingPrimitives); } else { bakingPrimitives = null; bakingAccel = null; } bakingViewDependent = options.getbool("baking.viewdep", bakingViewDependent); if ((bakingInstance != null && bakingViewDependent && camera == null) || (bakingInstance == null && camera == null)) { UI.printError(UI.Module.SCENE, "No camera found"); return; } // read from options threads = options.getInt("threads", 0); lowPriority = options.getbool("threads.lowPriority", true); imageWidth = options.getInt("resolutionX", 640); imageHeight = options.getInt("resolutionY", 480); // limit resolution to 16k imageWidth = MathUtils.clamp(imageWidth, 1, 1 << 14); imageHeight = MathUtils.clamp(imageHeight, 1, 1 << 14); // prepare lights createAreaLightInstances(); // get acceleration structure info // count scene primitives long numPrimitives = 0; for (int i = 0; i < instanceList.getNumPrimitives(); i++) { numPrimitives += instanceList.getNumPrimitives(i); } UI.printInfo(UI.Module.SCENE, "Scene stats:"); UI.printInfo(UI.Module.SCENE, " * Infinite instances: {0}", infiniteInstanceList.getNumPrimitives()); UI.printInfo(UI.Module.SCENE, " * Instances: {0}", instanceList.getNumPrimitives()); UI.printInfo(UI.Module.SCENE, " * Primitives: {0}", numPrimitives); string accelName = options.getstring("accel", null); if (accelName != null) { rebuildAccel = rebuildAccel || acceltype != accelName; acceltype = accelName; } UI.printInfo(UI.Module.SCENE, " * Instance accel: {0}", acceltype); if (rebuildAccel) { intAccel = AccelerationStructureFactory.create(acceltype, instanceList.getNumPrimitives(), false); intAccel.build(instanceList); rebuildAccel = false; } UI.printInfo(UI.Module.SCENE, " * Scene bounds: {0}", getBounds()); UI.printInfo(UI.Module.SCENE, " * Scene center: {0}", getBounds().getCenter()); UI.printInfo(UI.Module.SCENE, " * Scene diameter: {0}", getBounds().getExtents().Length()); UI.printInfo(UI.Module.SCENE, " * Lightmap bake: {0}", bakingInstance != null ? (bakingViewDependent ? "view" : "ortho") : "off"); if (sampler == null) { return; } if (!lightServer.build(options)) { return; } // render UI.printInfo(UI.Module.SCENE, "Rendering ..."); stats.setResolution(imageWidth, imageHeight); sampler.prepare(options, this, imageWidth, imageHeight); sampler.render(display); // show statistics stats.displayStats(); lightServer.showStats(); // discard area lights removeAreaLightInstances(); // discard baking tesselation/accel structure bakingPrimitives = null; bakingAccel = null; UI.printInfo(UI.Module.SCENE, "Done."); }