예제 #1
0
 public void render(IDisplay display)
 {
     this.display = display;
     display.imageBegin(imageWidth, imageHeight, 32);
     // set members variables
     bucketCounter = 0;
     // start task
     SunflowSharp.Systems.Timer timer = new SunflowSharp.Systems.Timer();
     timer.start();
     BucketThread[] renderThreads = new BucketThread[scene.getThreads()];
     for (int i = 0; i < renderThreads.Length; i++)
     {
         renderThreads[i] = new BucketThread(this);
         renderThreads[i].setPriority(scene.getThreadPriority());
         renderThreads[i].start();
     }
     for (int i = 0; i < renderThreads.Length; i++)
     {
         try
         {
             renderThreads[i].join();
         }
         catch (Exception e)
         {
             UI.printError(UI.Module.BCKT, "Bucket processing thread {0} of {1} was interrupted", i + 1, renderThreads.Length);
         }
     }
     timer.end();
     UI.printInfo(UI.Module.BCKT, "Render time: {0}", timer.ToString());
     display.imageEnd();
 }
예제 #2
0
 public void render(IDisplay display)
 {
     this.display = display;
     display.imageBegin(imageWidth, imageHeight, 32);
     // set members variables
     bucketCounter = 0;
     // start task
     SunflowSharp.Systems.Timer timer = new SunflowSharp.Systems.Timer();
     timer.start();
     BucketThread[] renderThreads = new BucketThread[scene.getThreads()];
     for (int i = 0; i < renderThreads.Length; i++)
     {
         renderThreads[i] = new BucketThread(this);
         renderThreads[i].setPriority(scene.getThreadPriority());
         renderThreads[i].start();
     }
     for (int i = 0; i < renderThreads.Length; i++)
     {
         try
         {
             renderThreads[i].join();
         }
         catch (Exception e)
         {
             UI.printError(UI.Module.BCKT, "Bucket processing thread {0} of {1} was interrupted", i + 1, renderThreads.Length);
         }
         finally
         {
             renderThreads[i].updateStats();
         }
     }
     timer.end();
     UI.printInfo(UI.Module.BCKT, "Render time: {0}", timer.ToString());
     display.imageEnd();
 }
 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));
 }
예제 #4
0
 public FastDisplay()
 {
     image = null;
     frame = null;
     t = new Timer();
     frames = 0;
     seconds = 0;
 }
예제 #5
0
 public RealtimeBenchmark(bool showGUI, int threads)
 {
     IDisplay display = /*showGUI ? new FastDisplay() :*/ new FileDisplay(false);
     UI.printInfo(UI.Module.BENCH, "Preparing benchmarking scene ...");
     // settings
     parameter("threads", threads);
     // spawn regular priority threads
     parameter("threads.lowPriority", false);
     parameter("resolutionX", 512);
     parameter("resolutionY", 512);
     parameter("aa.min", -3);
     parameter("aa.max", 0);
     parameter("depths.diffuse", 1);
     parameter("depths.reflection", 1);
     parameter("depths.refraction", 0);
     parameter("bucket.order", "hilbert");
     parameter("bucket.size", 32);
     options(SunflowAPI.DEFAULT_OPTIONS);
     // camera
     Point3 eye = new Point3(30, 0, 10.967f);
     Point3 target = new Point3(0, 0, 5.4f);
     Vector3 up = new Vector3(0, 0, 1);
     parameter("transform", Matrix4.lookAt(eye, target, up));
     parameter("fov", 45.0f);
     camera("camera", "pinhole");
     parameter("camera", "camera");
     options(SunflowAPI.DEFAULT_OPTIONS);
     // geometry
     createGeometry();
     // this first render is not timed, it caches the acceleration data
     // structures and tesselations so they won't be
     // included in the main timing
     UI.printInfo(UI.Module.BENCH, "Rendering warmup frame ...");
     render(SunflowAPI.DEFAULT_OPTIONS, display);
     // now disable all output - and run the benchmark
     UI.set(null);
     Timer t = new Timer();
     t.start();
     float phi = 0;
     int frames = 0;
     while (phi < 4 * Math.PI)
     {
         eye.x = 30 * (float)Math.Cos(phi);
         eye.y = 30 * (float)Math.Sin(phi);
         phi += (float)(Math.PI / 30);
         frames++;
         // update camera
         parameter("transform", Matrix4.lookAt(eye, target, up));
         camera("camera", null);
         render(SunflowAPI.DEFAULT_OPTIONS, display);
     }
     t.end();
     UI.set(new ConsoleInterface());
     UI.printInfo(UI.Module.BENCH, "Benchmark results:");
     UI.printInfo(UI.Module.BENCH, "  * Average FPS:         {0,6:0.00", frames / t.seconds());
     UI.printInfo(UI.Module.BENCH, "  * Total time:          {0}", t);
 }
예제 #6
0
        public bool build(Options options)
        {
            // read options
            maxDiffuseDepth    = options.getInt("depths.diffuse", maxDiffuseDepth);
            maxReflectionDepth = options.getInt("depths.reflection", maxReflectionDepth);
            maxRefractionDepth = options.getInt("depths.refraction", maxRefractionDepth);
            string giEngineType = options.getstring("gi.engine", null);

            giEngine = PluginRegistry.giEnginePlugins.createObject(giEngineType);
            string caustics = options.getstring("caustics", null);

            causticPhotonMap = PluginRegistry.causticPhotonMapPlugins.createObject(caustics);

            // validate options
            maxDiffuseDepth    = Math.Max(0, maxDiffuseDepth);
            maxReflectionDepth = Math.Max(0, maxReflectionDepth);
            maxRefractionDepth = Math.Max(0, maxRefractionDepth);

            SunflowSharp.Systems.Timer t = new SunflowSharp.Systems.Timer();
            t.start();
            // count total number of light samples
            int numLightSamples = 0;

            for (int i = 0; i < lights.Length; i++)
            {
                numLightSamples += lights[i].getNumSamples();
            }
            // initialize gi engine
            if (giEngine != null)
            {
                if (!giEngine.init(options, scene))
                {
                    return(false);
                }
            }

            if (!calculatePhotons(causticPhotonMap, "caustic", 0, options))
            {
                return(false);
            }
            t.end();

            UI.printInfo(UI.Module.LIGHT, "Light Server stats:");
            UI.printInfo(UI.Module.LIGHT, "  * Light sources found: {0}", lights.Length);
            UI.printInfo(UI.Module.LIGHT, "  * Light samples:       {0}", numLightSamples);
            UI.printInfo(UI.Module.LIGHT, "  * Max raytrace depth:");
            UI.printInfo(UI.Module.LIGHT, "      - Diffuse          {0}", maxDiffuseDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Reflection       {0}", maxReflectionDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Refraction       {0}", maxRefractionDepth);
            UI.printInfo(UI.Module.LIGHT, "  * GI engine            {0}", giEngineType == null ? "none" : giEngineType);
            UI.printInfo(UI.Module.LIGHT, "  * Caustics:            {0}", caustics == null ? "none" : caustics);
            UI.printInfo(UI.Module.LIGHT, "  * Shader override:     {0}", shaderOverride);
            UI.printInfo(UI.Module.LIGHT, "  * Photon override:     {0}", shaderOverridePhotons);
            UI.printInfo(UI.Module.LIGHT, "  * Build time:          {0}", t.ToString());
            return(true);
        }
예제 #7
0
 public void execute(BenchmarkTest test)
 {
     // clear previous results
     for (int i = 0; i < timers.Length; i++)
         timers[i] = null;
     // loop for the specified number of iterations or until the time limit
     long startTime = NanoTime.Now;
     for (int i = 0; i < timers.Length && ((NanoTime.Now - startTime) / 1000000000) < timeLimit; i++)
     {
         UI.printInfo(UI.Module.BENCH, "Running iteration {0}", (i + 1));
         timers[i] = new Timer();
         test.kernelBegin();
         timers[i].start();
         test.kernelMain();
         timers[i].end();
         test.kernelEnd();
     }
     // report stats
     double avg = 0;
     double min = double.PositiveInfinity;
     double max = double.NegativeInfinity;
     int n = 0;
     foreach (Timer t in timers)
     {
         if (t == null)
             break;
         double s = t.seconds();
         min = Math.Min(min, s);
         max = Math.Max(max, s);
         avg += s;
         n++;
     }
     if (n == 0)
         return;
     avg /= n;
     double stdDev = 0;
     foreach (Timer t in timers)
     {
         if (t == null)
             break;
         double s = t.seconds();
         stdDev += (s - avg) * (s - avg);
     }
     stdDev = Math.Sqrt(stdDev / n);
     UI.printInfo(UI.Module.BENCH, "Benchmark results:");
     UI.printInfo(UI.Module.BENCH, "  * Iterations: {0}", n);
     UI.printInfo(UI.Module.BENCH, "  * Average:    {0}", Timer.tostring(avg));
     UI.printInfo(UI.Module.BENCH, "  * Fastest:    {0}", Timer.tostring(min));
     UI.printInfo(UI.Module.BENCH, "  * Longest:    {0}", Timer.tostring(max));
     UI.printInfo(UI.Module.BENCH, "  * Deviation:  {0}", Timer.tostring(stdDev));
     for (int i = 0; i < timers.Length && timers[i] != null; i++)
         UI.printDetailed(UI.Module.BENCH, "  * Iteration {0}: {1}", i + 1, timers[i]);
 }
예제 #8
0
        public void render(IDisplay display)
        {
            this.display = display;
            display.imageBegin(imageWidth, imageHeight, 0);
            // create first bucket
            SmallBucket b = new SmallBucket();

            b.x = b.y = 0;
            int s = Math.Max(imageWidth, imageHeight);

            b.size = 1;
            while (b.size < s)
            {
                b.size <<= 1;
            }
            smallBucketQueue = new Queue <SmallBucket>();//PriorityBlockingQueue<SmallBucket>();
            smallBucketQueue.Enqueue(b);
            UI.taskStart("Progressive Render", 0, imageWidth * imageHeight);
            SunflowSharp.Systems.Timer t = new SunflowSharp.Systems.Timer();
            t.start();
            counter    = 0;
            counterMax = imageWidth * imageHeight;

            SmallBucketThread[] renderThreads = new SmallBucketThread[scene.getThreads()];
            for (int i = 0; i < renderThreads.Length; i++)
            {
                renderThreads[i] = new SmallBucketThread(this);
                renderThreads[i].setPriority(scene.getThreadPriority());
                renderThreads[i].start();
            }
            for (int i = 0; i < renderThreads.Length; i++)
            {
                try
                {
                    renderThreads[i].join();
                }
                catch (Exception e)
                {
                    UI.printError(UI.Module.IPR, "Thread {0} of {1} was interrupted", i + 1, renderThreads.Length);
                }
                finally
                {
                    renderThreads[i].updateStats();
                }
            }
            UI.taskStop();
            t.end();
            UI.printInfo(UI.Module.IPR, "Rendering time: {0}", t.ToString());
            display.imageEnd();
        }
예제 #9
0
        public bool build(Options options)
        {
            // read options
            maxDiffuseDepth = options.getInt("depths.diffuse", maxDiffuseDepth);
            maxReflectionDepth = options.getInt("depths.reflection", maxReflectionDepth);
            maxRefractionDepth = options.getInt("depths.refraction", maxRefractionDepth);
            string giEngineType = options.getstring("gi.engine", null);
            giEngine = PluginRegistry.giEnginePlugins.createObject(giEngineType);
            string caustics = options.getstring("caustics", null);
            causticPhotonMap = PluginRegistry.causticPhotonMapPlugins.createObject(caustics);

            // validate options
            maxDiffuseDepth = Math.Max(0, maxDiffuseDepth);
            maxReflectionDepth = Math.Max(0, maxReflectionDepth);
            maxRefractionDepth = Math.Max(0, maxRefractionDepth);

            SunflowSharp.Systems.Timer t = new SunflowSharp.Systems.Timer();
            t.start();
            // count total number of light samples
            int numLightSamples = 0;
            for (int i = 0; i < lights.Length; i++)
                numLightSamples += lights[i].getNumSamples();
            // initialize gi engine
            if (giEngine != null)
            {
                if (!giEngine.init(options, scene))
                    return false;
            }

            if (!calculatePhotons(causticPhotonMap, "caustic", 0, options))
                return false;
            t.end();

            UI.printInfo(UI.Module.LIGHT, "Light Server stats:");
            UI.printInfo(UI.Module.LIGHT, "  * Light sources found: {0}", lights.Length);
            UI.printInfo(UI.Module.LIGHT, "  * Light samples:       {0}", numLightSamples);
            UI.printInfo(UI.Module.LIGHT, "  * Max raytrace depth:");
            UI.printInfo(UI.Module.LIGHT, "      - Diffuse          {0}", maxDiffuseDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Reflection       {0}", maxReflectionDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Refraction       {0}", maxRefractionDepth);
            UI.printInfo(UI.Module.LIGHT, "  * GI engine            {0}", giEngineType == null ? "none" : giEngineType);
            UI.printInfo(UI.Module.LIGHT, "  * Caustics:            {0}", caustics == null ? "none" : caustics);
            UI.printInfo(UI.Module.LIGHT, "  * Shader override:     {0}", shaderOverride);
            UI.printInfo(UI.Module.LIGHT, "  * Photon override:     {0}", shaderOverridePhotons);
            UI.printInfo(UI.Module.LIGHT, "  * Build time:          {0}", t.ToString());
            return true;
        }
예제 #10
0
 /**
  * Compile the specified code string via Janino. The code must implement a
  * build method as described above. The build method is not called on the
  * output, it is up the caller to do so.
  *
  * @param code java code string
  * @return a valid SunflowAPI object upon succes, <code>null</code>
  *         otherwise.
  */
 public static SunflowAPI compile(string code)
 {
     try
     {
         Timer t = new Timer();
         t.start();
         SunflowAPI api = null;//(SunflowAPI) ClassBodyEvaluator.createFastClassBodyEvaluator(new Scanner(null, new stringReader(code)), SunflowAPI.class, (ClassLoader) null);
         //fixme: the dynamic loading
         t.end();
         UI.printInfo(UI.Module.API, "Compile time: {0}", t.ToString());
         return api;
     }
     catch (Exception e)
     {
         UI.printError(UI.Module.API, "{0}", e);
         return null;
     }
 }
예제 #11
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());
 }
예제 #12
0
 public bool calculatePhotons(PhotonStore map, string type, int seed, Options options)
 {
     if (map == null)
         return true;
     if (lights.Length == 0)
     {
         UI.printError(UI.Module.LIGHT, "Unable to trace {0} photons, no lights in scene", type);
         return false;
     }
     float[] histogram = new float[lights.Length];
     histogram[0] = lights[0].getPower();
     for (int i = 1; i < lights.Length; i++)
         histogram[i] = histogram[i - 1] + lights[i].getPower();
     UI.printInfo(UI.Module.LIGHT, "Tracing {0} photons ...", type);
     map.prepare(options, scene.getBounds());
     int numEmittedPhotons = map.numEmit();
     if (numEmittedPhotons <= 0 || histogram[histogram.Length - 1] <= 0)
     {
         UI.printError(UI.Module.LIGHT, "Photon mapping enabled, but no {0} photons to emit", type);
         return false;
     }
     UI.taskStart("Tracing " + type + " photons", 0, numEmittedPhotons);
     Thread[] photonThreads = new Thread[scene.getThreads()];
     float scale = 1.0f / numEmittedPhotons;
     int delta = numEmittedPhotons / photonThreads.Length;
     photonCounter = 0;
     SunflowSharp.Systems.Timer photonTimer = new SunflowSharp.Systems.Timer();
     photonTimer.start();
     for (int i = 0; i < photonThreads.Length; i++)
     {
         int threadID = i;
         int start = threadID * delta;
         int end = (threadID == (photonThreads.Length - 1)) ? numEmittedPhotons : (threadID + 1) * delta;
         photonThreads[i] = new Thread(new ThreadStart(new CalculatePhotons(start, end, this, seed, histogram, scale, map, lockObj).Run));
         photonThreads[i].Priority = scene.getThreadPriority();
         photonThreads[i].Start();
     }
     for (int i = 0; i < photonThreads.Length; i++)
     {
         try
         {
             photonThreads[i].Join();
         }
         catch (Exception e)
         {
             UI.printError(UI.Module.LIGHT, "Photon thread {0} of {1} was interrupted", i + 1, photonThreads.Length);
             return false;
         }
     }
     if (UI.taskCanceled())
     {
         UI.taskStop(); // shut down task cleanly
         return false;
     }
     photonTimer.end();
     UI.taskStop();
     UI.printInfo(UI.Module.LIGHT, "Tracing time for {0} photons: {1}", type, photonTimer.ToString());
     map.init();
     return true;
 }
예제 #13
0
 public static string tostring(double seconds)
 {
     Timer t = new Timer();
     t.endTime = (long)(seconds * 1e9);
     return t.ToString();
 }
예제 #14
0
 public static string tostring(long nanos)
 {
     Timer t = new Timer();
     t.endTime = nanos;
     return t.ToString();
 }
예제 #15
0
 public void init()
 {
     UI.printInfo(UI.Module.LIGHT, "Balancing caustics photon map ...");
     Timer t = new Timer();
     t.start();
     balance();
     t.end();
     UI.printInfo(UI.Module.LIGHT, "Caustic photon map:");
     UI.printInfo(UI.Module.LIGHT, "  * Photons stored:   %d", storedPhotons);
     UI.printInfo(UI.Module.LIGHT, "  * Photons/estimate: %d", gatherNum);
     maxRadius = 1.4f * (float)Math.Sqrt(maxPower * gatherNum);
     UI.printInfo(UI.Module.LIGHT, "  * Estimate radius:  %.3f", gatherRadius);
     UI.printInfo(UI.Module.LIGHT, "  * Maximum radius:   %.3f", maxRadius);
     UI.printInfo(UI.Module.LIGHT, "  * Balancing time:   %s", t.ToString());
     if (gatherRadius > maxRadius)
         gatherRadius = maxRadius;
 }
예제 #16
0
 public void init()
 {
     UI.printInfo(UI.Module.LIGHT, "Balancing global photon map ...");
     UI.taskStart("Balancing global photon map", 0, 1);
     Timer t = new Timer();
     t.start();
     balance();
     t.end();
     UI.taskStop();
     UI.printInfo(UI.Module.LIGHT, "Global photon map:");
     UI.printInfo(UI.Module.LIGHT, "  * Photons stored:   %d", storedPhotons);
     UI.printInfo(UI.Module.LIGHT, "  * Photons/estimate: %d", numGather);
     UI.printInfo(UI.Module.LIGHT, "  * Estimate radius:  %.3f", gatherRadius);
     maxRadius = 1.4f * (float)Math.Sqrt(maxPower * numGather);
     UI.printInfo(UI.Module.LIGHT, "  * Maximum radius:   %.3f", maxRadius);
     UI.printInfo(UI.Module.LIGHT, "  * Balancing time:   %s", t.ToString());
     if (gatherRadius > maxRadius)
         gatherRadius = maxRadius;
     t.start();
     precomputeRadiance();
     t.end();
     UI.printInfo(UI.Module.LIGHT, "  * Precompute time:  %s", t.ToString());
     UI.printInfo(UI.Module.LIGHT, "  * Radiance photons: %d", storedPhotons);
     UI.printInfo(UI.Module.LIGHT, "  * Search radius:    %.3f", gatherRadius);
 }
예제 #17
0
 public override bool parse(Stream stream, SunflowAPI api)
 {
     //string localDir = Path.GetFullPath(filename);
     numLightSamples = 1;
     Timer timer = new Timer();
     timer.start();
     UI.printInfo(UI.Module.API, "Parsing stream ...");
     try
     {
         p = new Systems.Parser(stream);
         while (true)
         {
             string token = p.getNextToken();
             if (token == null)
                 break;
             if (token == "image")
             {
                 UI.printInfo(UI.Module.API, "Reading image settings ...");
                 parseImageBlock(api);
             }
             else if (token == "background")
             {
                 UI.printInfo(UI.Module.API, "Reading background ...");
                 parseBackgroundBlock(api);
             }
             else if (token == "accel")
             {
                 UI.printInfo(UI.Module.API, "Reading accelerator type ...");
                 p.getNextToken();
                 UI.printWarning(UI.Module.API, "Setting accelerator type is not recommended - ignoring");
             }
             else if (token == "filter")
             {
                 UI.printInfo(UI.Module.API, "Reading image filter type ...");
                 parseFilter(api);
             }
             else if (token == "bucket")
             {
                 UI.printInfo(UI.Module.API, "Reading bucket settings ...");
                 api.parameter("bucket.size", p.getNextInt());
                 api.parameter("bucket.order", p.getNextToken());
                 api.options(SunflowAPI.DEFAULT_OPTIONS);
             }
             else if (token == "photons")
             {
                 UI.printInfo(UI.Module.API, "Reading photon settings ...");
                 parsePhotonBlock(api);
             }
             else if (token == "gi")
             {
                 UI.printInfo(UI.Module.API, "Reading global illumination settings ...");
                 parseGIBlock(api);
             }
             else if (token == "lightserver")
             {
                 UI.printInfo(UI.Module.API, "Reading light server settings ...");
                 parseLightserverBlock(api);
             }
             else if (token == "trace-depths")
             {
                 UI.printInfo(UI.Module.API, "Reading trace depths ...");
                 parseTraceBlock(api);
             }
             else if (token == "camera")
             {
                 parseCamera(api);
             }
             else if (token == "shader")
             {
                 if (!parseShader(api))
                     return false;
             }
             else if (token == "modifier")
             {
                 if (!parseModifier(api))
                     return false;
             }
             else if (token == "override")
             {
     api.parameter("override.shader", p.getNextToken());
     api.parameter("override.photons", p.getNextbool());
     api.options(SunflowAPI.DEFAULT_OPTIONS);
             }
             else if (token == "object")
             {
                 parseObjectBlock(api);
             }
             else if (token == "instance")
             {
                 parseInstanceBlock(api);
             }
             else if (token == "light")
             {
                 parseLightBlock(api);
             }
             else if (token == "texturepath")
             {
                 string path = p.getNextToken();
                 //if (!new File(path).isAbsolute())
                 //    path = localDir + File.separator + path;
     api.searchpath("texture", Path.GetFullPath(path));
             }
             else if (token == "includepath")
             {
                 string path = p.getNextToken();
                 //if (!new File(path).isAbsolute())
                 //    path = localDir + File.separator + path;
                 api.searchpath("include", Path.GetFullPath(path));
             }
             else if (token == "include")
             {
                 string file = p.getNextToken();
                 UI.printInfo(UI.Module.API, "Including: \"{0}\" ...", file);
                 api.include(file);
             }
             else
                 UI.printWarning(UI.Module.API, "Unrecognized token {0}", token);
         }
         p.close();
     }
     catch (Exception e)
     {
         UI.printError(UI.Module.API, "{0}", e);
         return false;
     }
     timer.end();
     UI.printInfo(UI.Module.API, "Done parsing.");
     UI.printInfo(UI.Module.API, "Parsing time: {0}", timer.ToString());
     return true;
 }
예제 #18
0
        public bool build(Options options)
        {
            // read options
            maxDiffuseDepth = options.getInt("depths.diffuse", maxDiffuseDepth);
            maxReflectionDepth = options.getInt("depths.reflection", maxReflectionDepth);
            maxRefractionDepth = options.getInt("depths.refraction", maxRefractionDepth);
            giEngine = GIEngineFactory.create(options);
            string caustics = options.getstring("caustics", null);
            if (caustics == null || caustics == "none")
                causticPhotonMap = null;
            else if (caustics != null && caustics == "kd")
                causticPhotonMap = new CausticPhotonMap(options);
            else
            {
                UI.printWarning(UI.Module.LIGHT, "Unrecognized caustics photon map engine \"{0}\" - ignoring", caustics);
                causticPhotonMap = null;
            }

            // validate options
            maxDiffuseDepth = Math.Max(0, maxDiffuseDepth);
            maxReflectionDepth = Math.Max(0, maxReflectionDepth);
            maxRefractionDepth = Math.Max(0, maxRefractionDepth);

            SunflowSharp.Systems.Timer t = new SunflowSharp.Systems.Timer();
            t.start();
            // count total number of light samples
            int numLightSamples = 0;
            for (int i = 0; i < lights.Length; i++)
                numLightSamples += lights[i].getNumSamples();
            // initialize gi engine
            if (giEngine != null)
            {
                if (!giEngine.init(scene))
                    return false;
            }

            if (!calculatePhotons(causticPhotonMap, "caustic", 0))
                return false;
            t.end();
            cacheLookups = 0;
            cacheHits = 0;
            cacheEmptyEntryMisses = 0;
            cacheWrongEntryMisses = 0;
            cacheEntryAdditions = 0;
            if (_shadingCache != null)
            {
                // clear shading cache
                for (int i = 0; i < _shadingCache.Length; i++)
                    _shadingCache[i] = null;
            }
            UI.printInfo(UI.Module.LIGHT, "Light Server stats:");
            UI.printInfo(UI.Module.LIGHT, "  * Light sources found: {0}", lights.Length);
            UI.printInfo(UI.Module.LIGHT, "  * Light samples:       {0}", numLightSamples);
            UI.printInfo(UI.Module.LIGHT, "  * Max raytrace depth:");
            UI.printInfo(UI.Module.LIGHT, "      - Diffuse          {0}", maxDiffuseDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Reflection       {0}", maxReflectionDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Refraction       {0}", maxRefractionDepth);
            UI.printInfo(UI.Module.LIGHT, "  * GI engine            {0}", options.getstring("gi.engine", "none"));
            UI.printInfo(UI.Module.LIGHT, "  * Caustics:            {0}", caustics == null ? "none" : caustics);
            UI.printInfo(UI.Module.LIGHT, "  * Shader override:     {0}", shaderOverride);
            UI.printInfo(UI.Module.LIGHT, "  * Photon override:     {0}", shaderOverridePhotons);
            UI.printInfo(UI.Module.LIGHT, "  * Shading cache:       {0}", _shadingCache == null ? "off" : "on");
            UI.printInfo(UI.Module.LIGHT, "  * Build time:          {0}", t.ToString());
            return true;
        }
예제 #19
0
 /**
  * Create an API object from the specified file. Java files are read by
  * Janino and are expected to implement a build method (they implement a
  * derived class of SunflowAPI. The build method is called if the code
  * compiles succesfully. Other files types are handled by the parse method.
  *
  * @param filename filename to load
  * @return a valid SunflowAPI object or <code>null</code> on failure
  */
 public static SunflowAPI create(string filename, int frameNumber)
 {
     if (filename == null)
         return new SunflowAPI();
     SunflowAPI api = null;
     if (filename.EndsWith(".java"))
     {
         Timer t = new Timer();
         UI.printInfo(UI.Module.API, "Compiling \"" + filename + "\" ...");
         t.start();
         try
         {
             //FileInputStream stream = new FileInputStream(filename);
             api = null;//(SunflowAPI) ClassBodyEvaluator.createFastClassBodyEvaluator(new Scanner(filename, stream), SunflowAPI.class, ClassLoader.getSystemClassLoader());
             //fixme: the dynamic loading
             //stream.close();
         }
         catch (Exception e)
         {
             UI.printError(UI.Module.API, "Could not compile: \"{0}\"", filename);
             UI.printError(UI.Module.API, "{0}", e);
             return null;
         }
         t.end();
         UI.printInfo(UI.Module.API, "Compile time: " + t.ToString());
         if (api != null)
         {
             string currentFolder = Path.GetDirectoryName(filename);//new File(filename).getAbsoluteFile().getParentFile().getAbsolutePath();
             api.includeSearchPath.addSearchPath(currentFolder);
             api.textureSearchPath.addSearchPath(currentFolder);
         }
         UI.printInfo(UI.Module.API, "Build script running ...");
         t.start();
         api.currentFrame = frameNumber;
         api.build();
         t.end();
         UI.printInfo(UI.Module.API, "Build script time: {0}", t.ToString());
     }
     else
     {
         api = new SunflowAPI();
         api = api.include(filename) ? api : null;
     }
     return api;
 }
예제 #20
0
        public bool calculatePhotons(PhotonStore map, string type, int seed)
        {
            if (map == null)
            {
                return(true);
            }
            if (lights.Length == 0)
            {
                UI.printError(UI.Module.LIGHT, "Unable to trace {0} photons, no lights in scene", type);
                return(false);
            }
            float[] histogram = new float[lights.Length];
            histogram[0] = lights[0].getPower();
            for (int i = 1; i < lights.Length; i++)
            {
                histogram[i] = histogram[i - 1] + lights[i].getPower();
            }
            UI.printInfo(UI.Module.LIGHT, "Tracing %s photons ...", type);
            int numEmittedPhotons = map.numEmit();

            if (numEmittedPhotons <= 0 || histogram[histogram.Length - 1] <= 0)
            {
                UI.printError(UI.Module.LIGHT, "Photon mapping enabled, but no {0} photons to emit", type);
                return(false);
            }
            map.prepare(scene.getBounds());
            UI.taskStart("Tracing " + type + " photons", 0, numEmittedPhotons);
            Thread[] photonThreads = new Thread[scene.getThreads()];
            float    scale         = 1.0f / numEmittedPhotons;
            int      delta         = numEmittedPhotons / photonThreads.Length;

            photonCounter = 0;
            SunflowSharp.Systems.Timer photonTimer = new SunflowSharp.Systems.Timer();
            photonTimer.start();
            for (int i = 0; i < photonThreads.Length; i++)
            {
                int threadID = i;
                int start    = threadID * delta;
                int end      = (threadID == (photonThreads.Length - 1)) ? numEmittedPhotons : (threadID + 1) * delta;
                photonThreads[i]          = new Thread(new ThreadStart(new CalculatePhotons(start, end, this, seed, histogram, scale, map, lockObj).Run));
                photonThreads[i].Priority = scene.getThreadPriority();
                photonThreads[i].Start();
            }
            for (int i = 0; i < photonThreads.Length; i++)
            {
                try
                {
                    photonThreads[i].Join();
                }
                catch (Exception e)
                {
                    UI.printError(UI.Module.LIGHT, "Photon thread {0} of {1} was interrupted", i + 1, photonThreads.Length);
                    return(false);
                }
            }
            if (UI.taskCanceled())
            {
                UI.taskStop(); // shut down task cleanly
                return(false);
            }
            photonTimer.end();
            UI.taskStop();
            UI.printInfo(UI.Module.LIGHT, "Tracing time for {0} photons: {1}", type, photonTimer.ToString());
            map.init();
            return(true);
        }
예제 #21
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);
         }
     }
 }
예제 #22
0
        public bool build(Options options)
        {
            // read options
            maxDiffuseDepth    = options.getInt("depths.diffuse", maxDiffuseDepth);
            maxReflectionDepth = options.getInt("depths.reflection", maxReflectionDepth);
            maxRefractionDepth = options.getInt("depths.refraction", maxRefractionDepth);
            giEngine           = GIEngineFactory.create(options);
            string caustics = options.getstring("caustics", null);

            if (caustics == null || caustics == "none")
            {
                causticPhotonMap = null;
            }
            else if (caustics != null && caustics == "kd")
            {
                causticPhotonMap = new CausticPhotonMap(options);
            }
            else
            {
                UI.printWarning(UI.Module.LIGHT, "Unrecognized caustics photon map engine \"{0}\" - ignoring", caustics);
                causticPhotonMap = null;
            }

            // validate options
            maxDiffuseDepth    = Math.Max(0, maxDiffuseDepth);
            maxReflectionDepth = Math.Max(0, maxReflectionDepth);
            maxRefractionDepth = Math.Max(0, maxRefractionDepth);

            SunflowSharp.Systems.Timer t = new SunflowSharp.Systems.Timer();
            t.start();
            // count total number of light samples
            int numLightSamples = 0;

            for (int i = 0; i < lights.Length; i++)
            {
                numLightSamples += lights[i].getNumSamples();
            }
            // initialize gi engine
            if (giEngine != null)
            {
                if (!giEngine.init(scene))
                {
                    return(false);
                }
            }

            if (!calculatePhotons(causticPhotonMap, "caustic", 0))
            {
                return(false);
            }
            t.end();
            cacheLookups          = 0;
            cacheHits             = 0;
            cacheEmptyEntryMisses = 0;
            cacheWrongEntryMisses = 0;
            cacheEntryAdditions   = 0;
            if (_shadingCache != null)
            {
                // clear shading cache
                for (int i = 0; i < _shadingCache.Length; i++)
                {
                    _shadingCache[i] = null;
                }
            }
            UI.printInfo(UI.Module.LIGHT, "Light Server stats:");
            UI.printInfo(UI.Module.LIGHT, "  * Light sources found: {0}", lights.Length);
            UI.printInfo(UI.Module.LIGHT, "  * Light samples:       {0}", numLightSamples);
            UI.printInfo(UI.Module.LIGHT, "  * Max raytrace depth:");
            UI.printInfo(UI.Module.LIGHT, "      - Diffuse          {0}", maxDiffuseDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Reflection       {0}", maxReflectionDepth);
            UI.printInfo(UI.Module.LIGHT, "      - Refraction       {0}", maxRefractionDepth);
            UI.printInfo(UI.Module.LIGHT, "  * GI engine            {0}", options.getstring("gi.engine", "none"));
            UI.printInfo(UI.Module.LIGHT, "  * Caustics:            {0}", caustics == null ? "none" : caustics);
            UI.printInfo(UI.Module.LIGHT, "  * Shader override:     {0}", shaderOverride);
            UI.printInfo(UI.Module.LIGHT, "  * Photon override:     {0}", shaderOverridePhotons);
            UI.printInfo(UI.Module.LIGHT, "  * Shading cache:       {0}", _shadingCache == null ? "off" : "on");
            UI.printInfo(UI.Module.LIGHT, "  * Build time:          {0}", t.ToString());
            return(true);
        }