// ThreeExtras.js r36 - http://github.com/mrdoob/three.js var GeometryUtils={merge:function(a,c){var b=c instanceof THREE.Mesh,e=a.vertices.length,h=b?c.geometry:c,d=a.vertices,f=h.vertices,g=a.faces,j=h.faces,o=a.uvs;h=h.uvs;b&&c.matrixAutoUpdate&&c.updateMatrix();for(var n=0,y=f.length;n= 0.0 )\npointSpecularWeight = pow( pointDotNormalHalf, uShininess );\npointDiffuse += vec4( uDiffuseColor, 1.0 ) * pointDiffuseWeight;\npointSpecular += vec4( uSpecularColor, 1.0 ) * pointSpecularWeight;\nvec4 dirDiffuse = vec4( 0.0, 0.0, 0.0, 0.0 );\nvec4 dirSpecular = vec4( 0.0, 0.0, 0.0, 0.0 );\nvec4 lDirection = viewMatrix * vec4( uDirLightPos, 0.0 );\nvec3 dirVector = normalize( lDirection.xyz );\nvec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );\nfloat dirDotNormalHalf = dot( normal, dirHalfVector );\nfloat dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );\nfloat dirSpecularWeight = 0.0;\nif ( dirDotNormalHalf >= 0.0 )\ndirSpecularWeight = pow( dirDotNormalHalf, uShininess );\ndirDiffuse += vec4( uDiffuseColor, 1.0 ) * dirDiffuseWeight;\ndirSpecular += vec4( uSpecularColor, 1.0 ) * dirSpecularWeight;\nvec4 totalLight = vec4( uAmbientLightColor * uAmbientColor, 1.0 );\ntotalLight += vec4( uDirLightColor, 1.0 ) * ( dirDiffuse + dirSpecular );\ntotalLight += vec4( uPointLightColor, 1.0 ) * ( pointDiffuse + pointSpecular );\ngl_FragColor = vec4( totalLight.xyz * aoTex * diffuseTex, 1.0 );\n}", vertexShader:"attribute vec4 tangent;\nuniform vec3 uPointLightPos;\n#ifdef VERTEX_TEXTURES\nuniform sampler2D tDisplacement;\nuniform float uDisplacementScale;\nuniform float uDisplacementBias;\n#endif\nvarying vec3 vTangent;\nvarying vec3 vBinormal;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vPointLightVector;\nvarying vec3 vViewPosition;\nvoid main() {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvNormal = normalize( normalMatrix * normal );\nvTangent = normalize( normalMatrix * tangent.xyz );\nvBinormal = cross( vNormal, vTangent ) * tangent.w;\nvBinormal = normalize( vBinormal );\nvUv = uv;\nvec4 lPosition = viewMatrix * vec4( uPointLightPos, 1.0 );\nvPointLightVector = normalize( lPosition.xyz - mvPosition.xyz );\n#ifdef VERTEX_TEXTURES\nvec3 dv = texture2D( tDisplacement, uv ).xyz;\nfloat df = uDisplacementScale * dv.x + uDisplacementBias;\nvec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;\ngl_Position = projectionMatrix * displacedPosition;\n#else\ngl_Position = projectionMatrix * mvPosition;\n#endif\n}"}, cube:{uniforms:{tCube:{type:"t",value:1,texture:null}},vertexShader:"varying vec3 vViewPosition;\nvoid main() {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform samplerCube tCube;\nvarying vec3 vViewPosition;\nvoid main() {\nvec3 wPos = cameraPosition - vViewPosition;\ngl_FragColor = textureCube( tCube, vec3( - wPos.x, wPos.yz ) );\n}"},convolution:{uniforms:{tDiffuse:{type:"t", value:0,texture:null},uImageIncrement:{type:"v2",value:new THREE.Vector2(0.001953125,0)},cKernel:{type:"fv1",value:[]}},vertexShader:"varying vec2 vUv;\nuniform vec2 uImageIncrement;\nvoid main(void) {\nvUv = uv - ((KERNEL_SIZE - 1.0) / 2.0) * uImageIncrement;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"varying vec2 vUv;\nuniform sampler2D tDiffuse;\nuniform vec2 uImageIncrement;\nuniform float cKernel[KERNEL_SIZE];\nvoid main(void) {\nvec2 imageCoord = vUv;\nvec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );\nfor( int i=0; i25&&(d=25);h=(d-1)*0.5;b=Array(d);for(c=e=0;c0||(n=this.vertices.push(new THREE.Vertex(new THREE.Vector3(y,g,u)))-1);o.push(n)}c.push(o)}var k,l,p;h=c.length;for(b=0;b0)for(e=0;e1){k=this.vertices[f].position.clone(); l=this.vertices[j].position.clone();p=this.vertices[o].position.clone();k.normalize();l.normalize();p.normalize();this.faces.push(new THREE.Face3(f,j,o,[new THREE.Vector3(k.x,k.y,k.z),new THREE.Vector3(l.x,l.y,l.z),new THREE.Vector3(p.x,p.y,p.z)]));this.uvs.push([n,y,v])}}}this.computeCentroids();this.computeFaceNormals();this.computeVertexNormals();this.boundingSphere={radius:a}};Sphere.prototype=new THREE.Geometry;Sphere.prototype.constructor=Sphere; var Torus=function(a,c,b,e){this.radius=a||100;this.tube=c||40;this.segmentsR=b||8;this.segmentsT=e||6;a=[];THREE.Geometry.call(this);for(c=0;c<=this.segmentsR;++c)for(b=0;b<=this.segmentsT;++b){e=b/this.segmentsT*2*Math.PI;var h=c/this.segmentsR*2*Math.PI;this.vertices.push(new THREE.Vertex(new THREE.Vector3((this.radius+this.tube*Math.cos(h))*Math.cos(e),(this.radius+this.tube*Math.cos(h))*Math.sin(e),this.tube*Math.sin(h))));a.push([b/this.segmentsT,1-c/this.segmentsR])}for(c=1;c<=this.segmentsR;++c)for(b= 1;b<=this.segmentsT;++b){e=(this.segmentsT+1)*c+b;h=(this.segmentsT+1)*c+b-1;var d=(this.segmentsT+1)*(c-1)+b-1,f=(this.segmentsT+1)*(c-1)+b;this.faces.push(new THREE.Face4(e,h,d,f));this.uvs.push([new THREE.UV(a[e][0],a[e][1]),new THREE.UV(a[h][0],a[h][1]),new THREE.UV(a[d][0],a[d][1]),new THREE.UV(a[f][0],a[f][1])])}delete a;this.computeCentroids();this.computeFaceNormals();this.computeVertexNormals()};Torus.prototype=new THREE.Geometry;Torus.prototype.constructor=Torus; var Icosahedron=function(a){function c(y,u,k){var l=Math.sqrt(y*y+u*u+k*k);return h.vertices.push(new THREE.Vertex(new THREE.Vector3(y/l,u/l,k/l)))-1}function b(y,u,k,l){l.faces.push(new THREE.Face3(y,u,k))}function e(y,u){var k=h.vertices[y].position,l=h.vertices[u].position;return c((k.x+l.x)/2,(k.y+l.y)/2,(k.z+l.z)/2)}var h=this,d=new THREE.Geometry,f;this.subdivisions=a||0;THREE.Geometry.call(this);a=(1+Math.sqrt(5))/2;c(-1,a,0);c(1,a,0);c(-1,-a,0);c(1,-a,0);c(0,-1,a);c(0,1,a);c(0,-1,-a);c(0, 1,-a);c(a,0,-1);c(a,0,1);c(-a,0,-1);c(-a,0,1);b(0,11,5,d);b(0,5,1,d);b(0,1,7,d);b(0,7,10,d);b(0,10,11,d);b(1,5,9,d);b(5,11,4,d);b(11,10,2,d);b(10,7,6,d);b(7,1,8,d);b(3,9,4,d);b(3,4,2,d);b(3,2,6,d);b(3,6,8,d);b(3,8,9,d);b(4,9,5,d);b(2,4,11,d);b(6,2,10,d);b(8,6,7,d);b(9,8,1,d);for(a=0;a=this.maxCount-3&&g(this)};this.begin= function(){this.count=0;this.hasPos=!1;this.hasNormal=!1};this.end=function(b){if(this.count!=0){for(var e=this.count*3;ethis.size-1&&(j=this.size-1);var u=Math.floor(o-g);u<1&&(u=1);o=Math.floor(o+g);o>this.size-1&&(o=this.size-1);var k=Math.floor(n-g);k<1&&(k=1);g=Math.floor(n+g); g>this.size-1&&(g=this.size-1);for(var l,p,v,t,w,m;y0&&(this.field[v+l]+=t)}}}};this.addPlaneX=function(b,e){var h,d,f,g,j,o=this.size,n=this.yd,y=this.zd,u=this.field,k=o*Math.sqrt(b/e);k>o&&(k=o);for(h=0;h0)for(d=0;dn&&(l=n);for(d=0;d0){j=d*y;for(h=0;hsize&&(dist=size);for(f=0;f0){j=zd*f;for(d=0;dthis.heightMax?this.heightMax:this.position.y)-this.heightMin)*this.heightCoef:0;(this.moveForward||this.autoForward)&&this.translateZ(-(this.movementSpeed+this.autoSpeedFactor));this.moveBackward&&this.translateZ(this.movementSpeed);this.moveLeft&&this.translateX(-this.movementSpeed);this.moveRight&&this.translateX(this.movementSpeed); var b=this.lookSpeed;this.dragToLook&&!this.mouseDragOn&&(b=0);this.lon+=this.mouseX*b;this.lookVertical&&(this.lat-=this.mouseY*b);this.lat=Math.max(-85,Math.min(85,this.lat));this.phi=(90-this.lat)*Math.PI/180;this.theta=this.lon*Math.PI/180;b=this.target.position;var e=this.position;b.x=e.x+100*Math.sin(this.phi)*Math.cos(this.theta);b.y=e.y+100*Math.cos(this.phi);b.z=e.z+100*Math.sin(this.phi)*Math.sin(this.theta);this.supr.update.call(this)};this.domElement.addEventListener("contextmenu",function(b){b.preventDefault()}, !1);this.domElement.addEventListener("mousemove",c(this,this.onMouseMove),!1);this.domElement.addEventListener("mousedown",c(this,this.onMouseDown),!1);this.domElement.addEventListener("mouseup",c(this,this.onMouseUp),!1);this.domElement.addEventListener("keydown",c(this,this.onKeyDown),!1);this.domElement.addEventListener("keyup",c(this,this.onKeyUp),!1)};THREE.QuakeCamera.prototype=new THREE.Camera;THREE.QuakeCamera.prototype.constructor=THREE.QuakeCamera;THREE.QuakeCamera.prototype.supr=THREE.Camera.prototype; THREE.QuakeCamera.prototype.translate=function(a,c){this.matrix.rotateAxis(c);if(this.noFly)c.y=0;this.position.addSelf(c.multiplyScalar(a));this.target.position.addSelf(c.multiplyScalar(a))}; THREE.PathCamera=function(a){function c(k,l){var p=k[0]-l[0],v=k[1]-l[1],t=k[2]-l[2];return Math.sqrt(p*p+v*v+t*t)}function b(k,l,p,v){var t={name:p,fps:0.6,length:v,hierarchy:[]},w,m,B=l.length,z=d(l),I=0;w=B-1;m={parent:-1,keys:[]};m.keys[0]={time:0,pos:l[0],rot:[0,0,0,1],scl:[1,1,1]};m.keys[w]={time:v,pos:l[w],rot:[0,0,0,1],scl:[1,1,1]};for(w=1;w=0?v:v+j;v=this.verticalAngleMap.srcRange;t=this.verticalAngleMap.dstRange;this.phi=(this.phi-v[0])*(t[1]-t[0])/(v[1]-v[0])+t[0];v=this.horizontalAngleMap.srcRange;t=this.horizontalAngleMap.dstRange; this.theta=(this.theta-v[0])*(t[1]-t[0])/(v[1]-v[0])+t[0];v=this.target.position;v.x=100*Math.sin(this.phi)*Math.cos(this.theta);v.y=100*Math.cos(this.phi);v.z=100*Math.sin(this.phi)*Math.sin(this.theta);this.supr.update.call(this,k,l,p)};this.onMouseMove=function(k){this.mouseX=k.clientX-this.windowHalfX;this.mouseY=k.clientY-this.windowHalfY};if(this.useConstantSpeed)this.waypoints=h(this.waypoints,this.resamplingCoef);if(this.createDebugDummy){a=new THREE.MeshLambertMaterial({color:30719});var n= new THREE.MeshLambertMaterial({color:65280}),y=new Cube(10,10,20),u=new Cube(2,2,10);this.animationParent=new THREE.Mesh(y,a);a=new THREE.Mesh(u,n);a.position.set(0,10,0);this.animation=b(this.animationParent,this.waypoints,this.id,this.duration);this.animationParent.addChild(this);this.animationParent.addChild(this.target);this.animationParent.addChild(a)}else{this.animation=b(this.animationParent,this.waypoints,this.id,this.duration);this.animationParent.addChild(this.target);this.animationParent.addChild(this)}this.createDebugPath&& g(this.debugPath,this.waypoints);this.domElement.addEventListener("mousemove",function(k,l){return function(){l.apply(k,arguments)}}(this,this.onMouseMove),!1)};THREE.PathCamera.prototype=new THREE.Camera;THREE.PathCamera.prototype.constructor=THREE.PathCamera;THREE.PathCamera.prototype.supr=THREE.Camera.prototype;THREE.PathCameraIdCounter=0;THREE.Loader=function(a){this.statusDomElement=(this.showStatus=a)?this.addStatusElement():null}; THREE.Loader.prototype={addStatusElement:function(){var a=document.createElement("div");a.style.fontSize="0.8em";a.style.textAlign="left";a.style.background="#b00";a.style.color="#fff";a.style.width="140px";a.style.padding="0.25em 0.25em 0.25em 0.5em";a.style.position="absolute";a.style.right="0px";a.style.top="0px";a.style.zIndex=1E3;a.innerHTML="Loading ...";return a},updateProgress:function(a){var c="Loaded ";c+=a.total?(100*a.loaded/a.total).toFixed(0)+"%":(a.loaded/1E3).toFixed(2)+" KB";this.statusDomElement.innerHTML= c},loadAsciiOld:function(a,c){var b=document.createElement("script");b.type="text/javascript";b.onload=c;b.src=a;document.getElementsByTagName("head")[0].appendChild(b)},loadAscii:function(a){var c=a.model,b=a.callback,e=a.texture_path?a.texture_path:THREE.Loader.prototype.extractUrlbase(c);a=(new Date).getTime();c=new Worker(c);c.onmessage=function(h){THREE.Loader.prototype.createModel(h.data,b,e)};c.postMessage(a)},loadBinary:function(a){var c=a.model,b=a.callback,e=a.texture_path?a.texture_path: THREE.Loader.prototype.extractUrlbase(c),h=a.bin_path?a.bin_path:THREE.Loader.prototype.extractUrlbase(c);a=(new Date).getTime();c=new Worker(c);var d=this.showProgress?THREE.Loader.prototype.updateProgress:null;c.onmessage=function(f){THREE.Loader.prototype.loadAjaxBuffers(f.data.buffers,f.data.materials,b,h,e,d)};c.onerror=function(f){alert("worker.onerror: "+f.message+"\n"+f.data);f.preventDefault()};c.postMessage(a)},loadAjaxBuffers:function(a,c,b,e,h,d){var f=new XMLHttpRequest,g=e+"/"+a,j=0; f.onreadystatechange=function(){if(f.readyState==4)f.status==200||f.status==0?THREE.Loader.prototype.createBinModel(f.responseText,b,h,c):alert("Couldn't load ["+g+"] ["+f.status+"]");else if(f.readyState==3){if(d){j==0&&(j=f.getResponseHeader("Content-Length"));d({total:j,loaded:f.responseText.length})}}else f.readyState==2&&(j=f.getResponseHeader("Content-Length"))};f.open("GET",g,!0);f.overrideMimeType("text/plain; charset=x-user-defined");f.setRequestHeader("Content-Type","text/plain");f.send(null)}, createBinModel:function(a,c,b,e){var h=function(d){function f(q,x){var A=n(q,x),C=n(q,x+1),H=n(q,x+2),L=n(q,x+3),P=(L<<1&255|H>>7)-127;A|=(H&127)<<16|C<<8;if(A==0&&P==-127)return 0;return(1-2*(L>>7))*(1+A*Math.pow(2,-23))*Math.pow(2,P)}function g(q,x){var A=n(q,x),C=n(q,x+1),H=n(q,x+2);return(n(q,x+3)<<24)+(H<<16)+(C<<8)+A}function j(q,x){var A=n(q,x);return(n(q,x+1)<<8)+A}function o(q,x){var A=n(q,x);return A>127?A-256:A}function n(q,x){return q.charCodeAt(x)&255}function y(q){var x,A,C;x=g(a,q); A=g(a,q+I);C=g(a,q+D);q=j(a,q+E);THREE.Loader.prototype.f3(t,x,A,C,q)}function u(q){var x,A,C,H,L,P;x=g(a,q);A=g(a,q+I);C=g(a,q+D);H=j(a,q+E);L=g(a,q+F);P=g(a,q+J);q=g(a,q+K);THREE.Loader.prototype.f3n(t,B,x,A,C,H,L,P,q)}function k(q){var x,A,C,H;x=g(a,q);A=g(a,q+O);C=g(a,q+G);H=g(a,q+N);q=j(a,q+M);THREE.Loader.prototype.f4(t,x,A,C,H,q)}function l(q){var x,A,C,H,L,P,Z,$;x=g(a,q);A=g(a,q+O);C=g(a,q+G);H=g(a,q+N);L=j(a,q+M);P=g(a,q+X);Z=g(a,q+Y);$=g(a,q+R);q=g(a,q+aa);THREE.Loader.prototype.f4n(t,B, x,A,C,H,L,P,Z,$,q)}function p(q){var x,A;x=g(a,q);A=g(a,q+ba);q=g(a,q+ca);THREE.Loader.prototype.uv3(t.uvs,z[x*2],z[x*2+1],z[A*2],z[A*2+1],z[q*2],z[q*2+1])}function v(q){var x,A,C;x=g(a,q);A=g(a,q+da);C=g(a,q+ea);q=g(a,q+fa);THREE.Loader.prototype.uv4(t.uvs,z[x*2],z[x*2+1],z[A*2],z[A*2+1],z[C*2],z[C*2+1],z[q*2],z[q*2+1])}var t=this,w=0,m,B=[],z=[],I,D,E,F,J,K,O,G,N,M,X,Y,R,aa,ba,ca,da,ea,fa,S,T,U,V,W,Q;THREE.Geometry.call(this);THREE.Loader.prototype.init_materials(t,e,d);m={signature:a.substr(w, 8),header_bytes:n(a,w+8),vertex_coordinate_bytes:n(a,w+9),normal_coordinate_bytes:n(a,w+10),uv_coordinate_bytes:n(a,w+11),vertex_index_bytes:n(a,w+12),normal_index_bytes:n(a,w+13),uv_index_bytes:n(a,w+14),material_index_bytes:n(a,w+15),nvertices:g(a,w+16),nnormals:g(a,w+16+4),nuvs:g(a,w+16+8),ntri_flat:g(a,w+16+12),ntri_smooth:g(a,w+16+16),ntri_flat_uv:g(a,w+16+20),ntri_smooth_uv:g(a,w+16+24),nquad_flat:g(a,w+16+28),nquad_smooth:g(a,w+16+32),nquad_flat_uv:g(a,w+16+36),nquad_smooth_uv:g(a,w+16+40)}; w+=m.header_bytes;I=m.vertex_index_bytes;D=m.vertex_index_bytes*2;E=m.vertex_index_bytes*3;F=m.vertex_index_bytes*3+m.material_index_bytes;J=m.vertex_index_bytes*3+m.material_index_bytes+m.normal_index_bytes;K=m.vertex_index_bytes*3+m.material_index_bytes+m.normal_index_bytes*2;O=m.vertex_index_bytes;G=m.vertex_index_bytes*2;N=m.vertex_index_bytes*3;M=m.vertex_index_bytes*4;X=m.vertex_index_bytes*4+m.material_index_bytes;Y=m.vertex_index_bytes*4+m.material_index_bytes+m.normal_index_bytes;R=m.vertex_index_bytes* 4+m.material_index_bytes+m.normal_index_bytes*2;aa=m.vertex_index_bytes*4+m.material_index_bytes+m.normal_index_bytes*3;ba=m.uv_index_bytes;ca=m.uv_index_bytes*2;da=m.uv_index_bytes;ea=m.uv_index_bytes*2;fa=m.uv_index_bytes*3;d=m.vertex_index_bytes*3+m.material_index_bytes;Q=m.vertex_index_bytes*4+m.material_index_bytes;S=m.ntri_flat*d;T=m.ntri_smooth*(d+m.normal_index_bytes*3);U=m.ntri_flat_uv*(d+m.uv_index_bytes*3);V=m.ntri_smooth_uv*(d+m.normal_index_bytes*3+m.uv_index_bytes*3);W=m.nquad_flat* Q;d=m.nquad_smooth*(Q+m.normal_index_bytes*4);Q=m.nquad_flat_uv*(Q+m.uv_index_bytes*4);w+=function(q){for(var x,A,C,H=m.vertex_coordinate_bytes*3,L=q+m.nvertices*H;q