Finds the convex hull of a finite set of 3d points
Last active
August 16, 2016 22:32
-
-
Save mauriciopoppe/9b19fccfa670c9e2597b to your computer and use it in GitHub Desktop.
requirebin sketch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) {} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)&¶ms.hideable){hideable_guis.push(this)}params.resizable=common.isUndefined(params.parent)&¶ms.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=" ";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&©&&(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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "requirebin-sketch", | |
"version": "1.0.0", | |
"dependencies": { | |
"quickhull3d": "2.0.0", | |
"t3-boilerplate": "0.2.7" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- 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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- contents of this file will be placed inside the <head> --> |
made with requirebin
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment