Skip to content

Instantly share code, notes, and snippets.

@mauriciopoppe
Last active August 16, 2016 22:32
Show Gist options
  • Save mauriciopoppe/9b19fccfa670c9e2597b to your computer and use it in GitHub Desktop.
Save mauriciopoppe/9b19fccfa670c9e2597b to your computer and use it in GitHub Desktop.
requirebin sketch
// made by @iMauricio
// github: https://github.com/maurizzzio/quickhull3d
// license: MIT
var qh = require('quickhull3d')
var t3 = require('t3-boilerplate')
t3.run({
selector: '#canvas',
helpersConfig: {
ground: false,
gridX: false,
gridY: false,
gridZ: false,
axes: false
},
init: function() {
var N_POINTS = 10000;
var LIMIT = 100;
var i;
function p() {
return -LIMIT + 2 * Math.random() * LIMIT;
}
function pointGenerator() {
return [p(), p(), p()];
}
// random points
var points = [];
for (i = 0; i < N_POINTS; i += 1) {
points.push(pointGenerator());
}
console.time('quickhull');
var faces = qh(points);
console.timeEnd('quickhull');
var geometry = new THREE.Geometry();
for (i = 0; i < points.length; i += 1) {
geometry.vertices.push(new THREE.Vector3().fromArray(points[i]));
}
var normal;
for (i = 0; i < faces.length; i += 1) {
var a = new THREE.Vector3().fromArray(points[faces[i][0]]);
var b = new THREE.Vector3().fromArray(points[faces[i][1]]);
var c = new THREE.Vector3().fromArray(points[faces[i][2]]);
normal = new THREE.Vector3()
.crossVectors(
new THREE.Vector3().subVectors(b, a),
new THREE.Vector3().subVectors(c, a)
)
.normalize();
geometry.faces.push(new THREE.Face3(
faces[i][0], faces[i][1], faces[i][2],
normal
));
}
var polyhedra = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({
// shading: THREE.NoShading
// wireframe: true
}))
this.activeScene.add(polyhedra);
var helper = new THREE.WireframeHelper(polyhedra);
helper.material.depthTest = false;
helper.material.opacity = 0.25;
helper.material.transparent = true;
this.activeScene.add(helper);
this.activeScene.add(new THREE.FaceNormalsHelper(polyhedra, 10));
},
update: function(delta) {}
});
setTimeout(function(){require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();Object.defineProperty(exports,"__esModule",{value:true});exports.DELETED=exports.NON_CONVEX=exports.VISIBLE=undefined;var _debugFn=require("debug-fn");var _debugFn2=_interopRequireDefault(_debugFn);var _dot=require("gl-vec3/dot");var _dot2=_interopRequireDefault(_dot);var _add=require("gl-vec3/add");var _add2=_interopRequireDefault(_add);var _subtract=require("gl-vec3/subtract");var _subtract2=_interopRequireDefault(_subtract);var _cross=require("gl-vec3/cross");var _cross2=_interopRequireDefault(_cross);var _copy=require("gl-vec3/copy");var _copy2=_interopRequireDefault(_copy);var _length=require("gl-vec3/length");var _length2=_interopRequireDefault(_length);var _scale=require("gl-vec3/scale");var _scale2=_interopRequireDefault(_scale);var _scaleAndAdd=require("gl-vec3/scaleAndAdd");var _scaleAndAdd2=_interopRequireDefault(_scaleAndAdd);var _normalize=require("gl-vec3/normalize");var _normalize2=_interopRequireDefault(_normalize);var _HalfEdge=require("./HalfEdge");var _HalfEdge2=_interopRequireDefault(_HalfEdge);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _typeof(obj){return obj&&typeof Symbol!=="undefined"&&obj.constructor===Symbol?"symbol":typeof obj}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var debug=(0,_debugFn2.default)("face");var VISIBLE=exports.VISIBLE=0;var NON_CONVEX=exports.NON_CONVEX=1;var DELETED=exports.DELETED=2;var Face=function(){function Face(){_classCallCheck(this,Face);this.normal=[];this.centroid=[];this.offset=0;this.outside=null;this.mark=VISIBLE;this.edge=null;this.nVertices=0}_createClass(Face,[{key:"getEdge",value:function getEdge(i){if(typeof i!=="number"){throw Error("requires a number")}var it=this.edge;while(i>0){it=it.next;i-=1}while(i<0){it=it.prev;i+=1}return it}},{key:"computeNormal",value:function computeNormal(){var e0=this.edge;var e1=e0.next;var e2=e1.next;var v2=(0,_subtract2.default)([],e1.head().point,e0.head().point);var t=[];var v1=[];this.nVertices=2;this.normal=[0,0,0];while(e2!==e0){(0,_copy2.default)(v1,v2);(0,_subtract2.default)(v2,e2.head().point,e0.head().point);(0,_add2.default)(this.normal,this.normal,(0,_cross2.default)(t,v1,v2));e2=e2.next;this.nVertices+=1}this.area=(0,_length2.default)(this.normal);this.normal=(0,_scale2.default)(this.normal,this.normal,1/this.area)}},{key:"computeNormalMinArea",value:function computeNormalMinArea(minArea){this.computeNormal();if(this.area<minArea){var maxEdge=undefined;var maxSquaredLength=0;var edge=this.edge;do{var lengthSquared=edge.lengthSquared();if(lengthSquared>maxSquaredLength){maxEdge=edge;maxSquaredLength=lengthSquared}edge=edge.next}while(edge!==this.edge);var p1=maxEdge.tail().point;var p2=maxEdge.head().point;var maxVector=(0,_subtract2.default)([],p2,p1);var maxLength=Math.sqrt(maxSquaredLength);(0,_scale2.default)(maxVector,maxVector,1/maxLength);var maxProjection=(0,_dot2.default)(this.normal,maxVector);(0,_scaleAndAdd2.default)(this.normal,this.normal,maxVector,-maxProjection);(0,_normalize2.default)(this.normal,this.normal)}}},{key:"computeCentroid",value:function computeCentroid(){this.centroid=[0,0,0];var edge=this.edge;do{(0,_add2.default)(this.centroid,this.centroid,edge.head().point);edge=edge.next}while(edge!==this.edge);(0,_scale2.default)(this.centroid,this.centroid,1/this.nVertices)}},{key:"computeNormalAndCentroid",value:function computeNormalAndCentroid(minArea){if((typeof minArea==="undefined"?"undefined":_typeof(minArea))!==undefined){this.computeNormalMinArea(minArea)}else{this.computeNormal()}this.computeCentroid();this.offset=(0,_dot2.default)(this.normal,this.centroid)}},{key:"distanceToPlane",value:function distanceToPlane(point){return(0,_dot2.default)(this.normal,point)-this.offset}},{key:"connectHalfEdges",value:function connectHalfEdges(prev,next){var discardedFace=undefined;if(prev.opposite.face===next.opposite.face){var oppositeFace=next.opposite.face;var oppositeEdge=undefined;if(prev===this.edge){this.edge=next}if(oppositeFace.nVertices===3){oppositeEdge=next.opposite.prev.opposite;oppositeFace.mark=DELETED;discardedFace=oppositeFace}else{oppositeEdge=next.opposite.next;if(oppositeFace.edge===oppositeEdge.prev){oppositeFace.edge=oppositeEdge}oppositeEdge.prev=oppositeEdge.prev.prev;oppositeEdge.prev.next=oppositeEdge}next.prev=prev.prev;next.prev.next=next;next.setOpposite(oppositeEdge);oppositeFace.computeNormalAndCentroid()}else{prev.next=next;next.prev=prev}return discardedFace}},{key:"mergeAdjacentFaces",value:function mergeAdjacentFaces(adjacentEdge,discardedFaces){var oppositeEdge=adjacentEdge.opposite;var oppositeFace=oppositeEdge.face;discardedFaces.push(oppositeFace);oppositeFace.mark=DELETED;var adjacentEdgePrev=adjacentEdge.prev;var adjacentEdgeNext=adjacentEdge.next;var oppositeEdgePrev=oppositeEdge.prev;var oppositeEdgeNext=oppositeEdge.next;while(adjacentEdgePrev.opposite.face===oppositeFace){adjacentEdgePrev=adjacentEdgePrev.prev;oppositeEdgeNext=oppositeEdgeNext.next}while(adjacentEdgeNext.opposite.face===oppositeFace){adjacentEdgeNext=adjacentEdgeNext.next;oppositeEdgePrev=oppositeEdgePrev.prev}var edge=undefined;for(edge=oppositeEdgeNext;edge!==oppositeEdgePrev.next;edge=edge.next){edge.face=this}this.edge=adjacentEdgeNext;var discardedFace=undefined;discardedFace=this.connectHalfEdges(oppositeEdgePrev,adjacentEdgeNext);if(discardedFace){discardedFaces.push(discardedFace)}discardedFace=this.connectHalfEdges(adjacentEdgePrev,oppositeEdgeNext);if(discardedFace){discardedFaces.push(discardedFace)}this.computeNormalAndCentroid();return discardedFaces}},{key:"collectIndices",value:function collectIndices(){var indices=[];var edge=this.edge;do{indices.push(edge.head().index);edge=edge.next}while(edge!==this.edge);return indices}}],[{key:"createTriangle",value:function createTriangle(v0,v1,v2){var minArea=arguments.length<=3||arguments[3]===undefined?0:arguments[3];var face=new Face;var e0=new _HalfEdge2.default(v0,face);var e1=new _HalfEdge2.default(v1,face);var e2=new _HalfEdge2.default(v2,face);e0.next=e2.prev=e1;e1.next=e0.prev=e2;e2.next=e1.prev=e0;face.edge=e0;face.computeNormalAndCentroid(minArea);debug(function(){this.log("face created %j",face.collectIndices())});return face}}]);return Face}();exports.default=Face},{"./HalfEdge":2,"debug-fn":6,"gl-vec3/add":11,"gl-vec3/copy":12,"gl-vec3/cross":13,"gl-vec3/dot":15,"gl-vec3/length":16,"gl-vec3/normalize":17,"gl-vec3/scale":18,"gl-vec3/scaleAndAdd":19,"gl-vec3/subtract":22}],2:[function(require,module,exports){"use strict";var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();Object.defineProperty(exports,"__esModule",{value:true});var _distance=require("gl-vec3/distance");var _distance2=_interopRequireDefault(_distance);var _squaredDistance=require("gl-vec3/squaredDistance");var _squaredDistance2=_interopRequireDefault(_squaredDistance);var _debugFn=require("debug-fn");var _debugFn2=_interopRequireDefault(_debugFn);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var debug=(0,_debugFn2.default)("halfedge");var HalfEdge=function(){function HalfEdge(vertex,face){_classCallCheck(this,HalfEdge);this.vertex=vertex;this.face=face;this.next=null;this.prev=null;this.opposite=null}_createClass(HalfEdge,[{key:"head",value:function head(){return this.vertex}},{key:"tail",value:function tail(){return this.prev?this.prev.vertex:null}},{key:"length",value:function length(){if(this.tail()){return(0,_distance2.default)(this.tail().point,this.head().point)}return-1}},{key:"lengthSquared",value:function lengthSquared(){if(this.tail()){return(0,_squaredDistance2.default)(this.tail().point,this.head().point)}return-1}},{key:"setOpposite",value:function setOpposite(edge){var me=this;debug(function(){this.log("opposite "+me.tail().index+" <--> "+me.head().index+" between "+me.face.collectIndices()+", "+edge.face.collectIndices())});this.opposite=edge;edge.opposite=this}}]);return HalfEdge}();exports.default=HalfEdge;module.exports=exports["default"]},{"debug-fn":6,"gl-vec3/distance":14,"gl-vec3/squaredDistance":20}],3:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();Object.defineProperty(exports,"__esModule",{value:true});var _pointLineDistance=require("point-line-distance");var _pointLineDistance2=_interopRequireDefault(_pointLineDistance);var _getPlaneNormal=require("get-plane-normal");var _getPlaneNormal2=_interopRequireDefault(_getPlaneNormal);var _debugFn=require("debug-fn");var _debugFn2=_interopRequireDefault(_debugFn);var _dot=require("gl-vec3/dot");var _dot2=_interopRequireDefault(_dot);var _VertexList=require("./VertexList");var _VertexList2=_interopRequireDefault(_VertexList);var _Vertex=require("./Vertex");var _Vertex2=_interopRequireDefault(_Vertex);var _Face=require("./Face");var _Face2=_interopRequireDefault(_Face);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var debug=(0,_debugFn2.default)("quickhull");var MERGE_NON_CONVEX_WRT_LARGER_FACE=1;var MERGE_NON_CONVEX=2;var QuickHull=function(){function QuickHull(points){_classCallCheck(this,QuickHull);if(!Array.isArray(points)){throw TypeError("input is not a valid array")}if(points.length<4){throw Error("cannot build a simplex out of <4 points")}this.tolerance=-1;this.nFaces=0;this.nPoints=points.length;this.faces=[];this.newFaces=[];this.claimed=new _VertexList2.default;this.unclaimed=new _VertexList2.default;this.vertices=[];for(var i=0;i<points.length;i+=1){this.vertices.push(new _Vertex2.default(points[i],i))}this.discardedFaces=[];this.vertexPointIndices=[]}_createClass(QuickHull,[{key:"addVertexToFace",value:function addVertexToFace(vertex,face){vertex.face=face;if(!face.outside){this.claimed.add(vertex)}else{this.claimed.insertBefore(face.outside,vertex)}face.outside=vertex}},{key:"removeVertexFromFace",value:function removeVertexFromFace(vertex,face){if(vertex===face.outside){if(vertex.next&&vertex.next.face===face){face.outside=vertex.next}else{face.outside=null}}this.claimed.remove(vertex)}},{key:"removeAllVerticesFromFace",value:function removeAllVerticesFromFace(face){if(face.outside){var end=face.outside;while(end.next&&end.next.face===face){end=end.next}this.claimed.removeChain(face.outside,end);end.next=null;return face.outside}}},{key:"deleteFaceVertices",value:function deleteFaceVertices(face,absorbingFace){var faceVertices=this.removeAllVerticesFromFace(face);if(faceVertices){if(!absorbingFace){this.unclaimed.addAll(faceVertices)}else{var nextVertex=undefined;for(var vertex=faceVertices;vertex;vertex=nextVertex){nextVertex=vertex.next;var distance=absorbingFace.distanceToPlane(vertex.point);if(distance>this.tolerance){this.addVertexToFace(vertex,absorbingFace)}else{this.unclaimed.add(vertex)}}}}}},{key:"resolveUnclaimedPoints",value:function resolveUnclaimedPoints(newFaces){var vertexNext=this.unclaimed.first();for(var vertex=vertexNext;vertex;vertex=vertexNext){vertexNext=vertex.next;var maxDistance=this.tolerance;var maxFace=undefined;for(var i=0;i<newFaces.length;i+=1){var face=newFaces[i];if(face.mark===_Face.VISIBLE){var dist=face.distanceToPlane(vertex.point);if(dist>maxDistance){maxDistance=dist;maxFace=face}if(maxDistance>1e3*this.tolerance){break}}}if(maxFace){this.addVertexToFace(vertex,maxFace)}}}},{key:"computeExtremes",value:function computeExtremes(){var me=this;var min=[];var max=[];var minVertices=[];var maxVertices=[];var i=undefined,j=undefined;for(i=0;i<3;i+=1){minVertices[i]=maxVertices[i]=this.vertices[0]}for(i=0;i<3;i+=1){min[i]=max[i]=this.vertices[0].point[i]}for(i=1;i<this.vertices.length;i+=1){var vertex=this.vertices[i];var point=vertex.point;for(j=0;j<3;j+=1){if(point[j]<min[j]){min[j]=point[j];minVertices[j]=vertex}}for(j=0;j<3;j+=1){if(point[j]>max[j]){max[j]=point[j];maxVertices[j]=vertex}}}this.tolerance=3*Number.EPSILON*(Math.max(Math.abs(min[0]),Math.abs(max[0]))+Math.max(Math.abs(min[1]),Math.abs(max[1]))+Math.max(Math.abs(min[2]),Math.abs(max[2])));debug(function(){this.log("tolerance %d",me.tolerance)});return[minVertices,maxVertices]}},{key:"createInitialSimplex",value:function createInitialSimplex(){var vertices=this.vertices;var _computeExtremes=this.computeExtremes();var _computeExtremes2=_slicedToArray(_computeExtremes,2);var min=_computeExtremes2[0];var max=_computeExtremes2[1];var v0=undefined,v1=undefined,v2=undefined,v3=undefined;var i=undefined,j=undefined;var maxDistance=0;var indexMax=0;for(i=0;i<3;i+=1){var distance=max[i].point[i]-min[i].point[i];if(distance>maxDistance){maxDistance=distance;indexMax=i}}v0=min[indexMax];v1=max[indexMax];maxDistance=0;for(i=0;i<this.vertices.length;i+=1){var vertex=this.vertices[i];if(vertex!==v0&&vertex!==v1){var distance=(0,_pointLineDistance2.default)(vertex.point,v0.point,v1.point);if(distance>maxDistance){maxDistance=distance;v2=vertex}}}var normal=(0,_getPlaneNormal2.default)([],v0.point,v1.point,v2.point);var distPO=(0,_dot2.default)(v0.point,normal);maxDistance=0;for(i=0;i<this.vertices.length;i+=1){var vertex=this.vertices[i];if(vertex!==v0&&vertex!==v1&&vertex!==v2){var distance=Math.abs((0,_dot2.default)(normal,vertex.point)-distPO);if(distance>maxDistance){maxDistance=distance;v3=vertex}}}var faces=[];if((0,_dot2.default)(v3.point,normal)-distPO<0){faces.push(_Face2.default.createTriangle(v0,v1,v2),_Face2.default.createTriangle(v3,v1,v0),_Face2.default.createTriangle(v3,v2,v1),_Face2.default.createTriangle(v3,v0,v2));for(i=0;i<3;i+=1){var _j=(i+1)%3;faces[i+1].getEdge(2).setOpposite(faces[0].getEdge(_j));faces[i+1].getEdge(1).setOpposite(faces[_j+1].getEdge(0))}}else{faces.push(_Face2.default.createTriangle(v0,v2,v1),_Face2.default.createTriangle(v3,v0,v1),_Face2.default.createTriangle(v3,v1,v2),_Face2.default.createTriangle(v3,v2,v0));for(i=0;i<3;i+=1){var _j2=(i+1)%3;faces[i+1].getEdge(2).setOpposite(faces[0].getEdge((3-i)%3));faces[i+1].getEdge(0).setOpposite(faces[_j2+1].getEdge(1))}}for(i=0;i<4;i+=1){this.faces.push(faces[i])}for(i=0;i<vertices.length;i+=1){var vertex=vertices[i];if(vertex!==v0&&vertex!==v1&&vertex!==v3&&vertex!==v3){maxDistance=this.tolerance;var maxFace=undefined;for(j=0;j<4;j+=1){var distance=faces[j].distanceToPlane(vertex.point);if(distance>maxDistance){maxDistance=distance;maxFace=faces[j]}}if(maxFace){this.addVertexToFace(vertex,maxFace)}}}}},{key:"reindexFaceAndVertices",value:function reindexFaceAndVertices(){var activeFaces=[];for(var i=0;i<this.faces.length;i+=1){var face=this.faces[i];if(face.mark===_Face.VISIBLE){activeFaces.push(face)}}this.faces=activeFaces}},{key:"collectFaces",value:function collectFaces(skipTriangulation){var faceIndices=[];for(var i=0;i<this.faces.length;i+=1){if(this.faces[i].mark!==_Face.VISIBLE){throw Error("attempt to include a destroyed face in the hull")}var indices=this.faces[i].collectIndices();if(skipTriangulation){faceIndices.push(indices)}else{for(var j=0;j<indices.length-2;j+=1){faceIndices.push([indices[0],indices[j+1],indices[j+2]])}}}return faceIndices}},{key:"nextVertexToAdd",value:function nextVertexToAdd(){if(!this.claimed.isEmpty()){var eyeVertex=undefined,vertex=undefined;var maxDistance=0;var eyeFace=this.claimed.first().face;for(vertex=eyeFace.outside;vertex&&vertex.face===eyeFace;vertex=vertex.next){var distance=eyeFace.distanceToPlane(vertex.point);if(distance>maxDistance){maxDistance=distance;eyeVertex=vertex}}return eyeVertex}}},{key:"computeHorizon",value:function computeHorizon(eyePoint,crossEdge,face,horizon){this.deleteFaceVertices(face);face.mark=_Face.DELETED;var edge=undefined;if(!crossEdge){edge=crossEdge=face.getEdge(0)}else{edge=crossEdge.next}do{var oppositeEdge=edge.opposite;var oppositeFace=oppositeEdge.face;if(oppositeFace.mark===_Face.VISIBLE){if(oppositeFace.distanceToPlane(eyePoint)>this.tolerance){this.computeHorizon(eyePoint,oppositeEdge,oppositeFace,horizon)}else{horizon.push(edge)}}edge=edge.next}while(edge!==crossEdge)}},{key:"addAdjoiningFace",value:function addAdjoiningFace(eyeVertex,horizonEdge){var face=_Face2.default.createTriangle(eyeVertex,horizonEdge.tail(),horizonEdge.head());this.faces.push(face);face.getEdge(-1).setOpposite(horizonEdge.opposite);return face.getEdge(0)}},{key:"addNewFaces",value:function addNewFaces(eyeVertex,horizon){this.newFaces=[];var firstSideEdge=undefined,previousSideEdge=undefined;for(var i=0;i<horizon.length;i+=1){var horizonEdge=horizon[i];var sideEdge=this.addAdjoiningFace(eyeVertex,horizonEdge);if(!firstSideEdge){firstSideEdge=sideEdge}else{sideEdge.next.setOpposite(previousSideEdge)}this.newFaces.push(sideEdge.face);previousSideEdge=sideEdge}firstSideEdge.next.setOpposite(previousSideEdge)}},{key:"getTriangulatedFaces",value:function getTriangulatedFaces(){var faces=[];for(var i=0;i<this.faces.length;i+=1){faces=faces.concat(this.faces[i].triangulate())}return faces}},{key:"oppositeFaceDistance",value:function oppositeFaceDistance(edge){return edge.face.distanceToPlane(edge.opposite.face.centroid)}},{key:"doAdjacentMerge",value:function doAdjacentMerge(face,mergeType){var edge=face.edge;var convex=true;var it=0;do{if(it>=face.nVertices){throw Error("merge recursion limit exceeded")}var oppositeFace=edge.opposite.face;var merge=false;if(mergeType===MERGE_NON_CONVEX){if(this.oppositeFaceDistance(edge)>-this.tolerance||this.oppositeFaceDistance(edge.opposite)>-this.tolerance){merge=true}}else{if(face.area>oppositeFace.area){if(this.oppositeFaceDistance(edge)>-this.tolerance){merge=true}else if(this.oppositeFaceDistance(edge.opposite)>-this.tolerance){convex=false}}else{if(this.oppositeFaceDistance(edge.opposite)>-this.tolerance){merge=true}else if(this.oppositeFaceDistance(edge)>-this.tolerance){convex=false}}if(merge){debug.logger("face merge");var discardedFaces=face.mergeAdjacentFaces(edge,[]);for(var i=0;i<discardedFaces.length;i+=1){this.deleteFaceVertices(discardedFaces[i],face)}return true}}edge=edge.next;it+=1}while(edge!==face.edge);if(!convex){face.mark=_Face.NON_CONVEX}return false}},{key:"addVertexToHull",value:function addVertexToHull(eyeVertex){var horizon=[];this.unclaimed.clear();this.removeVertexFromFace(eyeVertex,eyeVertex.face);this.computeHorizon(eyeVertex.point,null,eyeVertex.face,horizon);debug(function(){this.log("horizon %j",horizon.map(function(edge){return edge.head().index}))});this.addNewFaces(eyeVertex,horizon);debug.logger("first merge");for(var i=0;i<this.newFaces.length;i+=1){var face=this.newFaces[i];if(face.mark===_Face.VISIBLE){while(this.doAdjacentMerge(face,MERGE_NON_CONVEX_WRT_LARGER_FACE)){}}}debug.logger("second merge");for(var i=0;i<this.newFaces.length;i+=1){var face=this.newFaces[i];if(face.mark===_Face.NON_CONVEX){face.mark=_Face.VISIBLE;while(this.doAdjacentMerge(face,MERGE_NON_CONVEX)){}}}debug.logger("reassigning points to newFaces");this.resolveUnclaimedPoints(this.newFaces)}},{key:"build",value:function build(){var iterations=0;var eyeVertex=undefined;this.createInitialSimplex();while(eyeVertex=this.nextVertexToAdd()){iterations+=1;debug.logger("== iteration %j ==",iterations);debug.logger("next vertex to add = %d %j",eyeVertex.index,eyeVertex.point);this.addVertexToHull(eyeVertex);debug.logger("end")}this.reindexFaceAndVertices()}}]);return QuickHull}();exports.default=QuickHull;module.exports=exports["default"]},{"./Face":1,"./Vertex":4,"./VertexList":5,"debug-fn":6,"get-plane-normal":10,"gl-vec3/dot":15,"point-line-distance":23}],4:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var Vertex=function Vertex(point,index){_classCallCheck(this,Vertex);this.point=point;this.index=index;this.next=null;this.prev=null;this.face=null};exports.default=Vertex;module.exports=exports["default"]},{}],5:[function(require,module,exports){"use strict";var _createClass=function(){function defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}return function(Constructor,protoProps,staticProps){if(protoProps)defineProperties(Constructor.prototype,protoProps);if(staticProps)defineProperties(Constructor,staticProps);return Constructor}}();Object.defineProperty(exports,"__esModule",{value:true});function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var VertexList=function(){function VertexList(){_classCallCheck(this,VertexList);this.head=null;this.tail=null}_createClass(VertexList,[{key:"clear",value:function clear(){this.head=this.tail=null}},{key:"insertBefore",value:function insertBefore(target,node){node.prev=target.prev;node.next=target;if(!node.prev){this.head=node}else{node.prev.next=node}target.prev=node}},{key:"insertAfter",value:function insertAfter(target,node){node.prev=target;node.next=target.next;if(!node.next){this.tail=node}else{node.next.prev=node}target.next=node}},{key:"add",value:function add(node){if(!this.head){this.head=node}else{this.tail.next=node}node.prev=this.tail;node.next=null;this.tail=node}},{key:"addAll",value:function addAll(node){if(!this.head){this.head=node}else{this.tail.next=node}node.prev=this.tail;while(node.next){node=node.next}this.tail=node}},{key:"remove",value:function remove(node){if(!node.prev){this.head=node.next}else{node.prev.next=node.next}if(!node.next){this.tail=node.prev}else{node.next.prev=node.prev}}},{key:"removeChain",value:function removeChain(a,b){if(!a.prev){this.head=b.next}else{a.prev.next=b.next}if(!b.next){this.tail=a.prev}else{b.next.prev=a.prev}}},{key:"first",value:function first(){return this.head}},{key:"isEmpty",value:function isEmpty(){return!this.head}}]);return VertexList}();exports.default=VertexList;module.exports=exports["default"]},{}],6:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=function(ns){var logger=(0,_debug2.default)(ns);var scope={log:logger};function internal(fn){if(_debug2.default.enabled(ns)){fn.call(scope,logger)}}internal.logger=logger;return internal};var _debug=require("debug");var _debug2=_interopRequireDefault(_debug);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}module.exports=exports["default"]},{debug:7}],7:[function(require,module,exports){exports=module.exports=require("./debug");exports.log=log;exports.formatArgs=formatArgs;exports.save=save;exports.load=load;exports.useColors=useColors;exports.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:localstorage();exports.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"];function useColors(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}exports.formatters.j=function(v){return JSON.stringify(v)};function formatArgs(){var args=arguments;var useColors=this.useColors;args[0]=(useColors?"%c":"")+this.namespace+(useColors?" %c":" ")+args[0]+(useColors?"%c ":" ")+"+"+exports.humanize(this.diff);if(!useColors)return args;var c="color: "+this.color;args=[args[0],c,"color: inherit"].concat(Array.prototype.slice.call(args,1));var index=0;var lastC=0;args[0].replace(/%[a-z%]/g,function(match){if("%%"===match)return;index++;if("%c"===match){lastC=index}});args.splice(lastC,0,c);return args}function log(){return"object"===typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function save(namespaces){try{if(null==namespaces){exports.storage.removeItem("debug")}else{exports.storage.debug=namespaces}}catch(e){}}function load(){var r;try{r=exports.storage.debug}catch(e){}return r}exports.enable(load());function localstorage(){try{return window.localStorage}catch(e){}}},{"./debug":8}],8:[function(require,module,exports){exports=module.exports=debug;exports.coerce=coerce;exports.disable=disable;exports.enable=enable;exports.enabled=enabled;exports.humanize=require("ms");exports.names=[];exports.skips=[];exports.formatters={};var prevColor=0;var prevTime;function selectColor(){return exports.colors[prevColor++%exports.colors.length]}function debug(namespace){function disabled(){}disabled.enabled=false;function enabled(){var self=enabled;var curr=+new Date;var ms=curr-(prevTime||curr);self.diff=ms;self.prev=prevTime;self.curr=curr;prevTime=curr;if(null==self.useColors)self.useColors=exports.useColors();if(null==self.color&&self.useColors)self.color=selectColor();var args=Array.prototype.slice.call(arguments);args[0]=exports.coerce(args[0]);if("string"!==typeof args[0]){args=["%o"].concat(args)}var index=0;args[0]=args[0].replace(/%([a-z%])/g,function(match,format){if(match==="%%")return match;index++;var formatter=exports.formatters[format];if("function"===typeof formatter){var val=args[index];match=formatter.call(self,val);args.splice(index,1);index--}return match});if("function"===typeof exports.formatArgs){args=exports.formatArgs.apply(self,args)}var logFn=enabled.log||exports.log||console.log.bind(console);logFn.apply(self,args)}enabled.enabled=true;var fn=exports.enabled(namespace)?enabled:disabled;fn.namespace=namespace;return fn}function enable(namespaces){exports.save(namespaces);var split=(namespaces||"").split(/[\s,]+/);var len=split.length;for(var i=0;i<len;i++){if(!split[i])continue;namespaces=split[i].replace(/\*/g,".*?");if(namespaces[0]==="-"){exports.skips.push(new RegExp("^"+namespaces.substr(1)+"$"))}else{exports.names.push(new RegExp("^"+namespaces+"$"))}}}function disable(){exports.enable("")}function enabled(name){var i,len;for(i=0,len=exports.skips.length;i<len;i++){if(exports.skips[i].test(name)){return false}}for(i=0,len=exports.names.length;i<len;i++){if(exports.names[i].test(name)){return true}}return false}function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}},{ms:9}],9:[function(require,module,exports){var s=1e3;var m=s*60;var h=m*60;var d=h*24;var y=d*365.25;module.exports=function(val,options){options=options||{};if("string"==typeof val)return parse(val);return options.long?long(val):short(val)};function parse(str){str=""+str;if(str.length>1e4)return;var match=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);if(!match)return;var n=parseFloat(match[1]);var type=(match[2]||"ms").toLowerCase();switch(type){case"years":case"year":case"yrs":case"yr":case"y":return n*y;case"days":case"day":case"d":return n*d;case"hours":case"hour":case"hrs":case"hr":case"h":return n*h;case"minutes":case"minute":case"mins":case"min":case"m":return n*m;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n}}function short(ms){if(ms>=d)return Math.round(ms/d)+"d";if(ms>=h)return Math.round(ms/h)+"h";if(ms>=m)return Math.round(ms/m)+"m";if(ms>=s)return Math.round(ms/s)+"s";return ms+"ms"}function long(ms){return plural(ms,d,"day")||plural(ms,h,"hour")||plural(ms,m,"minute")||plural(ms,s,"second")||ms+" ms"}function plural(ms,n,name){if(ms<n)return;if(ms<n*1.5)return Math.floor(ms/n)+" "+name;return Math.ceil(ms/n)+" "+name+"s"}},{}],10:[function(require,module,exports){var normalize=require("gl-vec3/normalize");var sub=require("gl-vec3/subtract");var cross=require("gl-vec3/cross");var tmp=[0,0,0];module.exports=planeNormal;function planeNormal(out,point1,point2,point3){sub(out,point1,point2);sub(tmp,point2,point3);cross(out,out,tmp);return normalize(out,out)}},{"gl-vec3/cross":13,"gl-vec3/normalize":17,"gl-vec3/subtract":22}],11:[function(require,module,exports){module.exports=add;function add(out,a,b){out[0]=a[0]+b[0];out[1]=a[1]+b[1];out[2]=a[2]+b[2];return out}},{}],12:[function(require,module,exports){module.exports=copy;function copy(out,a){out[0]=a[0];out[1]=a[1];out[2]=a[2];return out}},{}],13:[function(require,module,exports){module.exports=cross;function cross(out,a,b){var ax=a[0],ay=a[1],az=a[2],bx=b[0],by=b[1],bz=b[2];out[0]=ay*bz-az*by;out[1]=az*bx-ax*bz;out[2]=ax*by-ay*bx;return out}},{}],14:[function(require,module,exports){module.exports=distance;function distance(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return Math.sqrt(x*x+y*y+z*z)}},{}],15:[function(require,module,exports){module.exports=dot;function dot(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]}},{}],16:[function(require,module,exports){module.exports=length;function length(a){var x=a[0],y=a[1],z=a[2];return Math.sqrt(x*x+y*y+z*z)}},{}],17:[function(require,module,exports){module.exports=normalize;function normalize(out,a){var x=a[0],y=a[1],z=a[2];var len=x*x+y*y+z*z;if(len>0){len=1/Math.sqrt(len);out[0]=a[0]*len;out[1]=a[1]*len;out[2]=a[2]*len}return out}},{}],18:[function(require,module,exports){module.exports=scale;function scale(out,a,b){out[0]=a[0]*b;out[1]=a[1]*b;out[2]=a[2]*b;
return out}},{}],19:[function(require,module,exports){module.exports=scaleAndAdd;function scaleAndAdd(out,a,b,scale){out[0]=a[0]+b[0]*scale;out[1]=a[1]+b[1]*scale;out[2]=a[2]+b[2]*scale;return out}},{}],20:[function(require,module,exports){module.exports=squaredDistance;function squaredDistance(a,b){var x=b[0]-a[0],y=b[1]-a[1],z=b[2]-a[2];return x*x+y*y+z*z}},{}],21:[function(require,module,exports){module.exports=squaredLength;function squaredLength(a){var x=a[0],y=a[1],z=a[2];return x*x+y*y+z*z}},{}],22:[function(require,module,exports){module.exports=subtract;function subtract(out,a,b){out[0]=a[0]-b[0];out[1]=a[1]-b[1];out[2]=a[2]-b[2];return out}},{}],23:[function(require,module,exports){"use strict";var distanceSquared=require("./squared");module.exports=function(point,a,b){return Math.sqrt(distanceSquared(point,a,b))}},{"./squared":24}],24:[function(require,module,exports){var subtract=require("gl-vec3/subtract");var cross=require("gl-vec3/cross");var squaredLength=require("gl-vec3/squaredLength");var ab=[];var ap=[];var cr=[];module.exports=function(p,a,b){subtract(ab,b,a);subtract(ap,p,a);var area=squaredLength(cross(cr,ap,ab));var s=squaredLength(ab);if(s===0){throw Error("a and b are the same point")}return area/s}},{"gl-vec3/cross":13,"gl-vec3/squaredLength":21,"gl-vec3/subtract":22}],quickhull3d:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=runner;var _QuickHull=require("./QuickHull");var _QuickHull2=_interopRequireDefault(_QuickHull);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function runner(points){var options=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];var instance=new _QuickHull2.default(points);instance.build();return instance.collectFaces(options.skipTriangulation)}module.exports=exports["default"]},{"./QuickHull":3}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){module.exports=require("./vendor/dat.gui");module.exports.color=require("./vendor/dat.color")},{"./vendor/dat.color":2,"./vendor/dat.gui":3}],2:[function(require,module,exports){var dat=module.exports=dat||{};dat.color=dat.color||{};dat.utils=dat.utils||{};dat.utils.common=function(){var ARR_EACH=Array.prototype.forEach;var ARR_SLICE=Array.prototype.slice;return{BREAK:{},extend:function(target){this.each(ARR_SLICE.call(arguments,1),function(obj){for(var key in obj)if(!this.isUndefined(obj[key]))target[key]=obj[key]},this);return target},defaults:function(target){this.each(ARR_SLICE.call(arguments,1),function(obj){for(var key in obj)if(this.isUndefined(target[key]))target[key]=obj[key]},this);return target},compose:function(){var toCall=ARR_SLICE.call(arguments);return function(){var args=ARR_SLICE.call(arguments);for(var i=toCall.length-1;i>=0;i--){args=[toCall[i].apply(this,args)]}return args[0]}},each:function(obj,itr,scope){if(ARR_EACH&&obj.forEach===ARR_EACH){obj.forEach(itr,scope)}else if(obj.length===obj.length+0){for(var key=0,l=obj.length;key<l;key++)if(key in obj&&itr.call(scope,obj[key],key)===this.BREAK)return}else{for(var key in obj)if(itr.call(scope,obj[key],key)===this.BREAK)return}},defer:function(fnc){setTimeout(fnc,0)},toArray:function(obj){if(obj.toArray)return obj.toArray();return ARR_SLICE.call(obj)},isUndefined:function(obj){return obj===undefined},isNull:function(obj){return obj===null},isNaN:function(obj){return obj!==obj},isArray:Array.isArray||function(obj){return obj.constructor===Array},isObject:function(obj){return obj===Object(obj)},isNumber:function(obj){return obj===obj+0},isString:function(obj){return obj===obj+""},isBoolean:function(obj){return obj===false||obj===true},isFunction:function(obj){return Object.prototype.toString.call(obj)==="[object Function]"}}}();dat.color.toString=function(common){return function(color){if(color.a==1||common.isUndefined(color.a)){var s=color.hex.toString(16);while(s.length<6){s="0"+s}return"#"+s}else{return"rgba("+Math.round(color.r)+","+Math.round(color.g)+","+Math.round(color.b)+","+color.a+")"}}}(dat.utils.common);dat.Color=dat.color.Color=function(interpret,math,toString,common){var Color=function(){this.__state=interpret.apply(this,arguments);if(this.__state===false){throw"Failed to interpret color arguments"}this.__state.a=this.__state.a||1};Color.COMPONENTS=["r","g","b","h","s","v","hex","a"];common.extend(Color.prototype,{toString:function(){return toString(this)},toOriginal:function(){return this.__state.conversion.write(this)}});defineRGBComponent(Color.prototype,"r",2);defineRGBComponent(Color.prototype,"g",1);defineRGBComponent(Color.prototype,"b",0);defineHSVComponent(Color.prototype,"h");defineHSVComponent(Color.prototype,"s");defineHSVComponent(Color.prototype,"v");Object.defineProperty(Color.prototype,"a",{get:function(){return this.__state.a},set:function(v){this.__state.a=v}});Object.defineProperty(Color.prototype,"hex",{get:function(){if(!this.__state.space!=="HEX"){this.__state.hex=math.rgb_to_hex(this.r,this.g,this.b)}return this.__state.hex},set:function(v){this.__state.space="HEX";this.__state.hex=v}});function defineRGBComponent(target,component,componentHexIndex){Object.defineProperty(target,component,{get:function(){if(this.__state.space==="RGB"){return this.__state[component]}recalculateRGB(this,component,componentHexIndex);return this.__state[component]},set:function(v){if(this.__state.space!=="RGB"){recalculateRGB(this,component,componentHexIndex);this.__state.space="RGB"}this.__state[component]=v}})}function defineHSVComponent(target,component){Object.defineProperty(target,component,{get:function(){if(this.__state.space==="HSV")return this.__state[component];recalculateHSV(this);return this.__state[component]},set:function(v){if(this.__state.space!=="HSV"){recalculateHSV(this);this.__state.space="HSV"}this.__state[component]=v}})}function recalculateRGB(color,component,componentHexIndex){if(color.__state.space==="HEX"){color.__state[component]=math.component_from_hex(color.__state.hex,componentHexIndex)}else if(color.__state.space==="HSV"){common.extend(color.__state,math.hsv_to_rgb(color.__state.h,color.__state.s,color.__state.v))}else{throw"Corrupted color state"}}function recalculateHSV(color){var result=math.rgb_to_hsv(color.r,color.g,color.b);common.extend(color.__state,{s:result.s,v:result.v});if(!common.isNaN(result.h)){color.__state.h=result.h}else if(common.isUndefined(color.__state.h)){color.__state.h=0}}return Color}(dat.color.interpret=function(toString,common){var result,toReturn;var interpret=function(){toReturn=false;var original=arguments.length>1?common.toArray(arguments):arguments[0];common.each(INTERPRETATIONS,function(family){if(family.litmus(original)){common.each(family.conversions,function(conversion,conversionName){result=conversion.read(original);if(toReturn===false&&result!==false){toReturn=result;result.conversionName=conversionName;result.conversion=conversion;return common.BREAK}});return common.BREAK}});return toReturn};var INTERPRETATIONS=[{litmus:common.isString,conversions:{THREE_CHAR_HEX:{read:function(original){var test=original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);if(test===null)return false;return{space:"HEX",hex:parseInt("0x"+test[1].toString()+test[1].toString()+test[2].toString()+test[2].toString()+test[3].toString()+test[3].toString())}},write:toString},SIX_CHAR_HEX:{read:function(original){var test=original.match(/^#([A-F0-9]{6})$/i);if(test===null)return false;return{space:"HEX",hex:parseInt("0x"+test[1].toString())}},write:toString},CSS_RGB:{read:function(original){var test=original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);if(test===null)return false;return{space:"RGB",r:parseFloat(test[1]),g:parseFloat(test[2]),b:parseFloat(test[3])}},write:toString},CSS_RGBA:{read:function(original){var test=original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);if(test===null)return false;return{space:"RGB",r:parseFloat(test[1]),g:parseFloat(test[2]),b:parseFloat(test[3]),a:parseFloat(test[4])}},write:toString}}},{litmus:common.isNumber,conversions:{HEX:{read:function(original){return{space:"HEX",hex:original,conversionName:"HEX"}},write:function(color){return color.hex}}}},{litmus:common.isArray,conversions:{RGB_ARRAY:{read:function(original){if(original.length!=3)return false;return{space:"RGB",r:original[0],g:original[1],b:original[2]}},write:function(color){return[color.r,color.g,color.b]}},RGBA_ARRAY:{read:function(original){if(original.length!=4)return false;return{space:"RGB",r:original[0],g:original[1],b:original[2],a:original[3]}},write:function(color){return[color.r,color.g,color.b,color.a]}}}},{litmus:common.isObject,conversions:{RGBA_OBJ:{read:function(original){if(common.isNumber(original.r)&&common.isNumber(original.g)&&common.isNumber(original.b)&&common.isNumber(original.a)){return{space:"RGB",r:original.r,g:original.g,b:original.b,a:original.a}}return false},write:function(color){return{r:color.r,g:color.g,b:color.b,a:color.a}}},RGB_OBJ:{read:function(original){if(common.isNumber(original.r)&&common.isNumber(original.g)&&common.isNumber(original.b)){return{space:"RGB",r:original.r,g:original.g,b:original.b}}return false},write:function(color){return{r:color.r,g:color.g,b:color.b}}},HSVA_OBJ:{read:function(original){if(common.isNumber(original.h)&&common.isNumber(original.s)&&common.isNumber(original.v)&&common.isNumber(original.a)){return{space:"HSV",h:original.h,s:original.s,v:original.v,a:original.a}}return false},write:function(color){return{h:color.h,s:color.s,v:color.v,a:color.a}}},HSV_OBJ:{read:function(original){if(common.isNumber(original.h)&&common.isNumber(original.s)&&common.isNumber(original.v)){return{space:"HSV",h:original.h,s:original.s,v:original.v}}return false},write:function(color){return{h:color.h,s:color.s,v:color.v}}}}}];return interpret}(dat.color.toString,dat.utils.common),dat.color.math=function(){var tmpComponent;return{hsv_to_rgb:function(h,s,v){var hi=Math.floor(h/60)%6;var f=h/60-Math.floor(h/60);var p=v*(1-s);var q=v*(1-f*s);var t=v*(1-(1-f)*s);var c=[[v,t,p],[q,v,p],[p,v,t],[p,q,v],[t,p,v],[v,p,q]][hi];return{r:c[0]*255,g:c[1]*255,b:c[2]*255}},rgb_to_hsv:function(r,g,b){var min=Math.min(r,g,b),max=Math.max(r,g,b),delta=max-min,h,s;if(max!=0){s=delta/max}else{return{h:NaN,s:0,v:0}}if(r==max){h=(g-b)/delta}else if(g==max){h=2+(b-r)/delta}else{h=4+(r-g)/delta}h/=6;if(h<0){h+=1}return{h:h*360,s:s,v:max/255}},rgb_to_hex:function(r,g,b){var hex=this.hex_with_component(0,2,r);hex=this.hex_with_component(hex,1,g);hex=this.hex_with_component(hex,0,b);return hex},component_from_hex:function(hex,componentIndex){return hex>>componentIndex*8&255},hex_with_component:function(hex,componentIndex,value){return value<<(tmpComponent=componentIndex*8)|hex&~(255<<tmpComponent)}}}(),dat.color.toString,dat.utils.common)},{}],3:[function(require,module,exports){var dat=module.exports=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(url,doc){doc=doc||document;var link=doc.createElement("link");link.type="text/css";link.rel="stylesheet";link.href=url;doc.getElementsByTagName("head")[0].appendChild(link)},inject:function(css,doc){doc=doc||document;var injected=document.createElement("style");injected.type="text/css";injected.innerHTML=css;doc.getElementsByTagName("head")[0].appendChild(injected)}}}();dat.utils.common=function(){var ARR_EACH=Array.prototype.forEach;var ARR_SLICE=Array.prototype.slice;return{BREAK:{},extend:function(target){this.each(ARR_SLICE.call(arguments,1),function(obj){for(var key in obj)if(!this.isUndefined(obj[key]))target[key]=obj[key]},this);return target},defaults:function(target){this.each(ARR_SLICE.call(arguments,1),function(obj){for(var key in obj)if(this.isUndefined(target[key]))target[key]=obj[key]},this);return target},compose:function(){var toCall=ARR_SLICE.call(arguments);return function(){var args=ARR_SLICE.call(arguments);for(var i=toCall.length-1;i>=0;i--){args=[toCall[i].apply(this,args)]}return args[0]}},each:function(obj,itr,scope){if(ARR_EACH&&obj.forEach===ARR_EACH){obj.forEach(itr,scope)}else if(obj.length===obj.length+0){for(var key=0,l=obj.length;key<l;key++)if(key in obj&&itr.call(scope,obj[key],key)===this.BREAK)return}else{for(var key in obj)if(itr.call(scope,obj[key],key)===this.BREAK)return}},defer:function(fnc){setTimeout(fnc,0)},toArray:function(obj){if(obj.toArray)return obj.toArray();return ARR_SLICE.call(obj)},isUndefined:function(obj){return obj===undefined},isNull:function(obj){return obj===null},isNaN:function(obj){return obj!==obj},isArray:Array.isArray||function(obj){return obj.constructor===Array},isObject:function(obj){return obj===Object(obj)},isNumber:function(obj){return obj===obj+0},isString:function(obj){return obj===obj+""},isBoolean:function(obj){return obj===false||obj===true},isFunction:function(obj){return Object.prototype.toString.call(obj)==="[object Function]"}}}();dat.controllers.Controller=function(common){var Controller=function(object,property){this.initialValue=object[property];this.domElement=document.createElement("div");this.object=object;this.property=property;this.__onChange=undefined;this.__onFinishChange=undefined};common.extend(Controller.prototype,{onChange:function(fnc){this.__onChange=fnc;return this},onFinishChange:function(fnc){this.__onFinishChange=fnc;return this},setValue:function(newValue){this.object[this.property]=newValue;if(this.__onChange){this.__onChange.call(this,newValue)}this.updateDisplay();return this},getValue:function(){return this.object[this.property]},updateDisplay:function(){return this},isModified:function(){return this.initialValue!==this.getValue()}});return Controller}(dat.utils.common);dat.dom.dom=function(common){var EVENT_MAP={HTMLEvents:["change"],MouseEvents:["click","mousemove","mousedown","mouseup","mouseover"],KeyboardEvents:["keydown"]};var EVENT_MAP_INV={};common.each(EVENT_MAP,function(v,k){common.each(v,function(e){EVENT_MAP_INV[e]=k})});var CSS_VALUE_PIXELS=/(\d+(\.\d+)?)px/;function cssValueToPixels(val){if(val==="0"||common.isUndefined(val))return 0;var match=val.match(CSS_VALUE_PIXELS);if(!common.isNull(match)){return parseFloat(match[1])}return 0}var dom={makeSelectable:function(elem,selectable){if(elem===undefined||elem.style===undefined)return;elem.onselectstart=selectable?function(){return false}:function(){};elem.style.MozUserSelect=selectable?"auto":"none";elem.style.KhtmlUserSelect=selectable?"auto":"none";elem.unselectable=selectable?"on":"off"},makeFullscreen:function(elem,horizontal,vertical){if(common.isUndefined(horizontal))horizontal=true;if(common.isUndefined(vertical))vertical=true;elem.style.position="absolute";if(horizontal){elem.style.left=0;elem.style.right=0}if(vertical){elem.style.top=0;elem.style.bottom=0}},fakeEvent:function(elem,eventType,params,aux){params=params||{};var className=EVENT_MAP_INV[eventType];if(!className){throw new Error("Event type "+eventType+" not supported.")}var evt=document.createEvent(className);switch(className){case"MouseEvents":var clientX=params.x||params.clientX||0;var clientY=params.y||params.clientY||0;evt.initMouseEvent(eventType,params.bubbles||false,params.cancelable||true,window,params.clickCount||1,0,0,clientX,clientY,false,false,false,false,0,null);break;case"KeyboardEvents":var init=evt.initKeyboardEvent||evt.initKeyEvent;common.defaults(params,{cancelable:true,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false,keyCode:undefined,charCode:undefined});init(eventType,params.bubbles||false,params.cancelable,window,params.ctrlKey,params.altKey,params.shiftKey,params.metaKey,params.keyCode,params.charCode);break;default:evt.initEvent(eventType,params.bubbles||false,params.cancelable||true);break}common.defaults(evt,aux);elem.dispatchEvent(evt)},bind:function(elem,event,func,bool){bool=bool||false;if(elem.addEventListener)elem.addEventListener(event,func,bool);else if(elem.attachEvent)elem.attachEvent("on"+event,func);return dom},unbind:function(elem,event,func,bool){bool=bool||false;if(elem.removeEventListener)elem.removeEventListener(event,func,bool);else if(elem.detachEvent)elem.detachEvent("on"+event,func);return dom},addClass:function(elem,className){if(elem.className===undefined){elem.className=className}else if(elem.className!==className){var classes=elem.className.split(/ +/);if(classes.indexOf(className)==-1){classes.push(className);elem.className=classes.join(" ").replace(/^\s+/,"").replace(/\s+$/,"")}}return dom},removeClass:function(elem,className){if(className){if(elem.className===undefined){}else if(elem.className===className){elem.removeAttribute("class")}else{var classes=elem.className.split(/ +/);var index=classes.indexOf(className);if(index!=-1){classes.splice(index,1);elem.className=classes.join(" ")}}}else{elem.className=undefined}return dom},hasClass:function(elem,className){return new RegExp("(?:^|\\s+)"+className+"(?:\\s+|$)").test(elem.className)||false},getWidth:function(elem){var style=getComputedStyle(elem);return cssValueToPixels(style["border-left-width"])+cssValueToPixels(style["border-right-width"])+cssValueToPixels(style["padding-left"])+cssValueToPixels(style["padding-right"])+cssValueToPixels(style["width"])},getHeight:function(elem){var style=getComputedStyle(elem);return cssValueToPixels(style["border-top-width"])+cssValueToPixels(style["border-bottom-width"])+cssValueToPixels(style["padding-top"])+cssValueToPixels(style["padding-bottom"])+cssValueToPixels(style["height"])},getOffset:function(elem){var offset={left:0,top:0};if(elem.offsetParent){do{offset.left+=elem.offsetLeft;offset.top+=elem.offsetTop}while(elem=elem.offsetParent)}return offset},isActive:function(elem){return elem===document.activeElement&&(elem.type||elem.href)}};return dom}(dat.utils.common);dat.controllers.OptionController=function(Controller,dom,common){var OptionController=function(object,property,options){OptionController.superclass.call(this,object,property);var _this=this;this.__select=document.createElement("select");if(common.isArray(options)){var map={};common.each(options,function(element){map[element]=element});options=map}common.each(options,function(value,key){var opt=document.createElement("option");opt.innerHTML=key;opt.setAttribute("value",value);_this.__select.appendChild(opt)});this.updateDisplay();dom.bind(this.__select,"change",function(){var desiredValue=this.options[this.selectedIndex].value;_this.setValue(desiredValue)});this.domElement.appendChild(this.__select)};OptionController.superclass=Controller;common.extend(OptionController.prototype,Controller.prototype,{setValue:function(v){var toReturn=OptionController.superclass.prototype.setValue.call(this,v);if(this.__onFinishChange){this.__onFinishChange.call(this,this.getValue())}return toReturn},updateDisplay:function(){this.__select.value=this.getValue();return OptionController.superclass.prototype.updateDisplay.call(this)}});return OptionController}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);dat.controllers.NumberController=function(Controller,common){var NumberController=function(object,property,params){NumberController.superclass.call(this,object,property);params=params||{};this.__min=params.min;this.__max=params.max;this.__step=params.step;if(common.isUndefined(this.__step)){if(this.initialValue==0){this.__impliedStep=1}else{this.__impliedStep=Math.pow(10,Math.floor(Math.log(this.initialValue)/Math.LN10))/10}}else{this.__impliedStep=this.__step}this.__precision=numDecimals(this.__impliedStep)};NumberController.superclass=Controller;common.extend(NumberController.prototype,Controller.prototype,{setValue:function(v){if(this.__min!==undefined&&v<this.__min){v=this.__min}else if(this.__max!==undefined&&v>this.__max){v=this.__max}if(this.__step!==undefined&&v%this.__step!=0){v=Math.round(v/this.__step)*this.__step}return NumberController.superclass.prototype.setValue.call(this,v)},min:function(v){this.__min=v;return this},max:function(v){this.__max=v;return this},step:function(v){this.__step=v;return this}});function numDecimals(x){x=x.toString();if(x.indexOf(".")>-1){return x.length-x.indexOf(".")-1}else{return 0}}return NumberController}(dat.controllers.Controller,dat.utils.common);dat.controllers.NumberControllerBox=function(NumberController,dom,common){var NumberControllerBox=function(object,property,params){this.__truncationSuspended=false;NumberControllerBox.superclass.call(this,object,property,params);var _this=this;var prev_y;this.__input=document.createElement("input");this.__input.setAttribute("type","text");dom.bind(this.__input,"change",onChange);dom.bind(this.__input,"blur",onBlur);dom.bind(this.__input,"mousedown",onMouseDown);dom.bind(this.__input,"keydown",function(e){if(e.keyCode===13){_this.__truncationSuspended=true;this.blur();_this.__truncationSuspended=false}});function onChange(){var attempted=parseFloat(_this.__input.value);if(!common.isNaN(attempted))_this.setValue(attempted)}function onBlur(){onChange();if(_this.__onFinishChange){_this.__onFinishChange.call(_this,_this.getValue())}}function onMouseDown(e){dom.bind(window,"mousemove",onMouseDrag);dom.bind(window,"mouseup",onMouseUp);prev_y=e.clientY}function onMouseDrag(e){var diff=prev_y-e.clientY;_this.setValue(_this.getValue()+diff*_this.__impliedStep);prev_y=e.clientY}function onMouseUp(){dom.unbind(window,"mousemove",onMouseDrag);dom.unbind(window,"mouseup",onMouseUp)}this.updateDisplay();this.domElement.appendChild(this.__input)};NumberControllerBox.superclass=NumberController;common.extend(NumberControllerBox.prototype,NumberController.prototype,{updateDisplay:function(){this.__input.value=this.__truncationSuspended?this.getValue():roundToDecimal(this.getValue(),this.__precision);return NumberControllerBox.superclass.prototype.updateDisplay.call(this)}});function roundToDecimal(value,decimals){var tenTo=Math.pow(10,decimals);return Math.round(value*tenTo)/tenTo}return NumberControllerBox}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common);dat.controllers.NumberControllerSlider=function(NumberController,dom,css,common,styleSheet){var NumberControllerSlider=function(object,property,min,max,step){NumberControllerSlider.superclass.call(this,object,property,{min:min,max:max,step:step});var _this=this;this.__background=document.createElement("div");this.__foreground=document.createElement("div");dom.bind(this.__background,"mousedown",onMouseDown);dom.addClass(this.__background,"slider");dom.addClass(this.__foreground,"slider-fg");function onMouseDown(e){dom.bind(window,"mousemove",onMouseDrag);dom.bind(window,"mouseup",onMouseUp);onMouseDrag(e)}function onMouseDrag(e){e.preventDefault();var offset=dom.getOffset(_this.__background);var width=dom.getWidth(_this.__background);_this.setValue(map(e.clientX,offset.left,offset.left+width,_this.__min,_this.__max));return false}function onMouseUp(){dom.unbind(window,"mousemove",onMouseDrag);dom.unbind(window,"mouseup",onMouseUp);if(_this.__onFinishChange){_this.__onFinishChange.call(_this,_this.getValue())}}this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};NumberControllerSlider.superclass=NumberController;NumberControllerSlider.useDefaultStyles=function(){css.inject(styleSheet)};common.extend(NumberControllerSlider.prototype,NumberController.prototype,{updateDisplay:function(){var pct=(this.getValue()-this.__min)/(this.__max-this.__min);this.__foreground.style.width=pct*100+"%";return NumberControllerSlider.superclass.prototype.updateDisplay.call(this)}});function map(v,i1,i2,o1,o2){return o1+(o2-o1)*((v-i1)/(i2-i1))}return NumberControllerSlider}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,".slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}");dat.controllers.FunctionController=function(Controller,dom,common){var FunctionController=function(object,property,text){FunctionController.superclass.call(this,object,property);var _this=this;this.__button=document.createElement("div");this.__button.innerHTML=text===undefined?"Fire":text;dom.bind(this.__button,"click",function(e){e.preventDefault();_this.fire();return false});dom.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};FunctionController.superclass=Controller;common.extend(FunctionController.prototype,Controller.prototype,{fire:function(){if(this.__onChange){this.__onChange.call(this)}if(this.__onFinishChange){this.__onFinishChange.call(this,this.getValue())}this.getValue().call(this.object)}});return FunctionController}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);dat.controllers.BooleanController=function(Controller,dom,common){var BooleanController=function(object,property){BooleanController.superclass.call(this,object,property);var _this=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");dom.bind(this.__checkbox,"change",onChange,false);this.domElement.appendChild(this.__checkbox);this.updateDisplay();function onChange(){_this.setValue(!_this.__prev)}};BooleanController.superclass=Controller;common.extend(BooleanController.prototype,Controller.prototype,{setValue:function(v){var toReturn=BooleanController.superclass.prototype.setValue.call(this,v);if(this.__onFinishChange){this.__onFinishChange.call(this,this.getValue())}this.__prev=this.getValue();return toReturn},updateDisplay:function(){if(this.getValue()===true){this.__checkbox.setAttribute("checked","checked");this.__checkbox.checked=true}else{this.__checkbox.checked=false}return BooleanController.superclass.prototype.updateDisplay.call(this)}});return BooleanController}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);dat.color.toString=function(common){return function(color){if(color.a==1||common.isUndefined(color.a)){var s=color.hex.toString(16);while(s.length<6){s="0"+s}return"#"+s}else{return"rgba("+Math.round(color.r)+","+Math.round(color.g)+","+Math.round(color.b)+","+color.a+")"}}}(dat.utils.common);dat.color.interpret=function(toString,common){var result,toReturn;var interpret=function(){toReturn=false;var original=arguments.length>1?common.toArray(arguments):arguments[0];common.each(INTERPRETATIONS,function(family){if(family.litmus(original)){common.each(family.conversions,function(conversion,conversionName){result=conversion.read(original);if(toReturn===false&&result!==false){toReturn=result;result.conversionName=conversionName;result.conversion=conversion;return common.BREAK}});return common.BREAK}});return toReturn};var INTERPRETATIONS=[{litmus:common.isString,conversions:{THREE_CHAR_HEX:{read:function(original){var test=original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);if(test===null)return false;return{space:"HEX",hex:parseInt("0x"+test[1].toString()+test[1].toString()+test[2].toString()+test[2].toString()+test[3].toString()+test[3].toString())}},write:toString},SIX_CHAR_HEX:{read:function(original){var test=original.match(/^#([A-F0-9]{6})$/i);if(test===null)return false;return{space:"HEX",hex:parseInt("0x"+test[1].toString())}},write:toString},CSS_RGB:{read:function(original){var test=original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);if(test===null)return false;return{space:"RGB",r:parseFloat(test[1]),g:parseFloat(test[2]),b:parseFloat(test[3])}},write:toString},CSS_RGBA:{read:function(original){var test=original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);if(test===null)return false;return{space:"RGB",r:parseFloat(test[1]),g:parseFloat(test[2]),b:parseFloat(test[3]),a:parseFloat(test[4])}},write:toString}}},{litmus:common.isNumber,conversions:{HEX:{read:function(original){return{space:"HEX",hex:original,conversionName:"HEX"}},write:function(color){return color.hex}}}},{litmus:common.isArray,conversions:{RGB_ARRAY:{read:function(original){if(original.length!=3)return false;return{space:"RGB",r:original[0],g:original[1],b:original[2]}},write:function(color){return[color.r,color.g,color.b]}},RGBA_ARRAY:{read:function(original){if(original.length!=4)return false;return{space:"RGB",r:original[0],g:original[1],b:original[2],a:original[3]}},write:function(color){return[color.r,color.g,color.b,color.a]}}}},{litmus:common.isObject,conversions:{RGBA_OBJ:{read:function(original){if(common.isNumber(original.r)&&common.isNumber(original.g)&&common.isNumber(original.b)&&common.isNumber(original.a)){return{space:"RGB",r:original.r,g:original.g,b:original.b,a:original.a}}return false},write:function(color){return{r:color.r,g:color.g,b:color.b,a:color.a}}},RGB_OBJ:{read:function(original){if(common.isNumber(original.r)&&common.isNumber(original.g)&&common.isNumber(original.b)){return{space:"RGB",r:original.r,g:original.g,b:original.b}}return false},write:function(color){return{r:color.r,g:color.g,b:color.b}}},HSVA_OBJ:{read:function(original){if(common.isNumber(original.h)&&common.isNumber(original.s)&&common.isNumber(original.v)&&common.isNumber(original.a)){return{space:"HSV",h:original.h,s:original.s,v:original.v,a:original.a}}return false},write:function(color){return{h:color.h,s:color.s,v:color.v,a:color.a}}},HSV_OBJ:{read:function(original){if(common.isNumber(original.h)&&common.isNumber(original.s)&&common.isNumber(original.v)){return{space:"HSV",h:original.h,s:original.s,v:original.v}}return false},write:function(color){return{h:color.h,s:color.s,v:color.v}}}}}];return interpret}(dat.color.toString,dat.utils.common);dat.GUI=dat.gui.GUI=function(css,saveDialogueContents,styleSheet,controllerFactory,Controller,BooleanController,FunctionController,NumberControllerBox,NumberControllerSlider,OptionController,ColorController,requestAnimationFrame,CenteredDiv,dom,common){css.inject(styleSheet);var CSS_NAMESPACE="dg";var HIDE_KEY_CODE=72;var CLOSE_BUTTON_HEIGHT=20;var DEFAULT_DEFAULT_PRESET_NAME="Default";var SUPPORTS_LOCAL_STORAGE=function(){try{return"localStorage"in window&&window["localStorage"]!==null}catch(e){return false}}();var SAVE_DIALOGUE;var auto_place_virgin=true;var auto_place_container;var hide=false;var hideable_guis=[];var GUI=function(params){var _this=this;this.domElement=document.createElement("div");this.__ul=document.createElement("ul");this.domElement.appendChild(this.__ul);dom.addClass(this.domElement,CSS_NAMESPACE);this.__folders={};this.__controllers=[];this.__rememberedObjects=[];this.__rememberedObjectIndecesToControllers=[];this.__listening=[];params=params||{};params=common.defaults(params,{autoPlace:true,width:GUI.DEFAULT_WIDTH});params=common.defaults(params,{resizable:params.autoPlace,hideable:params.autoPlace});if(!common.isUndefined(params.load)){if(params.preset)params.load.preset=params.preset}else{params.load={preset:DEFAULT_DEFAULT_PRESET_NAME}}if(common.isUndefined(params.parent)&&params.hideable){hideable_guis.push(this)}params.resizable=common.isUndefined(params.parent)&&params.resizable;if(params.autoPlace&&common.isUndefined(params.scrollable)){params.scrollable=true}var use_local_storage=SUPPORTS_LOCAL_STORAGE&&localStorage.getItem(getLocalStorageHash(this,"isLocal"))==="true";
Object.defineProperties(this,{parent:{get:function(){return params.parent}},scrollable:{get:function(){return params.scrollable}},autoPlace:{get:function(){return params.autoPlace}},preset:{get:function(){if(_this.parent){return _this.getRoot().preset}else{return params.load.preset}},set:function(v){if(_this.parent){_this.getRoot().preset=v}else{params.load.preset=v}setPresetSelectIndex(this);_this.revert()}},width:{get:function(){return params.width},set:function(v){params.width=v;setWidth(_this,v)}},name:{get:function(){return params.name},set:function(v){params.name=v;if(title_row_name){title_row_name.innerHTML=params.name}}},closed:{get:function(){return params.closed},set:function(v){params.closed=v;if(params.closed){dom.addClass(_this.__ul,GUI.CLASS_CLOSED)}else{dom.removeClass(_this.__ul,GUI.CLASS_CLOSED)}this.onResize();if(_this.__closeButton){_this.__closeButton.innerHTML=v?GUI.TEXT_OPEN:GUI.TEXT_CLOSED}}},load:{get:function(){return params.load}},useLocalStorage:{get:function(){return use_local_storage},set:function(bool){if(SUPPORTS_LOCAL_STORAGE){use_local_storage=bool;if(bool){dom.bind(window,"unload",saveToLocalStorage)}else{dom.unbind(window,"unload",saveToLocalStorage)}localStorage.setItem(getLocalStorageHash(_this,"isLocal"),bool)}}}});if(common.isUndefined(params.parent)){params.closed=false;dom.addClass(this.domElement,GUI.CLASS_MAIN);dom.makeSelectable(this.domElement,false);if(SUPPORTS_LOCAL_STORAGE){if(use_local_storage){_this.useLocalStorage=true;var saved_gui=localStorage.getItem(getLocalStorageHash(this,"gui"));if(saved_gui){params.load=JSON.parse(saved_gui)}}}this.__closeButton=document.createElement("div");this.__closeButton.innerHTML=GUI.TEXT_CLOSED;dom.addClass(this.__closeButton,GUI.CLASS_CLOSE_BUTTON);this.domElement.appendChild(this.__closeButton);dom.bind(this.__closeButton,"click",function(){_this.closed=!_this.closed})}else{if(params.closed===undefined){params.closed=true}var title_row_name=document.createTextNode(params.name);dom.addClass(title_row_name,"controller-name");var title_row=addRow(_this,title_row_name);var on_click_title=function(e){e.preventDefault();_this.closed=!_this.closed;return false};dom.addClass(this.__ul,GUI.CLASS_CLOSED);dom.addClass(title_row,"title");dom.bind(title_row,"click",on_click_title);if(!params.closed){this.closed=false}}if(params.autoPlace){if(common.isUndefined(params.parent)){if(auto_place_virgin){auto_place_container=document.createElement("div");dom.addClass(auto_place_container,CSS_NAMESPACE);dom.addClass(auto_place_container,GUI.CLASS_AUTO_PLACE_CONTAINER);document.body.appendChild(auto_place_container);auto_place_virgin=false}auto_place_container.appendChild(this.domElement);dom.addClass(this.domElement,GUI.CLASS_AUTO_PLACE)}if(!this.parent)setWidth(_this,params.width)}dom.bind(window,"resize",function(){_this.onResize()});dom.bind(this.__ul,"webkitTransitionEnd",function(){_this.onResize()});dom.bind(this.__ul,"transitionend",function(){_this.onResize()});dom.bind(this.__ul,"oTransitionEnd",function(){_this.onResize()});this.onResize();if(params.resizable){addResizeHandle(this)}function saveToLocalStorage(){localStorage.setItem(getLocalStorageHash(_this,"gui"),JSON.stringify(_this.getSaveObject()))}var root=_this.getRoot();function resetWidth(){var root=_this.getRoot();root.width+=1;common.defer(function(){root.width-=1})}if(!params.parent){resetWidth()}};GUI.toggleHide=function(){hide=!hide;common.each(hideable_guis,function(gui){gui.domElement.style.zIndex=hide?-999:999;gui.domElement.style.opacity=hide?0:1})};GUI.CLASS_AUTO_PLACE="a";GUI.CLASS_AUTO_PLACE_CONTAINER="ac";GUI.CLASS_MAIN="main";GUI.CLASS_CONTROLLER_ROW="cr";GUI.CLASS_TOO_TALL="taller-than-window";GUI.CLASS_CLOSED="closed";GUI.CLASS_CLOSE_BUTTON="close-button";GUI.CLASS_DRAG="drag";GUI.DEFAULT_WIDTH=245;GUI.TEXT_CLOSED="Close Controls";GUI.TEXT_OPEN="Open Controls";dom.bind(window,"keydown",function(e){if(document.activeElement.type!=="text"&&(e.which===HIDE_KEY_CODE||e.keyCode==HIDE_KEY_CODE)){GUI.toggleHide()}},false);common.extend(GUI.prototype,{add:function(object,property){return add(this,object,property,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(object,property){return add(this,object,property,{color:true})},remove:function(controller){this.__ul.removeChild(controller.__li);this.__controllers.slice(this.__controllers.indexOf(controller),1);var _this=this;common.defer(function(){_this.onResize()})},destroy:function(){if(this.autoPlace){auto_place_container.removeChild(this.domElement)}},addFolder:function(name){if(this.__folders[name]!==undefined){throw new Error("You already have a folder in this GUI by the"+' name "'+name+'"')}var new_gui_params={name:name,parent:this};new_gui_params.autoPlace=this.autoPlace;if(this.load&&this.load.folders&&this.load.folders[name]){new_gui_params.closed=this.load.folders[name].closed;new_gui_params.load=this.load.folders[name]}var gui=new GUI(new_gui_params);this.__folders[name]=gui;var li=addRow(this,gui.domElement);dom.addClass(li,"folder");return gui},open:function(){this.closed=false},close:function(){this.closed=true},onResize:function(){var root=this.getRoot();if(root.scrollable){var top=dom.getOffset(root.__ul).top;var h=0;common.each(root.__ul.childNodes,function(node){if(!(root.autoPlace&&node===root.__save_row))h+=dom.getHeight(node)});if(window.innerHeight-top-CLOSE_BUTTON_HEIGHT<h){dom.addClass(root.domElement,GUI.CLASS_TOO_TALL);root.__ul.style.height=window.innerHeight-top-CLOSE_BUTTON_HEIGHT+"px"}else{dom.removeClass(root.domElement,GUI.CLASS_TOO_TALL);root.__ul.style.height="auto"}}if(root.__resize_handle){common.defer(function(){root.__resize_handle.style.height=root.__ul.offsetHeight+"px"})}if(root.__closeButton){root.__closeButton.style.width=root.width+"px"}},remember:function(){if(common.isUndefined(SAVE_DIALOGUE)){SAVE_DIALOGUE=new CenteredDiv;SAVE_DIALOGUE.domElement.innerHTML=saveDialogueContents}if(this.parent){throw new Error("You can only call remember on a top level GUI.")}var _this=this;common.each(Array.prototype.slice.call(arguments),function(object){if(_this.__rememberedObjects.length==0){addSaveMenu(_this)}if(_this.__rememberedObjects.indexOf(object)==-1){_this.__rememberedObjects.push(object)}});if(this.autoPlace){setWidth(this,this.width)}},getRoot:function(){var gui=this;while(gui.parent){gui=gui.parent}return gui},getSaveObject:function(){var toReturn=this.load;toReturn.closed=this.closed;if(this.__rememberedObjects.length>0){toReturn.preset=this.preset;if(!toReturn.remembered){toReturn.remembered={}}toReturn.remembered[this.preset]=getCurrentPreset(this)}toReturn.folders={};common.each(this.__folders,function(element,key){toReturn.folders[key]=element.getSaveObject()});return toReturn},save:function(){if(!this.load.remembered){this.load.remembered={}}this.load.remembered[this.preset]=getCurrentPreset(this);markPresetModified(this,false)},saveAs:function(presetName){if(!this.load.remembered){this.load.remembered={};this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME]=getCurrentPreset(this,true)}this.load.remembered[presetName]=getCurrentPreset(this);this.preset=presetName;addPresetOption(this,presetName,true)},revert:function(gui){common.each(this.__controllers,function(controller){if(!this.getRoot().load.remembered){controller.setValue(controller.initialValue)}else{recallSavedValue(gui||this.getRoot(),controller)}},this);common.each(this.__folders,function(folder){folder.revert(folder)});if(!gui){markPresetModified(this.getRoot(),false)}},listen:function(controller){var init=this.__listening.length==0;this.__listening.push(controller);if(init)updateDisplays(this.__listening)}});function add(gui,object,property,params){if(object[property]===undefined){throw new Error("Object "+object+' has no property "'+property+'"')}var controller;if(params.color){controller=new ColorController(object,property)}else{var factoryArgs=[object,property].concat(params.factoryArgs);controller=controllerFactory.apply(gui,factoryArgs)}if(params.before instanceof Controller){params.before=params.before.__li}recallSavedValue(gui,controller);dom.addClass(controller.domElement,"c");var name=document.createElement("span");dom.addClass(name,"property-name");name.innerHTML=controller.property;var container=document.createElement("div");container.appendChild(name);container.appendChild(controller.domElement);var li=addRow(gui,container,params.before);dom.addClass(li,GUI.CLASS_CONTROLLER_ROW);dom.addClass(li,typeof controller.getValue());augmentController(gui,li,controller);gui.__controllers.push(controller);return controller}function addRow(gui,dom,liBefore){var li=document.createElement("li");if(dom)li.appendChild(dom);if(liBefore){gui.__ul.insertBefore(li,params.before)}else{gui.__ul.appendChild(li)}gui.onResize();return li}function augmentController(gui,li,controller){controller.__li=li;controller.__gui=gui;common.extend(controller,{options:function(options){if(arguments.length>1){controller.remove();return add(gui,controller.object,controller.property,{before:controller.__li.nextElementSibling,factoryArgs:[common.toArray(arguments)]})}if(common.isArray(options)||common.isObject(options)){controller.remove();return add(gui,controller.object,controller.property,{before:controller.__li.nextElementSibling,factoryArgs:[options]})}},name:function(v){controller.__li.firstElementChild.firstElementChild.innerHTML=v;return controller},listen:function(){controller.__gui.listen(controller);return controller},remove:function(){controller.__gui.remove(controller);return controller}});if(controller instanceof NumberControllerSlider){var box=new NumberControllerBox(controller.object,controller.property,{min:controller.__min,max:controller.__max,step:controller.__step});common.each(["updateDisplay","onChange","onFinishChange"],function(method){var pc=controller[method];var pb=box[method];controller[method]=box[method]=function(){var args=Array.prototype.slice.call(arguments);pc.apply(controller,args);return pb.apply(box,args)}});dom.addClass(li,"has-slider");controller.domElement.insertBefore(box.domElement,controller.domElement.firstElementChild)}else if(controller instanceof NumberControllerBox){var r=function(returned){if(common.isNumber(controller.__min)&&common.isNumber(controller.__max)){controller.remove();return add(gui,controller.object,controller.property,{before:controller.__li.nextElementSibling,factoryArgs:[controller.__min,controller.__max,controller.__step]})}return returned};controller.min=common.compose(r,controller.min);controller.max=common.compose(r,controller.max)}else if(controller instanceof BooleanController){dom.bind(li,"click",function(){dom.fakeEvent(controller.__checkbox,"click")});dom.bind(controller.__checkbox,"click",function(e){e.stopPropagation()})}else if(controller instanceof FunctionController){dom.bind(li,"click",function(){dom.fakeEvent(controller.__button,"click")});dom.bind(li,"mouseover",function(){dom.addClass(controller.__button,"hover")});dom.bind(li,"mouseout",function(){dom.removeClass(controller.__button,"hover")})}else if(controller instanceof ColorController){dom.addClass(li,"color");controller.updateDisplay=common.compose(function(r){li.style.borderLeftColor=controller.__color.toString();return r},controller.updateDisplay);controller.updateDisplay()}controller.setValue=common.compose(function(r){if(gui.getRoot().__preset_select&&controller.isModified()){markPresetModified(gui.getRoot(),true)}return r},controller.setValue)}function recallSavedValue(gui,controller){var root=gui.getRoot();var matched_index=root.__rememberedObjects.indexOf(controller.object);if(matched_index!=-1){var controller_map=root.__rememberedObjectIndecesToControllers[matched_index];if(controller_map===undefined){controller_map={};root.__rememberedObjectIndecesToControllers[matched_index]=controller_map}controller_map[controller.property]=controller;if(root.load&&root.load.remembered){var preset_map=root.load.remembered;var preset;if(preset_map[gui.preset]){preset=preset_map[gui.preset]}else if(preset_map[DEFAULT_DEFAULT_PRESET_NAME]){preset=preset_map[DEFAULT_DEFAULT_PRESET_NAME]}else{return}if(preset[matched_index]&&preset[matched_index][controller.property]!==undefined){var value=preset[matched_index][controller.property];controller.initialValue=value;controller.setValue(value)}}}}function getLocalStorageHash(gui,key){return document.location.href+"."+key}function addSaveMenu(gui){var div=gui.__save_row=document.createElement("li");dom.addClass(gui.domElement,"has-save");gui.__ul.insertBefore(div,gui.__ul.firstChild);dom.addClass(div,"save-row");var gears=document.createElement("span");gears.innerHTML="&nbsp;";dom.addClass(gears,"button gears");var button=document.createElement("span");button.innerHTML="Save";dom.addClass(button,"button");dom.addClass(button,"save");var button2=document.createElement("span");button2.innerHTML="New";dom.addClass(button2,"button");dom.addClass(button2,"save-as");var button3=document.createElement("span");button3.innerHTML="Revert";dom.addClass(button3,"button");dom.addClass(button3,"revert");var select=gui.__preset_select=document.createElement("select");if(gui.load&&gui.load.remembered){common.each(gui.load.remembered,function(value,key){addPresetOption(gui,key,key==gui.preset)})}else{addPresetOption(gui,DEFAULT_DEFAULT_PRESET_NAME,false)}dom.bind(select,"change",function(){for(var index=0;index<gui.__preset_select.length;index++){gui.__preset_select[index].innerHTML=gui.__preset_select[index].value}gui.preset=this.value});div.appendChild(select);div.appendChild(gears);div.appendChild(button);div.appendChild(button2);div.appendChild(button3);if(SUPPORTS_LOCAL_STORAGE){var saveLocally=document.getElementById("dg-save-locally");var explain=document.getElementById("dg-local-explain");saveLocally.style.display="block";var localStorageCheckBox=document.getElementById("dg-local-storage");if(localStorage.getItem(getLocalStorageHash(gui,"isLocal"))==="true"){localStorageCheckBox.setAttribute("checked","checked")}function showHideExplain(){explain.style.display=gui.useLocalStorage?"block":"none"}showHideExplain();dom.bind(localStorageCheckBox,"change",function(){gui.useLocalStorage=!gui.useLocalStorage;showHideExplain()})}var newConstructorTextArea=document.getElementById("dg-new-constructor");dom.bind(newConstructorTextArea,"keydown",function(e){if(e.metaKey&&(e.which===67||e.keyCode==67)){SAVE_DIALOGUE.hide()}});dom.bind(gears,"click",function(){newConstructorTextArea.innerHTML=JSON.stringify(gui.getSaveObject(),undefined,2);SAVE_DIALOGUE.show();newConstructorTextArea.focus();newConstructorTextArea.select()});dom.bind(button,"click",function(){gui.save()});dom.bind(button2,"click",function(){var presetName=prompt("Enter a new preset name.");if(presetName)gui.saveAs(presetName)});dom.bind(button3,"click",function(){gui.revert()})}function addResizeHandle(gui){gui.__resize_handle=document.createElement("div");common.extend(gui.__resize_handle.style,{width:"6px",marginLeft:"-3px",height:"200px",cursor:"ew-resize",position:"absolute"});var pmouseX;dom.bind(gui.__resize_handle,"mousedown",dragStart);dom.bind(gui.__closeButton,"mousedown",dragStart);gui.domElement.insertBefore(gui.__resize_handle,gui.domElement.firstElementChild);function dragStart(e){e.preventDefault();pmouseX=e.clientX;dom.addClass(gui.__closeButton,GUI.CLASS_DRAG);dom.bind(window,"mousemove",drag);dom.bind(window,"mouseup",dragStop);return false}function drag(e){e.preventDefault();gui.width+=pmouseX-e.clientX;gui.onResize();pmouseX=e.clientX;return false}function dragStop(){dom.removeClass(gui.__closeButton,GUI.CLASS_DRAG);dom.unbind(window,"mousemove",drag);dom.unbind(window,"mouseup",dragStop)}}function setWidth(gui,w){gui.domElement.style.width=w+"px";if(gui.__save_row&&gui.autoPlace){gui.__save_row.style.width=w+"px"}if(gui.__closeButton){gui.__closeButton.style.width=w+"px"}}function getCurrentPreset(gui,useInitialValues){var toReturn={};common.each(gui.__rememberedObjects,function(val,index){var saved_values={};var controller_map=gui.__rememberedObjectIndecesToControllers[index];common.each(controller_map,function(controller,property){saved_values[property]=useInitialValues?controller.initialValue:controller.getValue()});toReturn[index]=saved_values});return toReturn}function addPresetOption(gui,name,setSelected){var opt=document.createElement("option");opt.innerHTML=name;opt.value=name;gui.__preset_select.appendChild(opt);if(setSelected){gui.__preset_select.selectedIndex=gui.__preset_select.length-1}}function setPresetSelectIndex(gui){for(var index=0;index<gui.__preset_select.length;index++){if(gui.__preset_select[index].value==gui.preset){gui.__preset_select.selectedIndex=index}}}function markPresetModified(gui,modified){var opt=gui.__preset_select[gui.__preset_select.selectedIndex];if(modified){opt.innerHTML=opt.value+"*"}else{opt.innerHTML=opt.value}}function updateDisplays(controllerArray){if(controllerArray.length!=0){requestAnimationFrame(function(){updateDisplays(controllerArray)})}common.each(controllerArray,function(c){c.updateDisplay()})}return GUI}(dat.utils.css,'<div id="dg-save" class="dg dialogue">\n\n Here\'s the new load parameter for your <code>GUI</code>\'s constructor:\n\n <textarea id="dg-new-constructor"></textarea>\n\n <div id="dg-save-locally">\n\n <input id="dg-local-storage" type="checkbox"/> Automatically save\n values to <code>localStorage</code> on exit.\n\n <div id="dg-local-explain">The values saved to <code>localStorage</code> will\n override those passed to <code>dat.GUI</code>\'s constructor. This makes it\n easier to work incrementally, but <code>localStorage</code> is fragile,\n and your friends may not see the same values you do.\n \n </div>\n \n </div>\n\n</div>',".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n",dat.controllers.factory=function(OptionController,NumberControllerBox,NumberControllerSlider,StringController,FunctionController,BooleanController,common){return function(object,property){var initialValue=object[property];if(common.isArray(arguments[2])||common.isObject(arguments[2])){return new OptionController(object,property,arguments[2])}if(common.isNumber(initialValue)){if(common.isNumber(arguments[2])&&common.isNumber(arguments[3])){return new NumberControllerSlider(object,property,arguments[2],arguments[3])}else{return new NumberControllerBox(object,property,{min:arguments[2],max:arguments[3]})}}if(common.isString(initialValue)){return new StringController(object,property)}if(common.isFunction(initialValue)){return new FunctionController(object,property,"")}if(common.isBoolean(initialValue)){return new BooleanController(object,property)}}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(Controller,dom,common){var StringController=function(object,property){StringController.superclass.call(this,object,property);var _this=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");dom.bind(this.__input,"keyup",onChange);dom.bind(this.__input,"change",onChange);dom.bind(this.__input,"blur",onBlur);dom.bind(this.__input,"keydown",function(e){if(e.keyCode===13){this.blur()}});function onChange(){_this.setValue(_this.__input.value)}function onBlur(){if(_this.__onFinishChange){_this.__onFinishChange.call(_this,_this.getValue())}}this.updateDisplay();this.domElement.appendChild(this.__input)};StringController.superclass=Controller;common.extend(StringController.prototype,Controller.prototype,{updateDisplay:function(){if(!dom.isActive(this.__input)){this.__input.value=this.getValue()}return StringController.superclass.prototype.updateDisplay.call(this)}});return StringController}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController,dat.controllers.ColorController=function(Controller,dom,Color,interpret,common){var ColorController=function(object,property){ColorController.superclass.call(this,object,property);this.__color=new Color(this.getValue());this.__temp=new Color(0);var _this=this;this.domElement=document.createElement("div");dom.makeSelectable(this.domElement,false);this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input=document.createElement("input");this.__input.type="text";this.__input_textShadow="0 1px 1px ";dom.bind(this.__input,"keydown",function(e){if(e.keyCode===13){onBlur.call(this)}});dom.bind(this.__input,"blur",onBlur);dom.bind(this.__selector,"mousedown",function(e){dom.addClass(this,"drag").bind(window,"mouseup",function(e){dom.removeClass(_this.__selector,"drag")})});var value_field=document.createElement("div");common.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});common.extend(this.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(this.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});common.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});common.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});common.extend(value_field.style,{width:"100%",height:"100%",background:"none"});linearGradient(value_field,"top","rgba(0,0,0,0)","#000");common.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});hueGradient(this.__hue_field);common.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});dom.bind(this.__saturation_field,"mousedown",fieldDown);dom.bind(this.__field_knob,"mousedown",fieldDown);dom.bind(this.__hue_field,"mousedown",function(e){setH(e);dom.bind(window,"mousemove",setH);dom.bind(window,"mouseup",unbindH)});function fieldDown(e){setSV(e);dom.bind(window,"mousemove",setSV);dom.bind(window,"mouseup",unbindSV)}function unbindSV(){dom.unbind(window,"mousemove",setSV);dom.unbind(window,"mouseup",unbindSV)}function onBlur(){var i=interpret(this.value);if(i!==false){_this.__color.__state=i;_this.setValue(_this.__color.toOriginal())}else{this.value=_this.__color.toString()}}function unbindH(){dom.unbind(window,"mousemove",setH);dom.unbind(window,"mouseup",unbindH)}this.__saturation_field.appendChild(value_field);this.__selector.appendChild(this.__field_knob);this.__selector.appendChild(this.__saturation_field);this.__selector.appendChild(this.__hue_field);this.__hue_field.appendChild(this.__hue_knob);this.domElement.appendChild(this.__input);this.domElement.appendChild(this.__selector);this.updateDisplay();function setSV(e){e.preventDefault();var w=dom.getWidth(_this.__saturation_field);var o=dom.getOffset(_this.__saturation_field);var s=(e.clientX-o.left+document.body.scrollLeft)/w;var v=1-(e.clientY-o.top+document.body.scrollTop)/w;if(v>1)v=1;else if(v<0)v=0;if(s>1)s=1;else if(s<0)s=0;_this.__color.v=v;_this.__color.s=s;_this.setValue(_this.__color.toOriginal());return false}function setH(e){e.preventDefault();var s=dom.getHeight(_this.__hue_field);var o=dom.getOffset(_this.__hue_field);var h=1-(e.clientY-o.top+document.body.scrollTop)/s;if(h>1)h=1;else if(h<0)h=0;_this.__color.h=h*360;_this.setValue(_this.__color.toOriginal());return false}};ColorController.superclass=Controller;common.extend(ColorController.prototype,Controller.prototype,{updateDisplay:function(){var i=interpret(this.getValue());if(i!==false){var mismatch=false;common.each(Color.COMPONENTS,function(component){if(!common.isUndefined(i[component])&&!common.isUndefined(this.__color.__state[component])&&i[component]!==this.__color.__state[component]){mismatch=true;return{}}},this);if(mismatch){common.extend(this.__color.__state,i)}}common.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var flip=this.__color.v<.5||this.__color.s>.5?255:0;var _flip=255-flip;common.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toString(),border:this.__field_knob_border+"rgb("+flip+","+flip+","+flip+")"});this.__hue_knob.style.marginTop=(1-this.__color.h/360)*100+"px";this.__temp.s=1;this.__temp.v=1;linearGradient(this.__saturation_field,"left","#fff",this.__temp.toString());common.extend(this.__input.style,{backgroundColor:this.__input.value=this.__color.toString(),color:"rgb("+flip+","+flip+","+flip+")",textShadow:this.__input_textShadow+"rgba("+_flip+","+_flip+","+_flip+",.7)"})}});var vendors=["-moz-","-o-","-webkit-","-ms-",""];function linearGradient(elem,x,a,b){elem.style.background="";common.each(vendors,function(vendor){elem.style.cssText+="background: "+vendor+"linear-gradient("+x+", "+a+" 0%, "+b+" 100%); "})}function hueGradient(elem){elem.style.background="";elem.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";elem.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";elem.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";elem.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";elem.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}return ColorController}(dat.controllers.Controller,dat.dom.dom,dat.color.Color=function(interpret,math,toString,common){var Color=function(){this.__state=interpret.apply(this,arguments);if(this.__state===false){throw"Failed to interpret color arguments";
}this.__state.a=this.__state.a||1};Color.COMPONENTS=["r","g","b","h","s","v","hex","a"];common.extend(Color.prototype,{toString:function(){return toString(this)},toOriginal:function(){return this.__state.conversion.write(this)}});defineRGBComponent(Color.prototype,"r",2);defineRGBComponent(Color.prototype,"g",1);defineRGBComponent(Color.prototype,"b",0);defineHSVComponent(Color.prototype,"h");defineHSVComponent(Color.prototype,"s");defineHSVComponent(Color.prototype,"v");Object.defineProperty(Color.prototype,"a",{get:function(){return this.__state.a},set:function(v){this.__state.a=v}});Object.defineProperty(Color.prototype,"hex",{get:function(){if(!this.__state.space!=="HEX"){this.__state.hex=math.rgb_to_hex(this.r,this.g,this.b)}return this.__state.hex},set:function(v){this.__state.space="HEX";this.__state.hex=v}});function defineRGBComponent(target,component,componentHexIndex){Object.defineProperty(target,component,{get:function(){if(this.__state.space==="RGB"){return this.__state[component]}recalculateRGB(this,component,componentHexIndex);return this.__state[component]},set:function(v){if(this.__state.space!=="RGB"){recalculateRGB(this,component,componentHexIndex);this.__state.space="RGB"}this.__state[component]=v}})}function defineHSVComponent(target,component){Object.defineProperty(target,component,{get:function(){if(this.__state.space==="HSV")return this.__state[component];recalculateHSV(this);return this.__state[component]},set:function(v){if(this.__state.space!=="HSV"){recalculateHSV(this);this.__state.space="HSV"}this.__state[component]=v}})}function recalculateRGB(color,component,componentHexIndex){if(color.__state.space==="HEX"){color.__state[component]=math.component_from_hex(color.__state.hex,componentHexIndex)}else if(color.__state.space==="HSV"){common.extend(color.__state,math.hsv_to_rgb(color.__state.h,color.__state.s,color.__state.v))}else{throw"Corrupted color state"}}function recalculateHSV(color){var result=math.rgb_to_hsv(color.r,color.g,color.b);common.extend(color.__state,{s:result.s,v:result.v});if(!common.isNaN(result.h)){color.__state.h=result.h}else if(common.isUndefined(color.__state.h)){color.__state.h=0}}return Color}(dat.color.interpret,dat.color.math=function(){var tmpComponent;return{hsv_to_rgb:function(h,s,v){var hi=Math.floor(h/60)%6;var f=h/60-Math.floor(h/60);var p=v*(1-s);var q=v*(1-f*s);var t=v*(1-(1-f)*s);var c=[[v,t,p],[q,v,p],[p,v,t],[p,q,v],[t,p,v],[v,p,q]][hi];return{r:c[0]*255,g:c[1]*255,b:c[2]*255}},rgb_to_hsv:function(r,g,b){var min=Math.min(r,g,b),max=Math.max(r,g,b),delta=max-min,h,s;if(max!=0){s=delta/max}else{return{h:NaN,s:0,v:0}}if(r==max){h=(g-b)/delta}else if(g==max){h=2+(b-r)/delta}else{h=4+(r-g)/delta}h/=6;if(h<0){h+=1}return{h:h*360,s:s,v:max/255}},rgb_to_hex:function(r,g,b){var hex=this.hex_with_component(0,2,r);hex=this.hex_with_component(hex,1,g);hex=this.hex_with_component(hex,0,b);return hex},component_from_hex:function(hex,componentIndex){return hex>>componentIndex*8&255},hex_with_component:function(hex,componentIndex,value){return value<<(tmpComponent=componentIndex*8)|hex&~(255<<tmpComponent)}}}(),dat.color.toString,dat.utils.common),dat.color.interpret,dat.utils.common),dat.utils.requestAnimationFrame=function(){return window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback,element){window.setTimeout(callback,1e3/60)}}(),dat.dom.CenteredDiv=function(dom,common){var CenteredDiv=function(){this.backgroundElement=document.createElement("div");common.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear"});dom.makeFullscreen(this.backgroundElement);this.backgroundElement.style.position="fixed";this.domElement=document.createElement("div");common.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear"});document.body.appendChild(this.backgroundElement);document.body.appendChild(this.domElement);var _this=this;dom.bind(this.backgroundElement,"click",function(){_this.hide()})};CenteredDiv.prototype.show=function(){var _this=this;this.backgroundElement.style.display="block";this.domElement.style.display="block";this.domElement.style.opacity=0;this.domElement.style.webkitTransform="scale(1.1)";this.layout();common.defer(function(){_this.backgroundElement.style.opacity=1;_this.domElement.style.opacity=1;_this.domElement.style.webkitTransform="scale(1)"})};CenteredDiv.prototype.hide=function(){var _this=this;var hide=function(){_this.domElement.style.display="none";_this.backgroundElement.style.display="none";dom.unbind(_this.domElement,"webkitTransitionEnd",hide);dom.unbind(_this.domElement,"transitionend",hide);dom.unbind(_this.domElement,"oTransitionEnd",hide)};dom.bind(this.domElement,"webkitTransitionEnd",hide);dom.bind(this.domElement,"transitionend",hide);dom.bind(this.domElement,"oTransitionEnd",hide);this.backgroundElement.style.opacity=0;this.domElement.style.opacity=0;this.domElement.style.webkitTransform="scale(1.1)"};CenteredDiv.prototype.layout=function(){this.domElement.style.left=window.innerWidth/2-dom.getWidth(this.domElement)/2+"px";this.domElement.style.top=window.innerHeight/2-dom.getHeight(this.domElement)/2+"px"};function lockScroll(e){console.log(e)}return CenteredDiv}(dat.dom.dom,dat.utils.common),dat.dom.dom,dat.utils.common)},{}],4:[function(require,module,exports){var hasOwn=Object.prototype.hasOwnProperty;var toStr=Object.prototype.toString;var undefined;var isArray=function isArray(arr){if(typeof Array.isArray==="function"){return Array.isArray(arr)}return toStr.call(arr)==="[object Array]"};var isPlainObject=function isPlainObject(obj){"use strict";if(!obj||toStr.call(obj)!=="[object Object]"){return false}var has_own_constructor=hasOwn.call(obj,"constructor");var has_is_property_of_method=obj.constructor&&obj.constructor.prototype&&hasOwn.call(obj.constructor.prototype,"isPrototypeOf");if(obj.constructor&&!has_own_constructor&&!has_is_property_of_method){return false}var key;for(key in obj){}return key===undefined||hasOwn.call(obj,key)};module.exports=function extend(){"use strict";var options,name,src,copy,copyIsArray,clone,target=arguments[0],i=1,length=arguments.length,deep=false;if(typeof target==="boolean"){deep=target;target=arguments[1]||{};i=2}else if(typeof target!=="object"&&typeof target!=="function"||target==null){target={}}for(;i<length;++i){options=arguments[i];if(options!=null){for(name in options){src=target[name];copy=options[name];if(target===copy){continue}if(deep&&copy&&(isPlainObject(copy)||(copyIsArray=isArray(copy)))){if(copyIsArray){copyIsArray=false;clone=src&&isArray(src)?src:[]}else{clone=src&&isPlainObject(src)?src:{}}target[name]=extend(deep,clone,copy)}else if(copy!==undefined){target[name]=copy}}}}return target}},{}],5:[function(require,module,exports){var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div");k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display="block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1e3&&(h=Math.round(1e3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};"object"===typeof module&&(module.exports=Stats)},{}],6:[function(require,module,exports){"use strict";var assert=function(condition,message){if(!condition){throw message||"assertion failed"}};var emptyFn=function(){};var extend=require("extend");var Stats=require("stats-js");var dat=require("dat-gui");var THREE=window.THREE;var Coordinates=require("../model/Coordinates");var Keyboard=require("./Keyboard");var LoopManager=require("./LoopManager");var THREEx=require("../lib/THREEx/");var themes=require("../themes/");function Application(config){config=extend({selector:null,width:window.innerWidth,height:window.innerHeight,renderImmediately:true,injectCache:false,fullScreen:false,theme:"dark",helpersConfig:{},defaultSceneConfig:{fog:true}},config);this.initialConfig=config;this.scenes={};this.activeScene=null;this.cameras={};this.activeCamera=null;this.renderer=null;this.keyboard=null;this.datgui=null;this.stats=null;this.loopManager=null;this.theme=null;this.__t3cache__={};Application.prototype.initApplication.call(this)}Application.prototype.getConfig=function(){return this.initialConfig};Application.prototype.initApplication=function(){var me=this,config=me.getConfig();me.injectCache(config.injectCache);me.setTheme(config.theme);me.createDefaultRenderer();me.createDefaultScene();me.createDefaultCamera();me.createDefaultLights();me.initDatGui();me.initStats();me.initMask().maskVisible(!config.renderImmediately);me.initFullScreen();me.initKeyboard();me.initCoordinates();me.gameLoop()};Application.prototype.setActiveScene=function(key){this.activeScene=this.scenes[key];return this};Application.prototype.addScene=function(scene,key){console.assert(scene instanceof THREE.Scene);this.scenes[key]=scene;return this};Application.prototype.createDefaultScene=function(){var me=this,config=me.getConfig(),defaultScene=new THREE.Scene;if(config.defaultSceneConfig.fog){defaultScene.fog=new THREE.Fog(me.theme.fogColor,2e3,4e3)}me.addScene(defaultScene,"default").setActiveScene("default");return me};Application.prototype.createDefaultRenderer=function(){var me=this,config=me.getConfig();var renderer=new THREE.WebGLRenderer({});renderer.setClearColor(me.theme.clearColor,1);renderer.setSize(config.width,config.height);document.querySelector(config.selector).appendChild(renderer.domElement);me.renderer=renderer;return me};Application.prototype.setActiveCamera=function(key){this.activeCamera=this.cameras[key];return this};Application.prototype.addCamera=function(camera,key){console.assert(camera instanceof THREE.PerspectiveCamera||camera instanceof THREE.OrthographicCamera);this.cameras[key]=camera;return this};Application.prototype.createDefaultCamera=function(){var me=this,config=me.getConfig(),width=config.width,height=config.height,defaults={fov:38,ratio:width/height,near:1,far:1e4},defaultCamera;defaultCamera=new THREE.PerspectiveCamera(defaults.fov,defaults.ratio,defaults.near,defaults.far);defaultCamera.position.set(500,300,500);if(config.fullScreen){THREEx.WindowResize.bind(me.renderer,defaultCamera)}me.createCameraControls(defaultCamera).addCamera(defaultCamera,"default").setActiveCamera("default");return me};Application.prototype.createCameraControls=function(camera){var me=this;camera.cameraControls=new THREE.OrbitControls(camera,me.renderer.domElement);camera.cameraControls.target.set(0,0,0);return me};Application.prototype.createDefaultLights=function(){var light,scene=this.scenes["default"];light=new THREE.AmbientLight(2236962);scene.add(light).cache("ambient-light-1");light=new THREE.DirectionalLight(16777215,1);light.position.set(200,400,500);scene.add(light).cache("directional-light-1");light=new THREE.DirectionalLight(16777215,1);light.position.set(-500,250,-200);scene.add(light).cache("directional-light-2");return this};Application.prototype.setTheme=function(name){var me=this;if(themes[name]){me.theme=themes[name]}else{console.warn("theme not found!")}return me};Application.prototype.initMask=function(){var me=this,config=me.getConfig(),mask,hidden;mask=document.createElement("div");mask.className="t3-mask";mask.style.position="absolute";mask.style.top="0px";mask.style.width="100%";mask.style.height="100%";mask.style.background="rgba(0,0,0,0.5)";document.querySelector(config.selector).appendChild(mask);me.mask=mask;return me};Application.prototype.maskVisible=function(v){var mask=this.mask;mask.style.display=v?"block":"none"};Application.prototype.initDatGui=function(){var me=this,config=me.getConfig(),gui=new dat.GUI({autoPlace:false});extend(gui.domElement.style,{position:"absolute",top:"0px",right:"0px",zIndex:"1"});document.querySelector(config.selector).appendChild(gui.domElement);me.datgui=gui;return me};Application.prototype.initStats=function(){var me=this,config=me.getConfig(),stats;stats=new Stats;extend(stats.domElement.style,{position:"absolute",zIndex:1,bottom:"0px"});document.querySelector(config.selector).appendChild(stats.domElement);me.stats=stats;return me};Application.prototype.initFullScreen=function(){var config=this.getConfig();if(config.fullScreen&&THREEx.FullScreen.available()){THREEx.FullScreen.bindKey()}};Application.prototype.initCoordinates=function(){var config=this.getConfig();this.scenes["default"].add(new Coordinates(config.helpersConfig,this.theme).initDatGui(this.datgui).mesh)};Application.prototype.initKeyboard=function(){this.keyboard=new Keyboard;return this};Application.prototype.gameLoop=function(){var config=this.getConfig();this.loopManager=new LoopManager(this,config.renderImmediately).initDatGui(this.datgui).animate();return this};Application.prototype.update=function(delta){var me=this;me.stats.update();if(me.activeCamera.cameraControls){me.activeCamera.cameraControls.update(delta)}};Application.prototype.render=function(){var me=this;me.renderer.render(me.activeScene,me.activeCamera)};Application.prototype.injectCache=function(inject){var me=this,lastObject,lastMethod,add=THREE.Object3D.prototype.add,remove=THREE.Object3D.prototype.remove,cache=this.__t3cache__;if(inject){THREE.Object3D.prototype.add=function(object){lastMethod="add";lastObject=object;return add.apply(this,arguments)};THREE.Object3D.prototype.remove=function(object){lastMethod="remove";lastObject=object;return remove.apply(this,arguments)};THREE.Object3D.prototype.cache=function(name){assert(lastObject,"T3.Application.prototype.cache: this method"+" needs a previous call to add/remove");if(lastMethod==="add"){lastObject.name=lastObject.name||name;assert(lastObject.name);cache[lastObject.name]=lastObject}else{assert(lastObject.name);delete cache[lastObject.name]}lastObject=null;return me}}else{THREE.Object3D.prototype.cache=function(){return this}}};Application.prototype.getFromCache=function(name){return this.__t3cache__[name]};Application.run=function(options){options.init=options.init||emptyFn;options.update=options.update||emptyFn;assert(options.selector,"canvas selector required");var QuickLaunch=function(options){Application.call(this,options);options.init.call(this,options)};QuickLaunch.prototype=Object.create(Application.prototype);QuickLaunch.prototype.update=function(delta){Application.prototype.update.call(this,delta);options.update.call(this,delta)};return new QuickLaunch(options)};module.exports=Application},{"../lib/THREEx/":12,"../model/Coordinates":13,"../themes/":15,"./Keyboard":7,"./LoopManager":8,"dat-gui":1,extend:4,"stats-js":5}],7:[function(require,module,exports){function Keyboard(){this.keys=[]}Keyboard.prototype.init=function(){var me=this,i;for(i=0;i<256;i+=1){me.keys[i]=false}document.addEventListener("keydown",me.onKeyDown(),false);document.addEventListener("keyup",me.onKeyUp(),false)};Keyboard.prototype.onKeyDown=function(){var me=this;return function(event){me.keys[event.keyCode]=true}};Keyboard.prototype.onKeyUp=function(){var me=this;return function(event){me.keys[event.keyCode]=false}};Keyboard.prototype.get=function(key){return this.keys[key.charCodeAt(0)]};Keyboard.prototype.set=function(key,value){this.keys[key.charCodeAt(0)]=value};module.exports=Keyboard},{}],8:[function(require,module,exports){var Application=require("./Application");var THREE=window.THREE;function LoopManager(application,renderImmediately){this.application=application;this.clock=new THREE.Clock;this.pause=!renderImmediately;this.fps=60;this.guiControllers={}}LoopManager.prototype.initDatGui=function(gui){var me=this,folder=gui.addFolder("Game Loop");folder.add(this,"fps",10,60,1).name("Frame rate");me.guiControllers.pause=folder.add(this,"pause").name("Paused").onFinishChange(function(paused){if(!paused){me.animate()}me.application.maskVisible(paused)});return this};LoopManager.prototype.animate=function(){var me=this,elapsedTime=0,loop;loop=function(){if(me.pause){return}var delta=me.clock.getDelta(),frameRateInS=1/me.fps;delta=Math.min(delta,frameRateInS);elapsedTime+=delta;if(elapsedTime>=frameRateInS){me.application.update(delta);me.application.render();elapsedTime-=frameRateInS}window.requestAnimationFrame(loop)};loop();return me};LoopManager.prototype.start=function(){var me=this;me.guiControllers.pause.setValue(false)};LoopManager.prototype.stop=function(){var me=this;me.guiControllers.pause.setValue(true)};module.exports=LoopManager},{"./Application":6}],9:[function(require,module,exports){var THREE=window.THREE;THREE.OrbitControls=function(object,domElement){this.object=object;this.domElement=domElement!==undefined?domElement:document;this.enabled=true;this.target=new THREE.Vector3;this.center=this.target;this.noZoom=false;this.zoomSpeed=1;this.minDistance=0;this.maxDistance=Infinity;this.noRotate=false;this.rotateSpeed=1;this.noPan=false;this.keyPanSpeed=7;this.autoRotate=false;this.autoRotateSpeed=2;this.minPolarAngle=0;this.maxPolarAngle=Math.PI;this.noKeys=false;this.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40};var scope=this;var EPS=1e-6;var rotateStart=new THREE.Vector2;var rotateEnd=new THREE.Vector2;var rotateDelta=new THREE.Vector2;var panStart=new THREE.Vector2;var panEnd=new THREE.Vector2;var panDelta=new THREE.Vector2;var panOffset=new THREE.Vector3;var offset=new THREE.Vector3;var dollyStart=new THREE.Vector2;var dollyEnd=new THREE.Vector2;var dollyDelta=new THREE.Vector2;var phiDelta=0;var thetaDelta=0;var scale=1;var pan=new THREE.Vector3;var lastPosition=new THREE.Vector3;var lastQuaternion=new THREE.Quaternion;var STATE={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5};var state=STATE.NONE;this.target0=this.target.clone();this.position0=this.object.position.clone();var quat=(new THREE.Quaternion).setFromUnitVectors(object.up,new THREE.Vector3(0,1,0));var quatInverse=quat.clone().inverse();var changeEvent={type:"change"};var startEvent={type:"start"};var endEvent={type:"end"};this.rotateLeft=function(angle){if(angle===undefined){angle=getAutoRotationAngle()}thetaDelta-=angle};this.rotateUp=function(angle){if(angle===undefined){angle=getAutoRotationAngle()}phiDelta-=angle};this.panLeft=function(distance){var te=this.object.matrix.elements;panOffset.set(te[0],te[1],te[2]);panOffset.multiplyScalar(-distance);pan.add(panOffset)};this.panUp=function(distance){var te=this.object.matrix.elements;panOffset.set(te[4],te[5],te[6]);panOffset.multiplyScalar(distance);pan.add(panOffset)};this.pan=function(deltaX,deltaY){var element=scope.domElement===document?scope.domElement.body:scope.domElement;if(scope.object.fov!==undefined){var position=scope.object.position;var offset=position.clone().sub(scope.target);var targetDistance=offset.length();targetDistance*=Math.tan(scope.object.fov/2*Math.PI/180);scope.panLeft(2*deltaX*targetDistance/element.clientHeight);scope.panUp(2*deltaY*targetDistance/element.clientHeight)}else if(scope.object.top!==undefined){scope.panLeft(deltaX*(scope.object.right-scope.object.left)/element.clientWidth);scope.panUp(deltaY*(scope.object.top-scope.object.bottom)/element.clientHeight)}else{console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.")}};this.dollyIn=function(dollyScale){if(dollyScale===undefined){dollyScale=getZoomScale()}scale/=dollyScale};this.dollyOut=function(dollyScale){if(dollyScale===undefined){dollyScale=getZoomScale()}scale*=dollyScale};this.update=function(){var position=this.object.position;offset.copy(position).sub(this.target);offset.applyQuaternion(quat);var theta=Math.atan2(offset.x,offset.z);var phi=Math.atan2(Math.sqrt(offset.x*offset.x+offset.z*offset.z),offset.y);if(this.autoRotate){this.rotateLeft(getAutoRotationAngle())}theta+=thetaDelta;phi+=phiDelta;phi=Math.max(this.minPolarAngle,Math.min(this.maxPolarAngle,phi));phi=Math.max(EPS,Math.min(Math.PI-EPS,phi));var radius=offset.length()*scale;radius=Math.max(this.minDistance,Math.min(this.maxDistance,radius));this.target.add(pan);offset.x=radius*Math.sin(phi)*Math.sin(theta);offset.y=radius*Math.cos(phi);offset.z=radius*Math.sin(phi)*Math.cos(theta);offset.applyQuaternion(quatInverse);position.copy(this.target).add(offset);this.object.lookAt(this.target);thetaDelta=0;phiDelta=0;scale=1;pan.set(0,0,0);if(lastPosition.distanceToSquared(this.object.position)>EPS||8*(1-lastQuaternion.dot(this.object.quaternion))>EPS){this.dispatchEvent(changeEvent);lastPosition.copy(this.object.position);lastQuaternion.copy(this.object.quaternion)}};this.reset=function(){state=STATE.NONE;this.target.copy(this.target0);this.object.position.copy(this.position0);this.update()};function getAutoRotationAngle(){return 2*Math.PI/60/60*scope.autoRotateSpeed}function getZoomScale(){return Math.pow(.95,scope.zoomSpeed)}function onMouseDown(event){if(scope.enabled===false)return;event.preventDefault();if(event.button===0){if(scope.noRotate===true)return;state=STATE.ROTATE;rotateStart.set(event.clientX,event.clientY)}else if(event.button===1){if(scope.noZoom===true)return;state=STATE.DOLLY;dollyStart.set(event.clientX,event.clientY)}else if(event.button===2){if(scope.noPan===true)return;state=STATE.PAN;panStart.set(event.clientX,event.clientY)}document.addEventListener("mousemove",onMouseMove,false);document.addEventListener("mouseup",onMouseUp,false);scope.dispatchEvent(startEvent)}function onMouseMove(event){if(scope.enabled===false)return;event.preventDefault();var element=scope.domElement===document?scope.domElement.body:scope.domElement;if(state===STATE.ROTATE){if(scope.noRotate===true)return;rotateEnd.set(event.clientX,event.clientY);rotateDelta.subVectors(rotateEnd,rotateStart);scope.rotateLeft(2*Math.PI*rotateDelta.x/element.clientWidth*scope.rotateSpeed);scope.rotateUp(2*Math.PI*rotateDelta.y/element.clientHeight*scope.rotateSpeed);rotateStart.copy(rotateEnd)}else if(state===STATE.DOLLY){if(scope.noZoom===true)return;dollyEnd.set(event.clientX,event.clientY);dollyDelta.subVectors(dollyEnd,dollyStart);if(dollyDelta.y>0){scope.dollyIn()}else{scope.dollyOut()}dollyStart.copy(dollyEnd)}else if(state===STATE.PAN){if(scope.noPan===true)return;panEnd.set(event.clientX,event.clientY);panDelta.subVectors(panEnd,panStart);scope.pan(panDelta.x,panDelta.y);panStart.copy(panEnd)}scope.update()}function onMouseUp(){if(scope.enabled===false)return;document.removeEventListener("mousemove",onMouseMove,false);document.removeEventListener("mouseup",onMouseUp,false);scope.dispatchEvent(endEvent);state=STATE.NONE}function onMouseWheel(event){if(scope.enabled===false||scope.noZoom===true)return;event.preventDefault();event.stopPropagation();var delta=0;if(event.wheelDelta!==undefined){delta=event.wheelDelta}else if(event.detail!==undefined){delta=-event.detail}if(delta>0){scope.dollyOut()}else{scope.dollyIn()}scope.update();scope.dispatchEvent(startEvent);scope.dispatchEvent(endEvent)}function onKeyDown(event){if(scope.enabled===false||scope.noKeys===true||scope.noPan===true)return;switch(event.keyCode){case scope.keys.UP:scope.pan(0,scope.keyPanSpeed);scope.update();break;case scope.keys.BOTTOM:scope.pan(0,-scope.keyPanSpeed);scope.update();break;case scope.keys.LEFT:scope.pan(scope.keyPanSpeed,0);scope.update();break;case scope.keys.RIGHT:scope.pan(-scope.keyPanSpeed,0);scope.update();break}}function touchstart(event){if(scope.enabled===false)return;switch(event.touches.length){case 1:if(scope.noRotate===true)return;state=STATE.TOUCH_ROTATE;rotateStart.set(event.touches[0].pageX,event.touches[0].pageY);break;case 2:if(scope.noZoom===true)return;state=STATE.TOUCH_DOLLY;var dx=event.touches[0].pageX-event.touches[1].pageX;var dy=event.touches[0].pageY-event.touches[1].pageY;var distance=Math.sqrt(dx*dx+dy*dy);dollyStart.set(0,distance);break;case 3:if(scope.noPan===true)return;state=STATE.TOUCH_PAN;panStart.set(event.touches[0].pageX,event.touches[0].pageY);break;default:state=STATE.NONE}scope.dispatchEvent(startEvent)}function touchmove(event){if(scope.enabled===false)return;event.preventDefault();event.stopPropagation();var element=scope.domElement===document?scope.domElement.body:scope.domElement;switch(event.touches.length){case 1:if(scope.noRotate===true)return;if(state!==STATE.TOUCH_ROTATE)return;rotateEnd.set(event.touches[0].pageX,event.touches[0].pageY);rotateDelta.subVectors(rotateEnd,rotateStart);scope.rotateLeft(2*Math.PI*rotateDelta.x/element.clientWidth*scope.rotateSpeed);scope.rotateUp(2*Math.PI*rotateDelta.y/element.clientHeight*scope.rotateSpeed);rotateStart.copy(rotateEnd);scope.update();break;case 2:if(scope.noZoom===true)return;if(state!==STATE.TOUCH_DOLLY)return;var dx=event.touches[0].pageX-event.touches[1].pageX;var dy=event.touches[0].pageY-event.touches[1].pageY;var distance=Math.sqrt(dx*dx+dy*dy);dollyEnd.set(0,distance);dollyDelta.subVectors(dollyEnd,dollyStart);if(dollyDelta.y>0){scope.dollyOut()}else{scope.dollyIn()}dollyStart.copy(dollyEnd);scope.update();break;case 3:if(scope.noPan===true)return;if(state!==STATE.TOUCH_PAN)return;panEnd.set(event.touches[0].pageX,event.touches[0].pageY);panDelta.subVectors(panEnd,panStart);scope.pan(panDelta.x,panDelta.y);panStart.copy(panEnd);scope.update();break;default:state=STATE.NONE}}function touchend(){if(scope.enabled===false)return;scope.dispatchEvent(endEvent);state=STATE.NONE}this.domElement.addEventListener("contextmenu",function(event){event.preventDefault()},false);this.domElement.addEventListener("mousedown",onMouseDown,false);this.domElement.addEventListener("mousewheel",onMouseWheel,false);this.domElement.addEventListener("DOMMouseScroll",onMouseWheel,false);this.domElement.addEventListener("touchstart",touchstart,false);this.domElement.addEventListener("touchend",touchend,false);this.domElement.addEventListener("touchmove",touchmove,false);window.addEventListener("keydown",onKeyDown,false);this.update()};THREE.OrbitControls.prototype=Object.create(THREE.EventDispatcher.prototype)},{}],10:[function(require,module,exports){var fullScreen={};fullScreen.available=function(){return this._hasWebkitFullScreen||this._hasMozFullScreen};fullScreen.activated=function(){if(this._hasWebkitFullScreen){return document.webkitIsFullScreen}else if(this._hasMozFullScreen){return document.mozFullScreen}else{console.assert(false)}};fullScreen.request=function(element){element=element||document.body;if(this._hasWebkitFullScreen){element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}else if(this._hasMozFullScreen){element.mozRequestFullScreen()}else{console.assert(false)}};fullScreen.cancel=function(){if(this._hasWebkitFullScreen){document.webkitCancelFullScreen()}else if(this._hasMozFullScreen){document.mozCancelFullScreen()}else{console.assert(false)}};fullScreen._hasWebkitFullScreen="webkitCancelFullScreen"in document?true:false;fullScreen._hasMozFullScreen="mozCancelFullScreen"in document?true:false;fullScreen.bindKey=function(opts){opts=opts||{};var charCode=opts.charCode||"f".charCodeAt(0);var dblclick=opts.dblclick!==undefined?opts.dblclick:false;var element=opts.element;var toggle=function(){if(fullScreen.activated()){fullScreen.cancel()}else{fullScreen.request(element)}};var __bind=function(fn,me){return function(){return fn.apply(me,arguments)}};var onKeyPress=__bind(function(event){if(event.which!==charCode){return}toggle()},this);document.addEventListener("keypress",onKeyPress,false);dblclick&&document.addEventListener("dblclick",toggle,false);return{unbind:function(){document.removeEventListener("keypress",onKeyPress,false);dblclick&&document.removeEventListener("dblclick",toggle,false)}}};module.exports=fullScreen},{}],11:[function(require,module,exports){var windowResize=function(renderer,camera){var callback=function(){renderer.setSize(window.innerWidth,window.innerHeight);camera.aspect=window.innerWidth/window.innerHeight;camera.updateProjectionMatrix()};window.addEventListener("resize",callback,false);return{stop:function(){window.removeEventListener("resize",callback)}}};windowResize.bind=function(renderer,camera){return windowResize(renderer,camera)};module.exports=windowResize},{}],12:[function(require,module,exports){module.exports={WindowResize:require("./WindowResize"),FullScreen:require("./FullScreen")}},{"./FullScreen":10,"./WindowResize":11}],13:[function(require,module,exports){var THREE=window.THREE;function Coordinates(config,theme){config=config||{};this.mesh=new THREE.Object3D;this.axes={name:"Axes",mesh:this.drawAllAxes({axisLength:100,axisRadius:1,axisTess:50}),visible:config.axes!==undefined?config.axes:true};this.ground={name:"Ground",mesh:this.drawGround({size:1e5,color:theme.groundColor}),visible:config.ground!==undefined?config.ground:true};this.gridX={name:"XZ grid",mesh:this.drawGrid({size:1e4,scale:.01,color:theme.gridColor}),visible:config.gridX!==undefined?config.gridX:true};this.gridY={name:"YZ grid",mesh:this.drawGrid({size:1e4,scale:.01,orientation:"y",color:theme.gridColor}),visible:config.gridY!==undefined?config.gridY:false};this.gridZ={name:"XY grid",mesh:this.drawGrid({size:1e4,scale:.01,orientation:"z",color:theme.gridColor}),visible:config.gridZ!==undefined?config.gridZ:false};Coordinates.prototype.init.call(this,config)}Coordinates.prototype.init=function(options){var me=this;for(var key in me){if(me.hasOwnProperty(key)){var v=me[key];if(v.mesh){me.mesh.add(v.mesh);v.mesh.visible=v.visible}}}return me};Coordinates.prototype.initDatGui=function(gui){var me=this,folder;folder=gui.addFolder("Scene helpers");for(var key in me){if(me.hasOwnProperty(key)){var v=me[key];if(v.hasOwnProperty("mesh")){folder.add(v,"visible").name(v.name).onFinishChange(function(property){return function(newValue){property.mesh.visible=newValue}}(v))}}}return me};Coordinates.prototype.drawGrid=function(params){params=params||{};var color=params.color!==undefined?params.color:"#505050";var orientation=params.orientation!==undefined?params.orientation:"x";var grid=new THREE.GridHelper(500,10);grid.setColors(11053224,color);if(orientation==="x"){grid.rotation.x=-Math.PI/2}else if(orientation==="y"){grid.rotation.y=-Math.PI/2;
}else if(orientation==="z"){grid.rotation.z=-Math.PI/2}return grid};Coordinates.prototype.drawGround=function(params){params=params||{};var size=params.size!==undefined?params.size:100;var color=params.color!==undefined?params.color:0;var offset=params.offset!==undefined?params.offset:-.5;var ground=new THREE.Mesh(new THREE.PlaneGeometry(size,size),new THREE.MeshBasicMaterial({transparent:true,side:THREE.DoubleSide,opacity:.6,color:color}));ground.rotation.x=-Math.PI/2;ground.position.y=offset;return ground};Coordinates.prototype.drawAxes=function(params){params=params||{};var axisRadius=params.axisRadius!==undefined?params.axisRadius:.04;var axisLength=params.axisLength!==undefined?params.axisLength:11;var axisTess=params.axisTess!==undefined?params.axisTess:48;var axisOrientation=params.axisOrientation!==undefined?params.axisOrientation:"x";var wrap=new THREE.Object3D;var axisMaterial=new THREE.MeshLambertMaterial({color:0,side:THREE.DoubleSide});var axis=new THREE.Mesh(new THREE.CylinderGeometry(axisRadius,axisRadius,axisLength,axisTess,1,true),axisMaterial);if(axisOrientation==="x"){axis.rotation.z=-Math.PI/2;axis.position.x=axisLength/2-1}else if(axisOrientation==="y"){axis.position.y=axisLength/2-1}wrap.add(axis);var arrow=new THREE.Mesh(new THREE.CylinderGeometry(0,4*axisRadius,8*axisRadius,axisTess,1,true),axisMaterial);if(axisOrientation==="x"){arrow.rotation.z=-Math.PI/2;arrow.position.x=axisLength-1+axisRadius*4/2}else if(axisOrientation==="y"){arrow.position.y=axisLength-1+axisRadius*4/2}wrap.add(arrow);return wrap};Coordinates.prototype.drawAllAxes=function(params){params=params||{};var axisRadius=params.axisRadius!==undefined?params.axisRadius:.04;var axisLength=params.axisLength!==undefined?params.axisLength:10;var axisTess=params.axisTess!==undefined?params.axisTess:24;var wrap=new THREE.Object3D;var axisXMaterial=new THREE.MeshLambertMaterial({color:16711680});var axisYMaterial=new THREE.MeshLambertMaterial({color:65280});var axisZMaterial=new THREE.MeshLambertMaterial({color:255});axisXMaterial.side=THREE.DoubleSide;axisYMaterial.side=THREE.DoubleSide;axisZMaterial.side=THREE.DoubleSide;var axisX=new THREE.Mesh(new THREE.CylinderGeometry(axisRadius,axisRadius,axisLength,axisTess,1,true),axisXMaterial);var axisY=new THREE.Mesh(new THREE.CylinderGeometry(axisRadius,axisRadius,axisLength,axisTess,1,true),axisYMaterial);var axisZ=new THREE.Mesh(new THREE.CylinderGeometry(axisRadius,axisRadius,axisLength,axisTess,1,true),axisZMaterial);axisX.rotation.z=-Math.PI/2;axisX.position.x=axisLength/2-1;axisY.position.y=axisLength/2-1;axisZ.rotation.y=-Math.PI/2;axisZ.rotation.z=-Math.PI/2;axisZ.position.z=axisLength/2-1;wrap.add(axisX);wrap.add(axisY);wrap.add(axisZ);var arrowX=new THREE.Mesh(new THREE.CylinderGeometry(0,4*axisRadius,4*axisRadius,axisTess,1,true),axisXMaterial);var arrowY=new THREE.Mesh(new THREE.CylinderGeometry(0,4*axisRadius,4*axisRadius,axisTess,1,true),axisYMaterial);var arrowZ=new THREE.Mesh(new THREE.CylinderGeometry(0,4*axisRadius,4*axisRadius,axisTess,1,true),axisZMaterial);arrowX.rotation.z=-Math.PI/2;arrowX.position.x=axisLength-1+axisRadius*4/2;arrowY.position.y=axisLength-1+axisRadius*4/2;arrowZ.rotation.z=-Math.PI/2;arrowZ.rotation.y=-Math.PI/2;arrowZ.position.z=axisLength-1+axisRadius*4/2;wrap.add(arrowX);wrap.add(arrowY);wrap.add(arrowZ);return wrap};module.exports=Coordinates},{}],14:[function(require,module,exports){module.exports={clearColor:4144959,fogColor:4144959,groundColor:3355443,gridColor:5592405}},{}],15:[function(require,module,exports){module.exports={dark:require("./dark"),light:require("./light")}},{"./dark":14,"./light":16}],16:[function(require,module,exports){module.exports={clearColor:15924479,fogColor:15924479,groundColor:15658734}},{}],"t3-boilerplate":[function(require,module,exports){require("./lib/OrbitControls");var Application=require("./controller/Application");var t3={model:{Coordinates:require("./model/Coordinates")},themes:require("./themes/"),controller:{Application:Application,Keyboard:require("./controller/Keyboard"),LoopManager:require("./controller/LoopManager")},Application:Application,run:Application.run};module.exports=t3},{"./controller/Application":6,"./controller/Keyboard":7,"./controller/LoopManager":8,"./lib/OrbitControls":9,"./model/Coordinates":13,"./themes/":15}]},{},[]);var qh=require("quickhull3d");var t3=require("t3-boilerplate");t3.run({selector:"#canvas",helpersConfig:{ground:false,gridX:false,gridY:false,gridZ:false,axes:false},init:function(){var N_POINTS=1e4;var LIMIT=100;var i;function p(){return-LIMIT+2*Math.random()*LIMIT}function pointGenerator(){return[p(),p(),p()]}var points=[];for(i=0;i<N_POINTS;i+=1){points.push(pointGenerator())}console.time("quickhull");var faces=qh(points);console.timeEnd("quickhull");var geometry=new THREE.Geometry;for(i=0;i<points.length;i+=1){geometry.vertices.push((new THREE.Vector3).fromArray(points[i]))}var normal;for(i=0;i<faces.length;i+=1){var a=(new THREE.Vector3).fromArray(points[faces[i][0]]);var b=(new THREE.Vector3).fromArray(points[faces[i][1]]);var c=(new THREE.Vector3).fromArray(points[faces[i][2]]);normal=(new THREE.Vector3).crossVectors((new THREE.Vector3).subVectors(b,a),(new THREE.Vector3).subVectors(c,a)).normalize();geometry.faces.push(new THREE.Face3(faces[i][0],faces[i][1],faces[i][2],normal))}var polyhedra=new THREE.Mesh(geometry,new THREE.MeshNormalMaterial({}));this.activeScene.add(polyhedra);var helper=new THREE.WireframeHelper(polyhedra);helper.material.depthTest=false;helper.material.opacity=.25;helper.material.transparent=true;this.activeScene.add(helper);this.activeScene.add(new THREE.FaceNormalsHelper(polyhedra,10))},update:function(delta){}})},0);
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"quickhull3d": "2.0.0",
"t3-boilerplate": "0.2.7"
}
}
<!-- contents of this file will be placed inside the <body> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
<div id="canvas"></div>
<!-- contents of this file will be placed inside the <head> -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment