From 65836ced498704e5ea39b77af4d915b28c3944f8 Mon Sep 17 00:00:00 2001 From: gbiobob Date: Thu, 7 Apr 2016 21:06:31 +0200 Subject: [PATCH] Moving code to Three.js r75 --- .gitignore | 7 +- data/milkyway.json | 21 +- demo_galnet.html | 3 +- demo_infos.html | 2 +- demo_no_jsonfile.html | 2 +- demo_routes.html | 2 +- js/components/action.class.js | 10 +- js/components/grid.class.js | 4 +- js/components/hud.class.js | 4 +- js/ed3dmap.js | 22 +- js/ed3dmap.min.js | 2 +- vendor/renderstats/README.md | 51 + vendor/renderstats/threex.rendererstats.js | 66 ++ vendor/three-js/CSS3DRenderer.js | 75 +- vendor/three-js/OrbitControls.js | 1062 +++++++++++++----- vendor/three-js/Projector.js | 40 +- vendor/three-js/RaytracingRenderer.js | 545 +++------ vendor/three-js/shaders/ConvolutionShader.js | 101 ++ 18 files changed, 1231 insertions(+), 788 deletions(-) create mode 100644 vendor/renderstats/README.md create mode 100644 vendor/renderstats/threex.rendererstats.js create mode 100644 vendor/three-js/shaders/ConvolutionShader.js diff --git a/.gitignore b/.gitignore index 9ab9744..3b3cc6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ -minify/ \ No newline at end of file +minify/ +demo_planet.html +demo_edsm.html +js/ed3dplanet.js +json_samples/eddb.json +json_samples/edsm.json \ No newline at end of file diff --git a/data/milkyway.json b/data/milkyway.json index 03a587f..96e56af 100644 --- a/data/milkyway.json +++ b/data/milkyway.json @@ -45,41 +45,41 @@ {"x":-7265, "z":4226, "rotate":-35}, {"x":6858, "z":-576, "rotate":0} ], - "The outer arm vacuus" : [ + "The outer Arm vacuus" : [ {"x":10, "z":-14500, "rotate":0} ], - "The Sagittarius arm" : [ + "The Sagittarius Arm" : [ {"x":5379, "z":4768, "rotate":0} ], - "The Carina-Sagittarius arm" : [ + "The Carina-Sagittarius Arm" : [ {"x":22458, "z":10237, "rotate":45}, {"x":29632, "z":25285, "rotate":82}, {"x":28962, "z":40634, "rotate":105}, {"x":17446, "z":58185, "rotate":-40} ], - "The new outer arm" : [ + "The new outer Arm" : [ {"x":-31158, "z":16529, "rotate":90}, {"x":-28281, "z":3070, "rotate":112}, {"x":-18972, "z":-8546, "rotate":-35} ], - "The Perseus arm" : [ + "The Perseus Arm" : [ {"x":-19961, "z":30870, "rotate":60 }, {"x":-22778, "z":10633, "rotate":110 }, {"x":-7525, "z":-3597, "rotate":-25 }, {"x":8039, "z":-7019, "rotate":0 }, {"x":32905, "z":4565, "rotate":45 } ], - "The Norma arm" : [ + "The Norma Arm" : [ {"x":7944, "z":17960, "rotate":40 }, {"x":13524, "z":29918, "rotate":90 }, {"x":7498, "z":40348, "rotate":-35 } ], - "The Cygnus arm" : [ + "The Cygnus Arm" : [ {"x":-7724, "z":43523, "rotate":0 }, {"x":-22353, "z":37643, "rotate":38 } ], - "The Scutum-Centaurus arm" : [ + "The Scutum-Centaurus Arm" : [ {"x":-33364, "z":46016, "rotate":45 }, {"x":-15742, "z":54759, "rotate":0 }, {"x":-334, "z":53331, "rotate":-14 }, @@ -87,10 +87,10 @@ {"x":19815, "z":31418, "rotate":90 }, {"x":16637, "z":17458, "rotate":48 } ], - "The near 3KPC arm" : [ + "The near 3 KPC Arm" : [ {"x":5765, "z":22639, "rotate":45 } ], - "The far 3KPC arm" : [ + "The far 3 KPC Arm" : [ {"x":-4906 ,"z":28535, "rotate":45 } ] }, @@ -134,5 +134,4 @@ ] } - } \ No newline at end of file diff --git a/demo_galnet.html b/demo_galnet.html index 818a00d..0b2e98f 100644 --- a/demo_galnet.html +++ b/demo_galnet.html @@ -35,8 +35,7 @@ - - + diff --git a/demo_infos.html b/demo_infos.html index 13fd73c..7a63188 100644 --- a/demo_infos.html +++ b/demo_infos.html @@ -62,7 +62,7 @@

Milky Way

- + diff --git a/demo_no_jsonfile.html b/demo_no_jsonfile.html index 4e457ff..5cb8144 100644 --- a/demo_no_jsonfile.html +++ b/demo_no_jsonfile.html @@ -49,7 +49,7 @@

NO JSon file test

- +
diff --git a/demo_routes.html b/demo_routes.html index 8db6c2e..2276018 100644 --- a/demo_routes.html +++ b/demo_routes.html @@ -61,7 +61,7 @@

Milky Way

- + diff --git a/js/components/action.class.js b/js/components/action.class.js index a52e0fa..a947b24 100644 --- a/js/components/action.class.js +++ b/js/components/action.class.js @@ -264,7 +264,7 @@ var Action = { mx: Ed3d.playerPos[0], my: Ed3d.playerPos[1] , mz: -Ed3d.playerPos[2] }; camera.position.set(moveTo.x, moveTo.y, moveTo.z); - controls.center.set(moveTo.mx, moveTo.my, moveTo.mz); + controls.target.set(moveTo.mx, moveTo.my, moveTo.mz); }, @@ -281,7 +281,7 @@ var Action = { var moveFrom = { x: camera.position.x, y: camera.position.y , z: camera.position.z, - mx: controls.center.x, my: controls.center.y , mz: controls.center.z + mx: controls.target.x, my: controls.target.y , mz: controls.target.z }; //-- Move to player position if defined, else move to Sol @@ -307,7 +307,7 @@ var Action = { .start() .onUpdate(function () { camera.position.set(moveFrom.x, moveFrom.y, moveFrom.z); - controls.center.set(moveFrom.mx, moveFrom.my, moveFrom.mz); + controls.target.set(moveFrom.mx, moveFrom.my, moveFrom.mz); }) .onComplete(function () { controls.enabled = true; @@ -348,7 +348,7 @@ var Action = { var moveFrom = { x: camera.position.x, y: camera.position.y , z: camera.position.z, - mx: controls.center.x, my: controls.center.y , mz: controls.center.z + mx: controls.target.x, my: controls.target.y , mz: controls.target.z }; var moveCoords = { x: goX, y: goY + 15, z: goZ + 15, @@ -359,7 +359,7 @@ var Action = { .start() .onUpdate(function () { camera.position.set(moveFrom.x, moveFrom.y, moveFrom.z); - controls.center.set(moveFrom.mx, moveFrom.my, moveFrom.mz); + controls.target.set(moveFrom.mx, moveFrom.my, moveFrom.mz); }) .onComplete(function () { controls.update(); diff --git a/js/components/grid.class.js b/js/components/grid.class.js index 1b91b45..b58cc27 100644 --- a/js/components/grid.class.js +++ b/js/components/grid.class.js @@ -66,7 +66,7 @@ var Grid = { } - this.obj = new THREE.Line( geometry, material, THREE.LinePieces ); + this.obj = new THREE.LineSegments( geometry, material ); this.obj.position.set(0,0,-20000); //-- Add quadrant @@ -85,7 +85,7 @@ var Grid = { quadrant.vertices.push( new THREE.Vector3( 0, 0, - size ) ); quadrant.vertices.push( new THREE.Vector3( 0, 0, size ) ); - var quadrantL = new THREE.Line( quadrant, material, THREE.LinePieces ); + var quadrantL = new THREE.LineSegments( quadrant, material ); this.obj.add(quadrantL); diff --git a/js/components/hud.class.js b/js/components/hud.class.js index eeeb39b..7595f58 100644 --- a/js/components/hud.class.js +++ b/js/components/hud.class.js @@ -113,14 +113,14 @@ var HUD = { case 'top': Ed3d.isTopView = true; var moveFrom = {x: camera.position.x, y: camera.position.y , z: camera.position.z}; - var moveCoords = {x: controls.center.x, y: controls.center.y+500, z: controls.center.z}; + var moveCoords = {x: controls.target.x, y: controls.target.y+500, z: controls.target.z}; HUD.moveCamera(moveFrom,moveCoords); break; case '3d': Ed3d.isTopView = false; var moveFrom = {x: camera.position.x, y: camera.position.y , z: camera.position.z}; - var moveCoords = {x: controls.center.x-100, y: controls.center.y+500, z: controls.center.z+500}; + var moveCoords = {x: controls.target.x-100, y: controls.target.y+500, z: controls.target.z+500}; HUD.moveCamera(moveFrom,moveCoords); break; diff --git a/js/ed3dmap.js b/js/ed3dmap.js index 1150a70..f0ee141 100644 --- a/js/ed3dmap.js +++ b/js/ed3dmap.js @@ -282,8 +282,8 @@ var Ed3d = { }); Ed3d.material.glow_2 = new THREE.SpriteMaterial({ - map: Ed3d.textures.flare_white, transparent: true, size: 15, - vertexColors: THREE.VertexColors, + map: Ed3d.textures.flare_white, + transparent: true, blending: THREE.AdditiveBlending, depthWrite: false, opacity: 0.5 @@ -334,11 +334,11 @@ var Ed3d = { //controls controls = new THREE.OrbitControls(camera, container); - controls.rotateSpeed = 1.0; - controls.zoomSpeed = 3.0; + controls.rotateSpeed = 0.6; + controls.zoomSpeed = 2.0; controls.panSpeed = 0.8; controls.maxDistance = 60000; - controls.noZoom=!1;controls.noPan=!1;controls.staticMoving=!0;controls.dynamicDampingFactor=.3; + controls.enableZoom=1;controls.enablePan=1;controls.enableDamping=!0;controls.dampingFactor=.3; // Add Fog @@ -516,6 +516,8 @@ var Ed3d = { function animate(time) { + //rendererStats.update(renderer); + if(scene.visible == false) { requestAnimationFrame( animate ); return; @@ -534,16 +536,16 @@ function animate(time) { //-- If 2D top view, lock camera pos if(Ed3d.isTopView) { camera.rotation.set(-Math.PI/2,0,0); - camera.position.x = controls.center.x; - camera.position.z = controls.center.z; + camera.position.x = controls.target.x; + camera.position.z = controls.target.z; } renderer.render(scene, camera); - $('#cx').html(Math.round(controls.center.x)); - $('#cy').html(Math.round(controls.center.y)); - $('#cz').html(Math.round(-controls.center.z)); // Reverse z coord + $('#cx').html(Math.round(controls.target.x)); + $('#cy').html(Math.round(controls.target.y)); + $('#cz').html(Math.round(-controls.target.z)); // Reverse z coord $('#distsol').html(Ed3d.calcDistSol(controls.target)); diff --git a/js/ed3dmap.min.js b/js/ed3dmap.min.js index fc07233..3a27e26 100644 --- a/js/ed3dmap.min.js +++ b/js/ed3dmap.min.js @@ -1 +1 @@ -var isMinified=true;var camera;var controls;var scene;var light;var renderer;var raycaster;var composer;var container;var routes=[];var lensFlareSel;var Ed3d={container:null,basePath:"./",jsonPath:null,jsonContainer:null,grid1H:null,grid1K:null,grid1XL:null,tween:null,globalView:true,fogDensity:null,textSel:[],catObjs:[],material:{Trd:new THREE.MeshBasicMaterial({color:16777215}),line:new THREE.LineBasicMaterial({color:16777215}),white:new THREE.MeshBasicMaterial({color:16777215}),orange:new THREE.MeshBasicMaterial({color:16751872}),black:new THREE.MeshBasicMaterial({color:65793}),lightblue:new THREE.MeshBasicMaterial({color:950152}),darkblue:new THREE.MeshBasicMaterial({color:1452331}),selected:new THREE.MeshPhongMaterial({color:917503}),transparent:new THREE.MeshBasicMaterial({color:0,transparent:true,opacity:0}),glow_1:null,custom:[]},colors:[],textures:{},systemColor:"#eeeeee",withHudPanel:false,hudMultipleSelect:true,systems:[],starfield:null,startAnim:true,effectScaleSystem:[10,800],optDistObj:1500,playerPos:[0,0,0],cameraPos:null,isTopView:false,showGalaxyInfos:false,init:function(options){var options=$.extend({container:Ed3d.container,basePath:Ed3d.basePath,jsonPath:Ed3d.jsonPath,jsonContainer:Ed3d.jsonContainer,withHudPanel:Ed3d.withHudPanel,hudMultipleSelect:Ed3d.hudMultipleSelect,effectScaleSystem:Ed3d.effectScaleSystem,startAnim:Ed3d.startAnim,playerPos:Ed3d.playerPos,cameraPos:Ed3d.cameraPos,systemColor:Ed3d.systemColor,showGalaxyInfos:false},options);Loader.start();this.basePath=options.basePath;this.container=options.container;this.jsonPath=options.jsonPath;this.jsonContainer=options.jsonContainer;this.withHudPanel=options.withHudPanel;this.hudMultipleSelect=options.hudMultipleSelect;this.startAnim=options.startAnim;this.effectScaleSystem=options.effectScaleSystem;this.playerPos=options.playerPos;this.cameraPos=options.cameraPos;this.showGalaxyInfos=options.showGalaxyInfos;this.systemColor=options.systemColor;$("#"+Ed3d.container).append('
');Loader.update("Load core files");if(typeof isMinified!=="undefined"){return Ed3d.launchMap()}$.when($.getScript(Ed3d.basePath+"vendor/three-js/OrbitControls.js"),$.getScript(Ed3d.basePath+"vendor/three-js/CSS3DRenderer.js"),$.getScript(Ed3d.basePath+"vendor/three-js/Projector.js"),$.getScript(Ed3d.basePath+"vendor/three-js/FontUtils.js"),$.getScript(Ed3d.basePath+"vendor/three-js/helvetiker_regular.typeface.js"),$.getScript(Ed3d.basePath+"js/components/grid.class.js"),$.getScript(Ed3d.basePath+"js/components/icon.class.js"),$.getScript(Ed3d.basePath+"js/components/hud.class.js"),$.getScript(Ed3d.basePath+"js/components/action.class.js"),$.getScript(Ed3d.basePath+"js/components/route.class.js"),$.getScript(Ed3d.basePath+"js/components/system.class.js"),$.getScript(Ed3d.basePath+"js/components/galaxy.class.js"),$.getScript(Ed3d.basePath+"vendor/tween-js/Tween.js"),$.Deferred(function(deferred){$(deferred.resolve)})).done(function(){Loader.update("Done !");Ed3d.launchMap()})},rebuild:function(options){Loader.start();System.remove();HUD.removeFilters();if(this.jsonPath!=null){Ed3d.loadDatasFromFile()}else{if(this.jsonContainer!=null){Ed3d.loadDatasFromContainer()}}Action.moveInitalPosition();Loader.stop()},launchMap:function(){Loader.update("Textures");Ed3d.loadTextures();Loader.update("Launch scene");Ed3d.initScene();Ed3d.grid1H=$.extend({},Grid.init(100,1121827,0),{});Ed3d.grid1K=$.extend({},Grid.init(1000,2241082,1000),{});Ed3d.grid1XL=$.extend({},Grid.infos(10000,2241082,10000),{});Ed3d.skyboxStars();HUD.create("ed3dmap");Loader.update("Add Sagittarius A*");Galaxy.addGalaxyCenter();Loader.update("Loading json file");if(this.jsonPath!=null){Ed3d.loadDatasFromFile()}else{if(this.jsonContainer!=null){Ed3d.loadDatasFromContainer()}}if(!this.startAnim){Ed3d.grid1XL.hide();Galaxy.milkyway2D.visible=false}animate()},loadTextures:function(){var texloader=new THREE.TextureLoader();this.textures.flare_white=texloader.load(Ed3d.basePath+"textures/lensflare/flare2.png");this.textures.flare_yellow=texloader.load(Ed3d.basePath+"textures/lensflare/star_grey2.png");this.textures.flare_center=texloader.load(Ed3d.basePath+"textures/lensflare/flare3.png");Ed3d.material.glow_1=new THREE.SpriteMaterial({map:this.textures.flare_yellow,color:16777215,transparent:false,fog:true});Ed3d.material.glow_2=new THREE.SpriteMaterial({map:Ed3d.textures.flare_white,transparent:true,size:15,vertexColors:THREE.VertexColors,blending:THREE.AdditiveBlending,depthWrite:false,opacity:0.5})},addCustomMaterial:function(id,color){var color=new THREE.Color("#"+color);this.colors[id]=color},initScene:function(){container=document.getElementById("ed3dmap");scene=new THREE.Scene();scene.visible=false;camera=new THREE.PerspectiveCamera(45,container.offsetWidth/container.offsetHeight,1,200000);camera.position.set(0,500,500);light=new THREE.HemisphereLight(16777215,13421772);scene.add(light);renderer=new THREE.WebGLRenderer({antialias:true,alpha:true});renderer.setClearColor(0,1);renderer.setSize(container.offsetWidth,container.offsetHeight);renderer.domElement.style.zIndex=5;container.appendChild(renderer.domElement);controls=new THREE.OrbitControls(camera,container);controls.rotateSpeed=1;controls.zoomSpeed=3;controls.panSpeed=0.8;controls.maxDistance=60000;controls.noZoom=!1;controls.noPan=!1;controls.staticMoving=!0;controls.dynamicDampingFactor=0.3;scene.fog=new THREE.FogExp2(855312,0.000128);renderer.setClearColor(scene.fog.color,1);Ed3d.fogDensity=scene.fog.density},showScene:function(){Loader.stop();scene.visible=true},loadDatasFromFile:function(){$.getJSON(this.jsonPath,function(data){Ed3d.loadDatas(data)}).done(function(){Ed3d.loadDatasComplete();Ed3d.showScene()})},loadDatasFromContainer:function(){var content=$("#"+this.jsonContainer).html();var json=null;try{json=JSON.parse(content)}catch(e){console.log("Can't load JSon for systems")}if(json!=null){Ed3d.loadDatas(json)}Ed3d.loadDatasComplete();Ed3d.showScene()},loadDatas:function(data){System.initParticleSystem();if(data.categories!=undefined){HUD.initFilters(data.categories)}list=(data.systems!==undefined)?data.systems:data;Loader.update("Routes...");if(data.routes!=undefined){$.each(data.routes,function(key,route){Route.initRoute(key,route)})}Loader.update("Systems...");$.each(list,function(key,val){system=System.create(val);if(system!=undefined){if(val.cat!=undefined){Ed3d.addObjToCategories(system,val.cat)}if(val.cat!=undefined){Ed3d.systems.push(system)}}});if(data.routes!=undefined){$.each(data.routes,function(key,route){Route.createRoute(key,route)})}},loadDatasComplete:function(){System.endParticleSystem();HUD.init();Action.init()},addObjToCategories:function(index,catList){$.each(catList,function(keyArr,idCat){Ed3d.catObjs[idCat].push(index)})},skyboxStars:function(){var sizeStars=10000;var particles=new THREE.Geometry;for(var p=0;p<5;p++){var particle=new THREE.Vector3(Math.random()*sizeStars-(sizeStars/2),Math.random()*sizeStars-(sizeStars/2),Math.random()*sizeStars-(sizeStars/2));particles.vertices.push(particle)}var particleMaterial=new THREE.PointsMaterial({color:15658734,size:2});this.starfield=new THREE.Points(particles,particleMaterial);scene.add(this.starfield)},calcDistSol:function(target){var dx=target.x;var dy=target.y;var dz=target.z;return Math.round(Math.sqrt(dx*dx+dy*dy+dz*dz))}};function animate(time){if(scene.visible==false){requestAnimationFrame(animate);return}refreshWithCamPos();controls.update();TWEEN.update(time);if(Ed3d.isTopView){camera.rotation.set(-Math.PI/2,0,0);camera.position.x=controls.center.x;camera.position.z=controls.center.z}renderer.render(scene,camera);$("#cx").html(Math.round(controls.center.x));$("#cy").html(Math.round(controls.center.y));$("#cz").html(Math.round(-controls.center.z));$("#distsol").html(Ed3d.calcDistSol(controls.target));Ed3d.starfield.position.set(controls.target.x-(controls.target.x/10)%4000,controls.target.y-(controls.target.y/10)%4000,controls.target.z-(controls.target.z/10)%4000);var scale=distanceFromTarget(camera)/200;if(Action.cursorSel!=null){if(scale>=0.01&&scale<10){Action.cursorSel.scale.set(scale,scale,scale)}Action.cursorSel.rotation.y=camera.rotation.y}if(Ed3d.textSel.system!=undefined){if(Ed3d.isTopView){Ed3d.textSel.system.rotation.set(-Math.PI/2,0,0)}else{Ed3d.textSel.system.rotation.set(0,0,0)}}Action.sizeOnScroll(scale);Galaxy.infosUpdateCallback(scale);if(scale>25){enableFarView(scale)}else{disableFarView(scale)}requestAnimationFrame(animate)}var isFarView=false;function enableFarView(scale,withAnim){if(isFarView){return}if(withAnim==undefined){withAnim=true}isFarView=true;var scaleFrom={zoom:25};var scaleTo={zoom:500};if(withAnim){Ed3d.tween=new TWEEN.Tween(scaleFrom,{override:true}).to(scaleTo,500).start().onUpdate(function(){Galaxy.milkyway[0].material.size=scaleFrom.zoom;Galaxy.milkyway[1].material.size=scaleFrom.zoom*4})}else{Galaxy.milkyway[0].material.size=scaleTo;Galaxy.milkyway[1].material.size=scaleTo*4}Galaxy.milkyway2D.visible=true;Galaxy.infosShow();if(Action.cursorSel!=null){Action.cursorSel.scale.set(60,60,60)}Ed3d.grid1H.hide();Ed3d.grid1K.hide();Ed3d.grid1XL.show();Ed3d.starfield.visible=false;scene.fog.density=0.000009}function disableFarView(scale,withAnim){if(!isFarView){return}if(withAnim==undefined){withAnim=true}isFarView=false;var oldScale=parseFloat(1/(25/3));var scaleFrom={zoom:250};var scaleTo={zoom:64};if(withAnim){Ed3d.tween=new TWEEN.Tween(scaleFrom,{override:true}).to(scaleTo,500).start().onUpdate(function(){Galaxy.milkyway[0].material.size=scaleFrom.zoom;Galaxy.milkyway[1].material.size=scaleFrom.zoom})}else{Galaxy.milkyway[0].material.size=scaleTo;Galaxy.milkyway[1].material.size=scaleTo}Galaxy.milkyway2D.visible=false;Galaxy.infosHide();Galaxy.milkyway[0].material.size=16;camera.scale.set(1,1,1);if(Action.cursorSel!=null){Action.cursorSel.scale.set(1,1,1)}Ed3d.grid1H.show();Ed3d.grid1K.show();Ed3d.grid1XL.hide();Ed3d.starfield.visible=true;scene.fog.density=Ed3d.fogDensity}function render(){renderer.render(scene,camera)}window.addEventListener("resize",function(){if(renderer!=undefined){var width=container.offsetWidth;var height=container.offsetHeight;if(width<100){width=100}if(height<100){height=100}renderer.setSize(width,height);camera.aspect=width/height;camera.updateProjectionMatrix()}});function distance(v1,v2){var dx=v1.position.x-v2.position.x;var dy=v1.position.y-v2.position.y;var dz=v1.position.z-v2.position.z;return Math.round(Math.sqrt(dx*dx+dy*dy+dz*dz))}function distanceFromTarget(v1){var dx=v1.position.x-controls.target.x;var dy=v1.position.y-controls.target.y;var dz=v1.position.z-controls.target.z;return Math.round(Math.sqrt(dx*dx+dy*dy+dz*dz))}var camSave={x:0,y:0,z:0};function refreshWithCamPos(){var d=new Date();var n=d.getTime();if(n%1!=0){return}Ed3d.grid1H.addCoords();Ed3d.grid1K.addCoords();var p=Ed3d.optDistObj/2;if(camSave.x==Math.round(camera.position.x/p)*p&&camSave.y==Math.round(camera.position.y/p)*p&&camSave.z==Math.round(camera.position.z/p)*p){return}camSave.x=Math.round(camera.position.x/p)*p;camSave.y=Math.round(camera.position.y/p)*p;camSave.z=Math.round(camera.position.z/p)*p}var Loader={start:function(){$("#loader").remove();$("
").attr("id","loader").html(Loader.svgAnim).css("color","rgb(200, 110, 37)").css("font-size","1.5rem").css("font-family","Helvetica").css("font-variant","small-caps").appendTo("body");clearInterval(this.animCount);this.animCount=setInterval(function(){var animProgress=$("#loader #loadTimer");animProgress.append(".");if(animProgress.html().length>10){animProgress.html(".")}},1000)},update:function(info){$("#loader #loadInfos").html(info)},stop:function(){$("#loader").remove();clearInterval(this.animCount)},animCount:null,svgAnim:'
.
'};var Action={cursorSel:null,mouseVector:null,raycaster:null,oldSel:null,objHover:null,mouseUpDownTimer:null,animPosition:null,prevScale:null,init:function(){this.mouseVector=new THREE.Vector3();this.raycaster=new THREE.Raycaster();container.addEventListener("mousedown",this.onMouseDown,false);container.addEventListener("mouseup",this.onMouseUp,false);container.addEventListener("mousewheel",this.stopWinScroll,false);container.addEventListener("DOMMouseScroll",this.stopWinScroll,false)},stopWinScroll:function(event){event.preventDefault();event.stopPropagation()},sizeOnScroll:function(scale){if(System.particle==undefined||scale<=0){return}var minScale=Ed3d.effectScaleSystem[0];var maxScale=Ed3d.effectScaleSystem[1];var newScale=scale*20;if(this.prevScale==newScale){return}this.prevScale=newScale;if(newScale>maxScale){newScale=maxScale}if(newScale0){for(var i=0;i0.2){this.mouseUpDownTimer=null;return}this.mouseUpDownTimer=null;var position=$("#ed3dmap").offset();this.mouseVector=new THREE.Vector3(((e.clientX-position.left)/renderer.domElement.width)*2-1,-((e.clientY-position.top)/renderer.domElement.height)*2+1,1);this.mouseVector.unproject(camera);this.raycaster=new THREE.Raycaster(camera.position,this.mouseVector.sub(camera.position).normalize());this.raycaster.params.Points.threshold=2;var intersects=this.raycaster.intersectObjects(scene.children);if(intersects.length>0){for(var i=0;i"+selPoint.name+"");var isMove=Action.moveToObj(indexPoint,selPoint);if(isMove){return}}}if(intersection.object.showCoord){$("#debug").html(Math.round(intersection.point.x)+" , "+Math.round(-intersection.point.z));Route.addPoint(Math.round(intersection.point.x),0,Math.round(-intersection.point.z))}}}},moveNextPrev:function(indexPoint,increment){var find=false;while(!find){if(indexPoint<0){indexPoint=System.particleGeo.vertices.length-1}else{if(System.particleGeo.vertices[indexPoint]==undefined){indexPoint=0}}if(System.particleGeo.vertices[indexPoint].visible==true){find=true}else{indexPoint+=increment}}var selPoint=System.particleGeo.vertices[indexPoint];Action.moveToObj(indexPoint,selPoint)},disableSelection:function(){if(this.cursorSel==null){return}this.oldSel=null;this.cursorSel.visible=false;$("#hud #infos").html("")},moveInitalPositionNoAnim:function(timer){var cam=[Ed3d.playerPos[0],Ed3d.playerPos[1]+500,Ed3d.playerPos[2]+500];if(Ed3d.cameraPos!=null){cam=[Ed3d.cameraPos[0],Ed3d.cameraPos[1],-Ed3d.cameraPos[2]]}var moveTo={x:cam[0],y:cam[1],z:cam[2],mx:Ed3d.playerPos[0],my:Ed3d.playerPos[1],mz:-Ed3d.playerPos[2]};camera.position.set(moveTo.x,moveTo.y,moveTo.z);controls.center.set(moveTo.mx,moveTo.my,moveTo.mz)},moveInitalPosition:function(timer){if(timer==undefined){timer=800}this.disableSelection();var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z,mx:controls.center.x,my:controls.center.y,mz:controls.center.z};var cam=[Ed3d.playerPos[0],Ed3d.playerPos[1]+500,Ed3d.playerPos[2]+500];if(Ed3d.cameraPos!=null){cam=[Ed3d.cameraPos[0],Ed3d.cameraPos[1],-Ed3d.cameraPos[2]]}var moveCoords={x:cam[0],y:cam[1],z:cam[2],mx:Ed3d.playerPos[0],my:Ed3d.playerPos[1],mz:-Ed3d.playerPos[2]};controls.enabled=false;if(Ed3d.tween!=null){TWEEN.removeAll()}Ed3d.tween=new TWEEN.Tween(moveFrom,{override:true}).to(moveCoords,timer).start().onUpdate(function(){camera.position.set(moveFrom.x,moveFrom.y,moveFrom.z);controls.center.set(moveFrom.mx,moveFrom.my,moveFrom.mz)}).onComplete(function(){controls.enabled=true;controls.update()})},moveToObj:function(index,obj){if(this.oldSel!==null&&this.oldSel==index){return false}controls.enabled=false;HUD.setInfoPanel(index,obj);HUD.openHudDetails();this.oldSel=index;var goX=obj.x;var goY=obj.y;var goZ=obj.z;disableFarView(25,false);this.moveGridTo(goX,goY,goZ);var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z,mx:controls.center.x,my:controls.center.y,mz:controls.center.z};var moveCoords={x:goX,y:goY+15,z:goZ+15,mx:goX,my:goY,mz:goZ};Ed3d.tween=new TWEEN.Tween(moveFrom,{override:true}).to(moveCoords,800).start().onUpdate(function(){camera.position.set(moveFrom.x,moveFrom.y,moveFrom.z);controls.center.set(moveFrom.mx,moveFrom.my,moveFrom.mz)}).onComplete(function(){controls.update()});obj.material=Ed3d.material.selected;this.addCusorOnSelect(goX,goY,goZ);var textAdd=obj.name;var textAddC=Math.round(goX)+", "+Math.round(goY)+", "+Math.round(-goZ);HUD.addText("system",textAdd,8,20,0,6,this.cursorSel);HUD.addText("coords",textAddC,8,15,0,3,this.cursorSel);controls.enabled=true;return true},addCusorOnSelect:function(x,y,z){if(this.cursorSel==null){this.cursorSel=new THREE.Object3D();var geometryL=new THREE.TorusGeometry(12,0.4,3,30);var selection=new THREE.Mesh(geometryL,Ed3d.material.selected);selection.rotation.x=Math.PI/2;this.cursorSel.add(selection);var geometryCone=new THREE.CylinderGeometry(0,5,16,4,1,false);var cone=new THREE.Mesh(geometryCone,Ed3d.material.selected);cone.position.set(0,20,0);cone.rotation.x=Math.PI;this.cursorSel.add(cone);var geometryConeInner=new THREE.CylinderGeometry(0,3.6,16,4,1,false);var coneInner=new THREE.Mesh(geometryConeInner,Ed3d.material.black);coneInner.position.set(0,20.2,0);coneInner.rotation.x=Math.PI;this.cursorSel.add(coneInner);scene.add(this.cursorSel)}this.cursorSel.visible=true;this.cursorSel.position.set(x,y,z);this.cursorSel.scale.set(1,1,1)},moveGridTo:function(goX,goY,goZ){var posX=Math.floor(goX/1000)*1000;var posY=Math.floor(goY);var posZ=Math.floor(goZ/1000)*1000;if(!Ed3d.grid1H.fixed){Ed3d.grid1H.obj.position.set(posX,posY,posZ)}if(!Ed3d.grid1K.fixed){Ed3d.grid1K.obj.position.set(posX,posY,posZ)}if(!Ed3d.grid1XL.fixed){Ed3d.grid1XL.obj.position.set(posX,posY,posZ)}}};var Galaxy={obj:null,infos:null,milkyway:[],milkyway2D:null,backActive:true,colors:[],x:25,y:-21,z:25900,addGalaxyCenter:function(){var objVal=new Object;objVal.name="Sagittarius A*";objVal.coords={x:this.y,y:this.y,z:this.z};objVal.cat=[];this.obj=System.create(objVal,true);var sprite=new THREE.Sprite(Ed3d.material.glow_2);sprite.scale.set(50,40,2);this.obj.add(sprite);this.createParticles();this.add2DPlane()},createParticles:function(){var img=new Image();img.onload=function(){Galaxy.getHeightData(img);if(Ed3d.startAnim){camera.position.set(-10000,40000,50000);Action.moveInitalPosition(4000)}else{Action.moveInitalPositionNoAnim()}};img.src=Ed3d.basePath+"textures/heightmap7.jpg";this.showGalaxyInfos()},showGalaxyInfos:function(){if(!Ed3d.showGalaxyInfos){return}this.infos=new THREE.Object3D();$.getJSON(Ed3d.basePath+"data/milkyway.json",function(data){$.each(data.quadrants,function(key,val){Galaxy.addText(key,val.x,-100,val.z,val.rotate)});$.each(data.arms,function(key,val){$.each(val,function(keyCh,valCh){Galaxy.addText(key,valCh.x,0,valCh.z,valCh.rotate,300,true)})});$.each(data.gaps,function(key,val){$.each(val,function(keyCh,valCh){Galaxy.addText(key,valCh.x,0,valCh.z,valCh.rotate,160,true)})});$.each(data.others,function(key,val){$.each(val,function(keyCh,valCh){Galaxy.addText(key,valCh.x,0,valCh.z,valCh.rotate,160,true)})})}).done(function(){scene.add(Galaxy.infos)})},infosShow:function(){if(Galaxy.infos==null){this.showGalaxyInfos()}if(Galaxy.infos!==null){Galaxy.infos.visible=Ed3d.showGalaxyInfos}},infosHide:function(){if(Galaxy.infos!==null){Galaxy.infos.visible=false}},infosUpdateCallback:function(scale){if(!Ed3d.showGalaxyInfos||this.infos==null){return}scale-=70;var opacity=Math.round(scale/10)/10;if(opacity<0){opacity=0}if(opacity>0.8){opacity=0.8}if(Galaxy.infos.previousOpacity==opacity){return}var opacityMiddle=1.1-opacity;if(opacityMiddle<=0.4){opacityMiddle=0.2}for(var i=0;i0.5){i+=8}var all=pix[i]+pix[i+1]+pix[i+2];var avg=Math.round((pix[i]+pix[i+1]+pix[i+2])/3);if(avg>min){var x=scaleImg*((i/4)%img.width);var z=scaleImg*(Math.floor((i/4)/img.height));var density=Math.floor((pix[i]-min)/10);if(density>maxDensity){density=maxDensity}var add=Math.ceil(density/maxDensity*2);for(var y=-density;y=2&&Math.abs(y)-1==0&&Math.random()*1000<200){particlesBig.vertices.push(particle);colorsBig[nbBig]=new THREE.Color("rgb("+r+", "+g+", "+b+")");nbBig++}else{if(density<4||(Math.random()*1000<400-(density*2))){particles.vertices.push(particle);this.colors[nb]=new THREE.Color("rgb("+r+", "+g+", "+b+")");nb++}}}}}particles.colors=this.colors;var particleMaterial=new THREE.PointsMaterial({map:Ed3d.textures.flare_yellow,transparent:true,size:64,vertexColors:THREE.VertexColors,blending:THREE.AdditiveBlending,depthTest:true,depthWrite:false});var points=new THREE.Points(particles,particleMaterial);points.sortParticles=true;particles.center();this.milkyway[0]=points;this.milkyway[0].scale.set(20,20,20);this.obj.add(points);particlesBig.colors=colorsBig;var particleMaterialBig=new THREE.PointsMaterial({map:Ed3d.textures.flare_yellow,transparent:true,vertexColors:THREE.VertexColors,size:16,blending:THREE.AdditiveBlending,depthTest:true,depthWrite:false});var pointsBig=new THREE.Points(particlesBig,particleMaterialBig);pointsBig.sortParticles=true;particlesBig.center();this.milkyway[1]=pointsBig;this.milkyway[1].scale.set(20,20,20);this.obj.add(pointsBig)}};var Grid={obj:null,size:null,textShapes:null,textGeo:null,coordTxt:null,minDistView:null,visible:true,fixed:false,init:function(size,color,minDistView){this.size=size;this.obj=new THREE.GridHelper(1000000,size);this.obj.setColors(color,color);this.obj.minDistView=minDistView;scene.add(this.obj);this.obj.customUpdateCallback=this.addCoords;return this},infos:function(step,color,minDistView){var size=50000;if(step==undefined){step=10000}this.fixed=true;var geometry=new THREE.Geometry();var material=new THREE.LineBasicMaterial({color:5592405,transparent:true,opacity:0.2,blending:THREE.AdditiveBlending,depthWrite:false});for(var i=-size;i<=size;i+=step){geometry.vertices.push(new THREE.Vector3(-size,0,i));geometry.vertices.push(new THREE.Vector3(size,0,i));geometry.vertices.push(new THREE.Vector3(i,0,-size));geometry.vertices.push(new THREE.Vector3(i,0,size))}this.obj=new THREE.Line(geometry,material,THREE.LinePieces);this.obj.position.set(0,0,-20000);var quadrant=new THREE.Geometry();var material=new THREE.LineBasicMaterial({color:8947848,transparent:true,opacity:0.5,blending:THREE.AdditiveBlending,depthWrite:false});quadrant.vertices.push(new THREE.Vector3(-size,0,20000));quadrant.vertices.push(new THREE.Vector3(size,0,20000));quadrant.vertices.push(new THREE.Vector3(0,0,-size));quadrant.vertices.push(new THREE.Vector3(0,0,size));var quadrantL=new THREE.Line(quadrant,material,THREE.LinePieces);this.obj.add(quadrantL);scene.add(this.obj);return this},addCoords:function(){var textShow="0 : 0 : 0";var options={font:"helvetiker",weight:"normal",style:"normal",size:this.size/20,curveSegments:10};if(this.coordGrid!=null){if(Math.abs(camera.position.y-this.obj.position.y)>this.size*10||Math.abs(camera.position.y-this.obj.position.y) 3D 2D i '+Ico.cog+'
');this.createSubOptions()}if(!Ed3d.withHudPanel){return}$("#"+this.container).append('
');$("#hud").append('

Infos

Dist. Sol

');$("#"+this.container).append('')},createSubOptions:function(){$("").addClass("sub-opt active").attr("href","#").html("Toggle Milky Way").click(function(){var state=Galaxy.milkyway[0].visible;Galaxy.milkyway[0].visible=!state;Galaxy.milkyway[1].visible=!state;Galaxy.milkyway2D.visible=!state;$(this).toggleClass("active")}).appendTo("#options");$("").addClass("sub-opt active").attr("href","#").html("Toggle grid").click(function(){Ed3d.grid1H.toggleGrid();Ed3d.grid1K.toggleGrid();Ed3d.grid1XL.toggleGrid();$(this).toggleClass("active")}).appendTo("#options")},initControls:function(){$("#controls a").click(function(e){if($(this).hasClass("view")){$("#controls a.view").removeClass("selected");$(this).addClass("selected")}var view=$(this).data("view");switch(view){case"top":Ed3d.isTopView=true;var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z};var moveCoords={x:controls.center.x,y:controls.center.y+500,z:controls.center.z};HUD.moveCamera(moveFrom,moveCoords);break;case"3d":Ed3d.isTopView=false;var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z};var moveCoords={x:controls.center.x-100,y:controls.center.y+500,z:controls.center.z+500};HUD.moveCamera(moveFrom,moveCoords);break;case"infos":if(!Ed3d.showGalaxyInfos){Ed3d.showGalaxyInfos=true;Galaxy.infosShow()}else{Ed3d.showGalaxyInfos=false;Galaxy.infosHide()}$(this).toggleClass("selected");break;case"options":$("#options").toggle();break}})},moveCamera:function(from,to){Ed3d.tween=new TWEEN.Tween(from,{override:true}).to(to,800).start().onUpdate(function(){camera.position.set(from.x,from.y,from.z)}).onComplete(function(){controls.update()})},initHudAction:function(){$("canvas").hover(function(){controls.enabled=true},function(){controls.enabled=false});$("#hud").hover(function(){controls.enabled=false},function(){controls.enabled=true});$("#systemDetails").hide();$(".map_filter").each(function(e){var idCat=$(this).data("filter");var count=Ed3d.catObjs[idCat].length;if(count>1){$(this).append(" ("+count+")")}});$(".map_filter").click(function(e){e.preventDefault();var idCat=$(this).data("filter");var active=$(this).data("active");active=(Math.abs(active-1));if(!Ed3d.hudMultipleSelect){$(".map_filter").addClass("disabled");$(System.particleGeo.vertices).each(function(index,point){point.visible=0;point.filtered=0;System.particleGeo.colors[index]=new THREE.Color("#111111");active=1})}$(Ed3d.catObjs[idCat]).each(function(key,indexPoint){obj=System.particleGeo.vertices[indexPoint];System.particleGeo.colors[indexPoint]=(active==1)?obj.color:new THREE.Color("#111111");obj.visible=(active==1);obj.filtered=(active==1);System.particleGeo.colorsNeedUpdate=true});$(this).data("active",active);$(this).toggleClass("disabled");if(Action.oldSel!=null&&!Action.oldSel.visible){Action.disableSelection()}Action.moveInitalPosition()});$(".map_link").click(function(e){e.preventDefault();var elId=$(this).data("route");Action.moveToObj(routes[elId])});$(".map_link span").click(function(e){e.preventDefault();var elId=$(this).parent().data("route");routes[elId].visible=!routes[elId].visible})},initFilters:function(categories){Loader.update("HUD Filter...");var grpNb=1;$.each(categories,function(typeFilter,values){if(typeof values==="object"){var groupId="group_"+grpNb;$("#filters").append("

"+typeFilter+"

");$("#filters").append('
');$.each(values,function(key,val){HUD.addFilter(groupId,key,val);Ed3d.catObjs[key]=[]});grpNb++}})},removeFilters:function(){$("#hud #filters").html("")},addFilter:function(groupId,idCat,val){var back="#fff";if(val.color!=undefined){Ed3d.addCustomMaterial(idCat,val.color);back="#"+val.color}$("#"+groupId).append(' '+val.name+"")},openHudDetails:function(){$("#hud").hide();$("#systemDetails").show().hover(function(){controls.enabled=false},function(){controls.enabled=true})},closeHudDetails:function(){$("#hud").show();$("#systemDetails").hide()},setRoute:function(idRoute,nameR){$("#routes").append(' '+nameR+"")},setInfoPanel:function(index,point){$("#systemDetails").html("

"+point.name+'

'+point.x+""+point.y+""+(-point.z)+'

'+(point.infos!=undefined?"
"+point.infos+"
":"")+'');$("",{html:"<"}).click(function(){Action.moveNextPrev(index-1,-1)}).appendTo("#nav");$("",{html:"X"}).click(function(){HUD.closeHudDetails()}).appendTo("#nav");$("",{html:">"}).click(function(){Action.moveNextPrev(index+1,1)}).appendTo("#nav")},addText:function(id,textShow,x,y,z,size,addToObj){if(addToObj==undefined){addToObj=scene}var textShapes=THREE.FontUtils.generateShapes(textShow,{font:"helvetiker",weight:"normal",style:"normal",size:size,curveSegments:100});var textGeo=new THREE.ShapeGeometry(textShapes);if(Ed3d.textSel[id]==undefined){var textMesh=new THREE.Mesh(textGeo,new THREE.MeshBasicMaterial({color:16777215}))}else{var textMesh=Ed3d.textSel[id]}textMesh.geometry=textGeo;textMesh.geometry.needsUpdate=true;textMesh.position.set(x,y,z);Ed3d.textSel[id]=textMesh;addToObj.add(textMesh)}};var Ico={cog:' '};var Route={active:false,systems:[],list:[],initRoute:function(idRoute,route){Route.active=true;$.each(route.points,function(key,val){Route.systems[val.s]=false})},createRoute:function(idRoute,route){var geometryL=new THREE.Geometry();var nameR="";var first=null;var last=null;$.each(route.points,function(key2,val){if(Route.systems[val.s]!==false){var c=Route.systems[val.s];if(first==null){first=[c[0],c[1],c[2]]}last=[c[0],c[1],c[2]];geometryL.vertices.push(new THREE.Vector3(c[0],c[1],c[2]));Route.addPoint(c[0],c[1],c[2])}else{console.log("Missing point: "+val.s)}});routes[idRoute]=new THREE.Line(geometryL,Ed3d.material.line);if(first!==null){routes[idRoute].add(this.addCircle(first))}if(last!==null){routes[idRoute].add(this.addCircle(last))}scene.add(routes[idRoute])},addCircle:function(point){var cursor=new THREE.Object3D;var geometryL=new THREE.TorusGeometry(12,0.4,3,30);var selection=new THREE.Mesh(geometryL,Ed3d.material.orange);selection.rotation.x=Math.PI/2;cursor.add(selection);cursor.position.set(point[0],point[1],point[2]);cursor.scale.set(15,15,15);scene.add(cursor)},addPoint:function(x,y,z){}};var System={particle:null,particleGeo:null,particleColor:[],particleInfos:[],count:0,scaleSize:64,create:function(val,withSolid){if(withSolid==undefined){withSolid=false}if(val.coords==undefined){return false}var x=parseInt(val.coords.x);var y=parseInt(val.coords.y);var z=-parseInt(val.coords.z);var colors=[];if(this.particleGeo!==null){var idSys=x+"_"+y+"_"+z;if(val.infos!=undefined&&this.particleInfos[idSys]){var indexParticle=this.particleInfos[idSys];this.particleGeo.vertices[indexParticle].infos+=val.infos;if(val.cat!=undefined){Ed3d.addObjToCategories(indexParticle,val.cat)}return}var particle=new THREE.Vector3(x,y,z);if(val.cat!=undefined&&val.cat[0]!=undefined&&Ed3d.colors[val.cat[0]]!=undefined){this.particleColor[this.count]=Ed3d.colors[val.cat[0]]}else{this.particleColor[this.count]=new THREE.Color(Ed3d.systemColor)}if(val.cat!=undefined){Ed3d.addObjToCategories(this.count,val.cat);particle.color=this.particleColor[this.count]}particle.clickable=true;particle.visible=true;particle.name=val.name;if(val.infos!=undefined){particle.infos=val.infos;this.particleInfos[idSys]=this.count}this.particleGeo.vertices.push(particle);this.count++}if(Route.active==true){if(Route.systems[val.name]!=undefined){Route.systems[val.name]=[x,y,z]}}if(withSolid){var mat=Ed3d.material.glow_1;var sprite=new THREE.Sprite(mat);sprite.position.set(x,y,z);sprite.scale.set(50,50,1);scene.add(sprite);var geometry=new THREE.SphereGeometry(2,10,10);var sphere=new THREE.Mesh(geometry,Ed3d.material.white);sphere.position.set(x,y,z);sphere.name=val.name;sphere.clickable=true;sphere.idsprite=sprite.id;scene.add(sphere);return sphere}},initParticleSystem:function(){this.particleGeo=new THREE.Geometry},endParticleSystem:function(){if(this.particleGeo==null){return}this.particleGeo.colors=this.particleColor;var particleMaterial=new THREE.PointsMaterial({map:Ed3d.textures.flare_yellow,vertexColors:THREE.VertexColors,size:this.scaleSize,fog:false,blending:THREE.AdditiveBlending,transparent:true,depthTest:true,depthWrite:false});this.particle=new THREE.Points(this.particleGeo,particleMaterial);this.particle.sortParticles=true;this.particle.clickable=true;scene.add(this.particle)},remove:function(){this.particleColor=[];this.particleGeo=null;this.count=0;scene.remove(this.particle)},loadSpectral:function(val){}};THREE.CSS3DObject=function(element){THREE.Object3D.call(this);this.element=element;this.element.style.position="absolute";this.element.style.WebkitTransformStyle="preserve-3d";this.element.style.MozTransformStyle="preserve-3d";this.element.style.oTransformStyle="preserve-3d";this.element.style.transformStyle="preserve-3d";this.addEventListener("removed",function(event){if(this.element.parentNode!==null){this.element.parentNode.removeChild(this.element);for(var i=0,l=this.children.length;i":{x_min:18.0625,x_max:774,ha:792,o:"m 774 376 l 18 40 l 18 149 l 631 421 l 18 692 l 18 799 l 774 465 l 774 376 "},v:{x_min:0,x_max:675.15625,ha:761,o:"m 675 738 l 404 0 l 272 0 l 0 738 l 133 737 l 340 147 l 541 737 l 675 738 "},"τ":{x_min:0.28125,x_max:644.5,ha:703,o:"m 644 628 l 382 628 l 382 179 q 388 120 382 137 q 436 91 401 91 q 474 94 447 91 q 504 97 501 97 l 504 0 q 454 -9 482 -5 q 401 -14 426 -14 q 278 67 308 -14 q 260 233 260 118 l 260 628 l 0 628 l 0 739 l 644 739 l 644 628 "},"ξ":{x_min:0,x_max:624.9375,ha:699,o:"m 624 -37 q 608 -153 624 -96 q 563 -278 593 -211 l 454 -278 q 491 -183 486 -200 q 511 -83 511 -126 q 484 -23 511 -44 q 370 1 452 1 q 323 0 354 1 q 283 -1 293 -1 q 84 76 169 -1 q 0 266 0 154 q 56 431 0 358 q 197 538 108 498 q 94 613 134 562 q 54 730 54 665 q 77 823 54 780 q 143 901 101 867 l 27 901 l 27 1012 l 576 1012 l 576 901 l 380 901 q 244 863 303 901 q 178 745 178 820 q 312 600 178 636 q 532 582 380 582 l 532 479 q 276 455 361 479 q 118 281 118 410 q 165 173 118 217 q 274 120 208 133 q 494 101 384 110 q 624 -37 624 76 "},"&":{x_min:-3,x_max:894.25,ha:992,o:"m 894 0 l 725 0 l 624 123 q 471 0 553 40 q 306 -41 390 -41 q 168 -7 231 -41 q 62 92 105 26 q 14 187 31 139 q -3 276 -3 235 q 55 433 -3 358 q 248 581 114 508 q 170 689 196 640 q 137 817 137 751 q 214 985 137 922 q 384 1041 284 1041 q 548 988 483 1041 q 622 824 622 928 q 563 666 622 739 q 431 556 516 608 l 621 326 q 649 407 639 361 q 663 493 653 426 l 781 493 q 703 229 781 352 l 894 0 m 504 818 q 468 908 504 877 q 384 940 433 940 q 293 907 331 940 q 255 818 255 875 q 289 714 255 767 q 363 628 313 678 q 477 729 446 682 q 504 818 504 771 m 556 209 l 314 499 q 179 395 223 449 q 135 283 135 341 q 146 222 135 253 q 183 158 158 192 q 333 80 241 80 q 556 209 448 80 "},"Λ":{x_min:0,x_max:862.5,ha:942,o:"m 862 0 l 719 0 l 426 847 l 143 0 l 0 0 l 356 1013 l 501 1013 l 862 0 "},I:{x_min:41,x_max:180,ha:293,o:"m 180 0 l 41 0 l 41 1013 l 180 1013 l 180 0 "},G:{x_min:0,x_max:921,ha:1011,o:"m 921 0 l 832 0 l 801 136 q 655 15 741 58 q 470 -28 568 -28 q 126 133 259 -28 q 0 499 0 284 q 125 881 0 731 q 486 1043 259 1043 q 763 957 647 1043 q 905 709 890 864 l 772 709 q 668 866 747 807 q 486 926 589 926 q 228 795 322 926 q 142 507 142 677 q 228 224 142 342 q 483 94 323 94 q 712 195 625 94 q 796 435 796 291 l 477 435 l 477 549 l 921 549 l 921 0 "},"ΰ":{x_min:0,x_max:617,ha:725,o:"m 524 800 l 414 800 l 414 925 l 524 925 l 524 800 m 183 800 l 73 800 l 73 925 l 183 925 l 183 800 m 617 352 q 540 93 617 199 q 308 -24 455 -24 q 76 93 161 -24 q 0 352 0 199 l 0 738 l 126 738 l 126 354 q 169 185 126 257 q 312 98 220 98 q 451 185 402 98 q 492 354 492 257 l 492 738 l 617 738 l 617 352 m 489 1040 l 300 819 l 216 819 l 351 1040 l 489 1040 "},"`":{x_min:0,x_max:138.890625,ha:236,o:"m 138 699 l 0 699 l 0 861 q 36 974 0 929 q 138 1041 72 1020 l 138 977 q 82 931 95 969 q 69 839 69 893 l 138 839 l 138 699 "},"·":{x_min:0,x_max:142,ha:239,o:"m 142 585 l 0 585 l 0 738 l 142 738 l 142 585 "},"Υ":{x_min:0.328125,x_max:819.515625,ha:889,o:"m 819 1013 l 482 416 l 482 0 l 342 0 l 342 416 l 0 1013 l 140 1013 l 411 533 l 679 1013 l 819 1013 "},r:{x_min:0,x_max:355.5625,ha:432,o:"m 355 621 l 343 621 q 179 569 236 621 q 122 411 122 518 l 122 0 l 0 0 l 0 737 l 117 737 l 117 604 q 204 719 146 686 q 355 753 262 753 l 355 621 "},x:{x_min:0,x_max:675,ha:764,o:"m 675 0 l 525 0 l 331 286 l 144 0 l 0 0 l 256 379 l 12 738 l 157 737 l 336 473 l 516 738 l 661 738 l 412 380 l 675 0 "},"μ":{x_min:0,x_max:696.609375,ha:747,o:"m 696 -4 q 628 -14 657 -14 q 498 97 513 -14 q 422 8 470 41 q 313 -24 374 -24 q 207 3 258 -24 q 120 80 157 31 l 120 -278 l 0 -278 l 0 738 l 124 738 l 124 343 q 165 172 124 246 q 308 82 216 82 q 451 177 402 82 q 492 358 492 254 l 492 738 l 616 738 l 616 214 q 623 136 616 160 q 673 92 636 92 q 696 95 684 92 l 696 -4 "},h:{x_min:0,x_max:615,ha:724,o:"m 615 472 l 615 0 l 490 0 l 490 454 q 456 590 490 535 q 338 654 416 654 q 186 588 251 654 q 122 436 122 522 l 122 0 l 0 0 l 0 1013 l 122 1013 l 122 633 q 218 727 149 694 q 362 760 287 760 q 552 676 484 760 q 615 472 615 600 "},".":{x_min:0,x_max:142,ha:239,o:"m 142 0 l 0 0 l 0 151 l 142 151 l 142 0 "},"φ":{x_min:-2,x_max:878,ha:974,o:"m 496 -279 l 378 -279 l 378 -17 q 101 88 204 -17 q -2 367 -2 194 q 68 626 -2 510 q 283 758 151 758 l 283 646 q 167 537 209 626 q 133 373 133 462 q 192 177 133 254 q 378 93 259 93 l 378 758 q 445 764 426 763 q 476 765 464 765 q 765 659 653 765 q 878 377 878 553 q 771 96 878 209 q 496 -17 665 -17 l 496 -279 m 496 93 l 514 93 q 687 183 623 93 q 746 380 746 265 q 691 569 746 491 q 522 658 629 658 l 496 656 l 496 93 "},";":{x_min:0,x_max:142,ha:239,o:"m 142 585 l 0 585 l 0 738 l 142 738 l 142 585 m 142 -12 q 105 -132 142 -82 q 0 -206 68 -182 l 0 -138 q 58 -82 43 -123 q 68 0 68 -56 l 0 0 l 0 151 l 142 151 l 142 -12 "},f:{x_min:0,x_max:378,ha:472,o:"m 378 638 l 246 638 l 246 0 l 121 0 l 121 638 l 0 638 l 0 738 l 121 738 q 137 935 121 887 q 290 1028 171 1028 q 320 1027 305 1028 q 378 1021 334 1026 l 378 908 q 323 918 346 918 q 257 870 273 918 q 246 780 246 840 l 246 738 l 378 738 l 378 638 "},"“":{x_min:1,x_max:348.21875,ha:454,o:"m 140 670 l 1 670 l 1 830 q 37 943 1 897 q 140 1011 74 990 l 140 947 q 82 900 97 940 q 68 810 68 861 l 140 810 l 140 670 m 348 670 l 209 670 l 209 830 q 245 943 209 897 q 348 1011 282 990 l 348 947 q 290 900 305 940 q 276 810 276 861 l 348 810 l 348 670 "},A:{x_min:0.03125,x_max:906.953125,ha:1008,o:"m 906 0 l 756 0 l 648 303 l 251 303 l 142 0 l 0 0 l 376 1013 l 529 1013 l 906 0 m 610 421 l 452 867 l 293 421 l 610 421 "},"6":{x_min:53,x_max:739,ha:792,o:"m 739 312 q 633 62 739 162 q 400 -31 534 -31 q 162 78 257 -31 q 53 439 53 206 q 178 859 53 712 q 441 986 284 986 q 643 912 559 986 q 732 713 732 833 l 601 713 q 544 830 594 786 q 426 875 494 875 q 268 793 331 875 q 193 517 193 697 q 301 597 240 570 q 427 624 362 624 q 643 540 552 624 q 739 312 739 451 m 603 298 q 540 461 603 400 q 404 516 484 516 q 268 461 323 516 q 207 300 207 401 q 269 137 207 198 q 405 83 325 83 q 541 137 486 83 q 603 298 603 197 "},"‘":{x_min:1,x_max:139.890625,ha:236,o:"m 139 670 l 1 670 l 1 830 q 37 943 1 897 q 139 1011 74 990 l 139 947 q 82 900 97 940 q 68 810 68 861 l 139 810 l 139 670 "},"ϊ":{x_min:-70,x_max:283,ha:361,o:"m 283 800 l 173 800 l 173 925 l 283 925 l 283 800 m 40 800 l -70 800 l -70 925 l 40 925 l 40 800 m 283 3 q 232 -10 257 -5 q 181 -15 206 -15 q 84 26 118 -15 q 41 200 41 79 l 41 737 l 166 737 l 167 215 q 171 141 167 157 q 225 101 182 101 q 247 103 238 101 q 283 112 256 104 l 283 3 "},"π":{x_min:-0.21875,x_max:773.21875,ha:857,o:"m 773 -7 l 707 -11 q 575 40 607 -11 q 552 174 552 77 l 552 226 l 552 626 l 222 626 l 222 0 l 97 0 l 97 626 l 0 626 l 0 737 l 773 737 l 773 626 l 676 626 l 676 171 q 695 103 676 117 q 773 90 714 90 l 773 -7 "},"ά":{x_min:0,x_max:765.5625,ha:809,o:"m 765 -4 q 698 -14 726 -14 q 564 97 586 -14 q 466 7 525 40 q 337 -26 407 -26 q 88 98 186 -26 q 0 369 0 212 q 88 637 0 525 q 337 760 184 760 q 465 727 407 760 q 563 637 524 695 l 563 738 l 685 738 l 685 222 q 693 141 685 168 q 748 94 708 94 q 765 95 760 94 l 765 -4 m 584 371 q 531 562 584 485 q 360 653 470 653 q 192 566 254 653 q 135 379 135 489 q 186 181 135 261 q 358 84 247 84 q 528 176 465 84 q 584 371 584 260 m 604 1040 l 415 819 l 332 819 l 466 1040 l 604 1040 "},O:{x_min:0,x_max:958,ha:1057,o:"m 485 1041 q 834 882 702 1041 q 958 512 958 734 q 834 136 958 287 q 481 -26 702 -26 q 126 130 261 -26 q 0 504 0 279 q 127 880 0 728 q 485 1041 263 1041 m 480 98 q 731 225 638 98 q 815 504 815 340 q 733 783 815 669 q 480 912 640 912 q 226 784 321 912 q 142 504 142 670 q 226 224 142 339 q 480 98 319 98 "},n:{x_min:0,x_max:615,ha:724,o:"m 615 463 l 615 0 l 490 0 l 490 454 q 453 592 490 537 q 331 656 410 656 q 178 585 240 656 q 117 421 117 514 l 117 0 l 0 0 l 0 738 l 117 738 l 117 630 q 218 728 150 693 q 359 764 286 764 q 552 675 484 764 q 615 463 615 593 "},"3":{x_min:54,x_max:737,ha:792,o:"m 737 284 q 635 55 737 141 q 399 -25 541 -25 q 156 52 248 -25 q 54 308 54 140 l 185 308 q 245 147 185 202 q 395 96 302 96 q 539 140 484 96 q 602 280 602 190 q 510 429 602 390 q 324 454 451 454 l 324 565 q 487 584 441 565 q 565 719 565 617 q 515 835 565 791 q 395 879 466 879 q 255 824 307 879 q 203 661 203 769 l 78 661 q 166 909 78 822 q 387 992 250 992 q 603 921 513 992 q 701 723 701 844 q 669 607 701 656 q 578 524 637 558 q 696 434 655 499 q 737 284 737 369 "},"9":{x_min:53,x_max:739,ha:792,o:"m 739 524 q 619 94 739 241 q 362 -32 516 -32 q 150 47 242 -32 q 59 244 59 126 l 191 244 q 246 129 191 176 q 373 82 301 82 q 526 161 466 82 q 597 440 597 255 q 363 334 501 334 q 130 432 216 334 q 53 650 53 521 q 134 880 53 786 q 383 986 226 986 q 659 841 566 986 q 739 524 739 719 m 388 449 q 535 514 480 449 q 585 658 585 573 q 535 805 585 744 q 388 873 480 873 q 242 809 294 873 q 191 658 191 745 q 239 514 191 572 q 388 449 292 449 "},l:{x_min:41,x_max:166,ha:279,o:"m 166 0 l 41 0 l 41 1013 l 166 1013 l 166 0 "},"¤":{x_min:40.09375,x_max:728.796875,ha:825,o:"m 728 304 l 649 224 l 512 363 q 383 331 458 331 q 256 363 310 331 l 119 224 l 40 304 l 177 441 q 150 553 150 493 q 184 673 150 621 l 40 818 l 119 898 l 267 749 q 321 766 291 759 q 384 773 351 773 q 447 766 417 773 q 501 749 477 759 l 649 898 l 728 818 l 585 675 q 612 618 604 648 q 621 553 621 587 q 591 441 621 491 l 728 304 m 384 682 q 280 643 318 682 q 243 551 243 604 q 279 461 243 499 q 383 423 316 423 q 487 461 449 423 q 525 553 525 500 q 490 641 525 605 q 384 682 451 682 "},"κ":{x_min:0,x_max:632.328125,ha:679,o:"m 632 0 l 482 0 l 225 384 l 124 288 l 124 0 l 0 0 l 0 738 l 124 738 l 124 446 l 433 738 l 596 738 l 312 466 l 632 0 "},"4":{x_min:48,x_max:742.453125,ha:792,o:"m 742 243 l 602 243 l 602 0 l 476 0 l 476 243 l 48 243 l 48 368 l 476 958 l 602 958 l 602 354 l 742 354 l 742 243 m 476 354 l 476 792 l 162 354 l 476 354 "},p:{x_min:0,x_max:685,ha:786,o:"m 685 364 q 598 96 685 205 q 350 -23 504 -23 q 121 89 205 -23 l 121 -278 l 0 -278 l 0 738 l 121 738 l 121 633 q 220 726 159 691 q 351 761 280 761 q 598 636 504 761 q 685 364 685 522 m 557 371 q 501 560 557 481 q 330 651 437 651 q 162 559 223 651 q 108 366 108 479 q 162 177 108 254 q 333 87 224 87 q 502 178 441 87 q 557 371 557 258 "},"‡":{x_min:0,x_max:777,ha:835,o:"m 458 238 l 458 0 l 319 0 l 319 238 l 0 238 l 0 360 l 319 360 l 319 681 l 0 683 l 0 804 l 319 804 l 319 1015 l 458 1013 l 458 804 l 777 804 l 777 683 l 458 683 l 458 360 l 777 360 l 777 238 l 458 238 "},"ψ":{x_min:0,x_max:808,ha:907,o:"m 465 -278 l 341 -278 l 341 -15 q 87 102 180 -15 q 0 378 0 210 l 0 739 l 133 739 l 133 379 q 182 195 133 275 q 341 98 242 98 l 341 922 l 465 922 l 465 98 q 623 195 563 98 q 675 382 675 278 l 675 742 l 808 742 l 808 381 q 720 104 808 213 q 466 -13 627 -13 l 465 -278 "},"η":{x_min:0.78125,x_max:697,ha:810,o:"m 697 -278 l 572 -278 l 572 454 q 540 587 572 536 q 425 650 501 650 q 271 579 337 650 q 206 420 206 509 l 206 0 l 81 0 l 81 489 q 73 588 81 562 q 0 644 56 644 l 0 741 q 68 755 38 755 q 158 720 124 755 q 200 630 193 686 q 297 726 234 692 q 434 761 359 761 q 620 692 544 761 q 697 516 697 624 l 697 -278 "}},cssFontWeight:"normal",ascender:1189,underlinePosition:-100,cssFontStyle:"normal",boundingBox:{yMin:-334,xMin:-111,yMax:1189,xMax:1672},resolution:1000,original_font_information:{postscript_name:"Helvetiker-Regular",version_string:"Version 1.00 2004 initial release",vendor_url:"http://www.magenta.gr/",full_font_name:"Helvetiker",font_family_name:"Helvetiker",copyright:"Copyright (c) Μagenta ltd, 2004",description:"",trademark:"",designer:"",designer_url:"",unique_font_identifier:"Μagenta ltd:Helvetiker:22-10-104",license_url:"http://www.ellak.gr/fonts/MgOpen/license.html",license_description:'Copyright (c) 2004 by MAGENTA Ltd. All Rights Reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: \r\n\r\nThe above copyright and this permission notice shall be included in all copies of one or more of the Font Software typefaces.\r\n\r\nThe Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing the word "MgOpen", or if the modifications are accepted for inclusion in the Font Software itself by the each appointed Administrator.\r\n\r\nThis License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "MgOpen" name.\r\n\r\nThe Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. \r\n\r\nTHE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL MAGENTA OR PERSONS OR BODIES IN CHARGE OF ADMINISTRATION AND MAINTENANCE OF THE FONT SOFTWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.',manufacturer_name:"Μagenta ltd",font_sub_family_name:"Regular"},descender:-334,familyName:"Helvetiker",lineHeight:1522,underlineThickness:50})}THREE.OrbitControls=function(object,domElement,localElement){this.object=object;this.domElement=(domElement!==undefined)?domElement:document;this.localElement=(localElement!==undefined)?localElement: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=0.000001;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 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 STATE={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5};var state=STATE.NONE;var changeEvent={type:"change"};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 panOffset=new THREE.Vector3();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 panOffset=new THREE.Vector3();var te=this.object.matrix.elements;panOffset.set(te[4],te[5],te[6]);panOffset.multiplyScalar(distance);pan.add(panOffset)};this.pan=function(delta){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*delta.x*targetDistance/element.clientHeight);scope.panUp(2*delta.y*targetDistance/element.clientHeight)}else{if(scope.object.top!==undefined){scope.panLeft(delta.x*(scope.object.right-scope.object.left)/element.clientWidth);scope.panUp(delta.y*(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;var offset=position.clone().sub(this.target);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);position.copy(this.target).add(offset);this.object.lookAt(this.target);thetaDelta=0;phiDelta=0;scale=1;pan.set(0,0,0);if(lastPosition.distanceTo(this.object.position)>0){this.dispatchEvent(changeEvent);lastPosition.copy(this.object.position)}};function getAutoRotationAngle(){return 2*Math.PI/60/60*scope.autoRotateSpeed}function getZoomScale(){return Math.pow(0.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)}}}scope.domElement.addEventListener("mousemove",onMouseMove,false);scope.domElement.addEventListener("mouseup",onMouseUp,false)}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);panStart.copy(panEnd)}}}scope.update()}function onMouseUp(){if(scope.enabled===false){return}scope.domElement.removeEventListener("mousemove",onMouseMove,false);scope.domElement.removeEventListener("mouseup",onMouseUp,false);state=STATE.NONE}function onMouseWheel(event){if(scope.enabled===false||scope.noZoom===true){return}var delta=0;if(event.wheelDelta){delta=event.wheelDelta}else{if(event.detail){delta=-event.detail}}if(delta>0){scope.dollyOut()}else{scope.dollyIn()}}function onKeyDown(event){if(scope.enabled===false){return}if(scope.noKeys===true){return}if(scope.noPan===true){return}var needUpdate=false;switch(event.keyCode){case scope.keys.UP:scope.pan(new THREE.Vector2(0,scope.keyPanSpeed));needUpdate=true;break;case scope.keys.BOTTOM:scope.pan(new THREE.Vector2(0,-scope.keyPanSpeed));needUpdate=true;break;case scope.keys.LEFT:scope.pan(new THREE.Vector2(scope.keyPanSpeed,0));needUpdate=true;break;case scope.keys.RIGHT:scope.pan(new THREE.Vector2(-scope.keyPanSpeed,0));needUpdate=true;break}if(needUpdate){scope.update()}}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}}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);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);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);panStart.copy(panEnd);break;default:state=STATE.NONE}}function touchend(){if(scope.enabled===false){return}state=STATE.NONE}this.domElement.addEventListener("contextmenu",function(event){event.preventDefault()},false);this.localElement.addEventListener("mousedown",onMouseDown,false);this.domElement.addEventListener("mousewheel",onMouseWheel,false);this.domElement.addEventListener("DOMMouseScroll",onMouseWheel,false);this.domElement.addEventListener("keydown",onKeyDown,false);this.localElement.addEventListener("touchstart",touchstart,false);this.domElement.addEventListener("touchend",touchend,false);this.domElement.addEventListener("touchmove",touchmove,false)};THREE.OrbitControls.prototype=Object.create(THREE.EventDispatcher.prototype);THREE.RenderableObject=function(){this.id=0;this.object=null;this.z=0;this.renderOrder=0};THREE.RenderableFace=function(){this.id=0;this.v1=new THREE.RenderableVertex();this.v2=new THREE.RenderableVertex();this.v3=new THREE.RenderableVertex();this.normalModel=new THREE.Vector3();this.vertexNormalsModel=[new THREE.Vector3(),new THREE.Vector3(),new THREE.Vector3()];this.vertexNormalsLength=0;this.color=new THREE.Color();this.material=null;this.uvs=[new THREE.Vector2(),new THREE.Vector2(),new THREE.Vector2()];this.z=0;this.renderOrder=0};THREE.RenderableVertex=function(){this.position=new THREE.Vector3();this.positionWorld=new THREE.Vector3();this.positionScreen=new THREE.Vector4();this.visible=true};THREE.RenderableVertex.prototype.copy=function(vertex){this.positionWorld.copy(vertex.positionWorld);this.positionScreen.copy(vertex.positionScreen)};THREE.RenderableLine=function(){this.id=0;this.v1=new THREE.RenderableVertex();this.v2=new THREE.RenderableVertex();this.vertexColors=[new THREE.Color(),new THREE.Color()];this.material=null;this.z=0;this.renderOrder=0};THREE.RenderableSprite=function(){this.id=0;this.object=null;this.x=0;this.y=0;this.z=0;this.rotation=0;this.scale=new THREE.Vector2();this.material=null;this.renderOrder=0};THREE.Projector=function(){var _object,_objectCount,_objectPool=[],_objectPoolLength=0,_vertex,_vertexCount,_vertexPool=[],_vertexPoolLength=0,_face,_faceCount,_facePool=[],_facePoolLength=0,_line,_lineCount,_linePool=[],_linePoolLength=0,_sprite,_spriteCount,_spritePool=[],_spritePoolLength=0,_renderData={objects:[],lights:[],elements:[]},_vector3=new THREE.Vector3(),_vector4=new THREE.Vector4(),_clipBox=new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1)),_boundingBox=new THREE.Box3(),_points3=new Array(3),_points4=new Array(4),_viewMatrix=new THREE.Matrix4(),_viewProjectionMatrix=new THREE.Matrix4(),_modelMatrix,_modelViewProjectionMatrix=new THREE.Matrix4(),_normalMatrix=new THREE.Matrix3(),_frustum=new THREE.Frustum(),_clippedVertex1PositionScreen=new THREE.Vector4(),_clippedVertex2PositionScreen=new THREE.Vector4();this.projectVector=function(vector,camera){console.warn("THREE.Projector: .projectVector() is now vector.project().");vector.project(camera)};this.unprojectVector=function(vector,camera){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");vector.unproject(camera)};this.pickingRay=function(vector,camera){console.error("THREE.Projector: .pickingRay() is now raycaster.setFromCamera().")};var RenderList=function(){var normals=[];var uvs=[];var object=null;var material=null;var normalMatrix=new THREE.Matrix3();var setObject=function(value){object=value;material=object.material;normalMatrix.getNormalMatrix(object.matrixWorld);normals.length=0;uvs.length=0};var projectVertex=function(vertex){var position=vertex.position;var positionWorld=vertex.positionWorld;var positionScreen=vertex.positionScreen;positionWorld.copy(position).applyMatrix4(_modelMatrix);positionScreen.copy(positionWorld).applyMatrix4(_viewProjectionMatrix);var invW=1/positionScreen.w;positionScreen.x*=invW;positionScreen.y*=invW;positionScreen.z*=invW;vertex.visible=positionScreen.x>=-1&&positionScreen.x<=1&&positionScreen.y>=-1&&positionScreen.y<=1&&positionScreen.z>=-1&&positionScreen.z<=1};var pushVertex=function(x,y,z){_vertex=getNextVertexInPool();_vertex.position.set(x,y,z);projectVertex(_vertex)};var pushNormal=function(x,y,z){normals.push(x,y,z)};var pushUv=function(x,y){uvs.push(x,y)};var checkTriangleVisibility=function(v1,v2,v3){if(v1.visible===true||v2.visible===true||v3.visible===true){return true}_points3[0]=v1.positionScreen;_points3[1]=v2.positionScreen;_points3[2]=v3.positionScreen;return _clipBox.isIntersectionBox(_boundingBox.setFromPoints(_points3))};var checkBackfaceCulling=function(v1,v2,v3){return((v3.positionScreen.x-v1.positionScreen.x)*(v2.positionScreen.y-v1.positionScreen.y)-(v3.positionScreen.y-v1.positionScreen.y)*(v2.positionScreen.x-v1.positionScreen.x))<0};var pushLine=function(a,b){var v1=_vertexPool[a];var v2=_vertexPool[b];_line=getNextLineInPool();_line.id=object.id;_line.v1.copy(v1);_line.v2.copy(v2);_line.z=(v1.positionScreen.z+v2.positionScreen.z)/2;_line.renderOrder=object.renderOrder;_line.material=object.material;_renderData.elements.push(_line)};var pushTriangle=function(a,b,c){var v1=_vertexPool[a];var v2=_vertexPool[b];var v3=_vertexPool[c];if(checkTriangleVisibility(v1,v2,v3)===false){return}if(material.side===THREE.DoubleSide||checkBackfaceCulling(v1,v2,v3)===true){_face=getNextFaceInPool();_face.id=object.id;_face.v1.copy(v1);_face.v2.copy(v2);_face.v3.copy(v3);_face.z=(v1.positionScreen.z+v2.positionScreen.z+v3.positionScreen.z)/3;_face.renderOrder=object.renderOrder;_face.normalModel.fromArray(normals,a*3);_face.normalModel.applyMatrix3(normalMatrix).normalize();for(var i=0;i<3;i++){var normal=_face.vertexNormalsModel[i];normal.fromArray(normals,arguments[i]*3);normal.applyMatrix3(normalMatrix).normalize();var uv=_face.uvs[i];uv.fromArray(uvs,arguments[i]*2)}_face.vertexNormalsLength=3;_face.material=object.material;_renderData.elements.push(_face)}};return{setObject:setObject,projectVertex:projectVertex,checkTriangleVisibility:checkTriangleVisibility,checkBackfaceCulling:checkBackfaceCulling,pushVertex:pushVertex,pushNormal:pushNormal,pushUv:pushUv,pushLine:pushLine,pushTriangle:pushTriangle}};var renderList=new RenderList();this.projectScene=function(scene,camera,sortObjects,sortElements){_faceCount=0;_lineCount=0;_spriteCount=0;_renderData.elements.length=0;if(scene.autoUpdate===true){scene.updateMatrixWorld()}if(camera.parent===null){camera.updateMatrixWorld()}_viewMatrix.copy(camera.matrixWorldInverse.getInverse(camera.matrixWorld));_viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix,_viewMatrix);_frustum.setFromMatrix(_viewProjectionMatrix);_objectCount=0;_renderData.objects.length=0;_renderData.lights.length=0;scene.traverseVisible(function(object){if(object instanceof THREE.Light){_renderData.lights.push(object)}else{if(object instanceof THREE.Mesh||object instanceof THREE.Line||object instanceof THREE.Sprite){var material=object.material;if(material.visible===false){return}if(object.frustumCulled===false||_frustum.intersectsObject(object)===true){_object=getNextObjectInPool();_object.id=object.id;_object.object=object;_vector3.setFromMatrixPosition(object.matrixWorld);_vector3.applyProjection(_viewProjectionMatrix);_object.z=_vector3.z;_object.renderOrder=object.renderOrder;_renderData.objects.push(_object)}}}});if(sortObjects===true){_renderData.objects.sort(painterSort)}for(var o=0,ol=_renderData.objects.length;o0){for(var o=0;o0){continue}v2=_vertexPool[_vertexCount-2];_clippedVertex1PositionScreen.copy(v1.positionScreen);_clippedVertex2PositionScreen.copy(v2.positionScreen);if(clipLine(_clippedVertex1PositionScreen,_clippedVertex2PositionScreen)===true){_clippedVertex1PositionScreen.multiplyScalar(1/_clippedVertex1PositionScreen.w);_clippedVertex2PositionScreen.multiplyScalar(1/_clippedVertex2PositionScreen.w);_line=getNextLineInPool();_line.id=object.id;_line.v1.positionScreen.copy(_clippedVertex1PositionScreen);_line.v2.positionScreen.copy(_clippedVertex2PositionScreen);_line.z=Math.max(_clippedVertex1PositionScreen.z,_clippedVertex2PositionScreen.z);_line.renderOrder=object.renderOrder;_line.material=object.material;if(object.material.vertexColors===THREE.VertexColors){_line.vertexColors[0].copy(object.geometry.colors[v]);_line.vertexColors[1].copy(object.geometry.colors[v-1])}_renderData.elements.push(_line)}}}}}else{if(object instanceof THREE.Sprite){_vector4.set(_modelMatrix.elements[12],_modelMatrix.elements[13],_modelMatrix.elements[14],1);_vector4.applyMatrix4(_viewProjectionMatrix);var invW=1/_vector4.w;_vector4.z*=invW;if(_vector4.z>=-1&&_vector4.z<=1){_sprite=getNextSpriteInPool();_sprite.id=object.id;_sprite.x=_vector4.x*invW;_sprite.y=_vector4.y*invW;_sprite.z=_vector4.z;_sprite.renderOrder=object.renderOrder;_sprite.object=object;_sprite.rotation=object.rotation;_sprite.scale.x=object.scale.x*Math.abs(_sprite.x-(_vector4.x+camera.projectionMatrix.elements[0])/(_vector4.w+camera.projectionMatrix.elements[12]));_sprite.scale.y=object.scale.y*Math.abs(_sprite.y-(_vector4.y+camera.projectionMatrix.elements[5])/(_vector4.w+camera.projectionMatrix.elements[13]));_sprite.material=object.material;_renderData.elements.push(_sprite)}}}}}if(sortElements===true){_renderData.elements.sort(painterSort)}return _renderData};function getNextObjectInPool(){if(_objectCount===_objectPoolLength){var object=new THREE.RenderableObject();_objectPool.push(object);_objectPoolLength++;_objectCount++;return object}return _objectPool[_objectCount++]}function getNextVertexInPool(){if(_vertexCount===_vertexPoolLength){var vertex=new THREE.RenderableVertex();_vertexPool.push(vertex);_vertexPoolLength++;_vertexCount++;return vertex}return _vertexPool[_vertexCount++]}function getNextFaceInPool(){if(_faceCount===_facePoolLength){var face=new THREE.RenderableFace();_facePool.push(face);_facePoolLength++;_faceCount++;return face}return _facePool[_faceCount++]}function getNextLineInPool(){if(_lineCount===_linePoolLength){var line=new THREE.RenderableLine();_linePool.push(line);_linePoolLength++;_lineCount++;return line}return _linePool[_lineCount++]}function getNextSpriteInPool(){if(_spriteCount===_spritePoolLength){var sprite=new THREE.RenderableSprite();_spritePool.push(sprite);_spritePoolLength++;_spriteCount++;return sprite}return _spritePool[_spriteCount++]}function painterSort(a,b){if(a.renderOrder!==b.renderOrder){return a.renderOrder-b.renderOrder}else{if(a.z!==b.z){return b.z-a.z}else{if(a.id!==b.id){return a.id-b.id}else{return 0}}}}function clipLine(s1,s2){var alpha1=0,alpha2=1,bc1near=s1.z+s1.w,bc2near=s2.z+s2.w,bc1far=-s1.z+s1.w,bc2far=-s2.z+s2.w;if(bc1near>=0&&bc2near>=0&&bc1far>=0&&bc2far>=0){return true}else{if((bc1near<0&&bc2near<0)||(bc1far<0&&bc2far<0)){return false}else{if(bc1near<0){alpha1=Math.max(alpha1,bc1near/(bc1near-bc2near))}else{if(bc2near<0){alpha2=Math.min(alpha2,bc1near/(bc1near-bc2near))}}if(bc1far<0){alpha1=Math.max(alpha1,bc1far/(bc1far-bc2far))}else{if(bc2far<0){alpha2=Math.min(alpha2,bc1far/(bc1far-bc2far))}}if(alpha20){continue}outputColor.add(diffuseColor)}}else{if(material instanceof THREE.MeshLambertMaterial||material instanceof THREE.MeshPhongMaterial){var normalComputed=false;for(var i=0,l=lights.length;i0){continue}if(normalComputed===false){computePixelNormal(normalVector,localPoint,material.shading,face,vertices);normalVector.applyMatrix3(_object.normalMatrix).normalize();normalComputed=true}var attenuation=1;if(light.physicalAttenuation===true){attenuation=lightVector.length();attenuation=1/(attenuation*attenuation)}lightVector.normalize();var dot=Math.max(normalVector.dot(lightVector),0);var diffuseIntensity=dot*light.intensity;lightContribution.copy(diffuseColor);lightContribution.multiply(lightColor);lightContribution.multiplyScalar(diffuseIntensity*attenuation);outputColor.add(lightContribution);if(material instanceof THREE.MeshPhongMaterial){halfVector.addVectors(lightVector,eyeVector).normalize();var dotNormalHalf=Math.max(normalVector.dot(halfVector),0);var specularIntensity=Math.max(Math.pow(dotNormalHalf,material.shininess),0)*diffuseIntensity;var specularNormalization=(material.shininess+2)/8;specularColor.copyGammaToLinear(material.specular);var alpha=Math.pow(Math.max(1-lightVector.dot(halfVector),0),5);schlick.r=specularColor.r+(1-specularColor.r)*alpha;schlick.g=specularColor.g+(1-specularColor.g)*alpha;schlick.b=specularColor.b+(1-specularColor.b)*alpha;lightContribution.copy(schlick);lightContribution.multiply(lightColor);lightContribution.multiplyScalar(specularNormalization*specularIntensity*attenuation);outputColor.add(lightContribution)}}}}var reflectivity=material.reflectivity;if((material.mirror||material.glass)&&reflectivity>0&&recursionDepth=canvasWidth){blockX=0;blockY+=blockSize;if(blockY>=canvasHeight){scope.dispatchEvent({type:"complete"});return}}context.fillRect(blockX,blockY,blockSize,blockSize);animationFrameId=requestAnimationFrame(function(){renderBlock(blockX,blockY)})}}());this.render=function(scene,camera){if(this.autoClear===true){this.clear()}cancelAnimationFrame(animationFrameId);if(scene.autoUpdate===true){scene.updateMatrixWorld()}if(camera.parent===null){camera.updateMatrixWorld()}camera.matrixWorldInverse.getInverse(camera.matrixWorld);cameraPosition.setFromMatrixPosition(camera.matrixWorld);cameraNormalMatrix.getNormalMatrix(camera.matrixWorld);origin.copy(cameraPosition);perspective=0.5/Math.tan(THREE.Math.degToRad(camera.fov*0.5))*canvasHeight;objects=scene.children;lights.length=0;scene.traverse(function(object){if(object instanceof THREE.Light){lights.push(object)}if(cache[object.id]===undefined){cache[object.id]={normalMatrix:new THREE.Matrix3(),inverseMatrix:new THREE.Matrix4()}}modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse,object.matrixWorld);var _object=cache[object.id];_object.normalMatrix.getNormalMatrix(modelViewMatrix);_object.inverseMatrix.getInverse(object.matrixWorld)});renderBlock(0,0)}};THREE.EventDispatcher.prototype.apply(THREE.RaytracingRenderer.prototype);THREE.ShaderMaterial=function(parameters){THREE.Material.call(this);this.type="ShaderMaterial";this.defines={};this.uniforms={};this.vertexShader="void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";this.fragmentShader="void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";this.shading=THREE.SmoothShading;this.linewidth=1;this.wireframe=false;this.wireframeLinewidth=1;this.fog=false;this.lights=false;this.vertexColors=THREE.NoColors;this.skinning=false;this.morphTargets=false;this.morphNormals=false;this.derivatives=false;this.defaultAttributeValues={color:[1,1,1],uv:[0,0],uv2:[0,0]};this.index0AttributeName=undefined;if(parameters!==undefined){if(parameters.attributes!==undefined){console.error("THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.")}this.setValues(parameters)}};THREE.ShaderMaterial.prototype=Object.create(THREE.Material.prototype);THREE.ShaderMaterial.prototype.constructor=THREE.ShaderMaterial;THREE.ShaderMaterial.prototype.copy=function(source){THREE.Material.prototype.copy.call(this,source);this.fragmentShader=source.fragmentShader;this.vertexShader=source.vertexShader;this.uniforms=THREE.UniformsUtils.clone(source.uniforms);this.attributes=source.attributes;this.defines=source.defines;this.shading=source.shading;this.wireframe=source.wireframe;this.wireframeLinewidth=source.wireframeLinewidth;this.fog=source.fog;this.lights=source.lights;this.vertexColors=source.vertexColors;this.skinning=source.skinning;this.morphTargets=source.morphTargets;this.morphNormals=source.morphNormals;this.derivatives=source.derivatives;return this};THREE.ShaderMaterial.prototype.toJSON=function(meta){var data=THREE.Material.prototype.toJSON.call(this,meta);data.uniforms=this.uniforms;data.attributes=this.attributes;data.vertexShader=this.vertexShader;data.fragmentShader=this.fragmentShader;return data};THREE.TextGeometry=function(text,parameters){parameters=parameters||{};var textShapes=THREE.FontUtils.generateShapes(text,parameters);parameters.amount=parameters.height!==undefined?parameters.height:50;if(parameters.bevelThickness===undefined){parameters.bevelThickness=10}if(parameters.bevelSize===undefined){parameters.bevelSize=8}if(parameters.bevelEnabled===undefined){parameters.bevelEnabled=false}THREE.ExtrudeGeometry.call(this,textShapes,parameters);this.type="TextGeometry"};THREE.TextGeometry.prototype=Object.create(THREE.ExtrudeGeometry.prototype);THREE.TextGeometry.prototype.constructor=THREE.TextGeometry;(function(){if("performance" in window===false){window.performance={}}Date.now=(Date.now||function(){return new Date().getTime()});if("now" in window.performance===false){var offset=window.performance.timing&&window.performance.timing.navigationStart?window.performance.timing.navigationStart:Date.now();window.performance.now=function(){return Date.now()-offset}}})();var TWEEN=TWEEN||(function(){var _tweens=[];return{getAll:function(){return _tweens},removeAll:function(){_tweens=[]},add:function(tween){_tweens.push(tween)},remove:function(tween){var i=_tweens.indexOf(tween);if(i!==-1){_tweens.splice(i,1)}},update:function(time){if(_tweens.length===0){return false}var i=0;time=time!==undefined?time:window.performance.now();while(i<_tweens.length){if(_tweens[i].update(time)){i++}else{_tweens.splice(i,1)}}return true}}})();TWEEN.Tween=function(object){var _object=object;var _valuesStart={};var _valuesEnd={};var _valuesStartRepeat={};var _duration=1000;var _repeat=0;var _yoyo=false;var _isPlaying=false;var _reversed=false;var _delayTime=0;var _startTime=null;var _easingFunction=TWEEN.Easing.Linear.None;var _interpolationFunction=TWEEN.Interpolation.Linear;var _chainedTweens=[];var _onStartCallback=null;var _onStartCallbackFired=false;var _onUpdateCallback=null;var _onCompleteCallback=null;var _onStopCallback=null;for(var field in object){_valuesStart[field]=parseFloat(object[field],10)}this.to=function(properties,duration){if(duration!==undefined){_duration=duration}_valuesEnd=properties;return this};this.start=function(time){TWEEN.add(this);_isPlaying=true;_onStartCallbackFired=false;_startTime=time!==undefined?time:window.performance.now();_startTime+=_delayTime;for(var property in _valuesEnd){if(_valuesEnd[property] instanceof Array){if(_valuesEnd[property].length===0){continue}_valuesEnd[property]=[_object[property]].concat(_valuesEnd[property])}_valuesStart[property]=_object[property];if((_valuesStart[property] instanceof Array)===false){_valuesStart[property]*=1}_valuesStartRepeat[property]=_valuesStart[property]||0}return this};this.stop=function(){if(!_isPlaying){return this}TWEEN.remove(this);_isPlaying=false;if(_onStopCallback!==null){_onStopCallback.call(_object)}this.stopChainedTweens();return this};this.stopChainedTweens=function(){for(var i=0,numChainedTweens=_chainedTweens.length;i1?1:elapsed;value=_easingFunction(elapsed);for(property in _valuesEnd){var start=_valuesStart[property]||0;var end=_valuesEnd[property];if(end instanceof Array){_object[property]=_interpolationFunction(end,value)}else{if(typeof(end)==="string"){end=start+parseFloat(end,10)}if(typeof(end)==="number"){_object[property]=start+(end-start)*value}}}if(_onUpdateCallback!==null){_onUpdateCallback.call(_object,value)}if(elapsed===1){if(_repeat>0){if(isFinite(_repeat)){_repeat--}for(property in _valuesStartRepeat){if(typeof(_valuesEnd[property])==="string"){_valuesStartRepeat[property]=_valuesStartRepeat[property]+parseFloat(_valuesEnd[property],10)}if(_yoyo){var tmp=_valuesStartRepeat[property];_valuesStartRepeat[property]=_valuesEnd[property];_valuesEnd[property]=tmp}_valuesStart[property]=_valuesStartRepeat[property]}if(_yoyo){_reversed=!_reversed}_startTime=time+_delayTime;return true}else{if(_onCompleteCallback!==null){_onCompleteCallback.call(_object)}for(var i=0,numChainedTweens=_chainedTweens.length;i1){return fn(v[m],v[m-1],m-f)}return fn(v[i],v[i+1>m?m:i+1],f-i)},Bezier:function(v,k){var b=0;var n=v.length-1;var pw=Math.pow;var bn=TWEEN.Interpolation.Utils.Bernstein;for(var i=0;i<=n;i++){b+=pw(1-k,n-i)*pw(k,i)*v[i]*bn(n,i)}return b},CatmullRom:function(v,k){var m=v.length-1;var f=m*k;var i=Math.floor(f);var fn=TWEEN.Interpolation.Utils.CatmullRom;if(v[0]===v[m]){if(k<0){i=Math.floor(f=m*(1+k))}return fn(v[(i-1+m)%m],v[i],v[(i+1)%m],v[(i+2)%m],f-i)}else{if(k<0){return v[0]-(fn(v[0],v[0],v[1],v[1],-f)-v[0])}if(k>1){return v[m]-(fn(v[m],v[m],v[m-1],v[m-1],f-m)-v[m])}return fn(v[i?i-1:0],v[i],v[m1;i--){s*=i}a[n]=s;return s}})(),CatmullRom:function(p0,p1,p2,p3,t){var v0=(p2-p0)*0.5;var v1=(p3-p1)*0.5;var t2=t*t;var t3=t*t2;return(2*p1-2*p2+v0+v1)*t3+(-3*p1+3*p2-2*v0-v1)*t2+v0*t+p1}}};(function(root){if(typeof define==="function"&&define.amd){define([],function(){return TWEEN})}else{if(typeof exports==="object"){module.exports=TWEEN}else{root.TWEEN=TWEEN}}})(this); \ No newline at end of file +var isMinified=true;var camera;var controls;var scene;var light;var renderer;var raycaster;var composer;var container;var routes=[];var lensFlareSel;var Ed3d={container:null,basePath:"./",jsonPath:null,jsonContainer:null,grid1H:null,grid1K:null,grid1XL:null,tween:null,globalView:true,fogDensity:null,textSel:[],catObjs:[],material:{Trd:new THREE.MeshBasicMaterial({color:16777215}),line:new THREE.LineBasicMaterial({color:16777215}),white:new THREE.MeshBasicMaterial({color:16777215}),orange:new THREE.MeshBasicMaterial({color:16751872}),black:new THREE.MeshBasicMaterial({color:65793}),lightblue:new THREE.MeshBasicMaterial({color:950152}),darkblue:new THREE.MeshBasicMaterial({color:1452331}),selected:new THREE.MeshPhongMaterial({color:917503}),transparent:new THREE.MeshBasicMaterial({color:0,transparent:true,opacity:0}),glow_1:null,custom:[]},colors:[],textures:{},systemColor:"#eeeeee",withHudPanel:false,hudMultipleSelect:true,systems:[],starfield:null,startAnim:true,effectScaleSystem:[10,800],optDistObj:1500,playerPos:[0,0,0],cameraPos:null,isTopView:false,showGalaxyInfos:false,init:function(options){var options=$.extend({container:Ed3d.container,basePath:Ed3d.basePath,jsonPath:Ed3d.jsonPath,jsonContainer:Ed3d.jsonContainer,withHudPanel:Ed3d.withHudPanel,hudMultipleSelect:Ed3d.hudMultipleSelect,effectScaleSystem:Ed3d.effectScaleSystem,startAnim:Ed3d.startAnim,playerPos:Ed3d.playerPos,cameraPos:Ed3d.cameraPos,systemColor:Ed3d.systemColor,showGalaxyInfos:false},options);Loader.start();this.basePath=options.basePath;this.container=options.container;this.jsonPath=options.jsonPath;this.jsonContainer=options.jsonContainer;this.withHudPanel=options.withHudPanel;this.hudMultipleSelect=options.hudMultipleSelect;this.startAnim=options.startAnim;this.effectScaleSystem=options.effectScaleSystem;this.playerPos=options.playerPos;this.cameraPos=options.cameraPos;this.showGalaxyInfos=options.showGalaxyInfos;this.systemColor=options.systemColor;$("#"+Ed3d.container).append('
');Loader.update("Load core files");if(typeof isMinified!=="undefined"){return Ed3d.launchMap()}$.when($.getScript(Ed3d.basePath+"vendor/three-js/OrbitControls.js"),$.getScript(Ed3d.basePath+"vendor/three-js/CSS3DRenderer.js"),$.getScript(Ed3d.basePath+"vendor/three-js/Projector.js"),$.getScript(Ed3d.basePath+"vendor/three-js/FontUtils.js"),$.getScript(Ed3d.basePath+"vendor/three-js/helvetiker_regular.typeface.js"),$.getScript(Ed3d.basePath+"js/components/grid.class.js"),$.getScript(Ed3d.basePath+"js/components/icon.class.js"),$.getScript(Ed3d.basePath+"js/components/hud.class.js"),$.getScript(Ed3d.basePath+"js/components/action.class.js"),$.getScript(Ed3d.basePath+"js/components/route.class.js"),$.getScript(Ed3d.basePath+"js/components/system.class.js"),$.getScript(Ed3d.basePath+"js/components/galaxy.class.js"),$.getScript(Ed3d.basePath+"vendor/tween-js/Tween.js"),$.Deferred(function(deferred){$(deferred.resolve)})).done(function(){Loader.update("Done !");Ed3d.launchMap()})},rebuild:function(options){Loader.start();System.remove();HUD.removeFilters();if(this.jsonPath!=null){Ed3d.loadDatasFromFile()}else{if(this.jsonContainer!=null){Ed3d.loadDatasFromContainer()}}Action.moveInitalPosition();Loader.stop()},launchMap:function(){Loader.update("Textures");Ed3d.loadTextures();Loader.update("Launch scene");Ed3d.initScene();Ed3d.grid1H=$.extend({},Grid.init(100,1121827,0),{});Ed3d.grid1K=$.extend({},Grid.init(1000,2241082,1000),{});Ed3d.grid1XL=$.extend({},Grid.infos(10000,2241082,10000),{});Ed3d.skyboxStars();HUD.create("ed3dmap");Loader.update("Add Sagittarius A*");Galaxy.addGalaxyCenter();Loader.update("Loading json file");if(this.jsonPath!=null){Ed3d.loadDatasFromFile()}else{if(this.jsonContainer!=null){Ed3d.loadDatasFromContainer()}}if(!this.startAnim){Ed3d.grid1XL.hide();Galaxy.milkyway2D.visible=false}animate()},loadTextures:function(){var texloader=new THREE.TextureLoader();this.textures.flare_white=texloader.load(Ed3d.basePath+"textures/lensflare/flare2.png");this.textures.flare_yellow=texloader.load(Ed3d.basePath+"textures/lensflare/star_grey2.png");this.textures.flare_center=texloader.load(Ed3d.basePath+"textures/lensflare/flare3.png");Ed3d.material.glow_1=new THREE.SpriteMaterial({map:this.textures.flare_yellow,color:16777215,transparent:false,fog:true});Ed3d.material.glow_2=new THREE.SpriteMaterial({map:Ed3d.textures.flare_white,transparent:true,blending:THREE.AdditiveBlending,depthWrite:false,opacity:0.5})},addCustomMaterial:function(id,color){var color=new THREE.Color("#"+color);this.colors[id]=color},initScene:function(){container=document.getElementById("ed3dmap");scene=new THREE.Scene();scene.visible=false;camera=new THREE.PerspectiveCamera(45,container.offsetWidth/container.offsetHeight,1,200000);camera.position.set(0,500,500);light=new THREE.HemisphereLight(16777215,13421772);scene.add(light);renderer=new THREE.WebGLRenderer({antialias:true,alpha:true});renderer.setClearColor(0,1);renderer.setSize(container.offsetWidth,container.offsetHeight);renderer.domElement.style.zIndex=5;container.appendChild(renderer.domElement);controls=new THREE.OrbitControls(camera,container);controls.rotateSpeed=0.6;controls.zoomSpeed=2;controls.panSpeed=0.8;controls.maxDistance=60000;controls.enableZoom=1;controls.enablePan=1;controls.enableDamping=!0;controls.dampingFactor=0.3;scene.fog=new THREE.FogExp2(855312,0.000128);renderer.setClearColor(scene.fog.color,1);Ed3d.fogDensity=scene.fog.density},showScene:function(){Loader.stop();scene.visible=true},loadDatasFromFile:function(){$.getJSON(this.jsonPath,function(data){Ed3d.loadDatas(data)}).done(function(){Ed3d.loadDatasComplete();Ed3d.showScene()})},loadDatasFromContainer:function(){var content=$("#"+this.jsonContainer).html();var json=null;try{json=JSON.parse(content)}catch(e){console.log("Can't load JSon for systems")}if(json!=null){Ed3d.loadDatas(json)}Ed3d.loadDatasComplete();Ed3d.showScene()},loadDatas:function(data){System.initParticleSystem();if(data.categories!=undefined){HUD.initFilters(data.categories)}list=(data.systems!==undefined)?data.systems:data;Loader.update("Routes...");if(data.routes!=undefined){$.each(data.routes,function(key,route){Route.initRoute(key,route)})}Loader.update("Systems...");$.each(list,function(key,val){system=System.create(val);if(system!=undefined){if(val.cat!=undefined){Ed3d.addObjToCategories(system,val.cat)}if(val.cat!=undefined){Ed3d.systems.push(system)}}});if(data.routes!=undefined){$.each(data.routes,function(key,route){Route.createRoute(key,route)})}},loadDatasComplete:function(){System.endParticleSystem();HUD.init();Action.init()},addObjToCategories:function(index,catList){$.each(catList,function(keyArr,idCat){Ed3d.catObjs[idCat].push(index)})},skyboxStars:function(){var sizeStars=10000;var particles=new THREE.Geometry;for(var p=0;p<5;p++){var particle=new THREE.Vector3(Math.random()*sizeStars-(sizeStars/2),Math.random()*sizeStars-(sizeStars/2),Math.random()*sizeStars-(sizeStars/2));particles.vertices.push(particle)}var particleMaterial=new THREE.PointsMaterial({color:15658734,size:2});this.starfield=new THREE.Points(particles,particleMaterial);scene.add(this.starfield)},calcDistSol:function(target){var dx=target.x;var dy=target.y;var dz=target.z;return Math.round(Math.sqrt(dx*dx+dy*dy+dz*dz))}};function animate(time){if(scene.visible==false){requestAnimationFrame(animate);return}refreshWithCamPos();controls.update();TWEEN.update(time);if(Ed3d.isTopView){camera.rotation.set(-Math.PI/2,0,0);camera.position.x=controls.target.x;camera.position.z=controls.target.z}renderer.render(scene,camera);$("#cx").html(Math.round(controls.target.x));$("#cy").html(Math.round(controls.target.y));$("#cz").html(Math.round(-controls.target.z));$("#distsol").html(Ed3d.calcDistSol(controls.target));Ed3d.starfield.position.set(controls.target.x-(controls.target.x/10)%4000,controls.target.y-(controls.target.y/10)%4000,controls.target.z-(controls.target.z/10)%4000);var scale=distanceFromTarget(camera)/200;if(Action.cursorSel!=null){if(scale>=0.01&&scale<10){Action.cursorSel.scale.set(scale,scale,scale)}Action.cursorSel.rotation.y=camera.rotation.y}if(Ed3d.textSel.system!=undefined){if(Ed3d.isTopView){Ed3d.textSel.system.rotation.set(-Math.PI/2,0,0)}else{Ed3d.textSel.system.rotation.set(0,0,0)}}Action.sizeOnScroll(scale);Galaxy.infosUpdateCallback(scale);if(scale>25){enableFarView(scale)}else{disableFarView(scale)}requestAnimationFrame(animate)}var isFarView=false;function enableFarView(scale,withAnim){if(isFarView){return}if(withAnim==undefined){withAnim=true}isFarView=true;var scaleFrom={zoom:25};var scaleTo={zoom:500};if(withAnim){Ed3d.tween=new TWEEN.Tween(scaleFrom,{override:true}).to(scaleTo,500).start().onUpdate(function(){Galaxy.milkyway[0].material.size=scaleFrom.zoom;Galaxy.milkyway[1].material.size=scaleFrom.zoom*4})}else{Galaxy.milkyway[0].material.size=scaleTo;Galaxy.milkyway[1].material.size=scaleTo*4}Galaxy.milkyway2D.visible=true;Galaxy.infosShow();if(Action.cursorSel!=null){Action.cursorSel.scale.set(60,60,60)}Ed3d.grid1H.hide();Ed3d.grid1K.hide();Ed3d.grid1XL.show();Ed3d.starfield.visible=false;scene.fog.density=0.000009}function disableFarView(scale,withAnim){if(!isFarView){return}if(withAnim==undefined){withAnim=true}isFarView=false;var oldScale=parseFloat(1/(25/3));var scaleFrom={zoom:250};var scaleTo={zoom:64};if(withAnim){Ed3d.tween=new TWEEN.Tween(scaleFrom,{override:true}).to(scaleTo,500).start().onUpdate(function(){Galaxy.milkyway[0].material.size=scaleFrom.zoom;Galaxy.milkyway[1].material.size=scaleFrom.zoom})}else{Galaxy.milkyway[0].material.size=scaleTo;Galaxy.milkyway[1].material.size=scaleTo}Galaxy.milkyway2D.visible=false;Galaxy.infosHide();Galaxy.milkyway[0].material.size=16;camera.scale.set(1,1,1);if(Action.cursorSel!=null){Action.cursorSel.scale.set(1,1,1)}Ed3d.grid1H.show();Ed3d.grid1K.show();Ed3d.grid1XL.hide();Ed3d.starfield.visible=true;scene.fog.density=Ed3d.fogDensity}function render(){renderer.render(scene,camera)}window.addEventListener("resize",function(){if(renderer!=undefined){var width=container.offsetWidth;var height=container.offsetHeight;if(width<100){width=100}if(height<100){height=100}renderer.setSize(width,height);camera.aspect=width/height;camera.updateProjectionMatrix()}});function distance(v1,v2){var dx=v1.position.x-v2.position.x;var dy=v1.position.y-v2.position.y;var dz=v1.position.z-v2.position.z;return Math.round(Math.sqrt(dx*dx+dy*dy+dz*dz))}function distanceFromTarget(v1){var dx=v1.position.x-controls.target.x;var dy=v1.position.y-controls.target.y;var dz=v1.position.z-controls.target.z;return Math.round(Math.sqrt(dx*dx+dy*dy+dz*dz))}var camSave={x:0,y:0,z:0};function refreshWithCamPos(){var d=new Date();var n=d.getTime();if(n%1!=0){return}Ed3d.grid1H.addCoords();Ed3d.grid1K.addCoords();var p=Ed3d.optDistObj/2;if(camSave.x==Math.round(camera.position.x/p)*p&&camSave.y==Math.round(camera.position.y/p)*p&&camSave.z==Math.round(camera.position.z/p)*p){return}camSave.x=Math.round(camera.position.x/p)*p;camSave.y=Math.round(camera.position.y/p)*p;camSave.z=Math.round(camera.position.z/p)*p}var Loader={start:function(){$("#loader").remove();$("
").attr("id","loader").html(Loader.svgAnim).css("color","rgb(200, 110, 37)").css("font-size","1.5rem").css("font-family","Helvetica").css("font-variant","small-caps").appendTo("body");clearInterval(this.animCount);this.animCount=setInterval(function(){var animProgress=$("#loader #loadTimer");animProgress.append(".");if(animProgress.html().length>10){animProgress.html(".")}},1000)},update:function(info){$("#loader #loadInfos").html(info)},stop:function(){$("#loader").remove();clearInterval(this.animCount)},animCount:null,svgAnim:'
.
'};var Action={cursorSel:null,mouseVector:null,raycaster:null,oldSel:null,objHover:null,mouseUpDownTimer:null,animPosition:null,prevScale:null,init:function(){this.mouseVector=new THREE.Vector3();this.raycaster=new THREE.Raycaster();container.addEventListener("mousedown",this.onMouseDown,false);container.addEventListener("mouseup",this.onMouseUp,false);container.addEventListener("mousewheel",this.stopWinScroll,false);container.addEventListener("DOMMouseScroll",this.stopWinScroll,false)},stopWinScroll:function(event){event.preventDefault();event.stopPropagation()},sizeOnScroll:function(scale){if(System.particle==undefined||scale<=0){return}var minScale=Ed3d.effectScaleSystem[0];var maxScale=Ed3d.effectScaleSystem[1];var newScale=scale*20;if(this.prevScale==newScale){return}this.prevScale=newScale;if(newScale>maxScale){newScale=maxScale}if(newScale0){for(var i=0;i0.2){this.mouseUpDownTimer=null;return}this.mouseUpDownTimer=null;var position=$("#ed3dmap").offset();this.mouseVector=new THREE.Vector3(((e.clientX-position.left)/renderer.domElement.width)*2-1,-((e.clientY-position.top)/renderer.domElement.height)*2+1,1);this.mouseVector.unproject(camera);this.raycaster=new THREE.Raycaster(camera.position,this.mouseVector.sub(camera.position).normalize());this.raycaster.params.Points.threshold=2;var intersects=this.raycaster.intersectObjects(scene.children);if(intersects.length>0){for(var i=0;i"+selPoint.name+"");var isMove=Action.moveToObj(indexPoint,selPoint);if(isMove){return}}}if(intersection.object.showCoord){$("#debug").html(Math.round(intersection.point.x)+" , "+Math.round(-intersection.point.z));Route.addPoint(Math.round(intersection.point.x),0,Math.round(-intersection.point.z))}}}},moveNextPrev:function(indexPoint,increment){var find=false;while(!find){if(indexPoint<0){indexPoint=System.particleGeo.vertices.length-1}else{if(System.particleGeo.vertices[indexPoint]==undefined){indexPoint=0}}if(System.particleGeo.vertices[indexPoint].visible==true){find=true}else{indexPoint+=increment}}var selPoint=System.particleGeo.vertices[indexPoint];Action.moveToObj(indexPoint,selPoint)},disableSelection:function(){if(this.cursorSel==null){return}this.oldSel=null;this.cursorSel.visible=false;$("#hud #infos").html("")},moveInitalPositionNoAnim:function(timer){var cam=[Ed3d.playerPos[0],Ed3d.playerPos[1]+500,Ed3d.playerPos[2]+500];if(Ed3d.cameraPos!=null){cam=[Ed3d.cameraPos[0],Ed3d.cameraPos[1],-Ed3d.cameraPos[2]]}var moveTo={x:cam[0],y:cam[1],z:cam[2],mx:Ed3d.playerPos[0],my:Ed3d.playerPos[1],mz:-Ed3d.playerPos[2]};camera.position.set(moveTo.x,moveTo.y,moveTo.z);controls.target.set(moveTo.mx,moveTo.my,moveTo.mz)},moveInitalPosition:function(timer){if(timer==undefined){timer=800}this.disableSelection();var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z,mx:controls.target.x,my:controls.target.y,mz:controls.target.z};var cam=[Ed3d.playerPos[0],Ed3d.playerPos[1]+500,Ed3d.playerPos[2]+500];if(Ed3d.cameraPos!=null){cam=[Ed3d.cameraPos[0],Ed3d.cameraPos[1],-Ed3d.cameraPos[2]]}var moveCoords={x:cam[0],y:cam[1],z:cam[2],mx:Ed3d.playerPos[0],my:Ed3d.playerPos[1],mz:-Ed3d.playerPos[2]};controls.enabled=false;if(Ed3d.tween!=null){TWEEN.removeAll()}Ed3d.tween=new TWEEN.Tween(moveFrom,{override:true}).to(moveCoords,timer).start().onUpdate(function(){camera.position.set(moveFrom.x,moveFrom.y,moveFrom.z);controls.target.set(moveFrom.mx,moveFrom.my,moveFrom.mz)}).onComplete(function(){controls.enabled=true;controls.update()})},moveToObj:function(index,obj){if(this.oldSel!==null&&this.oldSel==index){return false}controls.enabled=false;HUD.setInfoPanel(index,obj);HUD.openHudDetails();this.oldSel=index;var goX=obj.x;var goY=obj.y;var goZ=obj.z;disableFarView(25,false);this.moveGridTo(goX,goY,goZ);var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z,mx:controls.target.x,my:controls.target.y,mz:controls.target.z};var moveCoords={x:goX,y:goY+15,z:goZ+15,mx:goX,my:goY,mz:goZ};Ed3d.tween=new TWEEN.Tween(moveFrom,{override:true}).to(moveCoords,800).start().onUpdate(function(){camera.position.set(moveFrom.x,moveFrom.y,moveFrom.z);controls.target.set(moveFrom.mx,moveFrom.my,moveFrom.mz)}).onComplete(function(){controls.update()});obj.material=Ed3d.material.selected;this.addCusorOnSelect(goX,goY,goZ);var textAdd=obj.name;var textAddC=Math.round(goX)+", "+Math.round(goY)+", "+Math.round(-goZ);HUD.addText("system",textAdd,8,20,0,6,this.cursorSel);HUD.addText("coords",textAddC,8,15,0,3,this.cursorSel);controls.enabled=true;return true},addCusorOnSelect:function(x,y,z){if(this.cursorSel==null){this.cursorSel=new THREE.Object3D();var geometryL=new THREE.TorusGeometry(12,0.4,3,30);var selection=new THREE.Mesh(geometryL,Ed3d.material.selected);selection.rotation.x=Math.PI/2;this.cursorSel.add(selection);var geometryCone=new THREE.CylinderGeometry(0,5,16,4,1,false);var cone=new THREE.Mesh(geometryCone,Ed3d.material.selected);cone.position.set(0,20,0);cone.rotation.x=Math.PI;this.cursorSel.add(cone);var geometryConeInner=new THREE.CylinderGeometry(0,3.6,16,4,1,false);var coneInner=new THREE.Mesh(geometryConeInner,Ed3d.material.black);coneInner.position.set(0,20.2,0);coneInner.rotation.x=Math.PI;this.cursorSel.add(coneInner);scene.add(this.cursorSel)}this.cursorSel.visible=true;this.cursorSel.position.set(x,y,z);this.cursorSel.scale.set(1,1,1)},moveGridTo:function(goX,goY,goZ){var posX=Math.floor(goX/1000)*1000;var posY=Math.floor(goY);var posZ=Math.floor(goZ/1000)*1000;if(!Ed3d.grid1H.fixed){Ed3d.grid1H.obj.position.set(posX,posY,posZ)}if(!Ed3d.grid1K.fixed){Ed3d.grid1K.obj.position.set(posX,posY,posZ)}if(!Ed3d.grid1XL.fixed){Ed3d.grid1XL.obj.position.set(posX,posY,posZ)}}};var Galaxy={obj:null,infos:null,milkyway:[],milkyway2D:null,backActive:true,colors:[],x:25,y:-21,z:25900,addGalaxyCenter:function(){var objVal=new Object;objVal.name="Sagittarius A*";objVal.coords={x:this.y,y:this.y,z:this.z};objVal.cat=[];this.obj=System.create(objVal,true);var sprite=new THREE.Sprite(Ed3d.material.glow_2);sprite.scale.set(50,40,2);this.obj.add(sprite);this.createParticles();this.add2DPlane()},createParticles:function(){var img=new Image();img.onload=function(){Galaxy.getHeightData(img);if(Ed3d.startAnim){camera.position.set(-10000,40000,50000);Action.moveInitalPosition(4000)}else{Action.moveInitalPositionNoAnim()}};img.src=Ed3d.basePath+"textures/heightmap7.jpg";this.showGalaxyInfos()},showGalaxyInfos:function(){if(!Ed3d.showGalaxyInfos){return}this.infos=new THREE.Object3D();$.getJSON(Ed3d.basePath+"data/milkyway.json",function(data){$.each(data.quadrants,function(key,val){Galaxy.addText(key,val.x,-100,val.z,val.rotate)});$.each(data.arms,function(key,val){$.each(val,function(keyCh,valCh){Galaxy.addText(key,valCh.x,0,valCh.z,valCh.rotate,300,true)})});$.each(data.gaps,function(key,val){$.each(val,function(keyCh,valCh){Galaxy.addText(key,valCh.x,0,valCh.z,valCh.rotate,160,true)})});$.each(data.others,function(key,val){$.each(val,function(keyCh,valCh){Galaxy.addText(key,valCh.x,0,valCh.z,valCh.rotate,160,true)})})}).done(function(){scene.add(Galaxy.infos)})},infosShow:function(){if(Galaxy.infos==null){this.showGalaxyInfos()}if(Galaxy.infos!==null){Galaxy.infos.visible=Ed3d.showGalaxyInfos}},infosHide:function(){if(Galaxy.infos!==null){Galaxy.infos.visible=false}},infosUpdateCallback:function(scale){if(!Ed3d.showGalaxyInfos||this.infos==null){return}scale-=70;var opacity=Math.round(scale/10)/10;if(opacity<0){opacity=0}if(opacity>0.8){opacity=0.8}if(Galaxy.infos.previousOpacity==opacity){return}var opacityMiddle=1.1-opacity;if(opacityMiddle<=0.4){opacityMiddle=0.2}for(var i=0;i0.5){i+=8}var all=pix[i]+pix[i+1]+pix[i+2];var avg=Math.round((pix[i]+pix[i+1]+pix[i+2])/3);if(avg>min){var x=scaleImg*((i/4)%img.width);var z=scaleImg*(Math.floor((i/4)/img.height));var density=Math.floor((pix[i]-min)/10);if(density>maxDensity){density=maxDensity}var add=Math.ceil(density/maxDensity*2);for(var y=-density;y=2&&Math.abs(y)-1==0&&Math.random()*1000<200){particlesBig.vertices.push(particle);colorsBig[nbBig]=new THREE.Color("rgb("+r+", "+g+", "+b+")");nbBig++}else{if(density<4||(Math.random()*1000<400-(density*2))){particles.vertices.push(particle);this.colors[nb]=new THREE.Color("rgb("+r+", "+g+", "+b+")");nb++}}}}}particles.colors=this.colors;var particleMaterial=new THREE.PointsMaterial({map:Ed3d.textures.flare_yellow,transparent:true,size:64,vertexColors:THREE.VertexColors,blending:THREE.AdditiveBlending,depthTest:true,depthWrite:false});var points=new THREE.Points(particles,particleMaterial);points.sortParticles=true;particles.center();this.milkyway[0]=points;this.milkyway[0].scale.set(20,20,20);this.obj.add(points);particlesBig.colors=colorsBig;var particleMaterialBig=new THREE.PointsMaterial({map:Ed3d.textures.flare_yellow,transparent:true,vertexColors:THREE.VertexColors,size:16,blending:THREE.AdditiveBlending,depthTest:true,depthWrite:false});var pointsBig=new THREE.Points(particlesBig,particleMaterialBig);pointsBig.sortParticles=true;particlesBig.center();this.milkyway[1]=pointsBig;this.milkyway[1].scale.set(20,20,20);this.obj.add(pointsBig)}};var Grid={obj:null,size:null,textShapes:null,textGeo:null,coordTxt:null,minDistView:null,visible:true,fixed:false,init:function(size,color,minDistView){this.size=size;this.obj=new THREE.GridHelper(1000000,size);this.obj.setColors(color,color);this.obj.minDistView=minDistView;scene.add(this.obj);this.obj.customUpdateCallback=this.addCoords;return this},infos:function(step,color,minDistView){var size=50000;if(step==undefined){step=10000}this.fixed=true;var geometry=new THREE.Geometry();var material=new THREE.LineBasicMaterial({color:5592405,transparent:true,opacity:0.2,blending:THREE.AdditiveBlending,depthWrite:false});for(var i=-size;i<=size;i+=step){geometry.vertices.push(new THREE.Vector3(-size,0,i));geometry.vertices.push(new THREE.Vector3(size,0,i));geometry.vertices.push(new THREE.Vector3(i,0,-size));geometry.vertices.push(new THREE.Vector3(i,0,size))}this.obj=new THREE.LineSegments(geometry,material);this.obj.position.set(0,0,-20000);var quadrant=new THREE.Geometry();var material=new THREE.LineBasicMaterial({color:8947848,transparent:true,opacity:0.5,blending:THREE.AdditiveBlending,depthWrite:false});quadrant.vertices.push(new THREE.Vector3(-size,0,20000));quadrant.vertices.push(new THREE.Vector3(size,0,20000));quadrant.vertices.push(new THREE.Vector3(0,0,-size));quadrant.vertices.push(new THREE.Vector3(0,0,size));var quadrantL=new THREE.LineSegments(quadrant,material);this.obj.add(quadrantL);scene.add(this.obj);return this},addCoords:function(){var textShow="0 : 0 : 0";var options={font:"helvetiker",weight:"normal",style:"normal",size:this.size/20,curveSegments:10};if(this.coordGrid!=null){if(Math.abs(camera.position.y-this.obj.position.y)>this.size*10||Math.abs(camera.position.y-this.obj.position.y)
3D 2D i '+Ico.cog+' ');this.createSubOptions()}if(!Ed3d.withHudPanel){return}$("#"+this.container).append('
');$("#hud").append('

Infos

Dist. Sol

');$("#"+this.container).append('')},createSubOptions:function(){$("").addClass("sub-opt active").attr("href","#").html("Toggle Milky Way").click(function(){var state=Galaxy.milkyway[0].visible;Galaxy.milkyway[0].visible=!state;Galaxy.milkyway[1].visible=!state;Galaxy.milkyway2D.visible=!state;$(this).toggleClass("active")}).appendTo("#options");$("").addClass("sub-opt active").attr("href","#").html("Toggle grid").click(function(){Ed3d.grid1H.toggleGrid();Ed3d.grid1K.toggleGrid();Ed3d.grid1XL.toggleGrid();$(this).toggleClass("active")}).appendTo("#options")},initControls:function(){$("#controls a").click(function(e){if($(this).hasClass("view")){$("#controls a.view").removeClass("selected");$(this).addClass("selected")}var view=$(this).data("view");switch(view){case"top":Ed3d.isTopView=true;var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z};var moveCoords={x:controls.target.x,y:controls.target.y+500,z:controls.target.z};HUD.moveCamera(moveFrom,moveCoords);break;case"3d":Ed3d.isTopView=false;var moveFrom={x:camera.position.x,y:camera.position.y,z:camera.position.z};var moveCoords={x:controls.target.x-100,y:controls.target.y+500,z:controls.target.z+500};HUD.moveCamera(moveFrom,moveCoords);break;case"infos":if(!Ed3d.showGalaxyInfos){Ed3d.showGalaxyInfos=true;Galaxy.infosShow()}else{Ed3d.showGalaxyInfos=false;Galaxy.infosHide()}$(this).toggleClass("selected");break;case"options":$("#options").toggle();break}})},moveCamera:function(from,to){Ed3d.tween=new TWEEN.Tween(from,{override:true}).to(to,800).start().onUpdate(function(){camera.position.set(from.x,from.y,from.z)}).onComplete(function(){controls.update()})},initHudAction:function(){$("canvas").hover(function(){controls.enabled=true},function(){controls.enabled=false});$("#hud").hover(function(){controls.enabled=false},function(){controls.enabled=true});$("#systemDetails").hide();$(".map_filter").each(function(e){var idCat=$(this).data("filter");var count=Ed3d.catObjs[idCat].length;if(count>1){$(this).append(" ("+count+")")}});$(".map_filter").click(function(e){e.preventDefault();var idCat=$(this).data("filter");var active=$(this).data("active");active=(Math.abs(active-1));if(!Ed3d.hudMultipleSelect){$(".map_filter").addClass("disabled");$(System.particleGeo.vertices).each(function(index,point){point.visible=0;point.filtered=0;System.particleGeo.colors[index]=new THREE.Color("#111111");active=1})}$(Ed3d.catObjs[idCat]).each(function(key,indexPoint){obj=System.particleGeo.vertices[indexPoint];System.particleGeo.colors[indexPoint]=(active==1)?obj.color:new THREE.Color("#111111");obj.visible=(active==1);obj.filtered=(active==1);System.particleGeo.colorsNeedUpdate=true});$(this).data("active",active);$(this).toggleClass("disabled");if(Action.oldSel!=null&&!Action.oldSel.visible){Action.disableSelection()}Action.moveInitalPosition()});$(".map_link").click(function(e){e.preventDefault();var elId=$(this).data("route");Action.moveToObj(routes[elId])});$(".map_link span").click(function(e){e.preventDefault();var elId=$(this).parent().data("route");routes[elId].visible=!routes[elId].visible})},initFilters:function(categories){Loader.update("HUD Filter...");var grpNb=1;$.each(categories,function(typeFilter,values){if(typeof values==="object"){var groupId="group_"+grpNb;$("#filters").append("

"+typeFilter+"

");$("#filters").append('
');$.each(values,function(key,val){HUD.addFilter(groupId,key,val);Ed3d.catObjs[key]=[]});grpNb++}})},removeFilters:function(){$("#hud #filters").html("")},addFilter:function(groupId,idCat,val){var back="#fff";if(val.color!=undefined){Ed3d.addCustomMaterial(idCat,val.color);back="#"+val.color}$("#"+groupId).append(' '+val.name+"")},openHudDetails:function(){$("#hud").hide();$("#systemDetails").show().hover(function(){controls.enabled=false},function(){controls.enabled=true})},closeHudDetails:function(){$("#hud").show();$("#systemDetails").hide()},setRoute:function(idRoute,nameR){$("#routes").append(' '+nameR+"")},setInfoPanel:function(index,point){$("#systemDetails").html("

"+point.name+'

'+point.x+""+point.y+""+(-point.z)+'

'+(point.infos!=undefined?"
"+point.infos+"
":"")+'');$("",{html:"<"}).click(function(){Action.moveNextPrev(index-1,-1)}).appendTo("#nav");$("",{html:"X"}).click(function(){HUD.closeHudDetails()}).appendTo("#nav");$("",{html:">"}).click(function(){Action.moveNextPrev(index+1,1)}).appendTo("#nav")},addText:function(id,textShow,x,y,z,size,addToObj){if(addToObj==undefined){addToObj=scene}var textShapes=THREE.FontUtils.generateShapes(textShow,{font:"helvetiker",weight:"normal",style:"normal",size:size,curveSegments:100});var textGeo=new THREE.ShapeGeometry(textShapes);if(Ed3d.textSel[id]==undefined){var textMesh=new THREE.Mesh(textGeo,new THREE.MeshBasicMaterial({color:16777215}))}else{var textMesh=Ed3d.textSel[id]}textMesh.geometry=textGeo;textMesh.geometry.needsUpdate=true;textMesh.position.set(x,y,z);Ed3d.textSel[id]=textMesh;addToObj.add(textMesh)}};var Ico={cog:' '};var Route={active:false,systems:[],list:[],initRoute:function(idRoute,route){Route.active=true;$.each(route.points,function(key,val){Route.systems[val.s]=false})},createRoute:function(idRoute,route){var geometryL=new THREE.Geometry();var nameR="";var first=null;var last=null;$.each(route.points,function(key2,val){if(Route.systems[val.s]!==false){var c=Route.systems[val.s];if(first==null){first=[c[0],c[1],c[2]]}last=[c[0],c[1],c[2]];geometryL.vertices.push(new THREE.Vector3(c[0],c[1],c[2]));Route.addPoint(c[0],c[1],c[2])}else{console.log("Missing point: "+val.s)}});routes[idRoute]=new THREE.Line(geometryL,Ed3d.material.line);if(first!==null){routes[idRoute].add(this.addCircle(first))}if(last!==null){routes[idRoute].add(this.addCircle(last))}scene.add(routes[idRoute])},addCircle:function(point){var cursor=new THREE.Object3D;var geometryL=new THREE.TorusGeometry(12,0.4,3,30);var selection=new THREE.Mesh(geometryL,Ed3d.material.orange);selection.rotation.x=Math.PI/2;cursor.add(selection);cursor.position.set(point[0],point[1],point[2]);cursor.scale.set(15,15,15);scene.add(cursor)},addPoint:function(x,y,z){}};var System={particle:null,particleGeo:null,particleColor:[],particleInfos:[],count:0,scaleSize:64,create:function(val,withSolid){if(withSolid==undefined){withSolid=false}if(val.coords==undefined){return false}var x=parseInt(val.coords.x);var y=parseInt(val.coords.y);var z=-parseInt(val.coords.z);var colors=[];if(this.particleGeo!==null){var idSys=x+"_"+y+"_"+z;if(val.infos!=undefined&&this.particleInfos[idSys]){var indexParticle=this.particleInfos[idSys];this.particleGeo.vertices[indexParticle].infos+=val.infos;if(val.cat!=undefined){Ed3d.addObjToCategories(indexParticle,val.cat)}return}var particle=new THREE.Vector3(x,y,z);if(val.cat!=undefined&&val.cat[0]!=undefined&&Ed3d.colors[val.cat[0]]!=undefined){this.particleColor[this.count]=Ed3d.colors[val.cat[0]]}else{this.particleColor[this.count]=new THREE.Color(Ed3d.systemColor)}if(val.cat!=undefined){Ed3d.addObjToCategories(this.count,val.cat);particle.color=this.particleColor[this.count]}particle.clickable=true;particle.visible=true;particle.name=val.name;if(val.infos!=undefined){particle.infos=val.infos;this.particleInfos[idSys]=this.count}this.particleGeo.vertices.push(particle);this.count++}if(Route.active==true){if(Route.systems[val.name]!=undefined){Route.systems[val.name]=[x,y,z]}}if(withSolid){var mat=Ed3d.material.glow_1;var sprite=new THREE.Sprite(mat);sprite.position.set(x,y,z);sprite.scale.set(50,50,1);scene.add(sprite);var geometry=new THREE.SphereGeometry(2,10,10);var sphere=new THREE.Mesh(geometry,Ed3d.material.white);sphere.position.set(x,y,z);sphere.name=val.name;sphere.clickable=true;sphere.idsprite=sprite.id;scene.add(sphere);return sphere}},initParticleSystem:function(){this.particleGeo=new THREE.Geometry},endParticleSystem:function(){if(this.particleGeo==null){return}this.particleGeo.colors=this.particleColor;var particleMaterial=new THREE.PointsMaterial({map:Ed3d.textures.flare_yellow,vertexColors:THREE.VertexColors,size:this.scaleSize,fog:false,blending:THREE.AdditiveBlending,transparent:true,depthTest:true,depthWrite:false});this.particle=new THREE.Points(this.particleGeo,particleMaterial);this.particle.sortParticles=true;this.particle.clickable=true;scene.add(this.particle)},remove:function(){this.particleColor=[];this.particleGeo=null;this.count=0;scene.remove(this.particle)},loadSpectral:function(val){}};THREE.CSS3DObject=function(element){THREE.Object3D.call(this);this.element=element;this.element.style.position="absolute";this.addEventListener("removed",function(event){if(this.element.parentNode!==null){this.element.parentNode.removeChild(this.element)}})};THREE.CSS3DObject.prototype=Object.create(THREE.Object3D.prototype);THREE.CSS3DObject.prototype.constructor=THREE.CSS3DObject;THREE.CSS3DSprite=function(element){THREE.CSS3DObject.call(this,element)};THREE.CSS3DSprite.prototype=Object.create(THREE.CSS3DObject.prototype);THREE.CSS3DSprite.prototype.constructor=THREE.CSS3DSprite;THREE.CSS3DRenderer=function(){console.log("THREE.CSS3DRenderer",THREE.REVISION);var _width,_height;var _widthHalf,_heightHalf;var matrix=new THREE.Matrix4();var cache={camera:{fov:0,style:""},objects:{}};var domElement=document.createElement("div");domElement.style.overflow="hidden";domElement.style.WebkitTransformStyle="preserve-3d";domElement.style.MozTransformStyle="preserve-3d";domElement.style.oTransformStyle="preserve-3d";domElement.style.transformStyle="preserve-3d";this.domElement=domElement;var cameraElement=document.createElement("div");cameraElement.style.WebkitTransformStyle="preserve-3d";cameraElement.style.MozTransformStyle="preserve-3d";cameraElement.style.oTransformStyle="preserve-3d";cameraElement.style.transformStyle="preserve-3d";domElement.appendChild(cameraElement);this.setClearColor=function(){};this.getSize=function(){return{width:_width,height:_height}};this.setSize=function(width,height){_width=width;_height=height;_widthHalf=_width/2;_heightHalf=_height/2;domElement.style.width=width+"px";domElement.style.height=height+"px";cameraElement.style.width=width+"px";cameraElement.style.height=height+"px"};var epsilon=function(value){return Math.abs(value)":{x_min:18.0625,x_max:774,ha:792,o:"m 774 376 l 18 40 l 18 149 l 631 421 l 18 692 l 18 799 l 774 465 l 774 376 "},v:{x_min:0,x_max:675.15625,ha:761,o:"m 675 738 l 404 0 l 272 0 l 0 738 l 133 737 l 340 147 l 541 737 l 675 738 "},"τ":{x_min:0.28125,x_max:644.5,ha:703,o:"m 644 628 l 382 628 l 382 179 q 388 120 382 137 q 436 91 401 91 q 474 94 447 91 q 504 97 501 97 l 504 0 q 454 -9 482 -5 q 401 -14 426 -14 q 278 67 308 -14 q 260 233 260 118 l 260 628 l 0 628 l 0 739 l 644 739 l 644 628 "},"ξ":{x_min:0,x_max:624.9375,ha:699,o:"m 624 -37 q 608 -153 624 -96 q 563 -278 593 -211 l 454 -278 q 491 -183 486 -200 q 511 -83 511 -126 q 484 -23 511 -44 q 370 1 452 1 q 323 0 354 1 q 283 -1 293 -1 q 84 76 169 -1 q 0 266 0 154 q 56 431 0 358 q 197 538 108 498 q 94 613 134 562 q 54 730 54 665 q 77 823 54 780 q 143 901 101 867 l 27 901 l 27 1012 l 576 1012 l 576 901 l 380 901 q 244 863 303 901 q 178 745 178 820 q 312 600 178 636 q 532 582 380 582 l 532 479 q 276 455 361 479 q 118 281 118 410 q 165 173 118 217 q 274 120 208 133 q 494 101 384 110 q 624 -37 624 76 "},"&":{x_min:-3,x_max:894.25,ha:992,o:"m 894 0 l 725 0 l 624 123 q 471 0 553 40 q 306 -41 390 -41 q 168 -7 231 -41 q 62 92 105 26 q 14 187 31 139 q -3 276 -3 235 q 55 433 -3 358 q 248 581 114 508 q 170 689 196 640 q 137 817 137 751 q 214 985 137 922 q 384 1041 284 1041 q 548 988 483 1041 q 622 824 622 928 q 563 666 622 739 q 431 556 516 608 l 621 326 q 649 407 639 361 q 663 493 653 426 l 781 493 q 703 229 781 352 l 894 0 m 504 818 q 468 908 504 877 q 384 940 433 940 q 293 907 331 940 q 255 818 255 875 q 289 714 255 767 q 363 628 313 678 q 477 729 446 682 q 504 818 504 771 m 556 209 l 314 499 q 179 395 223 449 q 135 283 135 341 q 146 222 135 253 q 183 158 158 192 q 333 80 241 80 q 556 209 448 80 "},"Λ":{x_min:0,x_max:862.5,ha:942,o:"m 862 0 l 719 0 l 426 847 l 143 0 l 0 0 l 356 1013 l 501 1013 l 862 0 "},I:{x_min:41,x_max:180,ha:293,o:"m 180 0 l 41 0 l 41 1013 l 180 1013 l 180 0 "},G:{x_min:0,x_max:921,ha:1011,o:"m 921 0 l 832 0 l 801 136 q 655 15 741 58 q 470 -28 568 -28 q 126 133 259 -28 q 0 499 0 284 q 125 881 0 731 q 486 1043 259 1043 q 763 957 647 1043 q 905 709 890 864 l 772 709 q 668 866 747 807 q 486 926 589 926 q 228 795 322 926 q 142 507 142 677 q 228 224 142 342 q 483 94 323 94 q 712 195 625 94 q 796 435 796 291 l 477 435 l 477 549 l 921 549 l 921 0 "},"ΰ":{x_min:0,x_max:617,ha:725,o:"m 524 800 l 414 800 l 414 925 l 524 925 l 524 800 m 183 800 l 73 800 l 73 925 l 183 925 l 183 800 m 617 352 q 540 93 617 199 q 308 -24 455 -24 q 76 93 161 -24 q 0 352 0 199 l 0 738 l 126 738 l 126 354 q 169 185 126 257 q 312 98 220 98 q 451 185 402 98 q 492 354 492 257 l 492 738 l 617 738 l 617 352 m 489 1040 l 300 819 l 216 819 l 351 1040 l 489 1040 "},"`":{x_min:0,x_max:138.890625,ha:236,o:"m 138 699 l 0 699 l 0 861 q 36 974 0 929 q 138 1041 72 1020 l 138 977 q 82 931 95 969 q 69 839 69 893 l 138 839 l 138 699 "},"·":{x_min:0,x_max:142,ha:239,o:"m 142 585 l 0 585 l 0 738 l 142 738 l 142 585 "},"Υ":{x_min:0.328125,x_max:819.515625,ha:889,o:"m 819 1013 l 482 416 l 482 0 l 342 0 l 342 416 l 0 1013 l 140 1013 l 411 533 l 679 1013 l 819 1013 "},r:{x_min:0,x_max:355.5625,ha:432,o:"m 355 621 l 343 621 q 179 569 236 621 q 122 411 122 518 l 122 0 l 0 0 l 0 737 l 117 737 l 117 604 q 204 719 146 686 q 355 753 262 753 l 355 621 "},x:{x_min:0,x_max:675,ha:764,o:"m 675 0 l 525 0 l 331 286 l 144 0 l 0 0 l 256 379 l 12 738 l 157 737 l 336 473 l 516 738 l 661 738 l 412 380 l 675 0 "},"μ":{x_min:0,x_max:696.609375,ha:747,o:"m 696 -4 q 628 -14 657 -14 q 498 97 513 -14 q 422 8 470 41 q 313 -24 374 -24 q 207 3 258 -24 q 120 80 157 31 l 120 -278 l 0 -278 l 0 738 l 124 738 l 124 343 q 165 172 124 246 q 308 82 216 82 q 451 177 402 82 q 492 358 492 254 l 492 738 l 616 738 l 616 214 q 623 136 616 160 q 673 92 636 92 q 696 95 684 92 l 696 -4 "},h:{x_min:0,x_max:615,ha:724,o:"m 615 472 l 615 0 l 490 0 l 490 454 q 456 590 490 535 q 338 654 416 654 q 186 588 251 654 q 122 436 122 522 l 122 0 l 0 0 l 0 1013 l 122 1013 l 122 633 q 218 727 149 694 q 362 760 287 760 q 552 676 484 760 q 615 472 615 600 "},".":{x_min:0,x_max:142,ha:239,o:"m 142 0 l 0 0 l 0 151 l 142 151 l 142 0 "},"φ":{x_min:-2,x_max:878,ha:974,o:"m 496 -279 l 378 -279 l 378 -17 q 101 88 204 -17 q -2 367 -2 194 q 68 626 -2 510 q 283 758 151 758 l 283 646 q 167 537 209 626 q 133 373 133 462 q 192 177 133 254 q 378 93 259 93 l 378 758 q 445 764 426 763 q 476 765 464 765 q 765 659 653 765 q 878 377 878 553 q 771 96 878 209 q 496 -17 665 -17 l 496 -279 m 496 93 l 514 93 q 687 183 623 93 q 746 380 746 265 q 691 569 746 491 q 522 658 629 658 l 496 656 l 496 93 "},";":{x_min:0,x_max:142,ha:239,o:"m 142 585 l 0 585 l 0 738 l 142 738 l 142 585 m 142 -12 q 105 -132 142 -82 q 0 -206 68 -182 l 0 -138 q 58 -82 43 -123 q 68 0 68 -56 l 0 0 l 0 151 l 142 151 l 142 -12 "},f:{x_min:0,x_max:378,ha:472,o:"m 378 638 l 246 638 l 246 0 l 121 0 l 121 638 l 0 638 l 0 738 l 121 738 q 137 935 121 887 q 290 1028 171 1028 q 320 1027 305 1028 q 378 1021 334 1026 l 378 908 q 323 918 346 918 q 257 870 273 918 q 246 780 246 840 l 246 738 l 378 738 l 378 638 "},"“":{x_min:1,x_max:348.21875,ha:454,o:"m 140 670 l 1 670 l 1 830 q 37 943 1 897 q 140 1011 74 990 l 140 947 q 82 900 97 940 q 68 810 68 861 l 140 810 l 140 670 m 348 670 l 209 670 l 209 830 q 245 943 209 897 q 348 1011 282 990 l 348 947 q 290 900 305 940 q 276 810 276 861 l 348 810 l 348 670 "},A:{x_min:0.03125,x_max:906.953125,ha:1008,o:"m 906 0 l 756 0 l 648 303 l 251 303 l 142 0 l 0 0 l 376 1013 l 529 1013 l 906 0 m 610 421 l 452 867 l 293 421 l 610 421 "},"6":{x_min:53,x_max:739,ha:792,o:"m 739 312 q 633 62 739 162 q 400 -31 534 -31 q 162 78 257 -31 q 53 439 53 206 q 178 859 53 712 q 441 986 284 986 q 643 912 559 986 q 732 713 732 833 l 601 713 q 544 830 594 786 q 426 875 494 875 q 268 793 331 875 q 193 517 193 697 q 301 597 240 570 q 427 624 362 624 q 643 540 552 624 q 739 312 739 451 m 603 298 q 540 461 603 400 q 404 516 484 516 q 268 461 323 516 q 207 300 207 401 q 269 137 207 198 q 405 83 325 83 q 541 137 486 83 q 603 298 603 197 "},"‘":{x_min:1,x_max:139.890625,ha:236,o:"m 139 670 l 1 670 l 1 830 q 37 943 1 897 q 139 1011 74 990 l 139 947 q 82 900 97 940 q 68 810 68 861 l 139 810 l 139 670 "},"ϊ":{x_min:-70,x_max:283,ha:361,o:"m 283 800 l 173 800 l 173 925 l 283 925 l 283 800 m 40 800 l -70 800 l -70 925 l 40 925 l 40 800 m 283 3 q 232 -10 257 -5 q 181 -15 206 -15 q 84 26 118 -15 q 41 200 41 79 l 41 737 l 166 737 l 167 215 q 171 141 167 157 q 225 101 182 101 q 247 103 238 101 q 283 112 256 104 l 283 3 "},"π":{x_min:-0.21875,x_max:773.21875,ha:857,o:"m 773 -7 l 707 -11 q 575 40 607 -11 q 552 174 552 77 l 552 226 l 552 626 l 222 626 l 222 0 l 97 0 l 97 626 l 0 626 l 0 737 l 773 737 l 773 626 l 676 626 l 676 171 q 695 103 676 117 q 773 90 714 90 l 773 -7 "},"ά":{x_min:0,x_max:765.5625,ha:809,o:"m 765 -4 q 698 -14 726 -14 q 564 97 586 -14 q 466 7 525 40 q 337 -26 407 -26 q 88 98 186 -26 q 0 369 0 212 q 88 637 0 525 q 337 760 184 760 q 465 727 407 760 q 563 637 524 695 l 563 738 l 685 738 l 685 222 q 693 141 685 168 q 748 94 708 94 q 765 95 760 94 l 765 -4 m 584 371 q 531 562 584 485 q 360 653 470 653 q 192 566 254 653 q 135 379 135 489 q 186 181 135 261 q 358 84 247 84 q 528 176 465 84 q 584 371 584 260 m 604 1040 l 415 819 l 332 819 l 466 1040 l 604 1040 "},O:{x_min:0,x_max:958,ha:1057,o:"m 485 1041 q 834 882 702 1041 q 958 512 958 734 q 834 136 958 287 q 481 -26 702 -26 q 126 130 261 -26 q 0 504 0 279 q 127 880 0 728 q 485 1041 263 1041 m 480 98 q 731 225 638 98 q 815 504 815 340 q 733 783 815 669 q 480 912 640 912 q 226 784 321 912 q 142 504 142 670 q 226 224 142 339 q 480 98 319 98 "},n:{x_min:0,x_max:615,ha:724,o:"m 615 463 l 615 0 l 490 0 l 490 454 q 453 592 490 537 q 331 656 410 656 q 178 585 240 656 q 117 421 117 514 l 117 0 l 0 0 l 0 738 l 117 738 l 117 630 q 218 728 150 693 q 359 764 286 764 q 552 675 484 764 q 615 463 615 593 "},"3":{x_min:54,x_max:737,ha:792,o:"m 737 284 q 635 55 737 141 q 399 -25 541 -25 q 156 52 248 -25 q 54 308 54 140 l 185 308 q 245 147 185 202 q 395 96 302 96 q 539 140 484 96 q 602 280 602 190 q 510 429 602 390 q 324 454 451 454 l 324 565 q 487 584 441 565 q 565 719 565 617 q 515 835 565 791 q 395 879 466 879 q 255 824 307 879 q 203 661 203 769 l 78 661 q 166 909 78 822 q 387 992 250 992 q 603 921 513 992 q 701 723 701 844 q 669 607 701 656 q 578 524 637 558 q 696 434 655 499 q 737 284 737 369 "},"9":{x_min:53,x_max:739,ha:792,o:"m 739 524 q 619 94 739 241 q 362 -32 516 -32 q 150 47 242 -32 q 59 244 59 126 l 191 244 q 246 129 191 176 q 373 82 301 82 q 526 161 466 82 q 597 440 597 255 q 363 334 501 334 q 130 432 216 334 q 53 650 53 521 q 134 880 53 786 q 383 986 226 986 q 659 841 566 986 q 739 524 739 719 m 388 449 q 535 514 480 449 q 585 658 585 573 q 535 805 585 744 q 388 873 480 873 q 242 809 294 873 q 191 658 191 745 q 239 514 191 572 q 388 449 292 449 "},l:{x_min:41,x_max:166,ha:279,o:"m 166 0 l 41 0 l 41 1013 l 166 1013 l 166 0 "},"¤":{x_min:40.09375,x_max:728.796875,ha:825,o:"m 728 304 l 649 224 l 512 363 q 383 331 458 331 q 256 363 310 331 l 119 224 l 40 304 l 177 441 q 150 553 150 493 q 184 673 150 621 l 40 818 l 119 898 l 267 749 q 321 766 291 759 q 384 773 351 773 q 447 766 417 773 q 501 749 477 759 l 649 898 l 728 818 l 585 675 q 612 618 604 648 q 621 553 621 587 q 591 441 621 491 l 728 304 m 384 682 q 280 643 318 682 q 243 551 243 604 q 279 461 243 499 q 383 423 316 423 q 487 461 449 423 q 525 553 525 500 q 490 641 525 605 q 384 682 451 682 "},"κ":{x_min:0,x_max:632.328125,ha:679,o:"m 632 0 l 482 0 l 225 384 l 124 288 l 124 0 l 0 0 l 0 738 l 124 738 l 124 446 l 433 738 l 596 738 l 312 466 l 632 0 "},"4":{x_min:48,x_max:742.453125,ha:792,o:"m 742 243 l 602 243 l 602 0 l 476 0 l 476 243 l 48 243 l 48 368 l 476 958 l 602 958 l 602 354 l 742 354 l 742 243 m 476 354 l 476 792 l 162 354 l 476 354 "},p:{x_min:0,x_max:685,ha:786,o:"m 685 364 q 598 96 685 205 q 350 -23 504 -23 q 121 89 205 -23 l 121 -278 l 0 -278 l 0 738 l 121 738 l 121 633 q 220 726 159 691 q 351 761 280 761 q 598 636 504 761 q 685 364 685 522 m 557 371 q 501 560 557 481 q 330 651 437 651 q 162 559 223 651 q 108 366 108 479 q 162 177 108 254 q 333 87 224 87 q 502 178 441 87 q 557 371 557 258 "},"‡":{x_min:0,x_max:777,ha:835,o:"m 458 238 l 458 0 l 319 0 l 319 238 l 0 238 l 0 360 l 319 360 l 319 681 l 0 683 l 0 804 l 319 804 l 319 1015 l 458 1013 l 458 804 l 777 804 l 777 683 l 458 683 l 458 360 l 777 360 l 777 238 l 458 238 "},"ψ":{x_min:0,x_max:808,ha:907,o:"m 465 -278 l 341 -278 l 341 -15 q 87 102 180 -15 q 0 378 0 210 l 0 739 l 133 739 l 133 379 q 182 195 133 275 q 341 98 242 98 l 341 922 l 465 922 l 465 98 q 623 195 563 98 q 675 382 675 278 l 675 742 l 808 742 l 808 381 q 720 104 808 213 q 466 -13 627 -13 l 465 -278 "},"η":{x_min:0.78125,x_max:697,ha:810,o:"m 697 -278 l 572 -278 l 572 454 q 540 587 572 536 q 425 650 501 650 q 271 579 337 650 q 206 420 206 509 l 206 0 l 81 0 l 81 489 q 73 588 81 562 q 0 644 56 644 l 0 741 q 68 755 38 755 q 158 720 124 755 q 200 630 193 686 q 297 726 234 692 q 434 761 359 761 q 620 692 544 761 q 697 516 697 624 l 697 -278 "}},cssFontWeight:"normal",ascender:1189,underlinePosition:-100,cssFontStyle:"normal",boundingBox:{yMin:-334,xMin:-111,yMax:1189,xMax:1672},resolution:1000,original_font_information:{postscript_name:"Helvetiker-Regular",version_string:"Version 1.00 2004 initial release",vendor_url:"http://www.magenta.gr/",full_font_name:"Helvetiker",font_family_name:"Helvetiker",copyright:"Copyright (c) Μagenta ltd, 2004",description:"",trademark:"",designer:"",designer_url:"",unique_font_identifier:"Μagenta ltd:Helvetiker:22-10-104",license_url:"http://www.ellak.gr/fonts/MgOpen/license.html",license_description:'Copyright (c) 2004 by MAGENTA Ltd. All Rights Reserved.\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions: \r\n\r\nThe above copyright and this permission notice shall be included in all copies of one or more of the Font Software typefaces.\r\n\r\nThe Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing the word "MgOpen", or if the modifications are accepted for inclusion in the Font Software itself by the each appointed Administrator.\r\n\r\nThis License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "MgOpen" name.\r\n\r\nThe Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself. \r\n\r\nTHE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL MAGENTA OR PERSONS OR BODIES IN CHARGE OF ADMINISTRATION AND MAINTENANCE OF THE FONT SOFTWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.',manufacturer_name:"Μagenta ltd",font_sub_family_name:"Regular"},descender:-334,familyName:"Helvetiker",lineHeight:1522,underlineThickness:50})}THREE.OrbitControls=function(object,domElement){this.object=object;this.domElement=(domElement!==undefined)?domElement:document;this.enabled=true;this.target=new THREE.Vector3();this.minDistance=0;this.maxDistance=Infinity;this.minZoom=0;this.maxZoom=Infinity;this.minPolarAngle=0;this.maxPolarAngle=Math.PI;this.minAzimuthAngle=-Infinity;this.maxAzimuthAngle=Infinity;this.enableDamping=false;this.dampingFactor=0.25;this.enableZoom=true;this.zoomSpeed=1;this.enableRotate=true;this.rotateSpeed=1;this.enablePan=true;this.keyPanSpeed=7;this.autoRotate=false;this.autoRotateSpeed=2;this.enableKeys=true;this.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40};this.mouseButtons={ORBIT:THREE.MOUSE.LEFT,ZOOM:THREE.MOUSE.MIDDLE,PAN:THREE.MOUSE.RIGHT};this.target0=this.target.clone();this.position0=this.object.position.clone();this.zoom0=this.object.zoom;this.getPolarAngle=function(){return phi};this.getAzimuthalAngle=function(){return theta};this.reset=function(){scope.target.copy(scope.target0);scope.object.position.copy(scope.position0);scope.object.zoom=scope.zoom0;scope.object.updateProjectionMatrix();scope.dispatchEvent(changeEvent);scope.update();state=STATE.NONE};this.update=function(){var offset=new THREE.Vector3();var quat=new THREE.Quaternion().setFromUnitVectors(object.up,new THREE.Vector3(0,1,0));var quatInverse=quat.clone().inverse();var lastPosition=new THREE.Vector3();var lastQuaternion=new THREE.Quaternion();return function(){var position=scope.object.position;offset.copy(position).sub(scope.target);offset.applyQuaternion(quat);spherical.setFromVector3(offset);if(scope.autoRotate&&state===STATE.NONE){rotateLeft(getAutoRotationAngle())}spherical.theta+=sphericalDelta.theta;spherical.phi+=sphericalDelta.phi;spherical.theta=Math.max(scope.minAzimuthAngle,Math.min(scope.maxAzimuthAngle,spherical.theta));spherical.phi=Math.max(scope.minPolarAngle,Math.min(scope.maxPolarAngle,spherical.phi));spherical.makeSafe();spherical.radius*=scale;spherical.radius=Math.max(scope.minDistance,Math.min(scope.maxDistance,spherical.radius));scope.target.add(panOffset);offset.setFromSpherical(spherical);offset.applyQuaternion(quatInverse);position.copy(scope.target).add(offset);scope.object.lookAt(scope.target);if(scope.enableDamping===true){sphericalDelta.theta*=(1-scope.dampingFactor);sphericalDelta.phi*=(1-scope.dampingFactor)}else{sphericalDelta.set(0,0,0)}scale=1;panOffset.set(0,0,0);if(zoomChanged||lastPosition.distanceToSquared(scope.object.position)>EPS||8*(1-lastQuaternion.dot(scope.object.quaternion))>EPS){scope.dispatchEvent(changeEvent);lastPosition.copy(scope.object.position);lastQuaternion.copy(scope.object.quaternion);zoomChanged=false;return true}return false}}();this.dispose=function(){scope.domElement.removeEventListener("contextmenu",onContextMenu,false);scope.domElement.removeEventListener("mousedown",onMouseDown,false);scope.domElement.removeEventListener("mousewheel",onMouseWheel,false);scope.domElement.removeEventListener("MozMousePixelScroll",onMouseWheel,false);scope.domElement.removeEventListener("touchstart",onTouchStart,false);scope.domElement.removeEventListener("touchend",onTouchEnd,false);scope.domElement.removeEventListener("touchmove",onTouchMove,false);document.removeEventListener("mousemove",onMouseMove,false);document.removeEventListener("mouseup",onMouseUp,false);document.removeEventListener("mouseout",onMouseUp,false);window.removeEventListener("keydown",onKeyDown,false)};var scope=this;var changeEvent={type:"change"};var startEvent={type:"start"};var endEvent={type:"end"};var STATE={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5};var state=STATE.NONE;var EPS=0.000001;var spherical=new THREE.Spherical();var sphericalDelta=new THREE.Spherical();var scale=1;var panOffset=new THREE.Vector3();var zoomChanged=false;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 dollyStart=new THREE.Vector2();var dollyEnd=new THREE.Vector2();var dollyDelta=new THREE.Vector2();function getAutoRotationAngle(){return 2*Math.PI/60/60*scope.autoRotateSpeed}function getZoomScale(){return Math.pow(0.95,scope.zoomSpeed)}function rotateLeft(angle){sphericalDelta.theta-=angle}function rotateUp(angle){sphericalDelta.phi-=angle}var panLeft=function(){var v=new THREE.Vector3();return function panLeft(distance,objectMatrix){v.setFromMatrixColumn(objectMatrix,0);v.multiplyScalar(-distance);panOffset.add(v)}}();var panUp=function(){var v=new THREE.Vector3();return function panUp(distance,objectMatrix){v.setFromMatrixColumn(objectMatrix,1);v.multiplyScalar(distance);panOffset.add(v)}}();var pan=function(){var offset=new THREE.Vector3();return function(deltaX,deltaY){var element=scope.domElement===document?scope.domElement.body:scope.domElement;if(scope.object instanceof THREE.PerspectiveCamera){var position=scope.object.position;offset.copy(position).sub(scope.target);var targetDistance=offset.length();targetDistance*=Math.tan((scope.object.fov/2)*Math.PI/180);panLeft(2*deltaX*targetDistance/element.clientHeight,scope.object.matrix);panUp(2*deltaY*targetDistance/element.clientHeight,scope.object.matrix)}else{if(scope.object instanceof THREE.OrthographicCamera){panLeft(deltaX*(scope.object.right-scope.object.left)/scope.object.zoom/element.clientWidth,scope.object.matrix);panUp(deltaY*(scope.object.top-scope.object.bottom)/scope.object.zoom/element.clientHeight,scope.object.matrix)}else{console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.");scope.enablePan=false}}}}();function dollyIn(dollyScale){if(scope.object instanceof THREE.PerspectiveCamera){scale/=dollyScale}else{if(scope.object instanceof THREE.OrthographicCamera){scope.object.zoom=Math.max(scope.minZoom,Math.min(scope.maxZoom,scope.object.zoom*dollyScale));scope.object.updateProjectionMatrix();zoomChanged=true}else{console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");scope.enableZoom=false}}}function dollyOut(dollyScale){if(scope.object instanceof THREE.PerspectiveCamera){scale*=dollyScale}else{if(scope.object instanceof THREE.OrthographicCamera){scope.object.zoom=Math.max(scope.minZoom,Math.min(scope.maxZoom,scope.object.zoom/dollyScale));scope.object.updateProjectionMatrix();zoomChanged=true}else{console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.");scope.enableZoom=false}}}function handleMouseDownRotate(event){rotateStart.set(event.clientX,event.clientY)}function handleMouseDownDolly(event){dollyStart.set(event.clientX,event.clientY)}function handleMouseDownPan(event){panStart.set(event.clientX,event.clientY)}function handleMouseMoveRotate(event){rotateEnd.set(event.clientX,event.clientY);rotateDelta.subVectors(rotateEnd,rotateStart);var element=scope.domElement===document?scope.domElement.body:scope.domElement;rotateLeft(2*Math.PI*rotateDelta.x/element.clientWidth*scope.rotateSpeed);rotateUp(2*Math.PI*rotateDelta.y/element.clientHeight*scope.rotateSpeed);rotateStart.copy(rotateEnd);scope.update()}function handleMouseMoveDolly(event){dollyEnd.set(event.clientX,event.clientY);dollyDelta.subVectors(dollyEnd,dollyStart);if(dollyDelta.y>0){dollyIn(getZoomScale())}else{if(dollyDelta.y<0){dollyOut(getZoomScale())}}dollyStart.copy(dollyEnd);scope.update()}function handleMouseMovePan(event){panEnd.set(event.clientX,event.clientY);panDelta.subVectors(panEnd,panStart);pan(panDelta.x,panDelta.y);panStart.copy(panEnd);scope.update()}function handleMouseUp(event){}function handleMouseWheel(event){var delta=0;if(event.wheelDelta!==undefined){delta=event.wheelDelta}else{if(event.detail!==undefined){delta=-event.detail}}if(delta>0){dollyOut(getZoomScale())}else{if(delta<0){dollyIn(getZoomScale())}}scope.update()}function handleKeyDown(event){switch(event.keyCode){case scope.keys.UP:pan(0,scope.keyPanSpeed);scope.update();break;case scope.keys.BOTTOM:pan(0,-scope.keyPanSpeed);scope.update();break;case scope.keys.LEFT:pan(scope.keyPanSpeed,0);scope.update();break;case scope.keys.RIGHT:pan(-scope.keyPanSpeed,0);scope.update();break}}function handleTouchStartRotate(event){rotateStart.set(event.touches[0].pageX,event.touches[0].pageY)}function handleTouchStartDolly(event){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)}function handleTouchStartPan(event){panStart.set(event.touches[0].pageX,event.touches[0].pageY)}function handleTouchMoveRotate(event){rotateEnd.set(event.touches[0].pageX,event.touches[0].pageY);rotateDelta.subVectors(rotateEnd,rotateStart);var element=scope.domElement===document?scope.domElement.body:scope.domElement;rotateLeft(2*Math.PI*rotateDelta.x/element.clientWidth*scope.rotateSpeed);rotateUp(2*Math.PI*rotateDelta.y/element.clientHeight*scope.rotateSpeed);rotateStart.copy(rotateEnd);scope.update()}function handleTouchMoveDolly(event){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){dollyOut(getZoomScale())}else{if(dollyDelta.y<0){dollyIn(getZoomScale())}}dollyStart.copy(dollyEnd);scope.update()}function handleTouchMovePan(event){panEnd.set(event.touches[0].pageX,event.touches[0].pageY);panDelta.subVectors(panEnd,panStart);pan(panDelta.x,panDelta.y);panStart.copy(panEnd);scope.update()}function handleTouchEnd(event){}function onMouseDown(event){if(scope.enabled===false){return}event.preventDefault();if(event.button===scope.mouseButtons.ORBIT){if(scope.enableRotate===false){return}handleMouseDownRotate(event);state=STATE.ROTATE}else{if(event.button===scope.mouseButtons.ZOOM){if(scope.enableZoom===false){return}handleMouseDownDolly(event);state=STATE.DOLLY}else{if(event.button===scope.mouseButtons.PAN){if(scope.enablePan===false){return}handleMouseDownPan(event);state=STATE.PAN}}}if(state!==STATE.NONE){document.addEventListener("mousemove",onMouseMove,false);document.addEventListener("mouseup",onMouseUp,false);document.addEventListener("mouseout",onMouseUp,false);scope.dispatchEvent(startEvent)}}function onMouseMove(event){if(scope.enabled===false){return}event.preventDefault();if(state===STATE.ROTATE){if(scope.enableRotate===false){return}handleMouseMoveRotate(event)}else{if(state===STATE.DOLLY){if(scope.enableZoom===false){return}handleMouseMoveDolly(event)}else{if(state===STATE.PAN){if(scope.enablePan===false){return}handleMouseMovePan(event)}}}}function onMouseUp(event){if(scope.enabled===false){return}handleMouseUp(event);document.removeEventListener("mousemove",onMouseMove,false);document.removeEventListener("mouseup",onMouseUp,false);document.removeEventListener("mouseout",onMouseUp,false);scope.dispatchEvent(endEvent);state=STATE.NONE}function onMouseWheel(event){if(scope.enabled===false||scope.enableZoom===false||state!==STATE.NONE){return}event.preventDefault();event.stopPropagation();handleMouseWheel(event);scope.dispatchEvent(startEvent);scope.dispatchEvent(endEvent)}function onKeyDown(event){if(scope.enabled===false||scope.enableKeys===false||scope.enablePan===false){return}handleKeyDown(event)}function onTouchStart(event){if(scope.enabled===false){return}switch(event.touches.length){case 1:if(scope.enableRotate===false){return}handleTouchStartRotate(event);state=STATE.TOUCH_ROTATE;break;case 2:if(scope.enableZoom===false){return}handleTouchStartDolly(event);state=STATE.TOUCH_DOLLY;break;case 3:if(scope.enablePan===false){return}handleTouchStartPan(event);state=STATE.TOUCH_PAN;break;default:state=STATE.NONE}if(state!==STATE.NONE){scope.dispatchEvent(startEvent)}}function onTouchMove(event){if(scope.enabled===false){return}event.preventDefault();event.stopPropagation();switch(event.touches.length){case 1:if(scope.enableRotate===false){return}if(state!==STATE.TOUCH_ROTATE){return}handleTouchMoveRotate(event);break;case 2:if(scope.enableZoom===false){return}if(state!==STATE.TOUCH_DOLLY){return}handleTouchMoveDolly(event);break;case 3:if(scope.enablePan===false){return}if(state!==STATE.TOUCH_PAN){return}handleTouchMovePan(event);break;default:state=STATE.NONE}}function onTouchEnd(event){if(scope.enabled===false){return}handleTouchEnd(event);scope.dispatchEvent(endEvent);state=STATE.NONE}function onContextMenu(event){event.preventDefault()}scope.domElement.addEventListener("contextmenu",onContextMenu,false);scope.domElement.addEventListener("mousedown",onMouseDown,false);scope.domElement.addEventListener("mousewheel",onMouseWheel,false);scope.domElement.addEventListener("MozMousePixelScroll",onMouseWheel,false);scope.domElement.addEventListener("touchstart",onTouchStart,false);scope.domElement.addEventListener("touchend",onTouchEnd,false);scope.domElement.addEventListener("touchmove",onTouchMove,false);window.addEventListener("keydown",onKeyDown,false);this.update()};THREE.OrbitControls.prototype=Object.create(THREE.EventDispatcher.prototype);THREE.OrbitControls.prototype.constructor=THREE.OrbitControls;Object.defineProperties(THREE.OrbitControls.prototype,{center:{get:function(){console.warn("THREE.OrbitControls: .center has been renamed to .target");return this.target}},noZoom:{get:function(){console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.");return !this.enableZoom},set:function(value){console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.");this.enableZoom=!value}},noRotate:{get:function(){console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.");return !this.enableRotate},set:function(value){console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.");this.enableRotate=!value}},noPan:{get:function(){console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.");return !this.enablePan},set:function(value){console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.");this.enablePan=!value}},noKeys:{get:function(){console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.");return !this.enableKeys},set:function(value){console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.");this.enableKeys=!value}},staticMoving:{get:function(){console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.");return !this.constraint.enableDamping},set:function(value){console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.");this.constraint.enableDamping=!value}},dynamicDampingFactor:{get:function(){console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.");return this.constraint.dampingFactor},set:function(value){console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.");this.constraint.dampingFactor=value}}});THREE.RenderableObject=function(){this.id=0;this.object=null;this.z=0;this.renderOrder=0};THREE.RenderableFace=function(){this.id=0;this.v1=new THREE.RenderableVertex();this.v2=new THREE.RenderableVertex();this.v3=new THREE.RenderableVertex();this.normalModel=new THREE.Vector3();this.vertexNormalsModel=[new THREE.Vector3(),new THREE.Vector3(),new THREE.Vector3()];this.vertexNormalsLength=0;this.color=new THREE.Color();this.material=null;this.uvs=[new THREE.Vector2(),new THREE.Vector2(),new THREE.Vector2()];this.z=0;this.renderOrder=0};THREE.RenderableVertex=function(){this.position=new THREE.Vector3();this.positionWorld=new THREE.Vector3();this.positionScreen=new THREE.Vector4();this.visible=true};THREE.RenderableVertex.prototype.copy=function(vertex){this.positionWorld.copy(vertex.positionWorld);this.positionScreen.copy(vertex.positionScreen)};THREE.RenderableLine=function(){this.id=0;this.v1=new THREE.RenderableVertex();this.v2=new THREE.RenderableVertex();this.vertexColors=[new THREE.Color(),new THREE.Color()];this.material=null;this.z=0;this.renderOrder=0};THREE.RenderableSprite=function(){this.id=0;this.object=null;this.x=0;this.y=0;this.z=0;this.rotation=0;this.scale=new THREE.Vector2();this.material=null;this.renderOrder=0};THREE.Projector=function(){var _object,_objectCount,_objectPool=[],_objectPoolLength=0,_vertex,_vertexCount,_vertexPool=[],_vertexPoolLength=0,_face,_faceCount,_facePool=[],_facePoolLength=0,_line,_lineCount,_linePool=[],_linePoolLength=0,_sprite,_spriteCount,_spritePool=[],_spritePoolLength=0,_renderData={objects:[],lights:[],elements:[]},_vector3=new THREE.Vector3(),_vector4=new THREE.Vector4(),_clipBox=new THREE.Box3(new THREE.Vector3(-1,-1,-1),new THREE.Vector3(1,1,1)),_boundingBox=new THREE.Box3(),_points3=new Array(3),_points4=new Array(4),_viewMatrix=new THREE.Matrix4(),_viewProjectionMatrix=new THREE.Matrix4(),_modelMatrix,_modelViewProjectionMatrix=new THREE.Matrix4(),_normalMatrix=new THREE.Matrix3(),_frustum=new THREE.Frustum(),_clippedVertex1PositionScreen=new THREE.Vector4(),_clippedVertex2PositionScreen=new THREE.Vector4();this.projectVector=function(vector,camera){console.warn("THREE.Projector: .projectVector() is now vector.project().");vector.project(camera)};this.unprojectVector=function(vector,camera){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");vector.unproject(camera)};this.pickingRay=function(vector,camera){console.error("THREE.Projector: .pickingRay() is now raycaster.setFromCamera().")};var RenderList=function(){var normals=[];var uvs=[];var object=null;var material=null;var normalMatrix=new THREE.Matrix3();function setObject(value){object=value;material=object.material;normalMatrix.getNormalMatrix(object.matrixWorld);normals.length=0;uvs.length=0}function projectVertex(vertex){var position=vertex.position;var positionWorld=vertex.positionWorld;var positionScreen=vertex.positionScreen;positionWorld.copy(position).applyMatrix4(_modelMatrix);positionScreen.copy(positionWorld).applyMatrix4(_viewProjectionMatrix);var invW=1/positionScreen.w;positionScreen.x*=invW;positionScreen.y*=invW;positionScreen.z*=invW;vertex.visible=positionScreen.x>=-1&&positionScreen.x<=1&&positionScreen.y>=-1&&positionScreen.y<=1&&positionScreen.z>=-1&&positionScreen.z<=1}function pushVertex(x,y,z){_vertex=getNextVertexInPool();_vertex.position.set(x,y,z);projectVertex(_vertex)}function pushNormal(x,y,z){normals.push(x,y,z)}function pushUv(x,y){uvs.push(x,y)}function checkTriangleVisibility(v1,v2,v3){if(v1.visible===true||v2.visible===true||v3.visible===true){return true}_points3[0]=v1.positionScreen;_points3[1]=v2.positionScreen;_points3[2]=v3.positionScreen;return _clipBox.intersectsBox(_boundingBox.setFromPoints(_points3))}function checkBackfaceCulling(v1,v2,v3){return((v3.positionScreen.x-v1.positionScreen.x)*(v2.positionScreen.y-v1.positionScreen.y)-(v3.positionScreen.y-v1.positionScreen.y)*(v2.positionScreen.x-v1.positionScreen.x))<0}function pushLine(a,b){var v1=_vertexPool[a];var v2=_vertexPool[b];_line=getNextLineInPool();_line.id=object.id;_line.v1.copy(v1);_line.v2.copy(v2);_line.z=(v1.positionScreen.z+v2.positionScreen.z)/2;_line.renderOrder=object.renderOrder;_line.material=object.material;_renderData.elements.push(_line)}function pushTriangle(a,b,c){var v1=_vertexPool[a];var v2=_vertexPool[b];var v3=_vertexPool[c];if(checkTriangleVisibility(v1,v2,v3)===false){return}if(material.side===THREE.DoubleSide||checkBackfaceCulling(v1,v2,v3)===true){_face=getNextFaceInPool();_face.id=object.id;_face.v1.copy(v1);_face.v2.copy(v2);_face.v3.copy(v3);_face.z=(v1.positionScreen.z+v2.positionScreen.z+v3.positionScreen.z)/3;_face.renderOrder=object.renderOrder;_face.normalModel.fromArray(normals,a*3);_face.normalModel.applyMatrix3(normalMatrix).normalize();for(var i=0;i<3;i++){var normal=_face.vertexNormalsModel[i];normal.fromArray(normals,arguments[i]*3);normal.applyMatrix3(normalMatrix).normalize();var uv=_face.uvs[i];uv.fromArray(uvs,arguments[i]*2)}_face.vertexNormalsLength=3;_face.material=object.material;_renderData.elements.push(_face)}}return{setObject:setObject,projectVertex:projectVertex,checkTriangleVisibility:checkTriangleVisibility,checkBackfaceCulling:checkBackfaceCulling,pushVertex:pushVertex,pushNormal:pushNormal,pushUv:pushUv,pushLine:pushLine,pushTriangle:pushTriangle}};var renderList=new RenderList();this.projectScene=function(scene,camera,sortObjects,sortElements){_faceCount=0;_lineCount=0;_spriteCount=0;_renderData.elements.length=0;if(scene.autoUpdate===true){scene.updateMatrixWorld()}if(camera.parent===null){camera.updateMatrixWorld()}_viewMatrix.copy(camera.matrixWorldInverse.getInverse(camera.matrixWorld));_viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix,_viewMatrix);_frustum.setFromMatrix(_viewProjectionMatrix);_objectCount=0;_renderData.objects.length=0;_renderData.lights.length=0;scene.traverseVisible(function(object){if(object instanceof THREE.Light){_renderData.lights.push(object)}else{if(object instanceof THREE.Mesh||object instanceof THREE.Line||object instanceof THREE.Sprite){var material=object.material;if(material.visible===false){return}if(object.frustumCulled===false||_frustum.intersectsObject(object)===true){_object=getNextObjectInPool();_object.id=object.id;_object.object=object;_vector3.setFromMatrixPosition(object.matrixWorld);_vector3.applyProjection(_viewProjectionMatrix);_object.z=_vector3.z;_object.renderOrder=object.renderOrder;_renderData.objects.push(_object)}}}});if(sortObjects===true){_renderData.objects.sort(painterSort)}for(var o=0,ol=_renderData.objects.length;o0){for(var o=0;o0){continue}v2=_vertexPool[_vertexCount-2];_clippedVertex1PositionScreen.copy(v1.positionScreen);_clippedVertex2PositionScreen.copy(v2.positionScreen);if(clipLine(_clippedVertex1PositionScreen,_clippedVertex2PositionScreen)===true){_clippedVertex1PositionScreen.multiplyScalar(1/_clippedVertex1PositionScreen.w);_clippedVertex2PositionScreen.multiplyScalar(1/_clippedVertex2PositionScreen.w);_line=getNextLineInPool();_line.id=object.id;_line.v1.positionScreen.copy(_clippedVertex1PositionScreen);_line.v2.positionScreen.copy(_clippedVertex2PositionScreen);_line.z=Math.max(_clippedVertex1PositionScreen.z,_clippedVertex2PositionScreen.z);_line.renderOrder=object.renderOrder;_line.material=object.material;if(object.material.vertexColors===THREE.VertexColors){_line.vertexColors[0].copy(object.geometry.colors[v]);_line.vertexColors[1].copy(object.geometry.colors[v-1])}_renderData.elements.push(_line)}}}}}else{if(object instanceof THREE.Sprite){_vector4.set(_modelMatrix.elements[12],_modelMatrix.elements[13],_modelMatrix.elements[14],1);_vector4.applyMatrix4(_viewProjectionMatrix);var invW=1/_vector4.w;_vector4.z*=invW;if(_vector4.z>=-1&&_vector4.z<=1){_sprite=getNextSpriteInPool();_sprite.id=object.id;_sprite.x=_vector4.x*invW;_sprite.y=_vector4.y*invW;_sprite.z=_vector4.z;_sprite.renderOrder=object.renderOrder;_sprite.object=object;_sprite.rotation=object.rotation;_sprite.scale.x=object.scale.x*Math.abs(_sprite.x-(_vector4.x+camera.projectionMatrix.elements[0])/(_vector4.w+camera.projectionMatrix.elements[12]));_sprite.scale.y=object.scale.y*Math.abs(_sprite.y-(_vector4.y+camera.projectionMatrix.elements[5])/(_vector4.w+camera.projectionMatrix.elements[13]));_sprite.material=object.material;_renderData.elements.push(_sprite)}}}}}if(sortElements===true){_renderData.elements.sort(painterSort)}return _renderData};function getNextObjectInPool(){if(_objectCount===_objectPoolLength){var object=new THREE.RenderableObject();_objectPool.push(object);_objectPoolLength++;_objectCount++;return object}return _objectPool[_objectCount++]}function getNextVertexInPool(){if(_vertexCount===_vertexPoolLength){var vertex=new THREE.RenderableVertex();_vertexPool.push(vertex);_vertexPoolLength++;_vertexCount++;return vertex}return _vertexPool[_vertexCount++]}function getNextFaceInPool(){if(_faceCount===_facePoolLength){var face=new THREE.RenderableFace();_facePool.push(face);_facePoolLength++;_faceCount++;return face}return _facePool[_faceCount++]}function getNextLineInPool(){if(_lineCount===_linePoolLength){var line=new THREE.RenderableLine();_linePool.push(line);_linePoolLength++;_lineCount++;return line}return _linePool[_lineCount++]}function getNextSpriteInPool(){if(_spriteCount===_spritePoolLength){var sprite=new THREE.RenderableSprite();_spritePool.push(sprite);_spritePoolLength++;_spriteCount++;return sprite}return _spritePool[_spriteCount++]}function painterSort(a,b){if(a.renderOrder!==b.renderOrder){return a.renderOrder-b.renderOrder}else{if(a.z!==b.z){return b.z-a.z}else{if(a.id!==b.id){return a.id-b.id}else{return 0}}}}function clipLine(s1,s2){var alpha1=0,alpha2=1,bc1near=s1.z+s1.w,bc2near=s2.z+s2.w,bc1far=-s1.z+s1.w,bc2far=-s2.z+s2.w;if(bc1near>=0&&bc2near>=0&&bc1far>=0&&bc2far>=0){return true}else{if((bc1near<0&&bc2near<0)||(bc1far<0&&bc2far<0)){return false}else{if(bc1near<0){alpha1=Math.max(alpha1,bc1near/(bc1near-bc2near))}else{if(bc2near<0){alpha2=Math.min(alpha2,bc1near/(bc1near-bc2near))}}if(bc1far<0){alpha1=Math.max(alpha1,bc1far/(bc1far-bc2far))}else{if(bc2far<0){alpha2=Math.min(alpha2,bc1far/(bc1far-bc2far))}}if(alpha2workers){pool.splice(pool.indexOf(this),1);return this.terminate()}renderNext(this)}};worker.color=new THREE.Color().setHSL(Math.random(),0.8,0.8).getHexString();pool.push(worker);if(renderering){updateSettings(worker);worker.postMessage({scene:sceneJSON,camera:cameraJSON,annex:materials,sceneId:sceneId});renderNext(worker)}}if(!renderering){while(pool.length>workers){pool.pop().terminate()}}};this.setWorkers(workers);this.setClearColor=function(color,alpha){clearColor.set(color)};this.setPixelRatio=function(){};this.setSize=function(width,height){canvas.width=width;canvas.height=height;canvasWidth=canvas.width;canvasHeight=canvas.height;canvasWidthHalf=Math.floor(canvasWidth/2);canvasHeightHalf=Math.floor(canvasHeight/2);context.fillStyle="white";pool.forEach(updateSettings)};this.setSize(canvas.width,canvas.height);this.clear=function(){};var totalBlocks,xblocks,yblocks;function updateSettings(worker){worker.postMessage({init:[canvasWidth,canvasHeight],worker:worker.id,blockSize:blockSize})}function renderNext(worker){if(!toRender.length){renderering=false;return scope.dispatchEvent({type:"complete"})}var current=toRender.pop();var blockX=(current%xblocks)*blockSize;var blockY=(current/xblocks|0)*blockSize;worker.postMessage({render:true,x:blockX,y:blockY,sceneId:sceneId});context.fillStyle="#"+worker.color;context.fillRect(blockX,blockY,blockSize,blockSize)}var materials={};var sceneJSON,cameraJSON,reallyThen;var _annex={mirror:1,reflectivity:1,refractionRatio:1,glass:1};function serializeObject(o){var mat=o.material;if(!mat||mat.uuid in materials){return}var props={};for(var m in _annex){if(mat[m]!==undefined){props[m]=mat[m]}}materials[mat.uuid]=props}this.render=function(scene,camera){renderering=true;if(scene.autoUpdate===true){scene.updateMatrixWorld()}if(camera.parent===null){camera.updateMatrixWorld()}sceneJSON=scene.toJSON();cameraJSON=camera.toJSON();++sceneId;scene.traverse(serializeObject);pool.forEach(function(worker){worker.postMessage({scene:sceneJSON,camera:cameraJSON,annex:materials,sceneId:sceneId})});context.clearRect(0,0,canvasWidth,canvasHeight);reallyThen=Date.now();xblocks=Math.ceil(canvasWidth/blockSize);yblocks=Math.ceil(canvasHeight/blockSize);totalBlocks=xblocks*yblocks;toRender=[];for(var i=0;i1?1:elapsed;value=_easingFunction(elapsed);for(property in _valuesEnd){var start=_valuesStart[property]||0;var end=_valuesEnd[property];if(end instanceof Array){_object[property]=_interpolationFunction(end,value)}else{if(typeof(end)==="string"){end=start+parseFloat(end,10)}if(typeof(end)==="number"){_object[property]=start+(end-start)*value}}}if(_onUpdateCallback!==null){_onUpdateCallback.call(_object,value)}if(elapsed===1){if(_repeat>0){if(isFinite(_repeat)){_repeat--}for(property in _valuesStartRepeat){if(typeof(_valuesEnd[property])==="string"){_valuesStartRepeat[property]=_valuesStartRepeat[property]+parseFloat(_valuesEnd[property],10)}if(_yoyo){var tmp=_valuesStartRepeat[property];_valuesStartRepeat[property]=_valuesEnd[property];_valuesEnd[property]=tmp}_valuesStart[property]=_valuesStartRepeat[property]}if(_yoyo){_reversed=!_reversed}_startTime=time+_delayTime;return true}else{if(_onCompleteCallback!==null){_onCompleteCallback.call(_object)}for(var i=0,numChainedTweens=_chainedTweens.length;i1){return fn(v[m],v[m-1],m-f)}return fn(v[i],v[i+1>m?m:i+1],f-i)},Bezier:function(v,k){var b=0;var n=v.length-1;var pw=Math.pow;var bn=TWEEN.Interpolation.Utils.Bernstein;for(var i=0;i<=n;i++){b+=pw(1-k,n-i)*pw(k,i)*v[i]*bn(n,i)}return b},CatmullRom:function(v,k){var m=v.length-1;var f=m*k;var i=Math.floor(f);var fn=TWEEN.Interpolation.Utils.CatmullRom;if(v[0]===v[m]){if(k<0){i=Math.floor(f=m*(1+k))}return fn(v[(i-1+m)%m],v[i],v[(i+1)%m],v[(i+2)%m],f-i)}else{if(k<0){return v[0]-(fn(v[0],v[0],v[1],v[1],-f)-v[0])}if(k>1){return v[m]-(fn(v[m],v[m],v[m-1],v[m-1],f-m)-v[m])}return fn(v[i?i-1:0],v[i],v[m1;i--){s*=i}a[n]=s;return s}})(),CatmullRom:function(p0,p1,p2,p3,t){var v0=(p2-p0)*0.5;var v1=(p3-p1)*0.5;var t2=t*t;var t3=t*t2;return(2*p1-2*p2+v0+v1)*t3+(-3*p1+3*p2-2*v0-v1)*t2+v0*t+p1}}};(function(root){if(typeof define==="function"&&define.amd){define([],function(){return TWEEN})}else{if(typeof exports==="object"){module.exports=TWEEN}else{root.TWEEN=TWEEN}}})(this); \ No newline at end of file diff --git a/vendor/renderstats/README.md b/vendor/renderstats/README.md new file mode 100644 index 0000000..9c1ae86 --- /dev/null +++ b/vendor/renderstats/README.md @@ -0,0 +1,51 @@ +threex.rendererstats +==================== + +It is a three.js extension to display realtime informations about ```THREE.WebGLRenderer```. +Here is a [basic example](http://jeromeetienne.github.io/threex.rendererstats/examples/basic.html). It is widely inpired from @mrdoob [stats.js](https://github.com/mrdoob/stats.js/). +It is released under MIT license. + +## How To install it + +You can install it manually or with +[bower](http://bower.io/). +for the manual version, first include ```threex.rendererstats.js``` with the usual + +```html + +``` + +or with +[bower](http://bower.io/) +you type the following to install the package. + +```bash +bower install -s threex.rendererstats=https://github.com/jeromeetienne/threex.rendererstats/archive/master.zip +``` + +then you add that in your html + +```html + +``` + +## How To Use It + +``` +var rendererStats = new THREEx.RendererStats() +``` + +position it on the page with css with something along this line + +``` +rendererStats.domElement.style.position = 'absolute' +rendererStats.domElement.style.left = '0px' +rendererStats.domElement.style.bottom = '0px' +document.body.appendChild( rendererStats.domElement ) +``` + +finally update it at every frame + +``` +rendererStats.update(renderer); +``` \ No newline at end of file diff --git a/vendor/renderstats/threex.rendererstats.js b/vendor/renderstats/threex.rendererstats.js new file mode 100644 index 0000000..36666e9 --- /dev/null +++ b/vendor/renderstats/threex.rendererstats.js @@ -0,0 +1,66 @@ +/** + * @author mrdoob / http://mrdoob.com/ + * @author jetienne / http://jetienne.com/ + */ +/** @namespace */ +var THREEx = THREEx || {} + +/** + * provide info on THREE.WebGLRenderer + * + * @param {Object} renderer the renderer to update + * @param {Object} Camera the camera to update +*/ +THREEx.RendererStats = function (){ + + var msMin = 100; + var msMax = 0; + + var container = document.createElement( 'div' ); + container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer'; + + var msDiv = document.createElement( 'div' ); + msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#200;'; + container.appendChild( msDiv ); + + var msText = document.createElement( 'div' ); + msText.style.cssText = 'color:#f00;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; + msText.innerHTML= 'WebGLRenderer'; + msDiv.appendChild( msText ); + + var msTexts = []; + var nLines = 9; + for(var i = 0; i < nLines; i++){ + msTexts[i] = document.createElement( 'div' ); + msTexts[i].style.cssText = 'color:#f00;background-color:#311;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; + msDiv.appendChild( msTexts[i] ); + msTexts[i].innerHTML= '-'; + } + + + var lastTime = Date.now(); + return { + domElement: container, + + update: function(webGLRenderer){ + // sanity check + console.assert(webGLRenderer instanceof THREE.WebGLRenderer) + + // refresh only 30time per second + if( Date.now() - lastTime < 1000/30 ) return; + lastTime = Date.now() + + var i = 0; + msTexts[i++].textContent = "== Memory ====="; + msTexts[i++].textContent = "Programs: " + webGLRenderer.info.memory.programs; + msTexts[i++].textContent = "Geometries: "+webGLRenderer.info.memory.geometries; + msTexts[i++].textContent = "Textures: " + webGLRenderer.info.memory.textures; + + msTexts[i++].textContent = "== Render ====="; + msTexts[i++].textContent = "Calls: " + webGLRenderer.info.render.calls; + msTexts[i++].textContent = "Vertices: " + webGLRenderer.info.render.vertices; + msTexts[i++].textContent = "Faces: " + webGLRenderer.info.render.faces; + msTexts[i++].textContent = "Points: " + webGLRenderer.info.render.points; + } + } +}; \ No newline at end of file diff --git a/vendor/three-js/CSS3DRenderer.js b/vendor/three-js/CSS3DRenderer.js index cd68fac..70c3b8f 100644 --- a/vendor/three-js/CSS3DRenderer.js +++ b/vendor/three-js/CSS3DRenderer.js @@ -9,10 +9,6 @@ THREE.CSS3DObject = function ( element ) { this.element = element; this.element.style.position = 'absolute'; - this.element.style.WebkitTransformStyle = 'preserve-3d'; - this.element.style.MozTransformStyle = 'preserve-3d'; - this.element.style.oTransformStyle = 'preserve-3d'; - this.element.style.transformStyle = 'preserve-3d'; this.addEventListener( 'removed', function ( event ) { @@ -20,12 +16,6 @@ THREE.CSS3DObject = function ( element ) { this.element.parentNode.removeChild( this.element ); - for ( var i = 0, l = this.children.length; i < l; i ++ ) { - - this.children[ i ].dispatchEvent( event ); - - } - } } ); @@ -33,6 +23,7 @@ THREE.CSS3DObject = function ( element ) { }; THREE.CSS3DObject.prototype = Object.create( THREE.Object3D.prototype ); +THREE.CSS3DObject.prototype.constructor = THREE.CSS3DObject; THREE.CSS3DSprite = function ( element ) { @@ -41,6 +32,7 @@ THREE.CSS3DSprite = function ( element ) { }; THREE.CSS3DSprite.prototype = Object.create( THREE.CSS3DObject.prototype ); +THREE.CSS3DSprite.prototype.constructor = THREE.CSS3DSprite; // @@ -53,6 +45,11 @@ THREE.CSS3DRenderer = function () { var matrix = new THREE.Matrix4(); + var cache = { + camera: { fov: 0, style: '' }, + objects: {} + }; + var domElement = document.createElement( 'div' ); domElement.style.overflow = 'hidden'; @@ -72,6 +69,17 @@ THREE.CSS3DRenderer = function () { domElement.appendChild( cameraElement ); + this.setClearColor = function () {}; + + this.getSize = function() { + + return { + width: _width, + height: _height + }; + + }; + this.setSize = function ( width, height ) { _width = width; @@ -90,7 +98,7 @@ THREE.CSS3DRenderer = function () { var epsilon = function ( value ) { - return Math.abs( value ) < 0.000001 ? 0 : value; + return Math.abs( value ) < Number.EPSILON ? 0 : value; }; @@ -173,11 +181,18 @@ THREE.CSS3DRenderer = function () { } var element = object.element; + var cachedStyle = cache.objects[ object.id ]; + + if ( cachedStyle === undefined || cachedStyle !== style ) { - element.style.WebkitTransform = style; - element.style.MozTransform = style; - element.style.oTransform = style; - element.style.transform = style; + element.style.WebkitTransform = style; + element.style.MozTransform = style; + element.style.oTransform = style; + element.style.transform = style; + + cache.objects[ object.id ] = style; + + } if ( element.parentNode !== cameraElement ) { @@ -199,24 +214,36 @@ THREE.CSS3DRenderer = function () { var fov = 0.5 / Math.tan( THREE.Math.degToRad( camera.fov * 0.5 ) ) * _height; - domElement.style.WebkitPerspective = fov + "px"; - domElement.style.MozPerspective = fov + "px"; - domElement.style.oPerspective = fov + "px"; - domElement.style.perspective = fov + "px"; + if ( cache.camera.fov !== fov ) { + + domElement.style.WebkitPerspective = fov + "px"; + domElement.style.MozPerspective = fov + "px"; + domElement.style.oPerspective = fov + "px"; + domElement.style.perspective = fov + "px"; + + cache.camera.fov = fov; + + } scene.updateMatrixWorld(); - if ( camera.parent === undefined ) camera.updateMatrixWorld(); + if ( camera.parent === null ) camera.updateMatrixWorld(); camera.matrixWorldInverse.getInverse( camera.matrixWorld ); var style = "translate3d(0,0," + fov + "px)" + getCameraCSSMatrix( camera.matrixWorldInverse ) + " translate3d(" + _widthHalf + "px," + _heightHalf + "px, 0)"; - cameraElement.style.WebkitTransform = style; - cameraElement.style.MozTransform = style; - cameraElement.style.oTransform = style; - cameraElement.style.transform = style; + if ( cache.camera.style !== style ) { + + cameraElement.style.WebkitTransform = style; + cameraElement.style.MozTransform = style; + cameraElement.style.oTransform = style; + cameraElement.style.transform = style; + + cache.camera.style = style; + + } renderObject( scene, camera ); diff --git a/vendor/three-js/OrbitControls.js b/vendor/three-js/OrbitControls.js index fbe44d0..45d1b41 100644 --- a/vendor/three-js/OrbitControls.js +++ b/vendor/three-js/OrbitControls.js @@ -4,273 +4,266 @@ * @author alteredq / http://alteredqualia.com/ * @author WestLangley / http://github.com/WestLangley * @author erich666 / http://erichaines.com - * @author mrflix / http://felixniklas.de - * - * released under MIT License (MIT) */ -/*global THREE, console */ -// This set of controls performs orbiting, dollying (zooming), and panning. It maintains -// the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is -// supported. +// This set of controls performs orbiting, dollying (zooming), and panning. +// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default). // // Orbit - left mouse / touch: one finger move // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish // Pan - right mouse, or arrow keys / touch: three finter swipe -// -// This is a drop-in replacement for (most) TrackballControls used in examples. -// That is, include this js file and wherever you see: -// controls = new THREE.TrackballControls( camera ); -// controls.target.z = 150; -// Simple substitute "OrbitControls" and the control should work as-is. -THREE.OrbitControls = function ( object, domElement, localElement ) { +THREE.OrbitControls = function ( object, domElement ) { this.object = object; - this.domElement = ( domElement !== undefined ) ? domElement : document; - this.localElement = ( localElement !== undefined ) ? localElement : document; - // API + this.domElement = ( domElement !== undefined ) ? domElement : document; // Set to false to disable this control this.enabled = true; - // "target" sets the location of focus, where the control orbits around - // and where it pans with respect to. + // "target" sets the location of focus, where the object orbits around this.target = new THREE.Vector3(); - // center is old, deprecated; use "target" instead - this.center = this.target; - // This option actually enables dollying in and out; left as "zoom" for - // backwards compatibility - this.noZoom = false; - this.zoomSpeed = 1.0; - // Limits to how far you can dolly in and out + // How far you can dolly in and out ( PerspectiveCamera only ) this.minDistance = 0; this.maxDistance = Infinity; - // Set to true to disable this control - this.noRotate = false; + // How far you can zoom in and out ( OrthographicCamera only ) + this.minZoom = 0; + this.maxZoom = Infinity; + + // How far you can orbit vertically, upper and lower limits. + // Range is 0 to Math.PI radians. + this.minPolarAngle = 0; // radians + this.maxPolarAngle = Math.PI; // radians + + // How far you can orbit horizontally, upper and lower limits. + // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ]. + this.minAzimuthAngle = - Infinity; // radians + this.maxAzimuthAngle = Infinity; // radians + + // Set to true to enable damping (inertia) + // If damping is enabled, you must call controls.update() in your animation loop + this.enableDamping = false; + this.dampingFactor = 0.25; + + // This option actually enables dollying in and out; left as "zoom" for backwards compatibility. + // Set to false to disable zooming + this.enableZoom = true; + this.zoomSpeed = 1.0; + + // Set to false to disable rotating + this.enableRotate = true; this.rotateSpeed = 1.0; - // Set to true to disable this control - this.noPan = false; + // Set to false to disable panning + this.enablePan = true; this.keyPanSpeed = 7.0; // pixels moved per arrow key push // Set to true to automatically rotate around the target + // If auto-rotate is enabled, you must call controls.update() in your animation loop this.autoRotate = false; this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60 - // How far you can orbit vertically, upper and lower limits. - // Range is 0 to Math.PI radians. - this.minPolarAngle = 0; // radians - this.maxPolarAngle = Math.PI; // radians + // Set to false to disable use of the keys + this.enableKeys = true; - // Set to true to disable use of the keys - this.noKeys = false; // The four arrow keys this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }; - //////////// - // internals - - var scope = this; - - var EPS = 0.000001; - - var rotateStart = new THREE.Vector2(); - var rotateEnd = new THREE.Vector2(); - var rotateDelta = new THREE.Vector2(); + // Mouse buttons + this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT }; - var panStart = new THREE.Vector2(); - var panEnd = new THREE.Vector2(); - var panDelta = new THREE.Vector2(); + // for reset + this.target0 = this.target.clone(); + this.position0 = this.object.position.clone(); + this.zoom0 = this.object.zoom; - var dollyStart = new THREE.Vector2(); - var dollyEnd = new THREE.Vector2(); - var dollyDelta = new THREE.Vector2(); + // + // public methods + // - var phiDelta = 0; - var thetaDelta = 0; - var scale = 1; - var pan = new THREE.Vector3(); + this.getPolarAngle = function () { - var lastPosition = new THREE.Vector3(); + return phi; - var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 }; - var state = STATE.NONE; + }; - // events + this.getAzimuthalAngle = function () { - var changeEvent = { type: 'change' }; + return theta; + }; - this.rotateLeft = function ( angle ) { + this.reset = function () { - if ( angle === undefined ) { + scope.target.copy( scope.target0 ); + scope.object.position.copy( scope.position0 ); + scope.object.zoom = scope.zoom0; - angle = getAutoRotationAngle(); + scope.object.updateProjectionMatrix(); + scope.dispatchEvent( changeEvent ); - } + scope.update(); - thetaDelta -= angle; + state = STATE.NONE; }; - this.rotateUp = function ( angle ) { + // this method is exposed, but perhaps it would be better if we can make it private... + this.update = function() { - if ( angle === undefined ) { + var offset = new THREE.Vector3(); - angle = getAutoRotationAngle(); + // so camera.up is the orbit axis + var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) ); + var quatInverse = quat.clone().inverse(); - } + var lastPosition = new THREE.Vector3(); + var lastQuaternion = new THREE.Quaternion(); - phiDelta -= angle; + return function () { - }; + var position = scope.object.position; - // pass in distance in world space to move left - this.panLeft = function ( distance ) { + offset.copy( position ).sub( scope.target ); - var panOffset = new THREE.Vector3(); - var te = this.object.matrix.elements; - // get X column of matrix - panOffset.set( te[0], te[1], te[2] ); - panOffset.multiplyScalar(-distance); - - pan.add( panOffset ); + // rotate offset to "y-axis-is-up" space + offset.applyQuaternion( quat ); - }; + // angle from z-axis around y-axis + spherical.setFromVector3( offset ); - // pass in distance in world space to move up - this.panUp = function ( distance ) { + if ( scope.autoRotate && state === STATE.NONE ) { - var panOffset = new THREE.Vector3(); - var te = this.object.matrix.elements; - // get Y column of matrix - panOffset.set( te[4], te[5], te[6] ); - panOffset.multiplyScalar(distance); - - pan.add( panOffset ); - }; - - // main entry point; pass in Vector2 of change desired in pixel space, - // right and down are positive - this.pan = function ( delta ) { + rotateLeft( getAutoRotationAngle() ); - var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + } - if ( scope.object.fov !== undefined ) { + spherical.theta += sphericalDelta.theta; + spherical.phi += sphericalDelta.phi; - // perspective - var position = scope.object.position; - var offset = position.clone().sub( scope.target ); - var targetDistance = offset.length(); + // restrict theta to be between desired limits + spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) ); - // half of the fov is center to top of screen - targetDistance *= Math.tan( (scope.object.fov/2) * Math.PI / 180.0 ); - // we actually don't use screenWidth, since perspective camera is fixed to screen height - scope.panLeft( 2 * delta.x * targetDistance / element.clientHeight ); - scope.panUp( 2 * delta.y * targetDistance / element.clientHeight ); + // restrict phi to be between desired limits + spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) ); - } else if ( scope.object.top !== undefined ) { + spherical.makeSafe(); - // orthographic - scope.panLeft( delta.x * (scope.object.right - scope.object.left) / element.clientWidth ); - scope.panUp( delta.y * (scope.object.top - scope.object.bottom) / element.clientHeight ); - } else { + spherical.radius *= scale; - // camera neither orthographic or perspective - warn user - console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); + // restrict radius to be between desired limits + spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) ); - } + // move target to panned location + scope.target.add( panOffset ); - }; + offset.setFromSpherical( spherical ); - this.dollyIn = function ( dollyScale ) { + // rotate offset back to "camera-up-vector-is-up" space + offset.applyQuaternion( quatInverse ); - if ( dollyScale === undefined ) { + position.copy( scope.target ).add( offset ); - dollyScale = getZoomScale(); + scope.object.lookAt( scope.target ); - } + if ( scope.enableDamping === true ) { - scale /= dollyScale; + sphericalDelta.theta *= ( 1 - scope.dampingFactor ); + sphericalDelta.phi *= ( 1 - scope.dampingFactor ); - }; + } else { - this.dollyOut = function ( dollyScale ) { + sphericalDelta.set( 0, 0, 0 ); - if ( dollyScale === undefined ) { + } - dollyScale = getZoomScale(); + scale = 1; + panOffset.set( 0, 0, 0 ); - } + // update condition is: + // min(camera displacement, camera rotation in radians)^2 > EPS + // using small-angle approximation cos(x/2) = 1 - x^2 / 8 - scale *= dollyScale; + if ( zoomChanged || + lastPosition.distanceToSquared( scope.object.position ) > EPS || + 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) { - }; + scope.dispatchEvent( changeEvent ); - this.update = function () { + lastPosition.copy( scope.object.position ); + lastQuaternion.copy( scope.object.quaternion ); + zoomChanged = false; - var position = this.object.position; - var offset = position.clone().sub( this.target ); + return true; - // angle from z-axis around y-axis + } - var theta = Math.atan2( offset.x, offset.z ); + return false; - // angle from y-axis + }; - var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y ); + }(); - if ( this.autoRotate ) { + this.dispose = function() { - this.rotateLeft( getAutoRotationAngle() ); + scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false ); + scope.domElement.removeEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.removeEventListener( 'mousewheel', onMouseWheel, false ); + scope.domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox - } + scope.domElement.removeEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.removeEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.removeEventListener( 'touchmove', onTouchMove, false ); - theta += thetaDelta; - phi += phiDelta; + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + document.removeEventListener( 'mouseout', onMouseUp, false ); - // restrict phi to be between desired limits - phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) ); + window.removeEventListener( 'keydown', onKeyDown, false ); - // restrict phi to be betwee EPS and PI-EPS - phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) ); + //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here? - var radius = offset.length() * scale; + }; - // restrict radius to be between desired limits - radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) ); - - // move target to panned location - this.target.add( pan ); + // + // internals + // - offset.x = radius * Math.sin( phi ) * Math.sin( theta ); - offset.y = radius * Math.cos( phi ); - offset.z = radius * Math.sin( phi ) * Math.cos( theta ); + var scope = this; - position.copy( this.target ).add( offset ); + var changeEvent = { type: 'change' }; + var startEvent = { type: 'start' }; + var endEvent = { type: 'end' }; - this.object.lookAt( this.target ); + var STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 }; - thetaDelta = 0; - phiDelta = 0; - scale = 1; - pan.set(0,0,0); + var state = STATE.NONE; - if ( lastPosition.distanceTo( this.object.position ) > 0 ) { + var EPS = 0.000001; - this.dispatchEvent( changeEvent ); + // current position in spherical coordinates + var spherical = new THREE.Spherical(); + var sphericalDelta = new THREE.Spherical(); - lastPosition.copy( this.object.position ); + var scale = 1; + var panOffset = new THREE.Vector3(); + var zoomChanged = false; - } + 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 dollyStart = new THREE.Vector2(); + var dollyEnd = new THREE.Vector2(); + var dollyDelta = new THREE.Vector2(); function getAutoRotationAngle() { @@ -284,122 +277,241 @@ THREE.OrbitControls = function ( object, domElement, localElement ) { } - function onMouseDown( event ) { + function rotateLeft( angle ) { - if ( scope.enabled === false ) { return; } - event.preventDefault(); + sphericalDelta.theta -= angle; - if ( event.button === 0 ) { - if ( scope.noRotate === true ) { return; } + } - state = STATE.ROTATE; + function rotateUp( angle ) { - rotateStart.set( event.clientX, event.clientY ); + sphericalDelta.phi -= angle; - } else if ( event.button === 1 ) { - if ( scope.noZoom === true ) { return; } + } - state = STATE.DOLLY; + var panLeft = function() { - dollyStart.set( event.clientX, event.clientY ); + var v = new THREE.Vector3(); - } else if ( event.button === 2 ) { - if ( scope.noPan === true ) { return; } + return function panLeft( distance, objectMatrix ) { - state = STATE.PAN; + v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix + v.multiplyScalar( - distance ); - panStart.set( event.clientX, event.clientY ); + panOffset.add( v ); - } + }; - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be - scope.domElement.addEventListener( 'mousemove', onMouseMove, false ); - scope.domElement.addEventListener( 'mouseup', onMouseUp, false ); + }(); - } + var panUp = function() { - function onMouseMove( event ) { + var v = new THREE.Vector3(); - if ( scope.enabled === false ) return; + return function panUp( distance, objectMatrix ) { - event.preventDefault(); + v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix + v.multiplyScalar( distance ); - var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + panOffset.add( v ); - if ( state === STATE.ROTATE ) { + }; - if ( scope.noRotate === true ) return; + }(); - rotateEnd.set( event.clientX, event.clientY ); - rotateDelta.subVectors( rotateEnd, rotateStart ); + // deltaX and deltaY are in pixels; right and down are positive + var pan = function() { - // rotating across whole screen goes 360 degrees around - scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); - // rotating up and down along whole screen attempts to go 360, but limited to 180 - scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + var offset = new THREE.Vector3(); - rotateStart.copy( rotateEnd ); + return function( deltaX, deltaY ) { - } else if ( state === STATE.DOLLY ) { + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + if ( scope.object instanceof THREE.PerspectiveCamera ) { - if ( scope.noZoom === true ) return; + // perspective + var position = scope.object.position; + offset.copy( position ).sub( scope.target ); + var targetDistance = offset.length(); - dollyEnd.set( event.clientX, event.clientY ); - dollyDelta.subVectors( dollyEnd, dollyStart ); + // half of the fov is center to top of screen + targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 ); - if ( dollyDelta.y > 0 ) { + // we actually don't use screenWidth, since perspective camera is fixed to screen height + panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix ); + panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix ); - scope.dollyIn(); + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + // orthographic + panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix ); + panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix ); } else { - scope.dollyOut(); + // camera neither orthographic nor perspective + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' ); + scope.enablePan = false; } - dollyStart.copy( dollyEnd ); + }; - } else if ( state === STATE.PAN ) { + }(); + + function dollyIn( dollyScale ) { + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale /= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { + + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { - if ( scope.noPan === true ) return; + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; - panEnd.set( event.clientX, event.clientY ); - panDelta.subVectors( panEnd, panStart ); - - scope.pan( panDelta ); + } + + } + + function dollyOut( dollyScale ) { + + if ( scope.object instanceof THREE.PerspectiveCamera ) { + + scale *= dollyScale; + + } else if ( scope.object instanceof THREE.OrthographicCamera ) { - panStart.copy( panEnd ); + scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) ); + scope.object.updateProjectionMatrix(); + zoomChanged = true; + + } else { + + console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' ); + scope.enableZoom = false; } - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be + } + + // + // event callbacks - update the object state + // + + function handleMouseDownRotate( event ) { + + //console.log( 'handleMouseDownRotate' ); + + rotateStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownDolly( event ) { + + //console.log( 'handleMouseDownDolly' ); + + dollyStart.set( event.clientX, event.clientY ); + + } + + function handleMouseDownPan( event ) { + + //console.log( 'handleMouseDownPan' ); + + panStart.set( event.clientX, event.clientY ); + + } + + function handleMouseMoveRotate( event ) { + + //console.log( 'handleMouseMoveRotate' ); + + rotateEnd.set( event.clientX, event.clientY ); + rotateDelta.subVectors( rotateEnd, rotateStart ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + // rotating across whole screen goes 360 degrees around + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); + + // rotating up and down along whole screen attempts to go 360, but limited to 180 + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + + rotateStart.copy( rotateEnd ); + scope.update(); } - function onMouseUp( /* event */ ) { + function handleMouseMoveDolly( event ) { - if ( scope.enabled === false ) return; + //console.log( 'handleMouseMoveDolly' ); - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be - scope.domElement.removeEventListener( 'mousemove', onMouseMove, false ); - scope.domElement.removeEventListener( 'mouseup', onMouseUp, false ); + dollyEnd.set( event.clientX, event.clientY ); - state = STATE.NONE; + dollyDelta.subVectors( dollyEnd, dollyStart ); + + if ( dollyDelta.y > 0 ) { + + dollyIn( getZoomScale() ); + + } else if ( dollyDelta.y < 0 ) { + + dollyOut( getZoomScale() ); + + } + + dollyStart.copy( dollyEnd ); + + scope.update(); } - function onMouseWheel( event ) { + function handleMouseMovePan( event ) { + + //console.log( 'handleMouseMovePan' ); + + panEnd.set( event.clientX, event.clientY ); + + panDelta.subVectors( panEnd, panStart ); + + pan( panDelta.x, panDelta.y ); - if ( scope.enabled === false || scope.noZoom === true ) return; + panStart.copy( panEnd ); + + scope.update(); + + } + + function handleMouseUp( event ) { + + //console.log( 'handleMouseUp' ); + + } + + function handleMouseWheel( event ) { + + //console.log( 'handleMouseWheel' ); var delta = 0; - if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9 + if ( event.wheelDelta !== undefined ) { + + // WebKit / Opera / Explorer 9 delta = event.wheelDelta; - } else if ( event.detail ) { // Firefox + } else if ( event.detail !== undefined ) { + + // Firefox delta = - event.detail; @@ -407,181 +519,519 @@ THREE.OrbitControls = function ( object, domElement, localElement ) { if ( delta > 0 ) { - scope.dollyOut(); + dollyOut( getZoomScale() ); - } else { + } else if ( delta < 0 ) { - scope.dollyIn(); + dollyIn( getZoomScale() ); } + scope.update(); + } - function onKeyDown( event ) { + function handleKeyDown( event ) { - if ( scope.enabled === false ) { return; } - if ( scope.noKeys === true ) { return; } - if ( scope.noPan === true ) { return; } + //console.log( 'handleKeyDown' ); - // pan a pixel - I guess for precise positioning? - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be - var needUpdate = false; - switch ( event.keyCode ) { case scope.keys.UP: - scope.pan( new THREE.Vector2( 0, scope.keyPanSpeed ) ); - needUpdate = true; + pan( 0, scope.keyPanSpeed ); + scope.update(); break; + case scope.keys.BOTTOM: - scope.pan( new THREE.Vector2( 0, -scope.keyPanSpeed ) ); - needUpdate = true; + pan( 0, - scope.keyPanSpeed ); + scope.update(); break; + case scope.keys.LEFT: - scope.pan( new THREE.Vector2( scope.keyPanSpeed, 0 ) ); - needUpdate = true; + pan( scope.keyPanSpeed, 0 ); + scope.update(); break; + case scope.keys.RIGHT: - scope.pan( new THREE.Vector2( -scope.keyPanSpeed, 0 ) ); - needUpdate = true; + pan( - scope.keyPanSpeed, 0 ); + scope.update(); break; + } - // Greggman fix: https://github.com/greggman/three.js/commit/fde9f9917d6d8381f06bf22cdff766029d1761be - if ( needUpdate ) { + } + + function handleTouchStartRotate( event ) { + + //console.log( 'handleTouchStartRotate' ); + + rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + } + + function handleTouchStartDolly( event ) { + + //console.log( 'handleTouchStartDolly' ); + + 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 ); + + } + + function handleTouchStartPan( event ) { + + //console.log( 'handleTouchStartPan' ); + + panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + } + + function handleTouchMoveRotate( event ) { + + //console.log( 'handleTouchMoveRotate' ); + + rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + rotateDelta.subVectors( rotateEnd, rotateStart ); + + var element = scope.domElement === document ? scope.domElement.body : scope.domElement; + + // rotating across whole screen goes 360 degrees around + rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); + + // rotating up and down along whole screen attempts to go 360, but limited to 180 + rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + + rotateStart.copy( rotateEnd ); + + scope.update(); + + } + + function handleTouchMoveDolly( event ) { - scope.update(); + //console.log( 'handleTouchMoveDolly' ); + + 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 ) { + + dollyOut( getZoomScale() ); + + } else if ( dollyDelta.y < 0 ) { + + dollyIn( getZoomScale() ); } + dollyStart.copy( dollyEnd ); + + scope.update(); + + } + + function handleTouchMovePan( event ) { + + //console.log( 'handleTouchMovePan' ); + + panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); + + panDelta.subVectors( panEnd, panStart ); + + pan( panDelta.x, panDelta.y ); + + panStart.copy( panEnd ); + + scope.update(); + + } + + function handleTouchEnd( event ) { + + //console.log( 'handleTouchEnd' ); + } - - function touchstart( event ) { - if ( scope.enabled === false ) { return; } + // + // event handlers - FSM: listen for events and reset state + // + + function onMouseDown( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + if ( event.button === scope.mouseButtons.ORBIT ) { + + if ( scope.enableRotate === false ) return; + + handleMouseDownRotate( event ); + + state = STATE.ROTATE; + + } else if ( event.button === scope.mouseButtons.ZOOM ) { + + if ( scope.enableZoom === false ) return; + + handleMouseDownDolly( event ); + + state = STATE.DOLLY; + + } else if ( event.button === scope.mouseButtons.PAN ) { + + if ( scope.enablePan === false ) return; + + handleMouseDownPan( event ); + + state = STATE.PAN; + + } + + if ( state !== STATE.NONE ) { + + document.addEventListener( 'mousemove', onMouseMove, false ); + document.addEventListener( 'mouseup', onMouseUp, false ); + document.addEventListener( 'mouseout', onMouseUp, false ); + + scope.dispatchEvent( startEvent ); + + } + + } + + function onMouseMove( event ) { + + if ( scope.enabled === false ) return; + + event.preventDefault(); + + if ( state === STATE.ROTATE ) { + + if ( scope.enableRotate === false ) return; + + handleMouseMoveRotate( event ); + + } else if ( state === STATE.DOLLY ) { + + if ( scope.enableZoom === false ) return; + + handleMouseMoveDolly( event ); + + } else if ( state === STATE.PAN ) { + + if ( scope.enablePan === false ) return; + + handleMouseMovePan( event ); + + } + + } + + function onMouseUp( event ) { + + if ( scope.enabled === false ) return; + + handleMouseUp( event ); + + document.removeEventListener( 'mousemove', onMouseMove, false ); + document.removeEventListener( 'mouseup', onMouseUp, false ); + document.removeEventListener( 'mouseout', onMouseUp, false ); + + scope.dispatchEvent( endEvent ); + + state = STATE.NONE; + + } + + function onMouseWheel( event ) { + + if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return; + + event.preventDefault(); + event.stopPropagation(); + + handleMouseWheel( event ); + + scope.dispatchEvent( startEvent ); // not sure why these are here... + scope.dispatchEvent( endEvent ); + + } + + function onKeyDown( event ) { + + if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return; + + handleKeyDown( event ); + + } + + function onTouchStart( event ) { + + if ( scope.enabled === false ) return; switch ( event.touches.length ) { case 1: // one-fingered touch: rotate - if ( scope.noRotate === true ) { return; } + + if ( scope.enableRotate === false ) return; + + handleTouchStartRotate( event ); state = STATE.TOUCH_ROTATE; - rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); break; case 2: // two-fingered touch: dolly - if ( scope.noZoom === true ) { return; } + + if ( scope.enableZoom === false ) return; + + handleTouchStartDolly( event ); 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: // three-fingered touch: pan - if ( scope.noPan === true ) { return; } + + if ( scope.enablePan === false ) return; + + handleTouchStartPan( event ); state = STATE.TOUCH_PAN; - panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); break; default: + state = STATE.NONE; } + + if ( state !== STATE.NONE ) { + + scope.dispatchEvent( startEvent ); + + } + } - function touchmove( event ) { + function onTouchMove( event ) { - if ( scope.enabled === false ) { return; } + 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: // one-fingered touch: rotate - 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 ); + if ( scope.enableRotate === false ) return; + if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?... - // rotating across whole screen goes 360 degrees around - scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed ); - // rotating up and down along whole screen attempts to go 360, but limited to 180 - scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed ); + handleTouchMoveRotate( event ); - rotateStart.copy( rotateEnd ); break; case 2: // two-fingered touch: dolly - 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 ) { + if ( scope.enableZoom === false ) return; + if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?... - scope.dollyOut(); + handleTouchMoveDolly( event ); - } else { - - scope.dollyIn(); - - } - - dollyStart.copy( dollyEnd ); break; case 3: // three-fingered touch: pan - 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 ); + if ( scope.enablePan === false ) return; + if ( state !== STATE.TOUCH_PAN ) return; // is this needed?... + + handleTouchMovePan( event ); - panStart.copy( panEnd ); break; default: + state = STATE.NONE; } } - function touchend( /* event */ ) { + function onTouchEnd( event ) { - if ( scope.enabled === false ) { return; } + if ( scope.enabled === false ) return; + + handleTouchEnd( event ); + + scope.dispatchEvent( endEvent ); state = STATE.NONE; + } - this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); - this.localElement.addEventListener( 'mousedown', onMouseDown, false ); - this.domElement.addEventListener( 'mousewheel', onMouseWheel, false ); - this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox + function onContextMenu( event ) { + + event.preventDefault(); + + } - this.domElement.addEventListener( 'keydown', onKeyDown, false ); + // - this.localElement.addEventListener( 'touchstart', touchstart, false ); - this.domElement.addEventListener( 'touchend', touchend, false ); - this.domElement.addEventListener( 'touchmove', touchmove, false ); + scope.domElement.addEventListener( 'contextmenu', onContextMenu, false ); + + scope.domElement.addEventListener( 'mousedown', onMouseDown, false ); + scope.domElement.addEventListener( 'mousewheel', onMouseWheel, false ); + scope.domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox + + scope.domElement.addEventListener( 'touchstart', onTouchStart, false ); + scope.domElement.addEventListener( 'touchend', onTouchEnd, false ); + scope.domElement.addEventListener( 'touchmove', onTouchMove, false ); + + window.addEventListener( 'keydown', onKeyDown, false ); + + // force an update at start + + this.update(); }; -THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); \ No newline at end of file +THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype ); +THREE.OrbitControls.prototype.constructor = THREE.OrbitControls; + +Object.defineProperties( THREE.OrbitControls.prototype, { + + center: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .center has been renamed to .target' ); + return this.target; + + } + + }, + + // backward compatibility + + noZoom: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + return ! this.enableZoom; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' ); + this.enableZoom = ! value; + + } + + }, + + noRotate: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + return ! this.enableRotate; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' ); + this.enableRotate = ! value; + + } + + }, + + noPan: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + return ! this.enablePan; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' ); + this.enablePan = ! value; + + } + + }, + + noKeys: { + + get: function () { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + return ! this.enableKeys; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' ); + this.enableKeys = ! value; + + } + + }, + + staticMoving : { + + get: function () { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + return ! this.constraint.enableDamping; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' ); + this.constraint.enableDamping = ! value; + + } + + }, + + dynamicDampingFactor : { + + get: function () { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + return this.constraint.dampingFactor; + + }, + + set: function ( value ) { + + console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' ); + this.constraint.dampingFactor = value; + + } + + } + +} ); diff --git a/vendor/three-js/Projector.js b/vendor/three-js/Projector.js index ac55d7a..c05f56b 100644 --- a/vendor/three-js/Projector.js +++ b/vendor/three-js/Projector.js @@ -161,7 +161,7 @@ THREE.Projector = function () { var normalMatrix = new THREE.Matrix3(); - var setObject = function ( value ) { + function setObject( value ) { object = value; material = object.material; @@ -171,9 +171,9 @@ THREE.Projector = function () { normals.length = 0; uvs.length = 0; - }; + } - var projectVertex = function ( vertex ) { + function projectVertex( vertex ) { var position = vertex.position; var positionWorld = vertex.positionWorld; @@ -192,30 +192,30 @@ THREE.Projector = function () { positionScreen.y >= - 1 && positionScreen.y <= 1 && positionScreen.z >= - 1 && positionScreen.z <= 1; - }; + } - var pushVertex = function ( x, y, z ) { + function pushVertex( x, y, z ) { _vertex = getNextVertexInPool(); _vertex.position.set( x, y, z ); projectVertex( _vertex ); - }; + } - var pushNormal = function ( x, y, z ) { + function pushNormal( x, y, z ) { normals.push( x, y, z ); - }; + } - var pushUv = function ( x, y ) { + function pushUv( x, y ) { uvs.push( x, y ); - }; + } - var checkTriangleVisibility = function ( v1, v2, v3 ) { + function checkTriangleVisibility( v1, v2, v3 ) { if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true; @@ -223,20 +223,20 @@ THREE.Projector = function () { _points3[ 1 ] = v2.positionScreen; _points3[ 2 ] = v3.positionScreen; - return _clipBox.isIntersectionBox( _boundingBox.setFromPoints( _points3 ) ); + return _clipBox.intersectsBox( _boundingBox.setFromPoints( _points3 ) ); - }; + } - var checkBackfaceCulling = function ( v1, v2, v3 ) { + function checkBackfaceCulling( v1, v2, v3 ) { return ( ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) - ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0; - }; + } - var pushLine = function ( a, b ) { + function pushLine( a, b ) { var v1 = _vertexPool[ a ]; var v2 = _vertexPool[ b ]; @@ -253,9 +253,9 @@ THREE.Projector = function () { _renderData.elements.push( _line ); - }; + } - var pushTriangle = function ( a, b, c ) { + function pushTriangle( a, b, c ) { var v1 = _vertexPool[ a ]; var v2 = _vertexPool[ b ]; @@ -298,7 +298,7 @@ THREE.Projector = function () { } - }; + } return { setObject: setObject, @@ -478,7 +478,7 @@ THREE.Projector = function () { var material = object.material; - var isFaceMaterial = material instanceof THREE.MeshFaceMaterial; + var isFaceMaterial = material instanceof THREE.MultiMaterial; var objectMaterials = isFaceMaterial === true ? object.material : null; for ( var v = 0, vl = vertices.length; v < vl; v ++ ) { diff --git a/vendor/three-js/RaytracingRenderer.js b/vendor/three-js/RaytracingRenderer.js index cbc7ad2..3fb3d4e 100644 --- a/vendor/three-js/RaytracingRenderer.js +++ b/vendor/three-js/RaytracingRenderer.js @@ -1,6 +1,9 @@ /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ + * RaytracingRenderer renders by raytracing it's scene. However, it does not + * compute the pixels itself but it hands off and coordinates the taks for workers. + * The workers compute the pixel values and this renderer simply paints it to the Canvas. + * + * @author zz85 / http://github.com/zz85 */ THREE.RaytracingRenderer = function ( parameters ) { @@ -10,6 +13,8 @@ THREE.RaytracingRenderer = function ( parameters ) { parameters = parameters || {}; var scope = this; + var pool = []; + var renderering = false; var canvas = document.createElement( 'canvas' ); var context = canvas.getContext( '2d', { @@ -23,469 +28,200 @@ THREE.RaytracingRenderer = function ( parameters ) { var clearColor = new THREE.Color( 0x000000 ); - var origin = new THREE.Vector3(); - var direction = new THREE.Vector3(); - - var cameraPosition = new THREE.Vector3(); - - var raycaster = new THREE.Raycaster( origin, direction ); - var raycasterLight = new THREE.Raycaster(); - - var perspective; - var modelViewMatrix = new THREE.Matrix4(); - var cameraNormalMatrix = new THREE.Matrix3(); - - var objects; - var lights = []; - var cache = {}; - - var animationFrameId = null; - this.domElement = canvas; this.autoClear = true; - this.setClearColor = function ( color, alpha ) { - - clearColor.set( color ); - - }; - - this.setPixelRatio = function () {}; - - this.setSize = function ( width, height ) { - - canvas.width = width; - canvas.height = height; - - canvasWidth = canvas.width; - canvasHeight = canvas.height; - - canvasWidthHalf = Math.floor( canvasWidth / 2 ); - canvasHeightHalf = Math.floor( canvasHeight / 2 ); - - context.fillStyle = 'white'; - - }; - - this.setSize( canvas.width, canvas.height ); - - this.clear = function () { - - }; - - // - - var spawnRay = ( function () { - - var diffuseColor = new THREE.Color(); - var specularColor = new THREE.Color(); - var lightColor = new THREE.Color(); - var schlick = new THREE.Color(); - - var lightContribution = new THREE.Color(); - - var eyeVector = new THREE.Vector3(); - var lightVector = new THREE.Vector3(); - var normalVector = new THREE.Vector3(); - var halfVector = new THREE.Vector3(); - - var localPoint = new THREE.Vector3(); - var reflectionVector = new THREE.Vector3(); - - var tmpVec = new THREE.Vector3(); - - var tmpColor = []; - - for ( var i = 0; i < maxRecursionDepth; i ++ ) { - - tmpColor[ i ] = new THREE.Color(); - - } - - return function spawnRay( rayOrigin, rayDirection, outputColor, recursionDepth ) { - - var ray = raycaster.ray; - - ray.origin = rayOrigin; - ray.direction = rayDirection; - - // - - var rayLight = raycasterLight.ray; - - // - - outputColor.setRGB( 0, 0, 0 ); - - // - - var intersections = raycaster.intersectObjects( objects, true ); - - // ray didn't find anything - // (here should come setting of background color?) - - if ( intersections.length === 0 ) { - - return; - - } - - // ray hit - - var intersection = intersections[ 0 ]; - - var point = intersection.point; - var object = intersection.object; - var material = object.material; - var face = intersection.face; - - var vertices = object.geometry.vertices; - - // - - var _object = cache[ object.id ]; - - localPoint.copy( point ).applyMatrix4( _object.inverseMatrix ); - eyeVector.subVectors( raycaster.ray.origin, point ).normalize(); - - // resolve pixel diffuse color + var workers = parameters.workers; + var blockSize = parameters.blockSize || 64; + this.randomize = parameters.randomize; - if ( material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshBasicMaterial ) { - - diffuseColor.copyGammaToLinear( material.color ); - - } else { - - diffuseColor.setRGB( 1, 1, 1 ); - - } - - if ( material.vertexColors === THREE.FaceColors ) { - - diffuseColor.multiply( face.color ); - - } - - // compute light shading - - rayLight.origin.copy( point ); - - if ( material instanceof THREE.MeshBasicMaterial ) { - - for ( var i = 0, l = lights.length; i < l; i ++ ) { - - var light = lights[ i ]; - - lightVector.setFromMatrixPosition( light.matrixWorld ); - lightVector.sub( point ); - - rayLight.direction.copy( lightVector ).normalize(); - - var intersections = raycasterLight.intersectObjects( objects, true ); - - // point in shadow - - if ( intersections.length > 0 ) continue; - - // point visible - - outputColor.add( diffuseColor ); - - } + var toRender = [], workerId = 0, sceneId = 0; - } else if ( material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.MeshPhongMaterial ) { + console.log( '%cSpinning off ' + workers + ' Workers ', 'font-size: 20px; background: black; color: white; font-family: monospace;' ); - var normalComputed = false; + this.setWorkers = function( w ) { - for ( var i = 0, l = lights.length; i < l; i ++ ) { + workers = w || navigator.hardwareConcurrency || 4; - var light = lights[ i ]; + while ( pool.length < workers ) { + var worker = new Worker( parameters.workerPath ); + worker.id = workerId++; - lightColor.copyGammaToLinear( light.color ); + worker.onmessage = function( e ) { - lightVector.setFromMatrixPosition( light.matrixWorld ); - lightVector.sub( point ); + var data = e.data; - rayLight.direction.copy( lightVector ).normalize(); + if ( ! data ) return; - var intersections = raycasterLight.intersectObjects( objects, true ); + if ( data.blockSize && sceneId == data.sceneId ) { // we match sceneId here to be sure - // point in shadow + var imagedata = new ImageData( new Uint8ClampedArray( data.data ), data.blockSize, data.blockSize ); + context.putImageData( imagedata, data.blockX, data.blockY ); - if ( intersections.length > 0 ) continue; + // completed - // point lit + console.log( 'Worker ' + this.id, data.time / 1000, ( Date.now() - reallyThen ) / 1000 + ' s' ); - if ( normalComputed === false ) { + if ( pool.length > workers ) { - // the same normal can be reused for all lights - // (should be possible to cache even more) - - computePixelNormal( normalVector, localPoint, material.shading, face, vertices ); - normalVector.applyMatrix3( _object.normalMatrix ).normalize(); - - normalComputed = true; - - } - - // compute attenuation - - var attenuation = 1.0; - - if ( light.physicalAttenuation === true ) { - - attenuation = lightVector.length(); - attenuation = 1.0 / ( attenuation * attenuation ); + pool.splice( pool.indexOf( this ), 1 ); + return this.terminate(); } - lightVector.normalize(); - - // compute diffuse - - var dot = Math.max( normalVector.dot( lightVector ), 0 ); - var diffuseIntensity = dot * light.intensity; - - lightContribution.copy( diffuseColor ); - lightContribution.multiply( lightColor ); - lightContribution.multiplyScalar( diffuseIntensity * attenuation ); - - outputColor.add( lightContribution ); - - // compute specular - - if ( material instanceof THREE.MeshPhongMaterial ) { - - halfVector.addVectors( lightVector, eyeVector ).normalize(); - - var dotNormalHalf = Math.max( normalVector.dot( halfVector ), 0.0 ); - var specularIntensity = Math.max( Math.pow( dotNormalHalf, material.shininess ), 0.0 ) * diffuseIntensity; - - var specularNormalization = ( material.shininess + 2.0 ) / 8.0; - - specularColor.copyGammaToLinear( material.specular ); - - var alpha = Math.pow( Math.max( 1.0 - lightVector.dot( halfVector ), 0.0 ), 5.0 ); - - schlick.r = specularColor.r + ( 1.0 - specularColor.r ) * alpha; - schlick.g = specularColor.g + ( 1.0 - specularColor.g ) * alpha; - schlick.b = specularColor.b + ( 1.0 - specularColor.b ) * alpha; - - lightContribution.copy( schlick ); - - lightContribution.multiply( lightColor ); - lightContribution.multiplyScalar( specularNormalization * specularIntensity * attenuation ); - outputColor.add( lightContribution ); - - } + renderNext( this ); } } - // reflection / refraction - - var reflectivity = material.reflectivity; - - if ( ( material.mirror || material.glass ) && reflectivity > 0 && recursionDepth < maxRecursionDepth ) { - - if ( material.mirror ) { - - reflectionVector.copy( rayDirection ); - reflectionVector.reflect( normalVector ); - - } else if ( material.glass ) { + worker.color = new THREE.Color().setHSL( Math.random() , 0.8, 0.8 ).getHexString(); + pool.push( worker ); - var eta = material.refractionRatio; + if ( renderering ) { - var dotNI = rayDirection.dot( normalVector ); - var k = 1.0 - eta * eta * ( 1.0 - dotNI * dotNI ); + updateSettings( worker ); - if ( k < 0.0 ) { + worker.postMessage( { + scene: sceneJSON, + camera: cameraJSON, + annex: materials, + sceneId: sceneId + } ); - reflectionVector.set( 0, 0, 0 ); - - } else { - - reflectionVector.copy( rayDirection ); - reflectionVector.multiplyScalar( eta ); - - var alpha = eta * dotNI + Math.sqrt( k ); - tmpVec.copy( normalVector ); - tmpVec.multiplyScalar( alpha ); - reflectionVector.sub( tmpVec ); - - } - - } - - var theta = Math.max( eyeVector.dot( normalVector ), 0.0 ); - var rf0 = reflectivity; - var fresnel = rf0 + ( 1.0 - rf0 ) * Math.pow( ( 1.0 - theta ), 5.0 ); - - var weight = fresnel; - - var zColor = tmpColor[ recursionDepth ]; - - spawnRay( point, reflectionVector, zColor, recursionDepth + 1 ); - - if ( material.specular !== undefined ) { - - zColor.multiply( material.specular ); - - } - - zColor.multiplyScalar( weight ); - outputColor.multiplyScalar( 1 - weight ); - outputColor.add( zColor ); + renderNext( worker ); } - }; - - }() ); + } - var computePixelNormal = ( function () { + if ( ! renderering ) { - var tmpVec1 = new THREE.Vector3(); - var tmpVec2 = new THREE.Vector3(); - var tmpVec3 = new THREE.Vector3(); + while ( pool.length > workers ) { - return function computePixelNormal( outputVector, point, shading, face, vertices ) { + pool.pop().terminate(); - var faceNormal = face.normal; - var vertexNormals = face.vertexNormals; + } - if ( shading === THREE.FlatShading ) { + } - outputVector.copy( faceNormal ); + }; - } else if ( shading === THREE.SmoothShading ) { + this.setWorkers( workers ); - // compute barycentric coordinates + this.setClearColor = function ( color, alpha ) { - var vA = vertices[ face.a ]; - var vB = vertices[ face.b ]; - var vC = vertices[ face.c ]; + clearColor.set( color ); - tmpVec3.crossVectors( tmpVec1.subVectors( vB, vA ), tmpVec2.subVectors( vC, vA ) ); - var areaABC = faceNormal.dot( tmpVec3 ); + }; - tmpVec3.crossVectors( tmpVec1.subVectors( vB, point ), tmpVec2.subVectors( vC, point ) ); - var areaPBC = faceNormal.dot( tmpVec3 ); - var a = areaPBC / areaABC; + this.setPixelRatio = function () {}; - tmpVec3.crossVectors( tmpVec1.subVectors( vC, point ), tmpVec2.subVectors( vA, point ) ); - var areaPCA = faceNormal.dot( tmpVec3 ); - var b = areaPCA / areaABC; + this.setSize = function ( width, height ) { - var c = 1.0 - a - b; + canvas.width = width; + canvas.height = height; - // compute interpolated vertex normal + canvasWidth = canvas.width; + canvasHeight = canvas.height; - tmpVec1.copy( vertexNormals[ 0 ] ); - tmpVec1.multiplyScalar( a ); + canvasWidthHalf = Math.floor( canvasWidth / 2 ); + canvasHeightHalf = Math.floor( canvasHeight / 2 ); - tmpVec2.copy( vertexNormals[ 1 ] ); - tmpVec2.multiplyScalar( b ); + context.fillStyle = 'white'; - tmpVec3.copy( vertexNormals[ 2 ] ); - tmpVec3.multiplyScalar( c ); + pool.forEach( updateSettings ); - outputVector.addVectors( tmpVec1, tmpVec2 ); - outputVector.add( tmpVec3 ); + }; - } + this.setSize( canvas.width, canvas.height ); - }; + this.clear = function () { - }() ); + }; - var renderBlock = ( function () { + // - var blockSize = 64; + var totalBlocks, xblocks, yblocks; - var canvasBlock = document.createElement( 'canvas' ); - canvasBlock.width = blockSize; - canvasBlock.height = blockSize; + function updateSettings( worker ) { - var contextBlock = canvasBlock.getContext( '2d', { + worker.postMessage( { - alpha: parameters.alpha === true + init: [ canvasWidth, canvasHeight ], + worker: worker.id, + // workers: pool.length, + blockSize: blockSize } ); - var imagedata = contextBlock.getImageData( 0, 0, blockSize, blockSize ); - var data = imagedata.data; - - var pixelColor = new THREE.Color(); + } - return function renderBlock( blockX, blockY ) { + function renderNext( worker ) { + if ( ! toRender.length ) { - var index = 0; + renderering = false; + return scope.dispatchEvent( { type: "complete" } ); - for ( var y = 0; y < blockSize; y ++ ) { - - for ( var x = 0; x < blockSize; x ++, index += 4 ) { - - // spawn primary ray at pixel position + } - origin.copy( cameraPosition ); + var current = toRender.pop(); - direction.set( x + blockX - canvasWidthHalf, - ( y + blockY - canvasHeightHalf ), - perspective ); - direction.applyMatrix3( cameraNormalMatrix ).normalize(); + var blockX = ( current % xblocks ) * blockSize; + var blockY = ( current / xblocks | 0 ) * blockSize; - spawnRay( origin, direction, pixelColor, 0 ); + worker.postMessage( { + render: true, + x: blockX, + y: blockY, + sceneId: sceneId + } ); - // convert from linear to gamma + context.fillStyle = '#' + worker.color; - data[ index ] = Math.sqrt( pixelColor.r ) * 255; - data[ index + 1 ] = Math.sqrt( pixelColor.g ) * 255; - data[ index + 2 ] = Math.sqrt( pixelColor.b ) * 255; + context.fillRect( blockX, blockY, blockSize, blockSize ); - } + } - } + var materials = {}; - context.putImageData( imagedata, blockX, blockY ); + var sceneJSON, cameraJSON, reallyThen; - blockX += blockSize; + // additional properties that were not serialize automatically - if ( blockX >= canvasWidth ) { + var _annex = { - blockX = 0; - blockY += blockSize; + mirror: 1, + reflectivity: 1, + refractionRatio: 1, + glass: 1, - if ( blockY >= canvasHeight ) { + }; - scope.dispatchEvent( { type: "complete" } ); - return; + function serializeObject( o ) { - } + var mat = o.material; - } + if ( ! mat || mat.uuid in materials ) return; - context.fillRect( blockX, blockY, blockSize, blockSize ); + var props = {}; + for ( var m in _annex ) { - animationFrameId = requestAnimationFrame( function () { + if ( mat[ m ] !== undefined ) { - renderBlock( blockX, blockY ); + props[ m ] = mat[ m ]; - } ); + } - }; + } - }() ); + materials[ mat.uuid ] = props; + } this.render = function ( scene, camera ) { - if ( this.autoClear === true ) this.clear(); - - cancelAnimationFrame( animationFrameId ); + renderering = true; // update scene graph @@ -495,49 +231,56 @@ THREE.RaytracingRenderer = function ( parameters ) { if ( camera.parent === null ) camera.updateMatrixWorld(); - camera.matrixWorldInverse.getInverse( camera.matrixWorld ); - cameraPosition.setFromMatrixPosition( camera.matrixWorld ); - // + sceneJSON = scene.toJSON(); + cameraJSON = camera.toJSON(); + ++ sceneId; - cameraNormalMatrix.getNormalMatrix( camera.matrixWorld ); - origin.copy( cameraPosition ); + scene.traverse( serializeObject ); - perspective = 0.5 / Math.tan( THREE.Math.degToRad( camera.fov * 0.5 ) ) * canvasHeight; + pool.forEach( function( worker ) { - objects = scene.children; + worker.postMessage( { + scene: sceneJSON, + camera: cameraJSON, + annex: materials, + sceneId: sceneId + } ); + } ); - // collect lights and set up object matrices + context.clearRect( 0, 0, canvasWidth, canvasHeight ); + reallyThen = Date.now(); - lights.length = 0; + xblocks = Math.ceil( canvasWidth / blockSize ); + yblocks = Math.ceil( canvasHeight / blockSize ); + totalBlocks = xblocks * yblocks; - scene.traverse( function ( object ) { + toRender = []; - if ( object instanceof THREE.Light ) { + for ( var i = 0; i < totalBlocks; i ++ ) { - lights.push( object ); + toRender.push( i ); - } + } - if ( cache[ object.id ] === undefined ) { - cache[ object.id ] = { - normalMatrix: new THREE.Matrix3(), - inverseMatrix: new THREE.Matrix4() - }; + // Randomize painting :) - } + if ( scope.randomize ) { - modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); + for ( var i = 0; i < totalBlocks; i ++ ) { - var _object = cache[ object.id ]; + var swap = Math.random() * totalBlocks | 0; + var tmp = toRender[ swap ]; + toRender[ swap ] = toRender[ i ]; + toRender[ i ] = tmp; - _object.normalMatrix.getNormalMatrix( modelViewMatrix ); - _object.inverseMatrix.getInverse( object.matrixWorld ); + } + + } - } ); - renderBlock( 0, 0 ); + pool.forEach( renderNext ); }; diff --git a/vendor/three-js/shaders/ConvolutionShader.js b/vendor/three-js/shaders/ConvolutionShader.js new file mode 100644 index 0000000..92027f2 --- /dev/null +++ b/vendor/three-js/shaders/ConvolutionShader.js @@ -0,0 +1,101 @@ +/** + * @author alteredq / http://alteredqualia.com/ + * + * Convolution shader + * ported from o3d sample to WebGL / GLSL + * http://o3d.googlecode.com/svn/trunk/samples/convolution.html + */ + +THREE.ConvolutionShader = { + + defines: { + + "KERNEL_SIZE_FLOAT": "25.0", + "KERNEL_SIZE_INT": "25", + + }, + + uniforms: { + + "tDiffuse": { type: "t", value: null }, + "uImageIncrement": { type: "v2", value: new THREE.Vector2( 0.001953125, 0.0 ) }, + "cKernel": { type: "fv1", value: [] } + + }, + + vertexShader: [ + + "uniform vec2 uImageIncrement;", + + "varying vec2 vUv;", + + "void main() {", + + "vUv = uv - ( ( KERNEL_SIZE_FLOAT - 1.0 ) / 2.0 ) * uImageIncrement;", + "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", + + "}" + + ].join( "\n" ), + + fragmentShader: [ + + "uniform float cKernel[ KERNEL_SIZE_INT ];", + + "uniform sampler2D tDiffuse;", + "uniform vec2 uImageIncrement;", + + "varying vec2 vUv;", + + "void main() {", + + "vec2 imageCoord = vUv;", + "vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );", + + "for( int i = 0; i < KERNEL_SIZE_INT; i ++ ) {", + + "sum += texture2D( tDiffuse, imageCoord ) * cKernel[ i ];", + "imageCoord += uImageIncrement;", + + "}", + + "gl_FragColor = sum;", + + "}" + + + ].join( "\n" ), + + buildKernel: function ( sigma ) { + + // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway. + + function gauss( x, sigma ) { + + return Math.exp( - ( x * x ) / ( 2.0 * sigma * sigma ) ); + + } + + var i, values, sum, halfWidth, kMaxKernelSize = 25, kernelSize = 2 * Math.ceil( sigma * 3.0 ) + 1; + + if ( kernelSize > kMaxKernelSize ) kernelSize = kMaxKernelSize; + halfWidth = ( kernelSize - 1 ) * 0.5; + + values = new Array( kernelSize ); + sum = 0.0; + for ( i = 0; i < kernelSize; ++ i ) { + + values[ i ] = gauss( i - halfWidth, sigma ); + sum += values[ i ]; + + } + + // normalize the kernel + + for ( i = 0; i < kernelSize; ++ i ) values[ i ] /= sum; + + return values; + + } + +};