// ThreeExtras.js r38 - http://github.com/mrdoob/three.js var GeometryUtils={merge:function(a,f){var b=f instanceof THREE.Mesh,e=a.vertices.length,c=b?f.geometry:f,d=a.vertices,g=c.vertices,h=a.faces,j=c.faces,m=a.faceVertexUvs[0];c=c.faceVertexUvs[0];b&&f.matrixAutoUpdate&&f.updateMatrix();for(var k=0,n=g.length;k= 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);c=(d-1)*0.5;b=Array(d);for(f=e=0;f this.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.activeLook||(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;var e=this.target.position,c=this.position;e.x=c.x+100*Math.sin(this.phi)*Math.cos(this.theta);e.y=c.y+100*Math.cos(this.phi);e.z=c.z+100*Math.sin(this.phi)*Math.sin(this.theta)}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;if(this.constrainVertical)this.phi=(this.phi-0)*(this.verticalMax-this.verticalMin)/ 3.14+this.verticalMin;e=this.target.position;c=this.position;e.x=c.x+100*Math.sin(this.phi)*Math.cos(this.theta);e.y=c.y+100*Math.cos(this.phi);e.z=c.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",f(this,this.onMouseMove),!1);this.domElement.addEventListener("mousedown",f(this,this.onMouseDown),!1);this.domElement.addEventListener("mouseup",f(this, this.onMouseUp),!1);this.domElement.addEventListener("keydown",f(this,this.onKeyDown),!1);this.domElement.addEventListener("keyup",f(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,f){this.matrix.rotateAxis(f);if(this.noFly)f.y=0;this.position.addSelf(f.multiplyScalar(a));this.target.position.addSelf(f.multiplyScalar(a))}; THREE.PathCamera=function(a){function f(m,k,n,p){var t={name:n,fps:0.6,length:p,hierarchy:[]},w,x=k.getControlPointsArray(),u=k.getLength(),B=x.length,z=0;w=B-1;k={parent:-1,keys:[]};k.keys[0]={time:0,pos:x[0],rot:[0,0,0,1],scl:[1,1,1]};k.keys[w]={time:p,pos:x[w],rot:[0,0,0,1],scl:[1,1,1]};for(w=1;w=0?p:p+c;p=this.verticalAngleMap.srcRange;t=this.verticalAngleMap.dstRange; this.phi=(this.phi-p[0])*(t[1]-t[0])/(p[1]-p[0])+t[0];p=this.horizontalAngleMap.srcRange;t=this.horizontalAngleMap.dstRange;this.theta=(this.theta-p[0])*(t[1]-t[0])/(p[1]-p[0])+t[0];p=this.target.position;p.x=100*Math.sin(this.phi)*Math.cos(this.theta);p.y=100*Math.cos(this.phi);p.z=100*Math.sin(this.phi)*Math.sin(this.theta);this.supr.update.call(this,m,k,n)};this.onMouseMove=function(m){this.mouseX=m.clientX-this.windowHalfX;this.mouseY=m.clientY-this.windowHalfY};this.spline=new THREE.Spline;this.spline.initFromArray(this.waypoints); this.useConstantSpeed&&this.spline.reparametrizeByArcLength(this.resamplingCoef);if(this.createDebugDummy){a=new THREE.MeshLambertMaterial({color:30719});var g=new THREE.MeshLambertMaterial({color:65280}),h=new Cube(10,10,20),j=new Cube(2,2,10);this.animationParent=new THREE.Mesh(h,a);a=new THREE.Mesh(j,g);a.position.set(0,10,0);this.animation=f(this.animationParent,this.spline,this.id,this.duration);this.animationParent.addChild(this);this.animationParent.addChild(this.target);this.animationParent.addChild(a)}else{this.animation= f(this.animationParent,this.spline,this.id,this.duration);this.animationParent.addChild(this.target);this.animationParent.addChild(this)}this.createDebugPath&&e(this.debugPath,this.spline);this.domElement.addEventListener("mousemove",function(m,k){return function(){k.apply(m,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; var Cube=function(a,f,b,e,c,d,g,h,j){function m(u,B,z,l,y,C,G,K){var J,I,E=e||1,L=c||1,P=y/2,Q=C/2,R=k.vertices.length;if(u=="x"&&B=="y"||u=="y"&&B=="x")J="z";else if(u=="x"&&B=="z"||u=="z"&&B=="x"){J="y";L=d||1}else if(u=="z"&&B=="y"||u=="y"&&B=="z"){J="x";E=d||1}var M=E+1,F=L+1;y/=E;var N=C/L;for(I=0;I0){g(0,0,-k-(d||0));for(j=a;j0){g(0,0,k+(c||0));for(j= a+a/2;j<2*a;j++)h.faces.push(new THREE.Face4(2*a+1,(2*j-2*a+2)%a+a,(2*j-2*a+1)%a+a,(2*j-2*a)%a+a))}j=0;for(a=this.faces.length;j0||(k=this.vertices.push(new THREE.Vertex(new THREE.Vector3(n,h,p)))-1);m.push(k)}f.push(m)}var t,w,x;c=f.length;for(b=0;b0)for(e=0;e1){t=this.vertices[g].position.clone(); w=this.vertices[j].position.clone();x=this.vertices[m].position.clone();t.normalize();w.normalize();x.normalize();this.faces.push(new THREE.Face3(g,j,m,[new THREE.Vector3(t.x,t.y,t.z),new THREE.Vector3(w.x,w.y,w.z),new THREE.Vector3(x.x,x.y,x.z)]));this.faceVertexUvs[0].push([k,n,u])}}}this.computeCentroids();this.computeFaceNormals();this.computeVertexNormals();this.boundingSphere={radius:a}};Sphere.prototype=new THREE.Geometry;Sphere.prototype.constructor=Sphere; var Torus=function(a,f,b,e){this.radius=a||100;this.tube=f||40;this.segmentsR=b||8;this.segmentsT=e||6;a=[];THREE.Geometry.call(this);for(f=0;f<=this.segmentsR;++f)for(b=0;b<=this.segmentsT;++b){e=b/this.segmentsT*2*Math.PI;var c=f/this.segmentsR*2*Math.PI;this.vertices.push(new THREE.Vertex(new THREE.Vector3((this.radius+this.tube*Math.cos(c))*Math.cos(e),(this.radius+this.tube*Math.cos(c))*Math.sin(e),this.tube*Math.sin(c))));a.push([b/this.segmentsT,1-f/this.segmentsR])}for(f=1;f<=this.segmentsR;++f)for(b= 1;b<=this.segmentsT;++b){e=(this.segmentsT+1)*f+b;c=(this.segmentsT+1)*f+b-1;var d=(this.segmentsT+1)*(f-1)+b-1,g=(this.segmentsT+1)*(f-1)+b;this.faces.push(new THREE.Face4(e,c,d,g));this.faceVertexUvs[0].push([new THREE.UV(a[e][0],a[e][1]),new THREE.UV(a[c][0],a[c][1]),new THREE.UV(a[d][0],a[d][1]),new THREE.UV(a[g][0],a[g][1])])}delete a;this.computeCentroids();this.computeFaceNormals();this.computeVertexNormals()};Torus.prototype=new THREE.Geometry;Torus.prototype.constructor=Torus; var TorusKnot=function(a,f,b,e,c,d,g){function h(n,p,t,w,x,u){p=t/w*n;t=Math.cos(p);return new THREE.Vector3(x*(2+t)*0.5*Math.cos(n),x*(2+t)*Math.sin(n)*0.5,u*x*Math.sin(p)*0.5)}THREE.Geometry.call(this);this.radius=a||200;this.tube=f||40;this.segmentsR=b||64;this.segmentsT=e||8;this.p=c||2;this.q=d||3;this.heightScale=g||1;this.grid=Array(this.segmentsR);b=new THREE.Vector3;e=new THREE.Vector3;d=new THREE.Vector3;for(a=0;a>7)-127;A|=(H&127)<<16|D<<8;if(A==0&&U==-127)return 0;return(1-2*(S>>7))*(1+A*Math.pow(2,-23))*Math.pow(2,U)}function h(o,v){var A=k(o,v),D=k(o,v+1),H=k(o,v+2);return(k(o,v+3)<<24)+(H<<16)+(D<<8)+A}function j(o,v){var A=k(o,v);return(k(o,v+1)<<8)+A}function m(o,v){var A=k(o,v);return A>127?A-256:A}function k(o, v){return o.charCodeAt(v)&255}function n(o){var v,A,D;v=h(a,o);A=h(a,o+G);D=h(a,o+K);o=j(a,o+J);THREE.BinaryLoader.prototype.f3(B,v,A,D,o)}function p(o){var v,A,D,H,S,U;v=h(a,o);A=h(a,o+G);D=h(a,o+K);H=j(a,o+J);S=h(a,o+I);U=h(a,o+E);o=h(a,o+L);THREE.BinaryLoader.prototype.f3n(B,y,v,A,D,H,S,U,o)}function t(o){var v,A,D,H;v=h(a,o);A=h(a,o+P);D=h(a,o+Q);H=h(a,o+R);o=j(a,o+M);THREE.BinaryLoader.prototype.f4(B,v,A,D,H,o)}function w(o){var v,A,D,H,S,U,ca,da;v=h(a,o);A=h(a,o+P);D=h(a,o+Q);H=h(a,o+R);S=j(a, o+M);U=h(a,o+F);ca=h(a,o+N);da=h(a,o+O);o=h(a,o+T);THREE.BinaryLoader.prototype.f4n(B,y,v,A,D,H,S,U,ca,da,o)}function x(o){var v,A;v=h(a,o);A=h(a,o+W);o=h(a,o+X);THREE.BinaryLoader.prototype.uv3(B.faceVertexUvs[0],C[v*2],C[v*2+1],C[A*2],C[A*2+1],C[o*2],C[o*2+1])}function u(o){var v,A,D;v=h(a,o);A=h(a,o+ea);D=h(a,o+fa);o=h(a,o+ga);THREE.BinaryLoader.prototype.uv4(B.faceVertexUvs[0],C[v*2],C[v*2+1],C[A*2],C[A*2+1],C[D*2],C[D*2+1],C[o*2],C[o*2+1])}var B=this,z=0,l,y=[],C=[],G,K,J,I,E,L,P,Q,R,M,F,N,O, T,W,X,ea,fa,ga,Y,Z,$,aa,ba,V;THREE.Geometry.call(this);THREE.Loader.prototype.init_materials(B,e,d);l={signature:a.substr(z,8),header_bytes:k(a,z+8),vertex_coordinate_bytes:k(a,z+9),normal_coordinate_bytes:k(a,z+10),uv_coordinate_bytes:k(a,z+11),vertex_index_bytes:k(a,z+12),normal_index_bytes:k(a,z+13),uv_index_bytes:k(a,z+14),material_index_bytes:k(a,z+15),nvertices:h(a,z+16),nnormals:h(a,z+16+4),nuvs:h(a,z+16+8),ntri_flat:h(a,z+16+12),ntri_smooth:h(a,z+16+16),ntri_flat_uv:h(a,z+16+20),ntri_smooth_uv:h(a, z+16+24),nquad_flat:h(a,z+16+28),nquad_smooth:h(a,z+16+32),nquad_flat_uv:h(a,z+16+36),nquad_smooth_uv:h(a,z+16+40)};z+=l.header_bytes;G=l.vertex_index_bytes;K=l.vertex_index_bytes*2;J=l.vertex_index_bytes*3;I=l.vertex_index_bytes*3+l.material_index_bytes;E=l.vertex_index_bytes*3+l.material_index_bytes+l.normal_index_bytes;L=l.vertex_index_bytes*3+l.material_index_bytes+l.normal_index_bytes*2;P=l.vertex_index_bytes;Q=l.vertex_index_bytes*2;R=l.vertex_index_bytes*3;M=l.vertex_index_bytes*4;F=l.vertex_index_bytes* 4+l.material_index_bytes;N=l.vertex_index_bytes*4+l.material_index_bytes+l.normal_index_bytes;O=l.vertex_index_bytes*4+l.material_index_bytes+l.normal_index_bytes*2;T=l.vertex_index_bytes*4+l.material_index_bytes+l.normal_index_bytes*3;W=l.uv_index_bytes;X=l.uv_index_bytes*2;ea=l.uv_index_bytes;fa=l.uv_index_bytes*2;ga=l.uv_index_bytes*3;d=l.vertex_index_bytes*3+l.material_index_bytes;V=l.vertex_index_bytes*4+l.material_index_bytes;Y=l.ntri_flat*d;Z=l.ntri_smooth*(d+l.normal_index_bytes*3);$=l.ntri_flat_uv* (d+l.uv_index_bytes*3);aa=l.ntri_smooth_uv*(d+l.normal_index_bytes*3+l.uv_index_bytes*3);ba=l.nquad_flat*V;d=l.nquad_smooth*(V+l.normal_index_bytes*4);V=l.nquad_flat_uv*(V+l.uv_index_bytes*4);z+=function(o){for(var v,A,D,H=l.vertex_coordinate_bytes*3,S=o+l.nvertices*H;o=this.maxCount-3&&h(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 p=Math.floor(m-h);p<1&&(p=1);m=Math.floor(m+h);m>this.size-1&&(m=this.size-1);var t=Math.floor(k-h);t<1&&(t=1);h=Math.floor(k+h); h>this.size-1&&(h=this.size-1);for(var w,x,u,B,z,l;n0&&(this.field[u+w]+=B)}}}};this.addPlaneX=function(b,e){var c,d,g,h,j,m=this.size,k=this.yd,n=this.zd,p=this.field,t=m*Math.sqrt(b/e);t>m&&(t=m);for(c=0;c0)for(d=0;dk&&(w=k);for(d=0;d0){j=d*n;for(c=0;csize&&(dist=size);for(g=0;g0){j=zd*g;for(d=0;d