133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// The ray tracer code in this file is written by Adam Burmister. It
233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// is available in its original form from:
333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//
433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   http://labs.flog.nz.co/raytracer/
533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//
633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// It has been modified slightly by Google to work as a standalone
733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// benchmark, but the all the computational code remains
833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// untouched. This file also contains a copy of parts of the Prototype
933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// JavaScript framework which is used by the ray tracer.
1033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
1133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkvar RayTrace = new BenchmarkSuite('RayTrace', 739989, [
1233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park  new Benchmark('RayTrace', renderScene)
1333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park]);
1433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
1533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
1633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// Variable used to hold a number that can be used to verify that
1733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// the scene was ray traced correctly.
1833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkvar checkNumber;
1933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
2033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
2133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// ------------------------------------------------------------------------
2233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// ------------------------------------------------------------------------
2333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
2433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// The following is a copy of parts of the Prototype JavaScript library:
2533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
2633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// Prototype JavaScript framework, version 1.5.0
2733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// (c) 2005-2007 Sam Stephenson
2833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//
2933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// Prototype is freely distributable under the terms of an MIT-style license.
3033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// For details, see the Prototype web site: http://prototype.conio.net/
3133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
3233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
3333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkvar Class = {
3433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park  create: function() {
3533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    return function() {
3633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park      this.initialize.apply(this, arguments);
3733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
3833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park  }
3933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park};
4033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
4133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
4233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkObject.extend = function(destination, source) {
4333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park  for (var property in source) {
4433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    destination[property] = source[property];
4533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park  }
4633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park  return destination;
4733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park};
4833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
4933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
5033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// ------------------------------------------------------------------------
5133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// ------------------------------------------------------------------------
5233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
5333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// The rest of this file is the actual ray tracer written by Adam
5433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park// Burmister. It's a concatenation of the following files:
5533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//
5633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/color.js
5733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/light.js
5833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/vector.js
5933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/ray.js
6033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/scene.js
6133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/material/basematerial.js
6233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/material/solid.js
6333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/material/chessboard.js
6433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/shape/baseshape.js
6533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/shape/sphere.js
6633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/shape/plane.js
6733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/intersectioninfo.js
6833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/camera.js
6933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/background.js
7033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park//   flog/engine.js
7133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
7233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
7333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
7433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
7533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
7633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
7733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Color = Class.create();
7833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
7933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Color.prototype = {
8033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    red : 0.0,
8133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    green : 0.0,
8233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    blue : 0.0,
8333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
8433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(r, g, b) {
8533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(!r) r = 0.0;
8633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(!g) g = 0.0;
8733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(!b) b = 0.0;
8833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
8933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.red = r;
9033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.green = g;
9133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.blue = b;
9233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
9333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
9433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    add : function(c1, c2){
9533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var result = new Flog.RayTracer.Color(0,0,0);
9633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
9733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.red = c1.red + c2.red;
9833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.green = c1.green + c2.green;
9933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.blue = c1.blue + c2.blue;
10033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
10133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return result;
10233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
10333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
10433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    addScalar: function(c1, s){
10533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var result = new Flog.RayTracer.Color(0,0,0);
10633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
10733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.red = c1.red + s;
10833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.green = c1.green + s;
10933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.blue = c1.blue + s;
11033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
11133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.limit();
11233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
11333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return result;
11433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
11533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
11633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    subtract: function(c1, c2){
11733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var result = new Flog.RayTracer.Color(0,0,0);
11833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
11933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.red = c1.red - c2.red;
12033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.green = c1.green - c2.green;
12133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.blue = c1.blue - c2.blue;
12233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
12333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return result;
12433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
12533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
12633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    multiply : function(c1, c2) {
12733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var result = new Flog.RayTracer.Color(0,0,0);
12833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
12933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.red = c1.red * c2.red;
13033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.green = c1.green * c2.green;
13133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.blue = c1.blue * c2.blue;
13233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
13333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return result;
13433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
13533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
13633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    multiplyScalar : function(c1, f) {
13733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var result = new Flog.RayTracer.Color(0,0,0);
13833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
13933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.red = c1.red * f;
14033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.green = c1.green * f;
14133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.blue = c1.blue * f;
14233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
14333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return result;
14433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
14533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
14633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    divideFactor : function(c1, f) {
14733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var result = new Flog.RayTracer.Color(0,0,0);
14833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
14933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.red = c1.red / f;
15033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.green = c1.green / f;
15133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result.blue = c1.blue / f;
15233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
15333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return result;
15433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
15533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
15633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    limit: function(){
15733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.red = (this.red > 0.0) ? ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
15833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.green = (this.green > 0.0) ? ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
15933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.blue = (this.blue > 0.0) ? ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
16033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
16133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
16233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    distance : function(color) {
16333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var d = Math.abs(this.red - color.red) + Math.abs(this.green - color.green) + Math.abs(this.blue - color.blue);
16433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return d;
16533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
16633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
16733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    blend: function(c1, c2, w){
16833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var result = new Flog.RayTracer.Color(0,0,0);
16933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        result = Flog.RayTracer.Color.prototype.add(
17033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
17133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
17233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                  );
17333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return result;
17433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
17533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
17633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    brightness : function() {
17733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var r = Math.floor(this.red*255);
17833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var g = Math.floor(this.green*255);
17933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var b = Math.floor(this.blue*255);
18033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return (r * 77 + g * 150 + b * 29) >> 8;
18133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
18233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
18333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
18433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var r = Math.floor(this.red*255);
18533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var g = Math.floor(this.green*255);
18633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var b = Math.floor(this.blue*255);
18733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
18833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return "rgb("+ r +","+ g +","+ b +")";
18933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
19033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
19133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
19233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
19333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
19433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
19533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Light = Class.create();
19633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
19733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Light.prototype = {
19833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    position: null,
19933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    color: null,
20033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    intensity: 10.0,
20133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
20233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(pos, color, intensity) {
20333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.position = pos;
20433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.color = color;
20533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.intensity = (intensity ? intensity : 10.0);
20633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
20733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
20833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
20933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Light [' + this.position.x + ',' + this.position.y + ',' + this.position.z + ']';
21033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
21133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
21233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
21333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
21433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
21533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
21633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Vector = Class.create();
21733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
21833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Vector.prototype = {
21933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    x : 0.0,
22033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    y : 0.0,
22133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    z : 0.0,
22233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
22333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(x, y, z) {
22433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.x = (x ? x : 0);
22533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.y = (y ? y : 0);
22633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.z = (z ? z : 0);
22733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
22833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
22933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    copy: function(vector){
23033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.x = vector.x;
23133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.y = vector.y;
23233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.z = vector.z;
23333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
23433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
23533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    normalize : function() {
23633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var m = this.magnitude();
23733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return new Flog.RayTracer.Vector(this.x / m, this.y / m, this.z / m);
23833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
23933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
24033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    magnitude : function() {
24133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
24233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
24333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
24433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    cross : function(w) {
24533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return new Flog.RayTracer.Vector(
24633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            -this.z * w.y + this.y * w.z,
24733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                           this.z * w.x - this.x * w.z,
24833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                          -this.y * w.x + this.x * w.y);
24933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
25033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
25133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    dot : function(w) {
25233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return this.x * w.x + this.y * w.y + this.z * w.z;
25333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
25433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
25533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    add : function(v, w) {
25633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return new Flog.RayTracer.Vector(w.x + v.x, w.y + v.y, w.z + v.z);
25733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
25833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
25933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    subtract : function(v, w) {
26033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(!w || !v) throw 'Vectors must be defined [' + v + ',' + w + ']';
26133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return new Flog.RayTracer.Vector(v.x - w.x, v.y - w.y, v.z - w.z);
26233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
26333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
26433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    multiplyVector : function(v, w) {
26533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return new Flog.RayTracer.Vector(v.x * w.x, v.y * w.y, v.z * w.z);
26633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
26733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
26833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    multiplyScalar : function(v, w) {
26933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return new Flog.RayTracer.Vector(v.x * w, v.y * w, v.z * w);
27033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
27133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
27233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
27333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
27433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
27533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
27633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
27733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
27833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
27933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
28033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Ray = Class.create();
28133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
28233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Ray.prototype = {
28333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    position : null,
28433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    direction : null,
28533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(pos, dir) {
28633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.position = pos;
28733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.direction = dir;
28833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
28933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
29033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
29133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Ray [' + this.position + ',' + this.direction + ']';
29233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
29333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
29433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
29533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
29633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
29733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
29833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Scene = Class.create();
29933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
30033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Scene.prototype = {
30133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    camera : null,
30233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    shapes : [],
30333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    lights : [],
30433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    background : null,
30533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
30633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function() {
30733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.camera = new Flog.RayTracer.Camera(
30833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            new Flog.RayTracer.Vector(0,0,-5),
30933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            new Flog.RayTracer.Vector(0,0,1),
31033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            new Flog.RayTracer.Vector(0,1,0)
31133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        );
31233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.shapes = new Array();
31333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.lights = new Array();
31433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.background = new Flog.RayTracer.Background(new Flog.RayTracer.Color(0,0,0.5), 0.2);
31533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
31633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
31733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
31833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
31933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
32033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer.Material) == 'undefined') Flog.RayTracer.Material = {};
32133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
32233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Material.BaseMaterial = Class.create();
32333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
32433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Material.BaseMaterial.prototype = {
32533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
32633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    gloss: 2.0,             // [0...infinity] 0 = matt
32733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    transparency: 0.0,      // 0=opaque
32833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    reflection: 0.0,        // [0...infinity] 0 = no reflection
32933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    refraction: 0.50,
33033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    hasTexture: false,
33133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
33233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function() {
33333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
33433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
33533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
33633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    getColor: function(u, v){
33733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
33833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
33933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
34033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    wrapUp: function(t){
34133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        t = t % 2.0;
34233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(t < -1) t += 2.0;
34333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(t >= 1) t -= 2.0;
34433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return t;
34533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
34633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
34733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
34833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
34933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
35033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
35133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
35233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
35333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
35433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
35533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Material.Solid = Class.create();
35633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
35733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Material.Solid.prototype = Object.extend(
35833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    new Flog.RayTracer.Material.BaseMaterial(), {
35933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        initialize : function(color, reflection, refraction, transparency, gloss) {
36033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.color = color;
36133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.reflection = reflection;
36233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.transparency = transparency;
36333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.gloss = gloss;
36433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.hasTexture = false;
36533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        },
36633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
36733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        getColor: function(u, v){
36833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            return this.color;
36933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        },
37033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
37133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        toString : function () {
37233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            return 'SolidMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
37333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
37433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
37533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park);
37633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
37733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
37833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
37933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
38033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Material.Chessboard = Class.create();
38133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
38233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Material.Chessboard.prototype = Object.extend(
38333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    new Flog.RayTracer.Material.BaseMaterial(), {
38433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        colorEven: null,
38533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        colorOdd: null,
38633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        density: 0.5,
38733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
38833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        initialize : function(colorEven, colorOdd, reflection, transparency, gloss, density) {
38933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.colorEven = colorEven;
39033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.colorOdd = colorOdd;
39133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.reflection = reflection;
39233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.transparency = transparency;
39333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.gloss = gloss;
39433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.density = density;
39533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.hasTexture = true;
39633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        },
39733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
39833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        getColor: function(u, v){
39933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
40033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
40133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            if(t < 0.0)
40233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                return this.colorEven;
40333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            else
40433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                return this.colorOdd;
40533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        },
40633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
40733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        toString : function () {
40833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            return 'ChessMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
40933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
41033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
41133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park);
41233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
41333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
41433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
41533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
41633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
41733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Shape.Sphere = Class.create();
41833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
41933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Shape.Sphere.prototype = {
42033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(pos, radius, material) {
42133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.radius = radius;
42233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.position = pos;
42333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.material = material;
42433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
42533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
42633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    intersect: function(ray){
42733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var info = new Flog.RayTracer.IntersectionInfo();
42833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        info.shape = this;
42933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
43033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var dst = Flog.RayTracer.Vector.prototype.subtract(ray.position, this.position);
43133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
43233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var B = dst.dot(ray.direction);
43333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var C = dst.dot(dst) - (this.radius * this.radius);
43433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var D = (B * B) - C;
43533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
43633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(D > 0){ // intersection!
43733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.isHit = true;
43833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.distance = (-B) - Math.sqrt(D);
43933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.position = Flog.RayTracer.Vector.prototype.add(
44033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                ray.position,
44133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                Flog.RayTracer.Vector.prototype.multiplyScalar(
44233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                    ray.direction,
44333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                    info.distance
44433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                )
44533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            );
44633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.normal = Flog.RayTracer.Vector.prototype.subtract(
44733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            info.position,
44833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            this.position
44933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                        ).normalize();
45033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
45133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.color = this.material.getColor(0,0);
45233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        } else {
45333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.isHit = false;
45433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
45533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return info;
45633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
45733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
45833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
45933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Sphere [position=' + this.position + ', radius=' + this.radius + ']';
46033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
46133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
46233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
46333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
46433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
46533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
46633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
46733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Shape.Plane = Class.create();
46833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
46933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Shape.Plane.prototype = {
47033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    d: 0.0,
47133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
47233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(pos, d, material) {
47333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.position = pos;
47433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.d = d;
47533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.material = material;
47633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
47733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
47833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    intersect: function(ray){
47933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var info = new Flog.RayTracer.IntersectionInfo();
48033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
48133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var Vd = this.position.dot(ray.direction);
48233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(Vd == 0) return info; // no intersection
48333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
48433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var t = -(this.position.dot(ray.position) + this.d) / Vd;
48533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(t <= 0) return info;
48633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
48733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        info.shape = this;
48833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        info.isHit = true;
48933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        info.position = Flog.RayTracer.Vector.prototype.add(
49033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            ray.position,
49133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            Flog.RayTracer.Vector.prototype.multiplyScalar(
49233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                ray.direction,
49333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                t
49433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            )
49533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                        );
49633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        info.normal = this.position;
49733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        info.distance = t;
49833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
49933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(this.material.hasTexture){
50033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x);
50133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var vV = vU.cross(this.position);
50233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var u = info.position.dot(vU);
50333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var v = info.position.dot(vV);
50433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.color = this.material.getColor(u,v);
50533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        } else {
50633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            info.color = this.material.getColor(0,0);
50733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
50833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
50933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return info;
51033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
51133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
51233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
51333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Plane [' + this.position + ', d=' + this.d + ']';
51433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
51533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
51633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
51733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
51833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
51933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
52033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.IntersectionInfo = Class.create();
52133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
52233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.IntersectionInfo.prototype = {
52333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    isHit: false,
52433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    hitCount: 0,
52533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    shape: null,
52633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    position: null,
52733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    normal: null,
52833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    color: null,
52933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    distance: null,
53033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
53133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function() {
53233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.color = new Flog.RayTracer.Color(0,0,0);
53333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
53433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
53533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
53633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Intersection [' + this.position + ']';
53733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
53833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
53933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
54033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
54133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
54233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
54333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Camera = Class.create();
54433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
54533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Camera.prototype = {
54633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    position: null,
54733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    lookAt: null,
54833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    equator: null,
54933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    up: null,
55033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    screen: null,
55133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
55233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(pos, lookAt, up) {
55333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.position = pos;
55433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.lookAt = lookAt;
55533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.up = up;
55633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.equator = lookAt.normalize().cross(this.up);
55733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.screen = Flog.RayTracer.Vector.prototype.add(this.position, this.lookAt);
55833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
55933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
56033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    getRay: function(vx, vy){
56133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var pos = Flog.RayTracer.Vector.prototype.subtract(
56233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.screen,
56333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            Flog.RayTracer.Vector.prototype.subtract(
56433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                Flog.RayTracer.Vector.prototype.multiplyScalar(this.equator, vx),
56533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                Flog.RayTracer.Vector.prototype.multiplyScalar(this.up, vy)
56633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            )
56733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        );
56833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        pos.y = pos.y * -1;
56933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var dir = Flog.RayTracer.Vector.prototype.subtract(
57033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            pos,
57133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            this.position
57233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        );
57333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
57433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var ray = new Flog.RayTracer.Ray(pos, dir.normalize());
57533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
57633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return ray;
57733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
57833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
57933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    toString : function () {
58033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return 'Ray []';
58133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
58233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
58333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
58433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
58533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
58633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
58733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Background = Class.create();
58833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
58933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Background.prototype = {
59033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    color : null,
59133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    ambience : 0.0,
59233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
59333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize : function(color, ambience) {
59433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.color = color;
59533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.ambience = ambience;
59633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
59733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
59833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park/* Fake a Flog.* namespace */
59933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog) == 'undefined') var Flog = {};
60033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkif(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
60133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
60233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Engine = Class.create();
60333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
60433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young ParkFlog.RayTracer.Engine.prototype = {
60533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    canvas: null, /* 2d context we can render to */
60633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
60733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    initialize: function(options){
60833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.options = Object.extend({
60933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                canvasHeight: 100,
61033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                canvasWidth: 100,
61133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                pixelWidth: 2,
61233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                pixelHeight: 2,
61333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                renderDiffuse: false,
61433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                renderShadows: false,
61533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                renderHighlights: false,
61633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                renderReflections: false,
61733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                rayDepth: 2
61833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            }, options || {});
61933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
62033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.options.canvasHeight /= this.options.pixelHeight;
62133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        this.options.canvasWidth /= this.options.pixelWidth;
62233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
62333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        /* TODO: dynamically include other scripts */
62433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
62533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
62633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    setPixel: function(x, y, color){
62733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var pxW, pxH;
62833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        pxW = this.options.pixelWidth;
62933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        pxH = this.options.pixelHeight;
63033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
63133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if (this.canvas) {
63233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          this.canvas.fillStyle = color.toString();
63333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
63433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        } else {
63533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          if (x ===  y) {
63633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            checkNumber += color.brightness();
63733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          }
63833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          // print(x * pxW, y * pxH, pxW, pxH);
63933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
64033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
64133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
64233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    renderScene: function(scene, canvas){
64333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        checkNumber = 0;
64433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        /* Get canvas */
64533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if (canvas) {
64633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          this.canvas = canvas.getContext("2d");
64733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        } else {
64833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          this.canvas = null;
64933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
65033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
65133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var canvasHeight = this.options.canvasHeight;
65233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var canvasWidth = this.options.canvasWidth;
65333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
65433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        for(var y=0; y < canvasHeight; y++){
65533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            for(var x=0; x < canvasWidth; x++){
65633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                var yp = y * 1.0 / canvasHeight * 2 - 1;
65733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          		var xp = x * 1.0 / canvasWidth * 2 - 1;
65833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
65933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          		var ray = scene.camera.getRay(xp, yp);
66033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
66133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          		var color = this.getPixelColor(ray, scene);
66233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
66333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            	this.setPixel(x, y, color);
66433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            }
66533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
66633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if (checkNumber !== 2321) {
66733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          throw new Error("Scene rendered incorrectly");
66833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
66933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
67033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
67133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    getPixelColor: function(ray, scene){
67233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var info = this.testIntersection(ray, scene, null);
67333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        if(info.isHit){
67433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var color = this.rayTrace(info, ray, scene, 0);
67533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            return color;
67633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
67733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return scene.background.color;
67833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
67933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
68033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    testIntersection: function(ray, scene, exclude){
68133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var hits = 0;
68233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var best = new Flog.RayTracer.IntersectionInfo();
68333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        best.distance = 2000;
68433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
68533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        for(var i=0; i<scene.shapes.length; i++){
68633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var shape = scene.shapes[i];
68733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
68833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            if(shape != exclude){
68933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                var info = shape.intersect(ray);
69033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                if(info.isHit && info.distance >= 0 && info.distance < best.distance){
69133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    best = info;
69233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    hits++;
69333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                }
69433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            }
69533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
69633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        best.hitCount = hits;
69733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return best;
69833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
69933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
70033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    getReflectionRay: function(P,N,V){
70133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var c1 = -N.dot(V);
70233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var R1 = Flog.RayTracer.Vector.prototype.add(
70333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
70433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            V
70533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        );
70633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return new Flog.RayTracer.Ray(P, R1);
70733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    },
70833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
70933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    rayTrace: function(info, ray, scene, depth){
71033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        // Calc ambient
71133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience);
71233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var oldColor = color;
71333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var shininess = Math.pow(10, info.shape.material.gloss + 1);
71433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
71533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        for(var i=0; i<scene.lights.length; i++){
71633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var light = scene.lights[i];
71733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
71833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            // Calc diffuse lighting
71933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var v = Flog.RayTracer.Vector.prototype.subtract(
72033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                light.position,
72133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                info.position
72233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            ).normalize();
72333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
72433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            if(this.options.renderDiffuse){
72533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                var L = v.dot(info.normal);
72633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                if(L > 0.0){
72733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    color = Flog.RayTracer.Color.prototype.add(
72833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                        color,
72933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                        Flog.RayTracer.Color.prototype.multiply(
73033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            info.color,
73133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            Flog.RayTracer.Color.prototype.multiplyScalar(
73233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                light.color,
73333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                                L
73433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                            )
73533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                        )
73633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                    );
73733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                }
73833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            }
73933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
74033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            // The greater the depth the more accurate the colours, but
74133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            // this is exponentially (!) expensive
74233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            if(depth <= this.options.rayDepth){
74333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          // calculate reflection ray
74433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          if(this.options.renderReflections && info.shape.material.reflection > 0)
74533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          {
74633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park              var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction);
74733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park              var refl = this.testIntersection(reflectionRay, scene, info.shape);
74833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
74933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park              if (refl.isHit && refl.distance > 0){
75033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                  refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
75133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park              } else {
75233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                  refl.color = scene.background.color;
75333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        }
75433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
75533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                  color = Flog.RayTracer.Color.prototype.blend(
75633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    color,
75733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    refl.color,
75833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    info.shape.material.reflection
75933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                  );
76033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park          }
76133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
76233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                // Refraction
76333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                /* TODO */
76433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            }
76533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
76633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            /* Render shadows and highlights */
76733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
76833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            var shadowInfo = new Flog.RayTracer.IntersectionInfo();
76933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
77033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            if(this.options.renderShadows){
77133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                var shadowRay = new Flog.RayTracer.Ray(info.position, v);
77233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
77333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
77433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                if(shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/){
77533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    var vA = Flog.RayTracer.Color.prototype.multiplyScalar(color, 0.5);
77633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
77733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    color = Flog.RayTracer.Color.prototype.addScalar(vA,dB);
77833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                }
77933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            }
78033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
78133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park      // Phong specular highlights
78233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park      if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0){
78333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var Lv = Flog.RayTracer.Vector.prototype.subtract(
78433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            info.shape.position,
78533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            light.position
78633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        ).normalize();
78733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
78833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var E = Flog.RayTracer.Vector.prototype.subtract(
78933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            scene.camera.position,
79033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            info.shape.position
79133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        ).normalize();
79233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
79333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var H = Flog.RayTracer.Vector.prototype.subtract(
79433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            E,
79533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            Lv
79633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        ).normalize();
79733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
79833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
79933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        color = Flog.RayTracer.Color.prototype.add(
80033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
80133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            color
80233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        );
80333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park      }
80433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
80533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        color.limit();
80633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        return color;
80733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    }
80833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park};
80933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
81033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
81133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Parkfunction renderScene(){
81233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var scene = new Flog.RayTracer.Scene();
81333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
81433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    scene.camera = new Flog.RayTracer.Camera(
81533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        new Flog.RayTracer.Vector(0, 0, -15),
81633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        new Flog.RayTracer.Vector(-0.2, 0, 5),
81733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                        new Flog.RayTracer.Vector(0, 1, 0)
81833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                    );
81933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
82033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    scene.background = new Flog.RayTracer.Background(
82133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                new Flog.RayTracer.Color(0.5, 0.5, 0.5),
82233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                0.4
82333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            );
82433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
82533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var sphere = new Flog.RayTracer.Shape.Sphere(
82633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Vector(-1.5, 1.5, 2),
82733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        1.5,
82833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Material.Solid(
82933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            new Flog.RayTracer.Color(0,0.5,0.5),
83033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            0.3,
83133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            0.0,
83233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            0.0,
83333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            2.0
83433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        )
83533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    );
83633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
83733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var sphere1 = new Flog.RayTracer.Shape.Sphere(
83833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Vector(1, 0.25, 1),
83933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        0.5,
84033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Material.Solid(
84133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            new Flog.RayTracer.Color(0.9,0.9,0.9),
84233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            0.1,
84333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            0.0,
84433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            0.0,
84533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            1.5
84633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        )
84733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    );
84833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
84933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var plane = new Flog.RayTracer.Shape.Plane(
85033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
85133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                1.2,
85233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                new Flog.RayTracer.Material.Chessboard(
85333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                    new Flog.RayTracer.Color(1,1,1),
85433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                    new Flog.RayTracer.Color(0,0,0),
85533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                    0.2,
85633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                    0.0,
85733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                    1.0,
85833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                    0.7
85933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                                )
86033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park                            );
86133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
86233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    scene.shapes.push(plane);
86333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    scene.shapes.push(sphere);
86433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    scene.shapes.push(sphere1);
86533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
86633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var light = new Flog.RayTracer.Light(
86733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Vector(5, 10, -1),
86833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Color(0.8, 0.8, 0.8)
86933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    );
87033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
87133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var light1 = new Flog.RayTracer.Light(
87233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Vector(-3, 5, -15),
87333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        new Flog.RayTracer.Color(0.8, 0.8, 0.8),
87433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        100
87533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    );
87633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
87733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    scene.lights.push(light);
87833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    scene.lights.push(light1);
87933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
88033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var imageWidth = 100; // $F('imageWidth');
88133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var imageHeight = 100; // $F('imageHeight');
88233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var pixelSize = "5,5".split(','); //  $F('pixelSize').split(',');
88333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var renderDiffuse = true; // $F('renderDiffuse');
88433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var renderShadows = true; // $F('renderShadows');
88533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var renderHighlights = true; // $F('renderHighlights');
88633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var renderReflections = true; // $F('renderReflections');
88733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var rayDepth = 2;//$F('rayDepth');
88833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
88933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    var raytracer = new Flog.RayTracer.Engine(
89033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        {
89133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            canvasWidth: imageWidth,
89233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            canvasHeight: imageHeight,
89333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            pixelWidth: pixelSize[0],
89433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            pixelHeight: pixelSize[1],
89533b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            "renderDiffuse": renderDiffuse,
89633b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            "renderHighlights": renderHighlights,
89733b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            "renderShadows": renderShadows,
89833b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            "renderReflections": renderReflections,
89933b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park            "rayDepth": rayDepth
90033b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park        }
90133b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    );
90233b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park
90333b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park    raytracer.renderScene(scene, null, 0);
90433b3414d84d5ad1dbfcddf43fe0b98ddb09a260bKeun young Park}
905