From 0c770644ee8b9086c4910b0f4d7b4d8905f78f18 Mon Sep 17 00:00:00 2001 From: alteredq Date: Fri, 28 Oct 2011 17:01:23 +0200 Subject: [PATCH] Trying to cleaned up a bit WebGLRenderer. Mostly just shuffling code around to have more organized "big picture" view. --- build/Three.js | 780 +++--- build/custom/ThreeWebGL.js | 394 +-- src/renderers/WebGLRenderer.js | 4565 ++++++++++++++++---------------- 3 files changed, 2891 insertions(+), 2848 deletions(-) diff --git a/build/Three.js b/build/Three.js index 363cfc76..c7d4bac3 100644 --- a/build/Three.js +++ b/build/Three.js @@ -15,64 +15,64 @@ Math.abs(c)>1.0E-5?(this.x=Math.atan2(-a.n23/c,a.n33/c),this.z=Math.atan2(-a.n12 THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,c,b,d){this.x=a;this.y=c;this.z=b;this.w=d;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w!==void 0?a.w:1},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)},add:function(a,c){this.x=a.x+c.x;this.y=a.y+c.y;this.z=a.z+c.z;this.w=a.w+c.w;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},sub:function(a,c){this.x=a.x-c.x;this.y=a.y-c.y;this.z=a.z- c.z;this.w=a.w-c.w;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},divideScalar:function(a){a?(this.x/=a,this.y/=a,this.z/=a,this.w/=a):(this.z=this.y=this.x=0,this.w=1);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.dot(this)},length:function(){return Math.sqrt(this.lengthSq())}, normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.normalize().multiplyScalar(a)},lerpSelf:function(a,c){this.x+=(a.x-this.x)*c;this.y+=(a.y-this.y)*c;this.z+=(a.z-this.z)*c;this.w+=(a.w-this.w)*c;return this}};THREE.Ray=function(a,c){this.origin=a||new THREE.Vector3;this.direction=c||new THREE.Vector3}; -THREE.Ray.prototype={constructor:THREE.Ray,intersectScene:function(a){return this.intersectObjects(a.children)},intersectObjects:function(a){var c,b,d=[];c=0;for(b=a.length;c=0&&p>=0&&o+p<1}for(var d=new THREE.Vector3,g=new THREE.Vector3,e=new THREE.Vector3,f,h,i,l,m,k,o,p,q,n=[],t=0,u=a.children.length;ta.scale.x)return[];q={distance:t,point:a.position, -face:null,object:a};n.push(q)}else if(a instanceof THREE.Mesh){t=c(this.origin,this.direction,a.matrixWorld.getPosition());if(t===null||t>a.geometry.boundingSphere.radius*Math.max(a.scale.x,Math.max(a.scale.y,a.scale.z)))return n;var v,r,z,E,N,A,J,x,w=a.geometry,D=w.vertices;a.matrixRotationWorld.extractRotation(a.matrixWorld);t=0;for(u=w.faces.length;t0:A<0)))if(A=N.dot((new THREE.Vector3).sub(v,J))/A,J=J.addSelf(x.multiplyScalar(A)),q instanceof THREE.Face3)b(J,v,r,z)&&(q={distance:this.origin.distanceTo(J),point:J,face:q,object:a}, -n.push(q));else if(q instanceof THREE.Face4&&(b(J,v,r,E)||b(J,r,z,E)))q={distance:this.origin.distanceTo(J),point:J,face:q,object:a},n.push(q)}return n}}; -THREE.Rectangle=function(){function a(){e=d-c;f=g-b}var c,b,d,g,e,f,h=!0;this.getX=function(){return c};this.getY=function(){return b};this.getWidth=function(){return e};this.getHeight=function(){return f};this.getLeft=function(){return c};this.getTop=function(){return b};this.getRight=function(){return d};this.getBottom=function(){return g};this.set=function(e,f,m,k){h=!1;c=e;b=f;d=m;g=k;a()};this.addPoint=function(e,f){h?(h=!1,c=e,b=f,d=e,g=f):(c=ce?d:e,g=g>f?g:f);a()};this.add3Points= -function(e,f,m,k,o,p){h?(h=!1,c=em?e>o?e:o:m>o?m:o,g=f>k?f>p?f:p:k>p?k:p):(c=em?e>o?e>d?e:d:o>d?o:d:m>o?m>d?m:d:o>d?o:d,g=f>k?f>p?f>g?f:g:p>g?p:g:k>p?k>g?k:g:p>g?p:g);a()};this.addRectangle=function(e){h?(h=!1,c=e.getLeft(),b=e.getTop(),d=e.getRight(),g=e.getBottom()):(c=ce.getRight()?d:e.getRight(),g=g> +THREE.Ray.prototype={constructor:THREE.Ray,intersectScene:function(a){return this.intersectObjects(a.children)},intersectObjects:function(a){var c,b,d=[];c=0;for(b=a.length;c=0&&n>=0&&o+n<1}for(var d=new THREE.Vector3,g=new THREE.Vector3,e=new THREE.Vector3,f,h,i,k,l,m,o,n,s,p=[],u=0,v=a.children.length;ua.scale.x)return[];s={distance:u,point:a.position, +face:null,object:a};p.push(s)}else if(a instanceof THREE.Mesh){u=c(this.origin,this.direction,a.matrixWorld.getPosition());if(u===null||u>a.geometry.boundingSphere.radius*Math.max(a.scale.x,Math.max(a.scale.y,a.scale.z)))return p;var y,q,t,w,z,L,J,I,D=a.geometry,C=D.vertices;a.matrixRotationWorld.extractRotation(a.matrixWorld);u=0;for(v=D.faces.length;u0:L<0)))if(L=z.dot((new THREE.Vector3).sub(y,J))/L,J=J.addSelf(I.multiplyScalar(L)),s instanceof THREE.Face3)b(J,y,q,t)&&(s={distance:this.origin.distanceTo(J),point:J,face:s,object:a}, +p.push(s));else if(s instanceof THREE.Face4&&(b(J,y,q,w)||b(J,q,t,w)))s={distance:this.origin.distanceTo(J),point:J,face:s,object:a},p.push(s)}return p}}; +THREE.Rectangle=function(){function a(){e=d-c;f=g-b}var c,b,d,g,e,f,h=!0;this.getX=function(){return c};this.getY=function(){return b};this.getWidth=function(){return e};this.getHeight=function(){return f};this.getLeft=function(){return c};this.getTop=function(){return b};this.getRight=function(){return d};this.getBottom=function(){return g};this.set=function(e,f,l,m){h=!1;c=e;b=f;d=l;g=m;a()};this.addPoint=function(e,f){h?(h=!1,c=e,b=f,d=e,g=f):(c=ce?d:e,g=g>f?g:f);a()};this.add3Points= +function(e,f,l,m,o,n){h?(h=!1,c=el?e>o?e:o:l>o?l:o,g=f>m?f>n?f:n:m>n?m:n):(c=el?e>o?e>d?e:d:o>d?o:d:l>o?l>d?l:d:o>d?o:d,g=f>m?f>n?f>g?f:g:n>g?n:g:m>n?m>g?m:g:n>g?n:g);a()};this.addRectangle=function(e){h?(h=!1,c=e.getLeft(),b=e.getTop(),d=e.getRight(),g=e.getBottom()):(c=ce.getRight()?d:e.getRight(),g=g> e.getBottom()?g:e.getBottom());a()};this.inflate=function(e){c-=e;b-=e;d+=e;g+=e;a()};this.minSelf=function(e){c=c>e.getLeft()?c:e.getLeft();b=b>e.getTop()?b:e.getTop();d=d=0&&Math.min(g,a.getBottom())-Math.max(b,a.getTop())>=0};this.empty=function(){h=!0;g=d=b=c=0;a()};this.isEmpty=function(){return h}}; THREE.Math={clamp:function(a,c,b){return ab?b:a},clampBottom:function(a,c){return a=0&&g>=0&&f>=0&&h>=0?!0:e<0&&g<0||f<0&&h<0?!1:(e<0?c=Math.max(c,e/(e-g)):g<0&&(d=Math.min(d,e/(e-g))),f<0?c=Math.max(c,f/(f-h)):h<0&&(d=Math.min(d,f/(f-h))),df&&h.positionScreen.z0&&A.z<1))f=z[r]=z[r]||new THREE.RenderableParticle,r++,v=f,v.x=A.x/A.w,v.y=A.y/A.w,v.z=A.z,v.rotation=$.rotation.z,v.scale.x=$.scale.x*Math.abs(v.x-(A.x+e.projectionMatrix.n11)/(A.w+e.projectionMatrix.n14)),v.scale.y=$.scale.y*Math.abs(v.y-(A.y+e.projectionMatrix.n22)/(A.w+e.projectionMatrix.n24)),v.material=$.material,E.elements.push(v); -g&&E.elements.sort(b);return E}};THREE.Quaternion=function(a,c,b,d){this.set(a||0,c||0,b||0,d!==void 0?d:1)}; +THREE.Projector=function(){function a(){var a=f[e]=f[e]||new THREE.RenderableObject;e++;return a}function c(){var a=k[i]=k[i]||new THREE.RenderableVertex;i++;return a}function b(a,b){return b.z-a.z}function d(a,b){var c=0,d=1,e=a.z+a.w,g=b.z+b.w,f=-a.z+a.w,h=-b.z+b.w;return e>=0&&g>=0&&f>=0&&h>=0?!0:e<0&&g<0||f<0&&h<0?!1:(e<0?c=Math.max(c,e/(e-g)):g<0&&(d=Math.min(d,e/(e-g))),f<0?c=Math.max(c,f/(f-h)):h<0&&(d=Math.min(d,f/(f-h))),df&&h.positionScreen.z0&&L.z<1))f=t[q]=t[q]||new THREE.RenderableParticle,q++,y=f,y.x=L.x/L.w,y.y=L.y/L.w,y.z=L.z,y.rotation=aa.rotation.z,y.scale.x=aa.scale.x*Math.abs(y.x-(L.x+e.projectionMatrix.n11)/(L.w+e.projectionMatrix.n14)),y.scale.y=aa.scale.y*Math.abs(y.y-(L.y+e.projectionMatrix.n22)/(L.w+e.projectionMatrix.n24)),y.material=aa.material,w.elements.push(y); +g&&w.elements.sort(b);return w}};THREE.Quaternion=function(a,c,b,d){this.set(a||0,c||0,b||0,d!==void 0?d:1)}; THREE.Quaternion.prototype={constructor:THREE.Quaternion,set:function(a,c,b,d){this.x=a;this.y=c;this.z=b;this.w=d;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w;return this},setFromEuler:function(a){var c=Math.PI/360,b=a.x*c,d=a.y*c,g=a.z*c,a=Math.cos(d),d=Math.sin(d),c=Math.cos(-g),g=Math.sin(-g),e=Math.cos(b),b=Math.sin(b),f=a*c,h=d*g;this.w=f*e-h*b;this.x=f*b+h*e;this.y=d*c*e+a*g*b;this.z=a*g*e-d*c*b;return this},setFromAxisAngle:function(a,c){var b=c/2,d=Math.sin(b); this.x=a.x*d;this.y=a.y*d;this.z=a.z*d;this.w=Math.cos(b);return this},setFromRotationMatrix:function(a){var c=Math.pow(a.determinant(),1/3);this.w=Math.sqrt(Math.max(0,c+a.n11+a.n22+a.n33))/2;this.x=Math.sqrt(Math.max(0,c+a.n11-a.n22-a.n33))/2;this.y=Math.sqrt(Math.max(0,c-a.n11+a.n22-a.n33))/2;this.z=Math.sqrt(Math.max(0,c-a.n11-a.n22+a.n33))/2;this.x=a.n32-a.n23<0?-Math.abs(this.x):Math.abs(this.x);this.y=a.n13-a.n31<0?-Math.abs(this.y):Math.abs(this.y);this.z=a.n21-a.n12<0?-Math.abs(this.z):Math.abs(this.z); this.normalize();return this},calculateW:function(){this.w=-Math.sqrt(Math.abs(1-this.x*this.x-this.y*this.y-this.z*this.z));return this},inverse:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},normalize:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);a===0?this.w=this.z=this.y=this.x=0:(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a);return this},multiplySelf:function(a){var c= -this.x,b=this.y,d=this.z,g=this.w,e=a.x,f=a.y,h=a.z,a=a.w;this.x=c*a+g*e+b*h-d*f;this.y=b*a+g*f+d*e-c*h;this.z=d*a+g*h+c*f-b*e;this.w=g*a-c*e-b*f-d*h;return this},multiply:function(a,c){this.x=a.x*c.w+a.y*c.z-a.z*c.y+a.w*c.x;this.y=-a.x*c.z+a.y*c.w+a.z*c.x+a.w*c.y;this.z=a.x*c.y-a.y*c.x+a.z*c.w+a.w*c.z;this.w=-a.x*c.x-a.y*c.y-a.z*c.z+a.w*c.w;return this},multiplyVector3:function(a,c){c||(c=a);var b=a.x,d=a.y,g=a.z,e=this.x,f=this.y,h=this.z,i=this.w,l=i*b+f*g-h*d,m=i*d+h*b-e*g,k=i*g+e*d-f*b,b=-e* -b-f*d-h*g;c.x=l*i+b*-e+m*-h-k*-f;c.y=m*i+b*-f+k*-e-l*-h;c.z=k*i+b*-h+l*-f-m*-e;return c}}; +this.x,b=this.y,d=this.z,g=this.w,e=a.x,f=a.y,h=a.z,a=a.w;this.x=c*a+g*e+b*h-d*f;this.y=b*a+g*f+d*e-c*h;this.z=d*a+g*h+c*f-b*e;this.w=g*a-c*e-b*f-d*h;return this},multiply:function(a,c){this.x=a.x*c.w+a.y*c.z-a.z*c.y+a.w*c.x;this.y=-a.x*c.z+a.y*c.w+a.z*c.x+a.w*c.y;this.z=a.x*c.y-a.y*c.x+a.z*c.w+a.w*c.z;this.w=-a.x*c.x-a.y*c.y-a.z*c.z+a.w*c.w;return this},multiplyVector3:function(a,c){c||(c=a);var b=a.x,d=a.y,g=a.z,e=this.x,f=this.y,h=this.z,i=this.w,k=i*b+f*g-h*d,l=i*d+h*b-e*g,m=i*g+e*d-f*b,b=-e* +b-f*d-h*g;c.x=k*i+b*-e+l*-h-m*-f;c.y=l*i+b*-f+m*-e-k*-h;c.z=m*i+b*-h+k*-f-l*-e;return c}}; THREE.Quaternion.slerp=function(a,c,b,d){var g=a.w*c.w+a.x*c.x+a.y*c.y+a.z*c.z;g<0?(b.w=-c.w,b.x=-c.x,b.y=-c.y,b.z=-c.z,g=-g):b.copy(c);if(Math.abs(g)>=1)return b.w=a.w,b.x=a.x,b.y=a.y,b.z=a.z,b;var e=Math.acos(g),g=Math.sqrt(1-g*g);if(Math.abs(g)<0.0010)return b.w=0.5*(a.w+c.w),b.x=0.5*(a.x+c.x),b.y=0.5*(a.y+c.y),b.z=0.5*(a.z+c.z),b;c=Math.sin((1-d)*e)/g;d=Math.sin(d*e)/g;b.w=a.w*c+b.w*d;b.x=a.x*c+b.x*d;b.y=a.y*c+b.y*d;b.z=a.z*c+b.z*d;return b};THREE.Vertex=function(a){this.position=a||new THREE.Vector3}; THREE.Face3=function(a,c,b,d,g,e){this.a=a;this.b=c;this.c=b;this.normal=d instanceof THREE.Vector3?d:new THREE.Vector3;this.vertexNormals=d instanceof Array?d:[];this.color=g instanceof THREE.Color?g:new THREE.Color;this.vertexColors=g instanceof Array?g:[];this.vertexTangents=[];this.materialIndex=e;this.centroid=new THREE.Vector3}; THREE.Face4=function(a,c,b,d,g,e,f){this.a=a;this.b=c;this.c=b;this.d=d;this.normal=g instanceof THREE.Vector3?g:new THREE.Vector3;this.vertexNormals=g instanceof Array?g:[];this.color=e instanceof THREE.Color?e:new THREE.Color;this.vertexColors=e instanceof Array?e:[];this.vertexTangents=[];this.materialIndex=f;this.centroid=new THREE.Vector3};THREE.UV=function(a,c){this.u=a||0;this.v=c||0}; @@ -83,15 +83,15 @@ c;a++)b=this.faces[a],b.centroid.set(0,0,0),b instanceof THREE.Face3?(b.centroid b,d,g,e,f,h=new THREE.Vector3,i=new THREE.Vector3;d=0;for(g=this.faces.length;d0){this.boundingBox={x:[this.vertices[0].position.x,this.vertices[0].position.x],y:[this.vertices[0].position.y, +b.vertexNormals[1].copy(d[b.b]),b.vertexNormals[2].copy(d[b.c]),b.vertexNormals[3].copy(d[b.d]))},computeTangents:function(){function a(a,b,c,d,e,g,O){h=a.vertices[b].position;i=a.vertices[c].position;k=a.vertices[d].position;l=f[e];m=f[g];o=f[O];n=i.x-h.x;s=k.x-h.x;p=i.y-h.y;u=k.y-h.y;v=i.z-h.z;y=k.z-h.z;q=m.u-l.u;t=o.u-l.u;w=m.v-l.v;z=o.v-l.v;L=1/(q*z-t*w);C.set((z*n-w*s)*L,(z*p-w*u)*L,(z*v-w*y)*L);P.set((q*s-t*n)*L,(q*u-t*p)*L,(q*y-t*v)*L);I[b].addSelf(C);I[c].addSelf(C);I[d].addSelf(C);D[b].addSelf(P); +D[c].addSelf(P);D[d].addSelf(P)}var c,b,d,g,e,f,h,i,k,l,m,o,n,s,p,u,v,y,q,t,w,z,L,J,I=[],D=[],C=new THREE.Vector3,P=new THREE.Vector3,R=new THREE.Vector3,fa=new THREE.Vector3,M=new THREE.Vector3;c=0;for(b=this.vertices.length;c0){this.boundingBox={x:[this.vertices[0].position.x,this.vertices[0].position.x],y:[this.vertices[0].position.y, this.vertices[0].position.y],z:[this.vertices[0].position.z,this.vertices[0].position.z]};for(var c=1,b=this.vertices.length;cthis.boundingBox.x[1])this.boundingBox.x[1]=a.position.x;if(a.position.ythis.boundingBox.y[1])this.boundingBox.y[1]=a.position.y;if(a.position.zthis.boundingBox.z[1])this.boundingBox.z[1]=a.position.z}}},computeBoundingSphere:function(){for(var a=0,c=0,b=this.vertices.length;cthis.points.length-2?e:e+1;b[3]=e>this.points.length-3?e:e+2;l=this.points[b[0]];m=this.points[b[1]]; -k=this.points[b[2]];o=this.points[b[3]];h=f*f;i=f*h;d.x=c(l.x,m.x,k.x,o.x,f,h,i);d.y=c(l.y,m.y,k.y,o.y,f,h,i);d.z=c(l.z,m.z,k.z,o.z,f,h,i);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;athis.points.length-2?e:e+1;b[3]=e>this.points.length-3?e:e+2;k=this.points[b[0]];l=this.points[b[1]]; +m=this.points[b[2]];o=this.points[b[3]];h=f*f;i=f*h;d.x=c(k.x,l.x,m.x,o.x,f,h,i);d.y=c(k.y,l.y,m.y,o.y,f,h,i);d.z=c(k.z,l.z,m.z,o.z,f,h,i);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a0&&(b(THREE.NormalBlending),c(1),g("rgba("+Math.floor(t.r*255)+","+Math.floor(t.g*255)+","+Math.floor(t.b*255)+","+u+")"),n.fillRect(Math.floor(H.getX()), -Math.floor(H.getY()),Math.floor(H.getWidth()),Math.floor(H.getHeight()))),H.empty())};this.render=function(a,m){function k(a){var b,c,d,e;la.setRGB(0,0,0);ka.setRGB(0,0,0);ma.setRGB(0,0,0);b=0;for(c=a.length;b>1,k=l.height>> -1,f=e.scale.x*p,i=e.scale.y*q,j=f*m,h=i*k,U.set(a.x-j,a.y-h,a.x+j,a.y+h),G.intersects(U)&&(n.save(),n.translate(a.x,a.y),n.rotate(-e.rotation),n.scale(f,-i),n.translate(-m,-k),n.drawImage(l,0,0),n.restore())}else f instanceof THREE.ParticleCanvasMaterial&&(j=e.scale.x*p,h=e.scale.y*q,U.set(a.x-j,a.y-h,a.x+j,a.y+h),G.intersects(U)&&(d(f.color.getContextStyle()),g(f.color.getContextStyle()),n.save(),n.translate(a.x,a.y),n.rotate(-e.rotation),n.scale(j,h),f.program(n),n.restore()))}function Ka(a,e,g, -f){c(f.opacity);b(f.blending);n.beginPath();n.moveTo(a.positionScreen.x,a.positionScreen.y);n.lineTo(e.positionScreen.x,e.positionScreen.y);n.closePath();if(f instanceof THREE.LineBasicMaterial){a=f.linewidth;if(N!=a)n.lineWidth=N=a;a=f.linecap;if(A!=a)n.lineCap=A=a;a=f.linejoin;if(J!=a)n.lineJoin=J=a;d(f.color.getContextStyle());n.stroke();U.inflate(f.linewidth*2)}}function r(a,d,f,g,h,l,p,k){e.info.render.vertices+=3;e.info.render.faces++;c(k.opacity);b(k.blending);L=a.positionScreen.x;P=a.positionScreen.y; -j=d.positionScreen.x;ea=d.positionScreen.y;ha=f.positionScreen.x;F=f.positionScreen.y;u(L,P,j,ea,ha,F);if(k instanceof THREE.MeshBasicMaterial)if(k.map)k.map.mapping instanceof THREE.UVMapping&&(na=p.uvs[0],Aa(L,P,j,ea,ha,F,na[g].u,na[g].v,na[h].u,na[h].v,na[l].u,na[l].v,k.map));else if(k.envMap){if(k.envMap.mapping instanceof THREE.SphericalReflectionMapping)a=m.matrixWorldInverse,W.copy(p.vertexNormalsWorld[g]),oa=(W.x*a.n11+W.y*a.n12+W.z*a.n13)*0.5+0.5,sa=-(W.x*a.n21+W.y*a.n22+W.z*a.n23)*0.5+0.5, -W.copy(p.vertexNormalsWorld[h]),ra=(W.x*a.n11+W.y*a.n12+W.z*a.n13)*0.5+0.5,ua=-(W.x*a.n21+W.y*a.n22+W.z*a.n23)*0.5+0.5,W.copy(p.vertexNormalsWorld[l]),xa=(W.x*a.n11+W.y*a.n12+W.z*a.n13)*0.5+0.5,Q=-(W.x*a.n21+W.y*a.n22+W.z*a.n23)*0.5+0.5,Aa(L,P,j,ea,ha,F,oa,sa,ra,ua,xa,Q,k.envMap)}else k.wireframe?v(k.color,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(k.color);else if(k instanceof THREE.MeshLambertMaterial)k.map&&!k.wireframe&&(k.map.mapping instanceof THREE.UVMapping&&(na=p.uvs[0], -Aa(L,P,j,ea,ha,F,na[g].u,na[g].v,na[h].u,na[h].v,na[l].u,na[l].v,k.map)),b(THREE.SubtractiveBlending)),fa?!k.wireframe&&k.shading==THREE.SmoothShading&&p.vertexNormalsWorld.length==3?(aa.r=ba.r=V.r=la.r,aa.g=ba.g=V.g=la.g,aa.b=ba.b=V.b=la.b,o(i,p.v1.positionWorld,p.vertexNormalsWorld[0],aa),o(i,p.v2.positionWorld,p.vertexNormalsWorld[1],ba),o(i,p.v3.positionWorld,p.vertexNormalsWorld[2],V),aa.r=Math.max(0,Math.min(k.color.r*aa.r,1)),aa.g=Math.max(0,Math.min(k.color.g*aa.g,1)),aa.b=Math.max(0,Math.min(k.color.b* -aa.b,1)),ba.r=Math.max(0,Math.min(k.color.r*ba.r,1)),ba.g=Math.max(0,Math.min(k.color.g*ba.g,1)),ba.b=Math.max(0,Math.min(k.color.b*ba.b,1)),V.r=Math.max(0,Math.min(k.color.r*V.r,1)),V.g=Math.max(0,Math.min(k.color.g*V.g,1)),V.b=Math.max(0,Math.min(k.color.b*V.b,1)),C.r=(ba.r+V.r)*0.5,C.g=(ba.g+V.g)*0.5,C.b=(ba.b+V.b)*0.5,ja=E(aa,ba,V,C),Ea(L,P,j,ea,ha,F,0,0,1,0,0,1,ja)):(X.r=la.r,X.g=la.g,X.b=la.b,o(i,p.centroidWorld,p.normalWorld,X),X.r=Math.max(0,Math.min(k.color.r*X.r,1)),X.g=Math.max(0,Math.min(k.color.g* -X.g,1)),X.b=Math.max(0,Math.min(k.color.b*X.b,1)),k.wireframe?v(X,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(X)):k.wireframe?v(k.color,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(k.color);else if(k instanceof THREE.MeshDepthMaterial)Z=m.near,da=m.far,aa.r=aa.g=aa.b=1-Da(a.positionScreen.z,Z,da),ba.r=ba.g=ba.b=1-Da(d.positionScreen.z,Z,da),V.r=V.g=V.b=1-Da(f.positionScreen.z,Z,da),C.r=(ba.r+V.r)*0.5,C.g=(ba.g+V.g)*0.5,C.b=(ba.b+V.b)*0.5,ja=E(aa,ba,V,C),Ea(L,P, -j,ea,ha,F,0,0,1,0,0,1,ja);else if(k instanceof THREE.MeshNormalMaterial)X.r=Fa(p.normalWorld.x),X.g=Fa(p.normalWorld.y),X.b=Fa(p.normalWorld.z),k.wireframe?v(X,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(X)}function La(a,d,f,g,h,p,l,k,qa){e.info.render.vertices+=4;e.info.render.faces++;c(k.opacity);b(k.blending);if(k.map||k.envMap)r(a,d,g,0,1,3,l,k,qa),r(h,f,p,1,2,3,l,k,qa);else if(L=a.positionScreen.x,P=a.positionScreen.y,j=d.positionScreen.x,ea=d.positionScreen.y,ha=f.positionScreen.x, -F=f.positionScreen.y,B=g.positionScreen.x,R=g.positionScreen.y,Y=h.positionScreen.x,O=h.positionScreen.y,ga=p.positionScreen.x,$=p.positionScreen.y,k instanceof THREE.MeshBasicMaterial)Ga(L,P,j,ea,ha,F,B,R),k.wireframe?v(k.color,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(k.color);else if(k instanceof THREE.MeshLambertMaterial)fa?!k.wireframe&&k.shading==THREE.SmoothShading&&l.vertexNormalsWorld.length==4?(aa.r=ba.r=V.r=C.r=la.r,aa.g=ba.g=V.g=C.g=la.g,aa.b=ba.b=V.b=C.b=la.b,o(i, -l.v1.positionWorld,l.vertexNormalsWorld[0],aa),o(i,l.v2.positionWorld,l.vertexNormalsWorld[1],ba),o(i,l.v4.positionWorld,l.vertexNormalsWorld[3],V),o(i,l.v3.positionWorld,l.vertexNormalsWorld[2],C),aa.r=Math.max(0,Math.min(k.color.r*aa.r,1)),aa.g=Math.max(0,Math.min(k.color.g*aa.g,1)),aa.b=Math.max(0,Math.min(k.color.b*aa.b,1)),ba.r=Math.max(0,Math.min(k.color.r*ba.r,1)),ba.g=Math.max(0,Math.min(k.color.g*ba.g,1)),ba.b=Math.max(0,Math.min(k.color.b*ba.b,1)),V.r=Math.max(0,Math.min(k.color.r*V.r,1)), -V.g=Math.max(0,Math.min(k.color.g*V.g,1)),V.b=Math.max(0,Math.min(k.color.b*V.b,1)),C.r=Math.max(0,Math.min(k.color.r*C.r,1)),C.g=Math.max(0,Math.min(k.color.g*C.g,1)),C.b=Math.max(0,Math.min(k.color.b*C.b,1)),ja=E(aa,ba,V,C),u(L,P,j,ea,B,R),Ea(L,P,j,ea,B,R,0,0,1,0,0,1,ja),u(Y,O,ha,F,ga,$),Ea(Y,O,ha,F,ga,$,1,0,1,1,0,1,ja)):(X.r=la.r,X.g=la.g,X.b=la.b,o(i,l.centroidWorld,l.normalWorld,X),X.r=Math.max(0,Math.min(k.color.r*X.r,1)),X.g=Math.max(0,Math.min(k.color.g*X.g,1)),X.b=Math.max(0,Math.min(k.color.b* -X.b,1)),Ga(L,P,j,ea,ha,F,B,R),k.wireframe?v(X,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(X)):(Ga(L,P,j,ea,ha,F,B,R),k.wireframe?v(k.color,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(k.color));else if(k instanceof THREE.MeshNormalMaterial)X.r=Fa(l.normalWorld.x),X.g=Fa(l.normalWorld.y),X.b=Fa(l.normalWorld.z),Ga(L,P,j,ea,ha,F,B,R),k.wireframe?v(X,k.wireframeLinewidth,k.wireframeLinecap,k.wireframeLinejoin):z(X);else if(k instanceof THREE.MeshDepthMaterial)Z=m.near, -da=m.far,aa.r=aa.g=aa.b=1-Da(a.positionScreen.z,Z,da),ba.r=ba.g=ba.b=1-Da(d.positionScreen.z,Z,da),V.r=V.g=V.b=1-Da(g.positionScreen.z,Z,da),C.r=C.g=C.b=1-Da(f.positionScreen.z,Z,da),ja=E(aa,ba,V,C),u(L,P,j,ea,B,R),Ea(L,P,j,ea,B,R,0,0,1,0,0,1,ja),u(Y,O,ha,F,ga,$),Ea(Y,O,ha,F,ga,$,1,0,1,1,0,1,ja)}function u(a,b,c,d,e,f){n.beginPath();n.moveTo(a,b);n.lineTo(c,d);n.lineTo(e,f);n.lineTo(a,b);n.closePath()}function Ga(a,b,c,d,e,f,g,h){n.beginPath();n.moveTo(a,b);n.lineTo(c,d);n.lineTo(e,f);n.lineTo(g, -h);n.lineTo(a,b);n.closePath()}function v(a,b,c,e){if(N!=b)n.lineWidth=N=b;if(A!=c)n.lineCap=A=c;if(J!=e)n.lineJoin=J=e;d(a.getContextStyle());n.stroke();U.inflate(b*2)}function z(a){g(a.getContextStyle());n.fill()}function Aa(a,b,c,d,e,f,h,j,i,k,l,p,m){if(m.image.width!=0){if(m.needsUpdate==!0||I[m.id]==void 0){var qa=m.wrapS==THREE.RepeatWrapping,o=m.wrapT==THREE.RepeatWrapping;I[m.id]=n.createPattern(m.image,qa&&o?"repeat":qa&&!o?"repeat-x":!qa&&o?"repeat-y":"no-repeat");m.needsUpdate=!1}g(I[m.id]); -var qa=m.offset.x/m.repeat.x,o=m.offset.y/m.repeat.y,Q=(m.image.width-1)*m.repeat.x,m=(m.image.height-1)*m.repeat.y,h=(h+qa)*Q,j=(j+o)*m,i=(i+qa)*Q,k=(k+o)*m,l=(l+qa)*Q,p=(p+o)*m;c-=a;d-=b;e-=a;f-=b;i-=h;k-=j;l-=h;p-=j;qa=1/(i*p-l*k);m=(p*c-k*e)*qa;k=(p*d-k*f)*qa;c=(i*e-l*c)*qa;d=(i*f-l*d)*qa;a=a-m*h-c*j;b=b-k*h-d*j;n.save();n.transform(m,k,c,d,a,b);n.fill();n.restore()}}function Ea(a,b,c,d,e,f,g,h,j,i,k,l,p){var m,qa;m=p.width-1;qa=p.height-1;g*=m;h*=qa;j*=m;i*=qa;k*=m;l*=qa;c-=a;d-=b;e-=a;f-=b; -j-=g;i-=h;k-=g;l-=h;qa=1/(j*l-k*i);m=(l*c-i*e)*qa;i=(l*d-i*f)*qa;c=(j*e-k*c)*qa;d=(j*f-k*d)*qa;a=a-m*g-c*h;b=b-i*g-d*h;n.save();n.transform(m,i,c,d,a,b);n.clip();n.drawImage(p,0,0);n.restore()}function E(a,b,c,d){var e=~~(a.r*255),f=~~(a.g*255),a=~~(a.b*255),g=~~(b.r*255),h=~~(b.g*255),b=~~(b.b*255),j=~~(c.r*255),i=~~(c.g*255),c=~~(c.b*255),k=~~(d.r*255),l=~~(d.g*255),d=~~(d.b*255);pa[0]=e<0?0:e>255?255:e;pa[1]=f<0?0:f>255?255:f;pa[2]=a<0?0:a>255?255:a;pa[4]=g<0?0:g>255?255:g;pa[5]=h<0?0:h>255?255: -h;pa[6]=b<0?0:b>255?255:b;pa[8]=j<0?0:j>255?255:j;pa[9]=i<0?0:i>255?255:i;pa[10]=c<0?0:c>255?255:c;pa[12]=k<0?0:k>255?255:k;pa[13]=l<0?0:l>255?255:l;pa[14]=d<0?0:d>255?255:d;ia.putImageData(ya,0,0);Ca.drawImage(va,0,0);return wa}function Da(a,b,c){a=(a-b)/(c-b);return a*a*(3-2*a)}function Fa(a){a=(a+1)*0.5;return a<0?0:a>1?1:a}function Ba(a,b){var c=b.x-a.x,d=b.y-a.y,e=c*c+d*d;e!=0&&(e=1/Math.sqrt(e),c*=e,d*=e,b.x+=c,b.y+=d,a.x-=c,a.y-=d)}var Ha,Ja,ta,za;this.autoClear?this.clear():n.setTransform(1, -0,0,-1,p,q);e.info.render.vertices=0;e.info.render.faces=0;f=l.projectScene(a,m,this.sortElements);h=f.elements;i=f.lights;(fa=i.length>0)&&k(i);Ha=0;for(Ja=h.length;Ha1?1:a}var d=this,g,e,f,h=new THREE.Projector,i=document.createElementNS("http://www.w3.org/2000/svg","svg"),l,m,k,o,p,q,n,t,u=new THREE.Rectangle,v=new THREE.Rectangle,r=!1,z=new THREE.Color,E=new THREE.Color,N=new THREE.Color,A=new THREE.Color,J,x=new THREE.Vector3,w=[],D=[],M,S,ca,L=1;this.domElement=i;this.sortElements=this.sortObjects=this.autoClear=!0;this.info={render:{vertices:0, -faces:0}};this.setQuality=function(a){switch(a){case "high":L=1;break;case "low":L=0}};this.setSize=function(a,b){l=a;m=b;k=l/2;o=m/2;i.setAttribute("viewBox",-k+" "+-o+" "+l+" "+m);i.setAttribute("width",l);i.setAttribute("height",m);u.set(-k,-o,k,o)};this.clear=function(){for(;i.childNodes.length>0;)i.removeChild(i.childNodes[0])};this.render=function(l,j){var m,x,F,B;this.autoClear&&this.clear();d.info.render.vertices=0;d.info.render.faces=0;g=h.projectScene(l,j,this.sortElements);e=g.elements; -f=g.lights;ca=S=0;if(r=f.length>0){E.setRGB(0,0,0);N.setRGB(0,0,0);A.setRGB(0,0,0);m=0;for(x=f.length;m0&&(b(THREE.NormalBlending),c(1),g("rgba("+Math.floor(u.r*255)+","+Math.floor(u.g*255)+","+Math.floor(u.b*255)+","+v+")"),p.fillRect(Math.floor(E.getX()), +Math.floor(E.getY()),Math.floor(E.getWidth()),Math.floor(E.getHeight()))),E.empty())};this.render=function(a,l){function m(a){var b,c,d,e;H.setRGB(0,0,0);ia.setRGB(0,0,0);W.setRGB(0,0,0);b=0;for(c=a.length;b>1,da=k.height>>1,f= +e.scale.x*n,i=e.scale.y*s,j=f*l,h=i*da,Y.set(a.x-j,a.y-h,a.x+j,a.y+h),S.intersects(Y)&&(p.save(),p.translate(a.x,a.y),p.rotate(-e.rotation),p.scale(f,-i),p.translate(-l,-da),p.drawImage(k,0,0),p.restore())}else f instanceof THREE.ParticleCanvasMaterial&&(j=e.scale.x*n,h=e.scale.y*s,Y.set(a.x-j,a.y-h,a.x+j,a.y+h),S.intersects(Y)&&(d(f.color.getContextStyle()),g(f.color.getContextStyle()),p.save(),p.translate(a.x,a.y),p.rotate(-e.rotation),p.scale(j,h),f.program(p),p.restore()))}function u(a,e,g,f){c(f.opacity); +b(f.blending);p.beginPath();p.moveTo(a.positionScreen.x,a.positionScreen.y);p.lineTo(e.positionScreen.x,e.positionScreen.y);p.closePath();if(f instanceof THREE.LineBasicMaterial){a=f.linewidth;if(z!=a)p.lineWidth=z=a;a=f.linecap;if(L!=a)p.lineCap=L=a;a=f.linejoin;if(J!=a)p.lineJoin=J=a;d(f.color.getContextStyle());p.stroke();Y.inflate(f.linewidth*2)}}function v(a,d,f,g,j,h,k,n){e.info.render.vertices+=3;e.info.render.faces++;c(n.opacity);b(n.blending);M=a.positionScreen.x;N=a.positionScreen.y;ga= +d.positionScreen.x;ka=d.positionScreen.y;Z=f.positionScreen.x;F=f.positionScreen.y;y(M,N,ga,ka,Z,F);if(n instanceof THREE.MeshBasicMaterial)if(n.map)n.map.mapping instanceof THREE.UVMapping&&(na=k.uvs[0],w(M,N,ga,ka,Z,F,na[g].u,na[g].v,na[j].u,na[j].v,na[h].u,na[h].v,n.map));else if(n.envMap){if(n.envMap.mapping instanceof THREE.SphericalReflectionMapping)a=l.matrixWorldInverse,X.copy(k.vertexNormalsWorld[g]),ua=(X.x*a.n11+X.y*a.n12+X.z*a.n13)*0.5+0.5,va=-(X.x*a.n21+X.y*a.n22+X.z*a.n23)*0.5+0.5,X.copy(k.vertexNormalsWorld[j]), +pa=(X.x*a.n11+X.y*a.n12+X.z*a.n13)*0.5+0.5,ra=-(X.x*a.n21+X.y*a.n22+X.z*a.n23)*0.5+0.5,X.copy(k.vertexNormalsWorld[h]),Aa=(X.x*a.n11+X.y*a.n12+X.z*a.n13)*0.5+0.5,x=-(X.x*a.n21+X.y*a.n22+X.z*a.n23)*0.5+0.5,w(M,N,ga,ka,Z,F,ua,va,pa,ra,Aa,x,n.envMap)}else n.wireframe?wa(n.color,n.wireframeLinewidth,n.wireframeLinecap,n.wireframeLinejoin):Ba(n.color);else if(n instanceof THREE.MeshLambertMaterial)n.map&&!n.wireframe&&(n.map.mapping instanceof THREE.UVMapping&&(na=k.uvs[0],w(M,N,ga,ka,Z,F,na[g].u,na[g].v, +na[j].u,na[j].v,na[h].u,na[h].v,n.map)),b(THREE.SubtractiveBlending)),ja?!n.wireframe&&n.shading==THREE.SmoothShading&&k.vertexNormalsWorld.length==3?(ba.r=U.r=ea.r=H.r,ba.g=U.g=ea.g=H.g,ba.b=U.b=ea.b=H.b,o(i,k.v1.positionWorld,k.vertexNormalsWorld[0],ba),o(i,k.v2.positionWorld,k.vertexNormalsWorld[1],U),o(i,k.v3.positionWorld,k.vertexNormalsWorld[2],ea),ba.r=Math.max(0,Math.min(n.color.r*ba.r,1)),ba.g=Math.max(0,Math.min(n.color.g*ba.g,1)),ba.b=Math.max(0,Math.min(n.color.b*ba.b,1)),U.r=Math.max(0, +Math.min(n.color.r*U.r,1)),U.g=Math.max(0,Math.min(n.color.g*U.g,1)),U.b=Math.max(0,Math.min(n.color.b*U.b,1)),ea.r=Math.max(0,Math.min(n.color.r*ea.r,1)),ea.g=Math.max(0,Math.min(n.color.g*ea.g,1)),ea.b=Math.max(0,Math.min(n.color.b*ea.b,1)),ca.r=(U.r+ea.r)*0.5,ca.g=(U.g+ea.g)*0.5,ca.b=(U.b+ea.b)*0.5,oa=Ga(ba,U,ea,ca),Ea(M,N,ga,ka,Z,F,0,0,1,0,0,1,oa)):(V.r=H.r,V.g=H.g,V.b=H.b,o(i,k.centroidWorld,k.normalWorld,V),V.r=Math.max(0,Math.min(n.color.r*V.r,1)),V.g=Math.max(0,Math.min(n.color.g*V.g,1)), +V.b=Math.max(0,Math.min(n.color.b*V.b,1)),n.wireframe?wa(V,n.wireframeLinewidth,n.wireframeLinecap,n.wireframeLinejoin):Ba(V)):n.wireframe?wa(n.color,n.wireframeLinewidth,n.wireframeLinecap,n.wireframeLinejoin):Ba(n.color);else if(n instanceof THREE.MeshDepthMaterial)$=l.near,la=l.far,ba.r=ba.g=ba.b=1-Da(a.positionScreen.z,$,la),U.r=U.g=U.b=1-Da(d.positionScreen.z,$,la),ea.r=ea.g=ea.b=1-Da(f.positionScreen.z,$,la),ca.r=(U.r+ea.r)*0.5,ca.g=(U.g+ea.g)*0.5,ca.b=(U.b+ea.b)*0.5,oa=Ga(ba,U,ea,ca),Ea(M, +N,ga,ka,Z,F,0,0,1,0,0,1,oa);else if(n instanceof THREE.MeshNormalMaterial)V.r=Fa(k.normalWorld.x),V.g=Fa(k.normalWorld.y),V.b=Fa(k.normalWorld.z),n.wireframe?wa(V,n.wireframeLinewidth,n.wireframeLinecap,n.wireframeLinejoin):Ba(V)}function Ja(a,d,f,g,h,n,k,da,m){e.info.render.vertices+=4;e.info.render.faces++;c(da.opacity);b(da.blending);if(da.map||da.envMap)v(a,d,g,0,1,3,k,da,m),v(h,f,n,1,2,3,k,da,m);else if(M=a.positionScreen.x,N=a.positionScreen.y,ga=d.positionScreen.x,ka=d.positionScreen.y,Z=f.positionScreen.x, +F=f.positionScreen.y,B=g.positionScreen.x,Q=g.positionScreen.y,O=h.positionScreen.x,j=h.positionScreen.y,ha=n.positionScreen.x,aa=n.positionScreen.y,da instanceof THREE.MeshBasicMaterial)t(M,N,ga,ka,Z,F,B,Q),da.wireframe?wa(da.color,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):Ba(da.color);else if(da instanceof THREE.MeshLambertMaterial)ja?!da.wireframe&&da.shading==THREE.SmoothShading&&k.vertexNormalsWorld.length==4?(ba.r=U.r=ea.r=ca.r=H.r,ba.g=U.g=ea.g=ca.g=H.g,ba.b=U.b=ea.b= +ca.b=H.b,o(i,k.v1.positionWorld,k.vertexNormalsWorld[0],ba),o(i,k.v2.positionWorld,k.vertexNormalsWorld[1],U),o(i,k.v4.positionWorld,k.vertexNormalsWorld[3],ea),o(i,k.v3.positionWorld,k.vertexNormalsWorld[2],ca),ba.r=Math.max(0,Math.min(da.color.r*ba.r,1)),ba.g=Math.max(0,Math.min(da.color.g*ba.g,1)),ba.b=Math.max(0,Math.min(da.color.b*ba.b,1)),U.r=Math.max(0,Math.min(da.color.r*U.r,1)),U.g=Math.max(0,Math.min(da.color.g*U.g,1)),U.b=Math.max(0,Math.min(da.color.b*U.b,1)),ea.r=Math.max(0,Math.min(da.color.r* +ea.r,1)),ea.g=Math.max(0,Math.min(da.color.g*ea.g,1)),ea.b=Math.max(0,Math.min(da.color.b*ea.b,1)),ca.r=Math.max(0,Math.min(da.color.r*ca.r,1)),ca.g=Math.max(0,Math.min(da.color.g*ca.g,1)),ca.b=Math.max(0,Math.min(da.color.b*ca.b,1)),oa=Ga(ba,U,ea,ca),y(M,N,ga,ka,B,Q),Ea(M,N,ga,ka,B,Q,0,0,1,0,0,1,oa),y(O,j,Z,F,ha,aa),Ea(O,j,Z,F,ha,aa,1,0,1,1,0,1,oa)):(V.r=H.r,V.g=H.g,V.b=H.b,o(i,k.centroidWorld,k.normalWorld,V),V.r=Math.max(0,Math.min(da.color.r*V.r,1)),V.g=Math.max(0,Math.min(da.color.g*V.g,1)), +V.b=Math.max(0,Math.min(da.color.b*V.b,1)),t(M,N,ga,ka,Z,F,B,Q),da.wireframe?wa(V,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):Ba(V)):(t(M,N,ga,ka,Z,F,B,Q),da.wireframe?wa(da.color,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):Ba(da.color));else if(da instanceof THREE.MeshNormalMaterial)V.r=Fa(k.normalWorld.x),V.g=Fa(k.normalWorld.y),V.b=Fa(k.normalWorld.z),t(M,N,ga,ka,Z,F,B,Q),da.wireframe?wa(V,da.wireframeLinewidth,da.wireframeLinecap,da.wireframeLinejoin):Ba(V); +else if(da instanceof THREE.MeshDepthMaterial)$=l.near,la=l.far,ba.r=ba.g=ba.b=1-Da(a.positionScreen.z,$,la),U.r=U.g=U.b=1-Da(d.positionScreen.z,$,la),ea.r=ea.g=ea.b=1-Da(g.positionScreen.z,$,la),ca.r=ca.g=ca.b=1-Da(f.positionScreen.z,$,la),oa=Ga(ba,U,ea,ca),y(M,N,ga,ka,B,Q),Ea(M,N,ga,ka,B,Q,0,0,1,0,0,1,oa),y(O,j,Z,F,ha,aa),Ea(O,j,Z,F,ha,aa,1,0,1,1,0,1,oa)}function y(a,b,c,d,e,f){p.beginPath();p.moveTo(a,b);p.lineTo(c,d);p.lineTo(e,f);p.lineTo(a,b);p.closePath()}function t(a,b,c,d,e,f,g,j){p.beginPath(); +p.moveTo(a,b);p.lineTo(c,d);p.lineTo(e,f);p.lineTo(g,j);p.lineTo(a,b);p.closePath()}function wa(a,b,c,e){if(z!=b)p.lineWidth=z=b;if(L!=c)p.lineCap=L=c;if(J!=e)p.lineJoin=J=e;d(a.getContextStyle());p.stroke();Y.inflate(b*2)}function Ba(a){g(a.getContextStyle());p.fill()}function w(a,b,c,d,e,f,j,h,i,n,k,da,l){if(l.image.width!=0){if(l.needsUpdate==!0||K[l.id]==void 0){var m=l.wrapS==THREE.RepeatWrapping,o=l.wrapT==THREE.RepeatWrapping;K[l.id]=p.createPattern(l.image,m&&o?"repeat":m&&!o?"repeat-x":!m&& +o?"repeat-y":"no-repeat");l.needsUpdate=!1}g(K[l.id]);var m=l.offset.x/l.repeat.x,o=l.offset.y/l.repeat.y,x=(l.image.width-1)*l.repeat.x,l=(l.image.height-1)*l.repeat.y,j=(j+m)*x,h=(h+o)*l,i=(i+m)*x,n=(n+o)*l,k=(k+m)*x,da=(da+o)*l;c-=a;d-=b;e-=a;f-=b;i-=j;n-=h;k-=j;da-=h;m=1/(i*da-k*n);l=(da*c-n*e)*m;n=(da*d-n*f)*m;c=(i*e-k*c)*m;d=(i*f-k*d)*m;a=a-l*j-c*h;b=b-n*j-d*h;p.save();p.transform(l,n,c,d,a,b);p.fill();p.restore()}}function Ea(a,b,c,d,e,f,g,j,h,i,n,k,da){var l,m;l=da.width-1;m=da.height-1;g*= +l;j*=m;h*=l;i*=m;n*=l;k*=m;c-=a;d-=b;e-=a;f-=b;h-=g;i-=j;n-=g;k-=j;m=1/(h*k-n*i);l=(k*c-i*e)*m;i=(k*d-i*f)*m;c=(h*e-n*c)*m;d=(h*f-n*d)*m;a=a-l*g-c*j;b=b-i*g-d*j;p.save();p.transform(l,i,c,d,a,b);p.clip();p.drawImage(da,0,0);p.restore()}function Ga(a,b,c,d){var e=~~(a.r*255),f=~~(a.g*255),a=~~(a.b*255),g=~~(b.r*255),j=~~(b.g*255),b=~~(b.b*255),h=~~(c.r*255),i=~~(c.g*255),c=~~(c.b*255),n=~~(d.r*255),k=~~(d.g*255),d=~~(d.b*255);G[0]=e<0?0:e>255?255:e;G[1]=f<0?0:f>255?255:f;G[2]=a<0?0:a>255?255:a;G[4]= +g<0?0:g>255?255:g;G[5]=j<0?0:j>255?255:j;G[6]=b<0?0:b>255?255:b;G[8]=h<0?0:h>255?255:h;G[9]=i<0?0:i>255?255:i;G[10]=c<0?0:c>255?255:c;G[12]=n<0?0:n>255?255:n;G[13]=k<0?0:k>255?255:k;G[14]=d<0?0:d>255?255:d;xa.putImageData(ma,0,0);ta.drawImage(sa,0,0);return ya}function Da(a,b,c){a=(a-b)/(c-b);return a*a*(3-2*a)}function Fa(a){a=(a+1)*0.5;return a<0?0:a>1?1:a}function Ca(a,b){var c=b.x-a.x,d=b.y-a.y,e=c*c+d*d;e!=0&&(e=1/Math.sqrt(e),c*=e,d*=e,b.x+=c,b.y+=d,a.x-=c,a.y-=d)}var Ha,Ia,qa,za;this.autoClear? +this.clear():p.setTransform(1,0,0,-1,n,s);e.info.render.vertices=0;e.info.render.faces=0;f=k.projectScene(a,l,this.sortElements);h=f.elements;i=f.lights;(ja=i.length>0)&&m(i);Ha=0;for(Ia=h.length;Ha1?1:a}var d=this,g,e,f,h=new THREE.Projector,i=document.createElementNS("http://www.w3.org/2000/svg","svg"),k,l,m,o,n,s,p,u,v=new THREE.Rectangle,y=new THREE.Rectangle,q=!1,t=new THREE.Color,w=new THREE.Color,z=new THREE.Color,L=new THREE.Color,J,I=new THREE.Vector3,D=[],C=[],P,R,fa,M=1;this.domElement=i;this.sortElements=this.sortObjects=this.autoClear=!0;this.info={render:{vertices:0, +faces:0}};this.setQuality=function(a){switch(a){case "high":M=1;break;case "low":M=0}};this.setSize=function(a,b){k=a;l=b;m=k/2;o=l/2;i.setAttribute("viewBox",-m+" "+-o+" "+k+" "+l);i.setAttribute("width",k);i.setAttribute("height",l);v.set(-m,-o,m,o)};this.clear=function(){for(;i.childNodes.length>0;)i.removeChild(i.childNodes[0])};this.render=function(k,l){var I,D,F,B;this.autoClear&&this.clear();d.info.render.vertices=0;d.info.render.faces=0;g=h.projectScene(k,l,this.sortElements);e=g.elements; +f=g.lights;fa=R=0;if(q=f.length>0){w.setRGB(0,0,0);z.setRGB(0,0,0);L.setRGB(0,0,0);I=0;for(D=f.length;I=0)return a.geometry.materials[b.materialIndex]}function d(a,b,c){var d,e,g,f,h=a.vertices;f=h.length;var i=a.colors,k=i.length,l=a.__vertexArray,m=a.__colorArray,p=a.__sortArray,n=a.__dirtyVertices,o=a.__dirtyColors,Q=a.__webglCustomAttributesList;if(c.sortParticles){sa.multiplySelf(c.matrixWorld);for(d=0;d=0)a&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglVertexBuffer),j.vertexAttribPointer(b.position,3,j.FLOAT,!1,0,0));else if(f.morphTargetBase){c=d.program.attributes;f.morphTargetBase!==-1?(j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphTargetsBuffers[f.morphTargetBase]), -j.vertexAttribPointer(c.position,3,j.FLOAT,!1,0,0)):c.position>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglVertexBuffer),j.vertexAttribPointer(c.position,3,j.FLOAT,!1,0,0));if(f.morphTargetForcedOrder.length){h=0;var k=f.morphTargetForcedOrder;for(i=f.morphTargetInfluences;hl&&(m=p,l=i[m]);j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphTargetsBuffers[m]);j.vertexAttribPointer(c["morphTarget"+h],3,j.FLOAT,!1,0,0);f.__webglMorphTargetInfluences[h]=l;k[m]=1;l=-1;h++}}d.program.uniforms.morphTargetInfluences!==null&&j.uniform1fv(d.program.uniforms.morphTargetInfluences,f.__webglMorphTargetInfluences)}if(a){if(e.__webglCustomAttributesList){h= -0;for(i=e.__webglCustomAttributesList.length;h=0&&(j.bindBuffer(j.ARRAY_BUFFER,c.buffer),j.vertexAttribPointer(b[c.buffer.belongsToAttribute],c.size,j.FLOAT,!1,0,0))}b.color>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglColorBuffer),j.vertexAttribPointer(b.color,3,j.FLOAT,!1,0,0));b.normal>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglNormalBuffer),j.vertexAttribPointer(b.normal,3,j.FLOAT,!1,0,0));b.tangent>=0&&(j.bindBuffer(j.ARRAY_BUFFER, -e.__webglTangentBuffer),j.vertexAttribPointer(b.tangent,4,j.FLOAT,!1,0,0));b.uv>=0&&(e.__webglUVBuffer?(j.bindBuffer(j.ARRAY_BUFFER,e.__webglUVBuffer),j.vertexAttribPointer(b.uv,2,j.FLOAT,!1,0,0),j.enableVertexAttribArray(b.uv)):j.disableVertexAttribArray(b.uv));b.uv2>=0&&(e.__webglUV2Buffer?(j.bindBuffer(j.ARRAY_BUFFER,e.__webglUV2Buffer),j.vertexAttribPointer(b.uv2,2,j.FLOAT,!1,0,0),j.enableVertexAttribArray(b.uv2)):j.disableVertexAttribArray(b.uv2));d.skinning&&b.skinVertexA>=0&&b.skinVertexB>= -0&&b.skinIndex>=0&&b.skinWeight>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinVertexABuffer),j.vertexAttribPointer(b.skinVertexA,4,j.FLOAT,!1,0,0),j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinVertexBBuffer),j.vertexAttribPointer(b.skinVertexB,4,j.FLOAT,!1,0,0),j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinIndicesBuffer),j.vertexAttribPointer(b.skinIndex,4,j.FLOAT,!1,0,0),j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinWeightsBuffer),j.vertexAttribPointer(b.skinWeight,4,j.FLOAT,!1,0,0))}f instanceof THREE.Mesh?(d.wireframe? -(d=d.wireframeLinewidth,d!==I&&(j.lineWidth(d),I=d),a&&j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,e.__webglLineBuffer),j.drawElements(j.LINES,e.__webglLineCount,j.UNSIGNED_SHORT,0)):(a&&j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,e.__webglFaceBuffer),j.drawElements(j.TRIANGLES,e.__webglFaceCount,j.UNSIGNED_SHORT,0)),P.info.render.calls++,P.info.render.vertices+=e.__webglFaceCount,P.info.render.faces+=e.__webglFaceCount/3):f instanceof THREE.Line?(f=f.type===THREE.LineStrip?j.LINE_STRIP:j.LINES,d=d.linewidth,d!== -I&&(j.lineWidth(d),I=d),j.drawArrays(f,0,e.__webglLineCount),P.info.render.calls++):f instanceof THREE.ParticleSystem?(j.drawArrays(j.POINTS,0,e.__webglParticleCount),P.info.render.calls++):f instanceof THREE.Ribbon&&(j.drawArrays(j.TRIANGLE_STRIP,0,e.__webglVertexCount),P.info.render.calls++)}}function f(a,b,c){if(!a.__webglVertexBuffer)a.__webglVertexBuffer=j.createBuffer();if(!a.__webglNormalBuffer)a.__webglNormalBuffer=j.createBuffer();a.hasPos&&(j.bindBuffer(j.ARRAY_BUFFER,a.__webglVertexBuffer), -j.bufferData(j.ARRAY_BUFFER,a.positionArray,j.DYNAMIC_DRAW),j.enableVertexAttribArray(b.attributes.position),j.vertexAttribPointer(b.attributes.position,3,j.FLOAT,!1,0,0));if(a.hasNormal){j.bindBuffer(j.ARRAY_BUFFER,a.__webglNormalBuffer);if(c===THREE.FlatShading){var d,e,f,g,h,i,k,l,m,p,n=a.count*3;for(p=0;p=0)b=b.geometry.materials[c],b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}else if(b=d)b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}function n(a,b){return b.z-a.z}function t(a){var b,c,d,l=0,m,p,n,q,Q,H,t=a.lights;W||(W=new THREE.PerspectiveCamera(P.shadowCameraFov,P.shadowMapWidth/P.shadowMapHeight,P.shadowCameraNear,P.shadowCameraFar));b=0;for(c= -t.length;b=0;c--)a[c].object===b&&a.splice(c,1)}function N(a,b,c){a.push({buffer:b,object:c, -opaque:null,transparent:null})}function A(a){if(a!==$){switch(a){case THREE.AdditiveBlending:j.blendEquation(j.FUNC_ADD);j.blendFunc(j.SRC_ALPHA,j.ONE);break;case THREE.SubtractiveBlending:j.blendEquation(j.FUNC_ADD);j.blendFunc(j.ZERO,j.ONE_MINUS_SRC_COLOR);break;case THREE.MultiplyBlending:j.blendEquation(j.FUNC_ADD);j.blendFunc(j.ZERO,j.SRC_COLOR);break;default:j.blendEquationSeparate(j.FUNC_ADD,j.FUNC_ADD),j.blendFuncSeparate(j.SRC_ALPHA,j.ONE_MINUS_SRC_ALPHA,j.ONE,j.ONE_MINUS_SRC_ALPHA)}$=a}} -function J(a,b,c){(c.width&c.width-1)===0&&(c.height&c.height-1)===0?(j.texParameteri(a,j.TEXTURE_WRAP_S,L(b.wrapS)),j.texParameteri(a,j.TEXTURE_WRAP_T,L(b.wrapT)),j.texParameteri(a,j.TEXTURE_MAG_FILTER,L(b.magFilter)),j.texParameteri(a,j.TEXTURE_MIN_FILTER,L(b.minFilter)),j.generateMipmap(a)):(j.texParameteri(a,j.TEXTURE_WRAP_S,j.CLAMP_TO_EDGE),j.texParameteri(a,j.TEXTURE_WRAP_T,j.CLAMP_TO_EDGE),j.texParameteri(a,j.TEXTURE_MAG_FILTER,ca(b.magFilter)),j.texParameteri(a,j.TEXTURE_MIN_FILTER,ca(b.minFilter)))} -function x(a,b){if(a.needsUpdate){if(!a.__webglInit)a.__webglInit=!0,a.__webglTexture=j.createTexture(),P.info.memory.textures++;j.activeTexture(j.TEXTURE0+b);j.bindTexture(j.TEXTURE_2D,a.__webglTexture);a instanceof THREE.DataTexture?j.texImage2D(j.TEXTURE_2D,0,L(a.format),a.image.width,a.image.height,0,L(a.format),j.UNSIGNED_BYTE,a.image.data):j.texImage2D(j.TEXTURE_2D,0,j.RGBA,j.RGBA,j.UNSIGNED_BYTE,a.image);J(j.TEXTURE_2D,a,a.image);a.needsUpdate=!1}else j.activeTexture(j.TEXTURE0+b),j.bindTexture(j.TEXTURE_2D, -a.__webglTexture)}function w(a,b){j.bindRenderbuffer(j.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(j.renderbufferStorage(j.RENDERBUFFER,j.DEPTH_COMPONENT16,b.width,b.height),j.framebufferRenderbuffer(j.FRAMEBUFFER,j.DEPTH_ATTACHMENT,j.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(j.renderbufferStorage(j.RENDERBUFFER,j.DEPTH_STENCIL,b.width,b.height),j.framebufferRenderbuffer(j.FRAMEBUFFER,j.DEPTH_STENCIL_ATTACHMENT,j.RENDERBUFFER,a)):j.renderbufferStorage(j.RENDERBUFFER,j.RGBA4,b.width,b.height)} -function D(a){var b=a instanceof THREE.WebGLRenderTargetCube;if(a&&!a.__webglFramebuffer){if(a.depthBuffer===void 0)a.depthBuffer=!0;if(a.stencilBuffer===void 0)a.stencilBuffer=!0;a.__webglTexture=j.createTexture();if(b){a.__webglFramebuffer=[];a.__webglRenderbuffer=[];j.bindTexture(j.TEXTURE_CUBE_MAP,a.__webglTexture);J(j.TEXTURE_CUBE_MAP,a,a);for(var c=0;c<6;c++){a.__webglFramebuffer[c]=j.createFramebuffer();a.__webglRenderbuffer[c]=j.createRenderbuffer();j.texImage2D(j.TEXTURE_CUBE_MAP_POSITIVE_X+ -c,0,L(a.format),a.width,a.height,0,L(a.format),L(a.type),null);var d=a,e=j.TEXTURE_CUBE_MAP_POSITIVE_X+c;j.bindFramebuffer(j.FRAMEBUFFER,a.__webglFramebuffer[c]);j.framebufferTexture2D(j.FRAMEBUFFER,j.COLOR_ATTACHMENT0,e,d.__webglTexture,0);w(a.__webglRenderbuffer[c],a)}}else a.__webglFramebuffer=j.createFramebuffer(),a.__webglRenderbuffer=j.createRenderbuffer(),j.bindTexture(j.TEXTURE_2D,a.__webglTexture),J(j.TEXTURE_2D,a,a),j.texImage2D(j.TEXTURE_2D,0,L(a.format),a.width,a.height,0,L(a.format), -L(a.type),null),c=j.TEXTURE_2D,j.bindFramebuffer(j.FRAMEBUFFER,a.__webglFramebuffer),j.framebufferTexture2D(j.FRAMEBUFFER,j.COLOR_ATTACHMENT0,c,a.__webglTexture,0),j.bindRenderbuffer(j.RENDERBUFFER,a.__webglRenderbuffer),w(a.__webglRenderbuffer,a);b?j.bindTexture(j.TEXTURE_CUBE_MAP,null):j.bindTexture(j.TEXTURE_2D,null);j.bindRenderbuffer(j.RENDERBUFFER,null);j.bindFramebuffer(j.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null, -c=ja,a=na,d=Z,e=da);b!==F&&(j.bindFramebuffer(j.FRAMEBUFFER,b),j.viewport(d,e,c,a),F=b)}function M(a){a instanceof THREE.WebGLRenderTargetCube?(j.bindTexture(j.TEXTURE_CUBE_MAP,a.__webglTexture),j.generateMipmap(j.TEXTURE_CUBE_MAP),j.bindTexture(j.TEXTURE_CUBE_MAP,null)):(j.bindTexture(j.TEXTURE_2D,a.__webglTexture),j.generateMipmap(j.TEXTURE_2D),j.bindTexture(j.TEXTURE_2D,null))}function S(a,b){var c;a==="fragment"?c=j.createShader(j.FRAGMENT_SHADER):a==="vertex"&&(c=j.createShader(j.VERTEX_SHADER)); -j.shaderSource(c,b);j.compileShader(c);if(!j.getShaderParameter(c,j.COMPILE_STATUS))return console.error(j.getShaderInfoLog(c)),console.error(b),null;return c}function ca(a){switch(a){case THREE.NearestFilter:case THREE.NearestMipMapNearestFilter:case THREE.NearestMipMapLinearFilter:return j.NEAREST;default:return j.LINEAR}}function L(a){switch(a){case THREE.RepeatWrapping:return j.REPEAT;case THREE.ClampToEdgeWrapping:return j.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return j.MIRRORED_REPEAT; -case THREE.NearestFilter:return j.NEAREST;case THREE.NearestMipMapNearestFilter:return j.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return j.NEAREST_MIPMAP_LINEAR;case THREE.LinearFilter:return j.LINEAR;case THREE.LinearMipMapNearestFilter:return j.LINEAR_MIPMAP_NEAREST;case THREE.LinearMipMapLinearFilter:return j.LINEAR_MIPMAP_LINEAR;case THREE.ByteType:return j.BYTE;case THREE.UnsignedByteType:return j.UNSIGNED_BYTE;case THREE.ShortType:return j.SHORT;case THREE.UnsignedShortType:return j.UNSIGNED_SHORT; -case THREE.IntType:return j.INT;case THREE.UnsignedShortType:return j.UNSIGNED_INT;case THREE.FloatType:return j.FLOAT;case THREE.AlphaFormat:return j.ALPHA;case THREE.RGBFormat:return j.RGB;case THREE.RGBAFormat:return j.RGBA;case THREE.LuminanceFormat:return j.LUMINANCE;case THREE.LuminanceAlphaFormat:return j.LUMINANCE_ALPHA}return 0}var P=this,j,ea=[],ha=null,F=null,B=-1,R=null,Y=0,O=null,ga=null,$=null,X=null,aa=null,ba=null,V=null,C=null,I=null,Z=0,da=0,ja=0,na=0,oa=[new THREE.Vector4,new THREE.Vector4, -new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4],sa=new THREE.Matrix4,ra=new Float32Array(16),ua=new Float32Array(16),xa=new THREE.Vector4,Q={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[]}},a=a||{},G=a.canvas!==void 0?a.canvas:document.createElement("canvas"),H=a.stencil!==void 0?a.stencil:!0,U=a.preserveDrawingBuffer!==void 0?a.preserveDrawingBuffer:!1,fa=a.antialias!==void 0?a.antialias:!1,la=a.clearColor!== -void 0?new THREE.Color(a.clearColor):new THREE.Color(0),ka=a.clearAlpha!==void 0?a.clearAlpha:0,ma=a.maxLights!==void 0?a.maxLights:4;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0}};this.maxMorphTargets=8;this.domElement=G;this.autoUpdateScene=this.autoUpdateObjects=this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.physicallyBasedShading=this.gammaOutput=this.gammaInput=!1;this.shadowMapBias=0.0039;this.shadowMapDarkness= -0.5;this.shadowMapHeight=this.shadowMapWidth=512;this.shadowCameraNear=1;this.shadowCameraFar=5E3;this.shadowCameraFov=50;this.shadowMap=[];this.shadowMapEnabled=!1;this.shadowMapSoft=this.shadowMapAutoUpdate=!0;var W,va=[],a=THREE.ShaderLib.depthRGBA,ia=THREE.UniformsUtils.clone(a.uniforms),ya=new THREE.ShaderMaterial({fragmentShader:a.fragmentShader,vertexShader:a.vertexShader,uniforms:ia}),pa=new THREE.ShaderMaterial({fragmentShader:a.fragmentShader,vertexShader:a.vertexShader,uniforms:ia,morphTargets:!0}); -ya._shadowPass=!0;pa._shadowPass=!0;try{if(!(j=G.getContext("experimental-webgl",{antialias:fa,stencil:H,preserveDrawingBuffer:U})))throw"Error creating WebGL context.";console.log(navigator.userAgent+" | "+j.getParameter(j.VERSION)+" | "+j.getParameter(j.VENDOR)+" | "+j.getParameter(j.RENDERER)+" | "+j.getParameter(j.SHADING_LANGUAGE_VERSION))}catch(wa){console.error(wa)}j.clearColor(0,0,0,1);j.clearDepth(1);j.clearStencil(0);j.enable(j.DEPTH_TEST);j.depthFunc(j.LEQUAL);j.frontFace(j.CCW);j.cullFace(j.BACK); -j.enable(j.CULL_FACE);j.enable(j.BLEND);j.blendEquation(j.FUNC_ADD);j.blendFunc(j.SRC_ALPHA,j.ONE_MINUS_SRC_ALPHA);j.clearColor(la.r,la.g,la.b,ka);this.context=j;var Ca=j.getParameter(j.MAX_VERTEX_TEXTURE_IMAGE_UNITS)>0,K={};K.vertices=new Float32Array(16);K.faces=new Uint16Array(6);H=0;K.vertices[H++]=-1;K.vertices[H++]=-1;K.vertices[H++]=0;K.vertices[H++]=1;K.vertices[H++]=1;K.vertices[H++]=-1;K.vertices[H++]=1;K.vertices[H++]=1;K.vertices[H++]=1;K.vertices[H++]=1;K.vertices[H++]=1;K.vertices[H++]= -0;K.vertices[H++]=-1;K.vertices[H++]=1;K.vertices[H++]=0;H=K.vertices[H++]=0;K.faces[H++]=0;K.faces[H++]=1;K.faces[H++]=2;K.faces[H++]=0;K.faces[H++]=2;K.faces[H++]=3;K.vertexBuffer=j.createBuffer();K.elementBuffer=j.createBuffer();j.bindBuffer(j.ARRAY_BUFFER,K.vertexBuffer);j.bufferData(j.ARRAY_BUFFER,K.vertices,j.STATIC_DRAW);j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,K.elementBuffer);j.bufferData(j.ELEMENT_ARRAY_BUFFER,K.faces,j.STATIC_DRAW);K.program=j.createProgram();j.attachShader(K.program,S("fragment", -THREE.ShaderLib.sprite.fragmentShader));j.attachShader(K.program,S("vertex",THREE.ShaderLib.sprite.vertexShader));j.linkProgram(K.program);K.attributes={};K.uniforms={};K.attributes.position=j.getAttribLocation(K.program,"position");K.attributes.uv=j.getAttribLocation(K.program,"uv");K.uniforms.uvOffset=j.getUniformLocation(K.program,"uvOffset");K.uniforms.uvScale=j.getUniformLocation(K.program,"uvScale");K.uniforms.rotation=j.getUniformLocation(K.program,"rotation");K.uniforms.scale=j.getUniformLocation(K.program, -"scale");K.uniforms.alignment=j.getUniformLocation(K.program,"alignment");K.uniforms.color=j.getUniformLocation(K.program,"color");K.uniforms.map=j.getUniformLocation(K.program,"map");K.uniforms.opacity=j.getUniformLocation(K.program,"opacity");K.uniforms.useScreenCoordinates=j.getUniformLocation(K.program,"useScreenCoordinates");K.uniforms.affectedByDistance=j.getUniformLocation(K.program,"affectedByDistance");K.uniforms.screenPosition=j.getUniformLocation(K.program,"screenPosition");K.uniforms.modelViewMatrix= -j.getUniformLocation(K.program,"modelViewMatrix");K.uniforms.projectionMatrix=j.getUniformLocation(K.program,"projectionMatrix");var Ia=!1;this.setSize=function(a,b){G.width=a;G.height=b;this.setViewport(0,0,G.width,G.height)};this.setViewport=function(a,b,c,d){Z=a;da=b;ja=c;na=d;j.viewport(Z,da,ja,na)};this.setScissor=function(a,b,c,d){j.scissor(a,b,c,d)};this.enableScissorTest=function(a){a?j.enable(j.SCISSOR_TEST):j.disable(j.SCISSOR_TEST)};this.setClearColorHex=function(a,b){la.setHex(a);ka=b; -j.clearColor(la.r,la.g,la.b,ka)};this.setClearColor=function(a,b){la.copy(a);ka=b;j.clearColor(la.r,la.g,la.b,ka)};this.getClearColor=function(){return la};this.getClearAlpha=function(){return ka};this.clear=function(a,b,c){var d=0;if(a===void 0||a)d|=j.COLOR_BUFFER_BIT;if(b===void 0||b)d|=j.DEPTH_BUFFER_BIT;if(c===void 0||c)d|=j.STENCIL_BUFFER_BIT;j.clear(d)};this.getContext=function(){return j};this.deallocateObject=function(a){if(a.__webglInit)if(a.__webglInit=!1,delete a._modelViewMatrix,delete a._normalMatrixArray, -delete a._modelViewMatrixArray,delete a._objectMatrixArray,a instanceof THREE.Mesh)for(var b in a.geometry.geometryGroups){var c=a.geometry.geometryGroups[b];j.deleteBuffer(c.__webglVertexBuffer);j.deleteBuffer(c.__webglNormalBuffer);j.deleteBuffer(c.__webglTangentBuffer);j.deleteBuffer(c.__webglColorBuffer);j.deleteBuffer(c.__webglUVBuffer);j.deleteBuffer(c.__webglUV2Buffer);j.deleteBuffer(c.__webglSkinVertexABuffer);j.deleteBuffer(c.__webglSkinVertexBBuffer);j.deleteBuffer(c.__webglSkinIndicesBuffer); -j.deleteBuffer(c.__webglSkinWeightsBuffer);j.deleteBuffer(c.__webglFaceBuffer);j.deleteBuffer(c.__webglLineBuffer);if(c.numMorphTargets)for(var d=0,e=c.numMorphTargets;d=0&&j.enableVertexAttribArray(n.position);n.color>=0&&j.enableVertexAttribArray(n.color);n.normal>=0&&j.enableVertexAttribArray(n.normal); -n.tangent>=0&&j.enableVertexAttribArray(n.tangent);a.skinning&&n.skinVertexA>=0&&n.skinVertexB>=0&&n.skinIndex>=0&&n.skinWeight>=0&&(j.enableVertexAttribArray(n.skinVertexA),j.enableVertexAttribArray(n.skinVertexB),j.enableVertexAttribArray(n.skinIndex),j.enableVertexAttribArray(n.skinWeight));if(a.attributes)for(f in a.attributes)n[f]!==void 0&&n[f]>=0&&j.enableVertexAttribArray(n[f]);if(a.morphTargets)for(f=a.numSupportedMorphTargets=0;f=0&&(j.enableVertexAttribArray(n[H]), -a.numSupportedMorphTargets++);a.uniformsList=[];for(e in a.uniforms)a.uniformsList.push([a.uniforms[e],e])};this.clearTarget=function(a,b,c,d){D(a);this.clear(b,c,d)};this.updateShadowMap=function(a,b){t(a,b)};this.render=function(a,b,c,d){var H,Q,r,G,z,U,Aa,C=a.lights,E=a.fog;B=-1;this.autoUpdateObjects&&this.initWebGLObjects(a);this.shadowMapEnabled&&this.shadowMapAutoUpdate&&t(a,b);P.info.render.calls=0;P.info.render.vertices=0;P.info.render.faces=0;b.parent===void 0&&(console.warn("DEPRECATED: Camera hasn't been added to a Scene. Adding it..."), -a.add(b));this.autoUpdateScene&&a.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);b.matrixWorldInverse.flattenToArray(ua);b.projectionMatrix.flattenToArray(ra);sa.multiply(b.projectionMatrix,b.matrixWorldInverse);k(sa);D(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);r=a.__webglObjects.length;for(d=0;d=0;d--)if(z=a.__webglObjects[d],z.render&&(U=z.object,Aa=z.buffer,Q=z.opaque))h(U),i(Q.depthTest),l(Q.depthWrite),m(Q.polygonOffset,Q.polygonOffsetFactor, -Q.polygonOffsetUnits),e(b,C,E,Q,Aa,U);for(d=0;d65535&&(Q[o].counter+=1,H=Q[o].hash+"_"+ -Q[o].counter,i.geometryGroups[H]===void 0&&(i.geometryGroups[H]={faces3:[],faces4:[],materialIndex:p,vertices:0,numMorphTargets:q})),m instanceof THREE.Face3?i.geometryGroups[H].faces3.push(k):i.geometryGroups[H].faces4.push(k),i.geometryGroups[H].vertices+=n;i.geometryGroupsList=[];k=void 0;for(k in i.geometryGroups)i.geometryGroups[k].id=Y++,i.geometryGroupsList.push(i.geometryGroups[k])}for(g in h.geometryGroups)if(i=h.geometryGroups[g],!i.__webglVertexBuffer){k=i;k.__webglVertexBuffer=j.createBuffer(); -k.__webglNormalBuffer=j.createBuffer();k.__webglTangentBuffer=j.createBuffer();k.__webglColorBuffer=j.createBuffer();k.__webglUVBuffer=j.createBuffer();k.__webglUV2Buffer=j.createBuffer();k.__webglSkinVertexABuffer=j.createBuffer();k.__webglSkinVertexBBuffer=j.createBuffer();k.__webglSkinIndicesBuffer=j.createBuffer();k.__webglSkinWeightsBuffer=j.createBuffer();k.__webglFaceBuffer=j.createBuffer();k.__webglLineBuffer=j.createBuffer();if(k.numMorphTargets){m=l=void 0;k.__webglMorphTargetsBuffers=[]; -l=0;for(m=k.numMorphTargets;l0||n.faceVertexUvs.length>0)i.__uvArray=new Float32Array(k*2);if(n.faceUvs.length>1||n.faceVertexUvs.length>1)i.__uv2Array=new Float32Array(k*2)}if(p.geometry.skinWeights.length&&p.geometry.skinIndices.length)i.__skinVertexAArray=new Float32Array(k*4),i.__skinVertexBArray=new Float32Array(k*4), -i.__skinIndexArray=new Float32Array(k*4),i.__skinWeightArray=new Float32Array(k*4);i.__faceArray=new Uint16Array(m*3);i.__lineArray=new Uint16Array(o*2);if(i.numMorphTargets){i.__morphTargetsArrays=[];p=0;for(n=i.numMorphTargets;p=0;h--)f[h]===g&&f.splice(h,1)}else(e instanceof THREE.MarchingCubes||e.immediateRenderCallback)&& -E(f.__webglObjectsImmediate,e);e.__webglActive=!1;a.__objectsRemoved.splice(0,1)}e=0;for(f=a.__webglObjects.length;e0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinVertexABuffer), -j.bufferData(j.ARRAY_BUFFER,fa,m),j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinVertexBBuffer),j.bufferData(j.ARRAY_BUFFER,Z,m),j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinIndicesBuffer),j.bufferData(j.ARRAY_BUFFER,B,m),j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinWeightsBuffer),j.bufferData(j.ARRAY_BUFFER,V,m))}if(na&&D){n=0;for(o=Q.length;n0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglColorBuffer),j.bufferData(j.ARRAY_BUFFER,L,m))}if(ha&&ja.hasTangents){n=0;for(o=Q.length;n0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglUVBuffer),j.bufferData(j.ARRAY_BUFFER,aa,m))}if(ea&&oa&&la){n=0;for(o=Q.length;n0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglUV2Buffer),j.bufferData(j.ARRAY_BUFFER,y,m))}if($){n=0;for(o=Q.length;n=0)return a.geometry.materials[b.materialIndex]}function d(a,b,c){var d,e,g,f,h=a.vertices;f=h.length;var i=a.colors,n=i.length,k=a.__vertexArray,l=a.__colorArray,m=a.__sortArray,p=a.__dirtyVertices,o=a.__dirtyColors,x=a.__webglCustomAttributesList;if(c.sortParticles){Y.multiplySelf(c.matrixWorld);for(d=0;d=0)a&&(j.bindBuffer(j.ARRAY_BUFFER, +e.__webglVertexBuffer),j.vertexAttribPointer(b.position,3,j.FLOAT,!1,0,0));else if(g.morphTargetBase){c=d.program.attributes;g.morphTargetBase!==-1?(j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphTargetsBuffers[g.morphTargetBase]),j.vertexAttribPointer(c.position,3,j.FLOAT,!1,0,0)):c.position>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglVertexBuffer),j.vertexAttribPointer(c.position,3,j.FLOAT,!1,0,0));if(g.morphTargetForcedOrder.length){f=0;var i=g.morphTargetForcedOrder;for(h=g.morphTargetInfluences;fn&&(k=l,n=h[k]);j.bindBuffer(j.ARRAY_BUFFER,e.__webglMorphTargetsBuffers[k]);j.vertexAttribPointer(c["morphTarget"+f],3,j.FLOAT,!1,0,0);g.__webglMorphTargetInfluences[f]= +n;i[k]=1;n=-1;f++}}d.program.uniforms.morphTargetInfluences!==null&&j.uniform1fv(d.program.uniforms.morphTargetInfluences,g.__webglMorphTargetInfluences)}if(a){if(e.__webglCustomAttributesList){f=0;for(h=e.__webglCustomAttributesList.length;f=0&&(j.bindBuffer(j.ARRAY_BUFFER,c.buffer),j.vertexAttribPointer(b[c.buffer.belongsToAttribute],c.size,j.FLOAT,!1,0,0))}b.color>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglColorBuffer),j.vertexAttribPointer(b.color, +3,j.FLOAT,!1,0,0));b.normal>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglNormalBuffer),j.vertexAttribPointer(b.normal,3,j.FLOAT,!1,0,0));b.tangent>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglTangentBuffer),j.vertexAttribPointer(b.tangent,4,j.FLOAT,!1,0,0));b.uv>=0&&(e.__webglUVBuffer?(j.bindBuffer(j.ARRAY_BUFFER,e.__webglUVBuffer),j.vertexAttribPointer(b.uv,2,j.FLOAT,!1,0,0),j.enableVertexAttribArray(b.uv)):j.disableVertexAttribArray(b.uv));b.uv2>=0&&(e.__webglUV2Buffer?(j.bindBuffer(j.ARRAY_BUFFER,e.__webglUV2Buffer), +j.vertexAttribPointer(b.uv2,2,j.FLOAT,!1,0,0),j.enableVertexAttribArray(b.uv2)):j.disableVertexAttribArray(b.uv2));d.skinning&&b.skinVertexA>=0&&b.skinVertexB>=0&&b.skinIndex>=0&&b.skinWeight>=0&&(j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinVertexABuffer),j.vertexAttribPointer(b.skinVertexA,4,j.FLOAT,!1,0,0),j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinVertexBBuffer),j.vertexAttribPointer(b.skinVertexB,4,j.FLOAT,!1,0,0),j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinIndicesBuffer),j.vertexAttribPointer(b.skinIndex, +4,j.FLOAT,!1,0,0),j.bindBuffer(j.ARRAY_BUFFER,e.__webglSkinWeightsBuffer),j.vertexAttribPointer(b.skinWeight,4,j.FLOAT,!1,0,0))}g instanceof THREE.Mesh?(d.wireframe?(d=d.wireframeLinewidth,d!==pa&&(j.lineWidth(d),pa=d),a&&j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,e.__webglLineBuffer),j.drawElements(j.LINES,e.__webglLineCount,j.UNSIGNED_SHORT,0)):(a&&j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,e.__webglFaceBuffer),j.drawElements(j.TRIANGLES,e.__webglFaceCount,j.UNSIGNED_SHORT,0)),O.info.render.calls++,O.info.render.vertices+= +e.__webglFaceCount,O.info.render.faces+=e.__webglFaceCount/3):g instanceof THREE.Line?(g=g.type===THREE.LineStrip?j.LINE_STRIP:j.LINES,d=d.linewidth,d!==pa&&(j.lineWidth(d),pa=d),j.drawArrays(g,0,e.__webglLineCount),O.info.render.calls++):g instanceof THREE.ParticleSystem?(j.drawArrays(j.POINTS,0,e.__webglParticleCount),O.info.render.calls++):g instanceof THREE.Ribbon&&(j.drawArrays(j.TRIANGLE_STRIP,0,e.__webglVertexCount),O.info.render.calls++)}}function f(a){E[0].set(a.n41-a.n11,a.n42-a.n12,a.n43- +a.n13,a.n44-a.n14);E[1].set(a.n41+a.n11,a.n42+a.n12,a.n43+a.n13,a.n44+a.n14);E[2].set(a.n41+a.n21,a.n42+a.n22,a.n43+a.n23,a.n44+a.n24);E[3].set(a.n41-a.n21,a.n42-a.n22,a.n43-a.n23,a.n44-a.n24);E[4].set(a.n41-a.n31,a.n42-a.n32,a.n43-a.n33,a.n44-a.n34);E[5].set(a.n41+a.n31,a.n42+a.n32,a.n43+a.n33,a.n44+a.n34);for(var b,a=0;a<6;a++)b=E[a],b.divideScalar(Math.sqrt(b.x*b.x+b.y*b.y+b.z*b.z))}function h(a){for(var b=a.matrixWorld,c=-a.geometry.boundingSphere.radius*Math.max(a.scale.x,Math.max(a.scale.y, +a.scale.z)),d=0;d<6;d++)if(a=E[d].x*b.n14+E[d].y*b.n24+E[d].z*b.n34+E[d].w,a<=c)return!1;return!0}function i(a,b){return b.z-a.z}function k(a){var b,c,d,i=0,n,k,l,m,p,o,x=a.lights;X||(X=new THREE.PerspectiveCamera(O.shadowCameraFov,O.shadowMapWidth/O.shadowMapHeight,O.shadowCameraNear,O.shadowCameraFar));b=0;for(c=x.length;b=0)b=b.geometry.materials[c],b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}else if(b=d)b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}function o(a,b){var c,d,e;c=G.attributes;var g=G.uniforms,f=S/x,h,n=[],k=x*0.5,l=S*0.5,m=!0;j.useProgram(G.program);aa=G.program;U=la=$=-1; +ya||(j.enableVertexAttribArray(G.attributes.position),j.enableVertexAttribArray(G.attributes.uv),ya=!0);j.disable(j.CULL_FACE);j.enable(j.BLEND);j.depthMask(!0);j.bindBuffer(j.ARRAY_BUFFER,G.vertexBuffer);j.vertexAttribPointer(c.position,2,j.FLOAT,!1,16,0);j.vertexAttribPointer(c.uv,2,j.FLOAT,!1,16,8);j.bindBuffer(j.ELEMENT_ARRAY_BUFFER,G.elementBuffer);j.uniformMatrix4fv(g.projectionMatrix,!1,ja);j.activeTexture(j.TEXTURE0);j.uniform1i(g.map,0);c=0;for(d=a.__webglSprites.length;c=0;c--)a[c].object===b&&a.splice(c,1)}function v(a,b,c,d,e){d.program||O.initMaterial(d,b,c,e);if(d.morphTargets&&!e.__webglMorphTargetInfluences){e.__webglMorphTargetInfluences=new Float32Array(O.maxMorphTargets);for(var g=0,f=O.maxMorphTargets;g0;this.getContext=function(){return j};this.supportsVertexTextures=function(){return ta};this.setSize=function(a,b){N.width=a;N.height=b;this.setViewport(0,0,N.width,N.height)};this.setViewport=function(a,b,c,d){ra=a;Aa=b;x=c;S=d;j.viewport(ra,Aa,x,S)};this.setScissor=function(a,b,c,d){j.scissor(a,b,c,d)};this.enableScissorTest=function(a){a?j.enable(j.SCISSOR_TEST):j.disable(j.SCISSOR_TEST)}; +this.setClearColorHex=function(a,b){F.setHex(a);B=b;j.clearColor(F.r,F.g,F.b,B)};this.setClearColor=function(a,b){F.copy(a);B=b;j.clearColor(F.r,F.g,F.b,B)};this.getClearColor=function(){return F};this.getClearAlpha=function(){return B};this.clear=function(a,b,c){var d=0;if(a===void 0||a)d|=j.COLOR_BUFFER_BIT;if(b===void 0||b)d|=j.DEPTH_BUFFER_BIT;if(c===void 0||c)d|=j.STENCIL_BUFFER_BIT;j.clear(d)};this.clearTarget=function(a,b,c,d){P(a);this.clear(b,c,d)};this.deallocateObject=function(a){if(a.__webglInit)if(a.__webglInit= +!1,delete a._modelViewMatrix,delete a._normalMatrixArray,delete a._modelViewMatrixArray,delete a._objectMatrixArray,a instanceof THREE.Mesh)for(var b in a.geometry.geometryGroups){var c=a.geometry.geometryGroups[b];j.deleteBuffer(c.__webglVertexBuffer);j.deleteBuffer(c.__webglNormalBuffer);j.deleteBuffer(c.__webglTangentBuffer);j.deleteBuffer(c.__webglColorBuffer);j.deleteBuffer(c.__webglUVBuffer);j.deleteBuffer(c.__webglUV2Buffer);j.deleteBuffer(c.__webglSkinVertexABuffer);j.deleteBuffer(c.__webglSkinVertexBBuffer); +j.deleteBuffer(c.__webglSkinIndicesBuffer);j.deleteBuffer(c.__webglSkinWeightsBuffer);j.deleteBuffer(c.__webglFaceBuffer);j.deleteBuffer(c.__webglLineBuffer);if(c.numMorphTargets)for(var d=0,e=c.numMorphTargets;d=0;d--)if(u=a.__webglObjects[d],u.render&&(S=u.object,wa=u.buffer,p=u.opaque))q(S),t(p.depthTest),w(p.depthWrite),z(p.polygonOffset,p.polygonOffsetFactor,p.polygonOffsetUnits),e(b,B,ca,p,wa,S);for(d=0;d65535&&(q[E].counter+=1,S=q[E].hash+"_"+q[E].counter,i.geometryGroups[S]===void 0&&(i.geometryGroups[S]={faces3:[],faces4:[],materialIndex:o,vertices:0,numMorphTargets:v})),m instanceof THREE.Face3?i.geometryGroups[S].faces3.push(k):i.geometryGroups[S].faces4.push(k),i.geometryGroups[S].vertices+=x;i.geometryGroupsList=[];k=void 0;for(k in i.geometryGroups)i.geometryGroups[k].id= +ea++,i.geometryGroupsList.push(i.geometryGroups[k])}for(f in h.geometryGroups)if(i=h.geometryGroups[f],!i.__webglVertexBuffer){k=i;k.__webglVertexBuffer=j.createBuffer();k.__webglNormalBuffer=j.createBuffer();k.__webglTangentBuffer=j.createBuffer();k.__webglColorBuffer=j.createBuffer();k.__webglUVBuffer=j.createBuffer();k.__webglUV2Buffer=j.createBuffer();k.__webglSkinVertexABuffer=j.createBuffer();k.__webglSkinVertexBBuffer=j.createBuffer();k.__webglSkinIndicesBuffer=j.createBuffer();k.__webglSkinWeightsBuffer= +j.createBuffer();k.__webglFaceBuffer=j.createBuffer();k.__webglLineBuffer=j.createBuffer();if(k.numMorphTargets){m=l=void 0;k.__webglMorphTargetsBuffers=[];l=0;for(m=k.numMorphTargets;l0||x.faceVertexUvs.length>0)i.__uvArray=new Float32Array(k*2);if(x.faceUvs.length>1||x.faceVertexUvs.length>1)i.__uv2Array=new Float32Array(k* +2)}if(o.geometry.skinWeights.length&&o.geometry.skinIndices.length)i.__skinVertexAArray=new Float32Array(k*4),i.__skinVertexBArray=new Float32Array(k*4),i.__skinIndexArray=new Float32Array(k*4),i.__skinWeightArray=new Float32Array(k*4);i.__faceArray=new Uint16Array(m*3);i.__lineArray=new Uint16Array(E*2);if(i.numMorphTargets){i.__morphTargetsArrays=[];o=0;for(x=i.numMorphTargets;o=0;h--)g[h]===f&&g.splice(h,1)}else(e instanceof THREE.MarchingCubes||e.immediateRenderCallback)&&u(g.__webglObjectsImmediate,e);e.__webglActive=!1;a.__objectsRemoved.splice(0,1)}e=0;for(g=a.__webglObjects.length;e0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinVertexABuffer),j.bufferData(j.ARRAY_BUFFER,M,m),j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinVertexBBuffer),j.bufferData(j.ARRAY_BUFFER,$,m),j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinIndicesBuffer),j.bufferData(j.ARRAY_BUFFER,C,m),j.bindBuffer(j.ARRAY_BUFFER,l.__webglSkinWeightsBuffer),j.bufferData(j.ARRAY_BUFFER,U,m))}if(xa&&I){x=0;for(E=q.length;x0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglColorBuffer),j.bufferData(j.ARRAY_BUFFER, +ja,m))}if(ka&&Z.hasTangents){x=0;for(E=q.length;x0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglUVBuffer),j.bufferData(j.ARRAY_BUFFER,ba,m))}if(oa&&ya&&L){x=0;for(E=q.length;x0&&(j.bindBuffer(j.ARRAY_BUFFER,l.__webglUV2Buffer),j.bufferData(j.ARRAY_BUFFER,A,m))}if(aa){x=0;for(E=q.length;x=0&&j.enableVertexAttribArray(m.position);m.color>=0&&j.enableVertexAttribArray(m.color);m.normal>=0&&j.enableVertexAttribArray(m.normal); +m.tangent>=0&&j.enableVertexAttribArray(m.tangent);a.skinning&&m.skinVertexA>=0&&m.skinVertexB>=0&&m.skinIndex>=0&&m.skinWeight>=0&&(j.enableVertexAttribArray(m.skinVertexA),j.enableVertexAttribArray(m.skinVertexB),j.enableVertexAttribArray(m.skinIndex),j.enableVertexAttribArray(m.skinWeight));if(a.attributes)for(g in a.attributes)m[g]!==void 0&&m[g]>=0&&j.enableVertexAttribArray(m[g]);if(a.morphTargets)for(g=a.numSupportedMorphTargets=0;g=0&&(j.enableVertexAttribArray(m[p]), +a.numSupportedMorphTargets++);a.uniformsList=[];for(e in a.uniforms)a.uniformsList.push([a.uniforms[e],e])};this.setFaceCulling=function(a,b){a?(!b||b==="ccw"?j.frontFace(j.CCW):j.frontFace(j.CW),a==="back"?j.cullFace(j.BACK):a==="front"?j.cullFace(j.FRONT):j.cullFace(j.FRONT_AND_BACK),j.enable(j.CULL_FACE)):j.disable(j.CULL_FACE)}}; THREE.WebGLRenderTarget=function(a,c,b){this.width=a;this.height=c;b=b||{};this.wrapS=b.wrapS!==void 0?b.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=b.wrapT!==void 0?b.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=b.magFilter!==void 0?b.magFilter:THREE.LinearFilter;this.minFilter=b.minFilter!==void 0?b.minFilter:THREE.LinearMipMapLinearFilter;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=b.format!==void 0?b.format:THREE.RGBAFormat;this.type=b.type!==void 0?b.type: THREE.UnsignedByteType;this.depthBuffer=b.depthBuffer!==void 0?b.depthBuffer:!0;this.stencilBuffer=b.stencilBuffer!==void 0?b.stencilBuffer:!0}; THREE.WebGLRenderTarget.prototype.clone=function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;return a};THREE.WebGLRenderTargetCube=function(a,c,b){THREE.WebGLRenderTarget.call(this,a,c,b);this.activeCubeFace=0}; @@ -355,19 +355,19 @@ THREE.RenderableFace4=function(){this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableParticle=function(){this.rotation=this.z=this.y=this.x=null;this.scale=new THREE.Vector2;this.material=null};THREE.RenderableLine=function(){this.z=null;this.v1=new THREE.RenderableVertex;this.v2=new THREE.RenderableVertex;this.material=null}; THREE.ColorUtils={adjustHSV:function(a,c,b,d){var g=THREE.ColorUtils.__hsv;THREE.ColorUtils.rgbToHsv(a,g);g.h=THREE.Math.clamp(g.h+c,0,1);g.s=THREE.Math.clamp(g.s+b,0,1);g.v=THREE.Math.clamp(g.v+d,0,1);a.setHSV(g.h,g.s,g.v)},rgbToHsv:function(a,c){var b=a.r,d=a.g,g=a.b,e=Math.max(Math.max(b,d),g),f=Math.min(Math.min(b,d),g);if(f===e)f=b=0;else{var h=e-f,f=h/e,b=b===e?(d-g)/h:d===e?2+(g-b)/h:4+(b-d)/h;b/=6;b<0&&(b+=1);b>1&&(b-=1)}c===void 0&&(c={h:0,s:0,v:0});c.h=b;c.s=f;c.v=e;return c}}; THREE.ColorUtils.__hsv={h:0,s:0,v:0}; -THREE.GeometryUtils={merge:function(a,c){for(var b,d,g=a.vertices.length,e=c instanceof THREE.Mesh?c.geometry:c,f=a.vertices,h=e.vertices,i=a.faces,l=e.faces,m=a.faceVertexUvs[0],k=e.faceVertexUvs[0],o={},p=0;p1&&(d=1-d,g=1-g);e=1-d-g;f.copy(a);f.multiplyScalar(d);h.copy(c);h.multiplyScalar(g);f.addSelf(h);h.copy(b);h.multiplyScalar(e);f.addSelf(h);return f},randomPointInFace:function(a,c,b){var d,g,e;if(a instanceof THREE.Face3)return d=c.vertices[a.a].position,g=c.vertices[a.b].position, e=c.vertices[a.c].position,THREE.GeometryUtils.randomPointInTriangle(d,g,e);else if(a instanceof THREE.Face4){d=c.vertices[a.a].position;g=c.vertices[a.b].position;e=c.vertices[a.c].position;var c=c.vertices[a.d].position,f;b?a._area1&&a._area2?(b=a._area1,f=a._area2):(b=THREE.GeometryUtils.triangleArea(d,g,c),f=THREE.GeometryUtils.triangleArea(g,e,c),a._area1=b,a._area2=f):(b=THREE.GeometryUtils.triangleArea(d,g,c),f=THREE.GeometryUtils.triangleArea(g,e,c));return THREE.GeometryUtils.random()*(b+ -f)a?b(c,e-1):l[e]a?b(c,e-1):k[e]0?(f=b[b.length-1],p=f.x,q=f.y):(f=this.actions[d-1].args,p=f[f.length-2],q=f[f.length-1]);for(f=1;f<=a;f++)n=f/a,e=THREE.Shape.Utils.b2(n,p,k,h),n=THREE.Shape.Utils.b2(n,q,o, -i),b.push(new THREE.Vector2(e,n));break;case THREE.PathActions.BEZIER_CURVE_TO:h=e[4];i=e[5];k=e[0];o=e[1];l=e[2];m=e[3];b.length>0?(f=b[b.length-1],p=f.x,q=f.y):(f=this.actions[d-1].args,p=f[f.length-2],q=f[f.length-1]);for(f=1;f<=a;f++)n=f/a,e=THREE.Shape.Utils.b3(n,p,k,l,h),n=THREE.Shape.Utils.b3(n,q,o,m,i),b.push(new THREE.Vector2(e,n));break;case THREE.PathActions.CSPLINE_THRU:f=this.actions[d-1].args;f=[new THREE.Vector2(f[f.length-2],f[f.length-1])];n=a*e[0].length;f=f.concat(e[0]);e=new THREE.SplineCurve(f); -for(f=1;f<=n;f++)b.push(e.getPointAt(f/n));break;case THREE.PathActions.ARC:f=this.actions[d-1].args;h=e[0];i=e[1];l=e[2];k=e[3];n=e[4];o=!!e[5];m=f[f.length-2];p=f[f.length-1];f.length==0&&(m=p=0);q=n-k;var t=a*2;for(f=1;f<=t;f++)n=f/t,o||(n=1-n),n=k+n*q,e=m+h+l*Math.cos(n),n=p+i+l*Math.sin(n),b.push(new THREE.Vector2(e,n))}c&&b.push(b[0]);return b};THREE.Path.prototype.transform=function(a,c){this.getBoundingBox();return this.getWrapPoints(this.getPoints(c),a)}; -THREE.Path.prototype.nltransform=function(a,c,b,d,g,e){var f=this.getPoints(),h,i,l,m,k;h=0;for(i=f.length;h0?(f=b[b.length-1],n=f.x,s=f.y):(f=this.actions[d-1].args,n=f[f.length-2],s=f[f.length-1]);for(f=1;f<=a;f++)p=f/a,e=THREE.Shape.Utils.b2(p,n,m,h),p=THREE.Shape.Utils.b2(p,s,o, +i),b.push(new THREE.Vector2(e,p));break;case THREE.PathActions.BEZIER_CURVE_TO:h=e[4];i=e[5];m=e[0];o=e[1];k=e[2];l=e[3];b.length>0?(f=b[b.length-1],n=f.x,s=f.y):(f=this.actions[d-1].args,n=f[f.length-2],s=f[f.length-1]);for(f=1;f<=a;f++)p=f/a,e=THREE.Shape.Utils.b3(p,n,m,k,h),p=THREE.Shape.Utils.b3(p,s,o,l,i),b.push(new THREE.Vector2(e,p));break;case THREE.PathActions.CSPLINE_THRU:f=this.actions[d-1].args;f=[new THREE.Vector2(f[f.length-2],f[f.length-1])];p=a*e[0].length;f=f.concat(e[0]);e=new THREE.SplineCurve(f); +for(f=1;f<=p;f++)b.push(e.getPointAt(f/p));break;case THREE.PathActions.ARC:f=this.actions[d-1].args;h=e[0];i=e[1];k=e[2];m=e[3];p=e[4];o=!!e[5];l=f[f.length-2];n=f[f.length-1];f.length==0&&(l=n=0);s=p-m;var u=a*2;for(f=1;f<=u;f++)p=f/u,o||(p=1-p),p=m+p*s,e=l+h+k*Math.cos(p),p=n+i+k*Math.sin(p),b.push(new THREE.Vector2(e,p))}c&&b.push(b[0]);return b};THREE.Path.prototype.transform=function(a,c){this.getBoundingBox();return this.getWrapPoints(this.getPoints(c),a)}; +THREE.Path.prototype.nltransform=function(a,c,b,d,g,e){var f=this.getPoints(),h,i,k,l,m;h=0;for(i=f.length;h=0?h-1:b.length-1;e=f-1>=0?f-1:l.length-1;var n=[l[f],b[h],b[g]];k=THREE.FontUtils.Triangulate.area(n);var t=[l[f],l[e],b[h]];o=THREE.FontUtils.Triangulate.area(t);p=h;m=f;h+=1;f+=-1;h< -0&&(h+=b.length);h%=b.length;f<0&&(f+=l.length);f%=l.length;g=h-1>=0?h-1:b.length-1;e=f-1>=0?f-1:l.length-1;n=[l[f],b[h],b[g]];n=THREE.FontUtils.Triangulate.area(n);t=[l[f],l[e],b[h]];t=THREE.FontUtils.Triangulate.area(t);k+o>n+t&&(h=p,f=m,h<0&&(h+=b.length),h%=b.length,f<0&&(f+=l.length),f%=l.length,g=h-1>=0?h-1:b.length-1,e=f-1>=0?f-1:l.length-1);k=b.slice(0,h);o=b.slice(h);p=l.slice(f);m=l.slice(0,f);e=[l[f],l[e],b[h]];q.push([l[f],b[h],b[g]]);q.push(e);b=k.concat(p).concat(m).concat(o)}return{shape:b, -isolatedPts:q,allpoints:d}},triangulateShape:function(a,c){var b=THREE.Shape.Utils.removeHoles(a,c),d=b.allpoints,g=b.isolatedPts,b=THREE.FontUtils.Triangulate(b.shape,!1),e,f,h,i,l={};e=0;for(f=d.length;e=0?h-1:b.length-1;e=f-1>=0?f-1:k.length-1;var p=[k[f],b[h],b[g]];m=THREE.FontUtils.Triangulate.area(p);var u=[k[f],k[e],b[h]];o=THREE.FontUtils.Triangulate.area(u);n=h;l=f;h+=1;f+=-1;h< +0&&(h+=b.length);h%=b.length;f<0&&(f+=k.length);f%=k.length;g=h-1>=0?h-1:b.length-1;e=f-1>=0?f-1:k.length-1;p=[k[f],b[h],b[g]];p=THREE.FontUtils.Triangulate.area(p);u=[k[f],k[e],b[h]];u=THREE.FontUtils.Triangulate.area(u);m+o>p+u&&(h=n,f=l,h<0&&(h+=b.length),h%=b.length,f<0&&(f+=k.length),f%=k.length,g=h-1>=0?h-1:b.length-1,e=f-1>=0?f-1:k.length-1);m=b.slice(0,h);o=b.slice(h);n=k.slice(f);l=k.slice(0,f);e=[k[f],k[e],b[h]];s.push([k[f],b[h],b[g]]);s.push(e);b=m.concat(n).concat(l).concat(o)}return{shape:b, +isolatedPts:s,allpoints:d}},triangulateShape:function(a,c){var b=THREE.Shape.Utils.removeHoles(a,c),d=b.allpoints,g=b.isolatedPts,b=THREE.FontUtils.Triangulate(b.shape,!1),e,f,h,i,k={};e=0;for(f=d.length;e1)console.log("THREE.Animation.update: Warning! Scale out of bounds:"+d+" on bone "+p),d=d<0?0:1;if(b==="pos")if(b=a.position,this.interpolationType===THREE.AnimationHandler.LINEAR)b.x=g[0]+(e[0]-g[0])*d,b.y=g[1]+(e[1]-g[1])*d,b.z=g[2]+(e[2]-g[2])*d;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)if(this.points[0]= -this.getPrevKeyWith("pos",p,f.index-1).pos,this.points[1]=g,this.points[2]=e,this.points[3]=this.getNextKeyWith("pos",p,h.index+1).pos,d=d*0.33+0.33,g=this.interpolateCatmullRom(this.points,d),b.x=g[0],b.y=g[1],b.z=g[2],this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)d=this.interpolateCatmullRom(this.points,d*1.01),this.target.set(d[0],d[1],d[2]),this.target.subSelf(b),this.target.y=0,this.target.normalize(),d=Math.atan2(this.target.x,this.target.z),a.rotation.set(0,d,0)}else if(b=== -"rot")THREE.Quaternion.slerp(g,e,a.quaternion,d);else if(b==="scl")b=a.scale,b.x=g[0]+(e[0]-g[0])*d,b.y=g[1]+(e[1]-g[1])*d,b.z=g[2]+(e[2]-g[2])*d}}if(this.JITCompile&&m[0][l]===void 0){this.hierarchy[0].update(null,!0);for(p=0;pa.length-2?e:e+1;b[3]=e>a.length-3?e:e+2;e=a[b[0]];h=a[b[1]];i=a[b[2]];l=a[b[3]];b=g*g;f=g*b;d[0]=this.interpolate(e[0],h[0],i[0],l[0],g,b,f);d[1]=this.interpolate(e[1],h[1],i[1],l[1],g,b,f);d[2]=this.interpolate(e[2],h[2],i[2],l[2],g,b,f);return d}; +THREE.Animation.prototype.update=function(a){if(this.isPlaying){var c=["pos","rot","scl"],b,d,g,e,f,h,i,k,l=this.data.JIT.hierarchy,m,o;this.currentTime+=a*this.timeScale;o=this.currentTime;m=this.currentTime%=this.data.length;k=parseInt(Math.min(m*this.data.fps,this.data.length*this.data.fps),10);for(var n=0,s=this.hierarchy.length;n1)console.log("THREE.Animation.update: Warning! Scale out of bounds:"+d+" on bone "+n),d=d<0?0:1;if(b==="pos")if(b=a.position,this.interpolationType===THREE.AnimationHandler.LINEAR)b.x=g[0]+(e[0]-g[0])*d,b.y=g[1]+(e[1]-g[1])*d,b.z=g[2]+(e[2]-g[2])*d;else{if(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)if(this.points[0]= +this.getPrevKeyWith("pos",n,f.index-1).pos,this.points[1]=g,this.points[2]=e,this.points[3]=this.getNextKeyWith("pos",n,h.index+1).pos,d=d*0.33+0.33,g=this.interpolateCatmullRom(this.points,d),b.x=g[0],b.y=g[1],b.z=g[2],this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD)d=this.interpolateCatmullRom(this.points,d*1.01),this.target.set(d[0],d[1],d[2]),this.target.subSelf(b),this.target.y=0,this.target.normalize(),d=Math.atan2(this.target.x,this.target.z),a.rotation.set(0,d,0)}else if(b=== +"rot")THREE.Quaternion.slerp(g,e,a.quaternion,d);else if(b==="scl")b=a.scale,b.x=g[0]+(e[0]-g[0])*d,b.y=g[1]+(e[1]-g[1])*d,b.z=g[2]+(e[2]-g[2])*d}}if(this.JITCompile&&l[0][k]===void 0){this.hierarchy[0].update(null,!0);for(n=0;na.length-2?e:e+1;b[3]=e>a.length-3?e:e+2;e=a[b[0]];h=a[b[1]];i=a[b[2]];k=a[b[3]];b=g*g;f=g*b;d[0]=this.interpolate(e[0],h[0],i[0],k[0],g,b,f);d[1]=this.interpolate(e[1],h[1],i[1],k[1],g,b,f);d[2]=this.interpolate(e[2],h[2],i[2],k[2],g,b,f);return d}; THREE.Animation.prototype.interpolate=function(a,c,b,d,g,e,f){a=(b-a)*0.5;d=(d-c)*0.5;return(2*(c-b)+a+d)*f+(-3*(c-b)-2*a-d)*e+a*g+c};THREE.Animation.prototype.getNextKeyWith=function(a,c,b){var d=this.data.hierarchy[c].keys;for(this.interpolationType===THREE.AnimationHandler.CATMULLROM||this.interpolationType===THREE.AnimationHandler.CATMULLROM_FORWARD?b=b0?b:0:b>=0?b:b+d.length;b>=0;b--)if(d[b][a]!==void 0)return d[b];return this.data.hierarchy[c].keys[d.length-1]}; THREE.CubeCamera=function(a,c,b,d){this.heightOffset=b;this.position=new THREE.Vector3(0,b,0);this.cameraPX=new THREE.PerspectiveCamera(90,1,a,c);this.cameraNX=new THREE.PerspectiveCamera(90,1,a,c);this.cameraPY=new THREE.PerspectiveCamera(90,1,a,c);this.cameraNY=new THREE.PerspectiveCamera(90,1,a,c);this.cameraPZ=new THREE.PerspectiveCamera(90,1,a,c);this.cameraNZ=new THREE.PerspectiveCamera(90,1,a,c);this.cameraPX.position=this.position;this.cameraNX.position=this.position;this.cameraPY.position= @@ -458,14 +458,14 @@ function(a){switch(a.keyCode){case 38:case 87:this.moveForward=!0;break;case 37: this.moveUp&&this.object.translateY(b);this.moveDown&&this.object.translateY(-b);b=a*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 a=this.target,c=this.object.position;a.x=c.x+100*Math.sin(this.phi)*Math.cos(this.theta);a.y=c.y+100*Math.cos(this.phi);a.z=c.z+100*Math.sin(this.phi)*Math.sin(this.theta)}a=1;this.constrainVertical&& (a=Math.PI/(this.verticalMax-this.verticalMin));this.lon+=this.mouseX*b;this.lookVertical&&(this.lat-=this.mouseY*b*a);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=THREE.Math.mapLinear(this.phi,0,Math.PI,this.verticalMin,this.verticalMax);a=this.target;c=this.object.position;a.x=c.x+100*Math.sin(this.phi)*Math.cos(this.theta);a.y=c.y+100*Math.cos(this.phi);a.z=c.z+100*Math.sin(this.phi)*Math.sin(this.theta); this.object.lookAt(a)};this.domElement.addEventListener("contextmenu",function(a){a.preventDefault()},!1);this.domElement.addEventListener("mousemove",b(this,this.onMouseMove),!1);this.domElement.addEventListener("mousedown",b(this,this.onMouseDown),!1);this.domElement.addEventListener("mouseup",b(this,this.onMouseUp),!1);this.domElement.addEventListener("keydown",b(this,this.onKeyDown),!1);this.domElement.addEventListener("keyup",b(this,this.onKeyUp),!1)}; -THREE.PathControls=function(a,c){function b(a){if((a*=2)<1)return 0.5*a*a;return-0.5*(--a*(a-2)-1)}function d(a,b){return function(){b.apply(a,arguments)}}function g(a,b,c,d){var e={name:c,fps:0.6,length:d,hierarchy:[]},f,g=b.getControlPointsArray(),h=b.getLength(),t=g.length,u=0;f=t-1;b={parent:-1,keys:[]};b.keys[0]={time:0,pos:g[0],rot:[0,0,0,1],scl:[1,1,1]};b.keys[f]={time:d,pos:g[f],rot:[0,0,0,1],scl:[1,1,1]};for(f=1;f=0?a:a+f;c=this.verticalAngleMap.srcRange; a=this.verticalAngleMap.dstRange;c=THREE.Math.mapLinear(this.phi,c[0],c[1],a[0],a[1]);var d=a[1]-a[0];this.phi=b((c-a[0])/d)*d+a[0];c=this.horizontalAngleMap.srcRange;a=this.horizontalAngleMap.dstRange;c=THREE.Math.mapLinear(this.theta,c[0],c[1],a[0],a[1]);d=a[1]-a[0];this.theta=b((c-a[0])/d)*d+a[0];a=this.target.position;a.x=100*Math.sin(this.phi)*Math.cos(this.theta);a.y=100*Math.cos(this.phi);a.z=100*Math.sin(this.phi)*Math.sin(this.theta);this.object.lookAt(this.target.position)};this.onMouseMove= function(a){this.domElement===document?(this.mouseX=a.pageX-this.viewHalfX,this.mouseY=a.pageY-this.viewHalfY):(this.mouseX=a.pageX-this.domElement.offsetLeft-this.viewHalfX,this.mouseY=a.pageY-this.domElement.offsetTop-this.viewHalfY)};this.init=function(){this.spline=new THREE.Spline;this.spline.initFromArray(this.waypoints);this.useConstantSpeed&&this.spline.reparametrizeByArcLength(this.resamplingCoef);if(this.createDebugDummy){var a=new THREE.MeshLambertMaterial({color:30719}),b=new THREE.MeshLambertMaterial({color:65280}), c=new THREE.CubeGeometry(10,10,20),f=new THREE.CubeGeometry(2,2,10);this.animationParent=new THREE.Mesh(c,a);a=new THREE.Mesh(f,b);a.position.set(0,10,0);this.animation=g(this.animationParent,this.spline,this.id,this.duration);this.animationParent.add(this.object);this.animationParent.add(this.target);this.animationParent.add(a)}else this.animation=g(this.animationParent,this.spline,this.id,this.duration),this.animationParent.add(this.target),this.animationParent.add(this.object);if(this.createDebugPath){var a= -this.debugPath,b=this.spline,f=e(b,10),c=e(b,10),h=new THREE.LineBasicMaterial({color:16711680,linewidth:3}),f=new THREE.Line(f,h),c=new THREE.ParticleSystem(c,new THREE.ParticleBasicMaterial({color:16755200,size:3}));f.scale.set(1,1,1);a.add(f);c.scale.set(1,1,1);a.add(c);for(var f=new THREE.SphereGeometry(1,16,8),h=new THREE.MeshBasicMaterial({color:65280}),p=0;p0||this.autoForward&&!(i<0)?1:i));this.object.translateX(c*l);this.object.translateY(c*m);f&&(this.roll+=this.rollSpeed*a*h);if(this.forward.y>this.constrainVertical[1])this.forward.y=this.constrainVertical[1],this.forward.normalize();else if(this.forward.y0||this.autoForward&&!(i<0)?1:i));this.object.translateX(c*k);this.object.translateY(c*l);f&&(this.roll+=this.rollSpeed*a*h);if(this.forward.y>this.constrainVertical[1])this.forward.y=this.constrainVertical[1],this.forward.normalize();else if(this.forward.y1?d.normalize():d.z=Math.sqrt(1-e*e);f.copy(b.object.position).subSelf(b.target);e=b.object.up.clone().setLength(d.y);e.addSelf(b.object.up.clone().crossSelf(f).setLength(d.x));e.addSelf(f.setLength(d.z));return e};this.rotateCamera=function(){var a=Math.acos(h.dot(i)/h.length()/i.length());if(a){var c=(new THREE.Vector3).cross(h,i).normalize(),d=new THREE.Quaternion;a*=b.rotateSpeed;d.setFromAxisAngle(c,-a);d.multiplyVector3(f); -d.multiplyVector3(b.object.up);d.multiplyVector3(i);b.staticMoving?h=i:(d.setFromAxisAngle(c,a*(b.dynamicDampingFactor-1)),d.multiplyVector3(h))}};this.zoomCamera=function(){var a=1+(m.y-l.y)*b.zoomSpeed;a!==1&&a>0&&(f.multiplyScalar(a),b.staticMoving?l=m:l.y+=(m.y-l.y)*this.dynamicDampingFactor)};this.panCamera=function(){var a=o.clone().subSelf(k);if(a.lengthSq()){a.multiplyScalar(f.length()*b.panSpeed);var c=f.clone().crossSelf(b.object.up).setLength(a.x);c.addSelf(b.object.up.clone().setLength(a.y)); -b.object.position.addSelf(c);b.target.addSelf(c);b.staticMoving?k=o:k.addSelf(a.sub(o,k).multiplyScalar(b.dynamicDampingFactor))}};this.checkDistances=function(){if(!b.noZoom||!b.noPan)b.object.position.lengthSq()>b.maxDistance*b.maxDistance&&b.object.position.setLength(b.maxDistance),f.lengthSq()0&&(f.multiplyScalar(a),b.staticMoving?k=l:k.y+=(l.y-k.y)*this.dynamicDampingFactor)};this.panCamera=function(){var a=o.clone().subSelf(m);if(a.lengthSq()){a.multiplyScalar(f.length()*b.panSpeed);var c=f.clone().crossSelf(b.object.up).setLength(a.x);c.addSelf(b.object.up.clone().setLength(a.y)); +b.object.position.addSelf(c);b.target.addSelf(c);b.staticMoving?m=o:m.addSelf(a.sub(o,m).multiplyScalar(b.dynamicDampingFactor))}};this.checkDistances=function(){if(!b.noZoom||!b.noPan)b.object.position.lengthSq()>b.maxDistance*b.maxDistance&&b.object.position.setLength(b.maxDistance),f.lengthSq()0){this.vertices.push(new THREE.Vertex(new THREE.Vector3(0,f,0)));for(h=0;h0){this.vertices.push(new THREE.Vertex(new THREE.Vector3(0,-f,0)));for(h=0;h0){this.vertices.push(new THREE.Vertex(new THREE.Vector3(0,f,0)));for(h=0;h0){this.vertices.push(new THREE.Vertex(new THREE.Vector3(0,-f,0)));for(h=0;ha&&(a+=Math.PI*2),a=(b+a)/2,new THREE.Vector2(-Math.cos(a),-Math.sin(a));return d.multiplyScalar(g).addSelf(h).subSelf(a).clone()}function g(a){for(D=a.length;--D>=0;){Y=D;O=D-1;O<0&&(O=a.length-1);for(var b= -0,c=p+m*2,b=0;b=0;S--){ca=S/m;L=i*(1-ca);ca=l*Math.sin(ca*Math.PI/2);D=0;for(M=v.length;Da&&(a+=Math.PI*2),a=(b+a)/2,new THREE.Vector2(-Math.cos(a),-Math.sin(a));return d.multiplyScalar(g).addSelf(h).subSelf(a).clone()}function g(a){for(C=a.length;--C>=0;){O=C;j=C-1;j<0&&(j=a.length-1);for(var b= +0,c=n+l*2,b=0;b=0;R--){fa=R/l;M=i*(1-fa);fa=k*Math.sin(fa*Math.PI/2);C=0;for(P=y.length;C0||(m=this.vertices.push(new THREE.Vertex(new THREE.Vector3(k,h,o)))-1);l.push(m)}c.push(l)}for(var p,q,n,g=c.length,b=0;b0)for(d=0;d1&&(p= -this.vertices[f].position.clone(),q=this.vertices[i].position.clone(),n=this.vertices[l].position.clone(),p.normalize(),q.normalize(),n.normalize(),this.faces.push(new THREE.Face3(f,i,l,[new THREE.Vector3(p.x,p.y,p.z),new THREE.Vector3(q.x,q.y,q.z),new THREE.Vector3(n.x,n.y,n.z)])),this.faceVertexUvs[0].push([m,k,t]))}this.computeCentroids();this.computeFaceNormals();this.computeVertexNormals();this.boundingSphere={radius:a}};THREE.SphereGeometry.prototype=new THREE.Geometry; +THREE.SphereGeometry=function(a,c,b){THREE.Geometry.call(this);for(var a=a||50,d,g=Math.PI,e=Math.max(3,c||8),f=Math.max(2,b||6),c=[],b=0;b0||(l=this.vertices.push(new THREE.Vertex(new THREE.Vector3(m,h,o)))-1);k.push(l)}c.push(k)}for(var n,s,p,g=c.length,b=0;b0)for(d=0;d1&&(n= +this.vertices[f].position.clone(),s=this.vertices[i].position.clone(),p=this.vertices[k].position.clone(),n.normalize(),s.normalize(),p.normalize(),this.faces.push(new THREE.Face3(f,i,k,[new THREE.Vector3(n.x,n.y,n.z),new THREE.Vector3(s.x,s.y,s.z),new THREE.Vector3(p.x,p.y,p.z)])),this.faceVertexUvs[0].push([l,m,u]))}this.computeCentroids();this.computeFaceNormals();this.computeVertexNormals();this.boundingSphere={radius:a}};THREE.SphereGeometry.prototype=new THREE.Geometry; THREE.SphereGeometry.prototype.constructor=THREE.SphereGeometry; THREE.TextGeometry=function(a,c){var b=(new THREE.TextPath(a,c)).toShapes();c.amount=c.height!==void 0?c.height:50;if(c.bevelThickness===void 0)c.bevelThickness=10;if(c.bevelSize===void 0)c.bevelSize=8;if(c.bevelEnabled===void 0)c.bevelEnabled=!1;if(c.bend){var d=b[b.length-1].getBoundingBox().maxX;c.bendPath=new THREE.QuadraticBezierCurve(new THREE.Vector2(0,0),new THREE.Vector2(d/2,120),new THREE.Vector2(d,0))}THREE.ExtrudeGeometry.call(this,b,c)};THREE.TextGeometry.prototype=new THREE.ExtrudeGeometry; THREE.TextGeometry.prototype.constructor=THREE.TextGeometry; THREE.FontUtils={faces:{},face:"helvetiker",weight:"normal",style:"normal",size:150,divisions:10,getFace:function(){return this.faces[this.face][this.weight][this.style]},loadFace:function(a){var c=a.familyName.toLowerCase();this.faces[c]=this.faces[c]||{};this.faces[c][a.cssFontWeight]=this.faces[c][a.cssFontWeight]||{};this.faces[c][a.cssFontWeight][a.cssFontStyle]=a;return this.faces[c][a.cssFontWeight][a.cssFontStyle]=a},drawText:function(a){for(var c=this.getFace(),b=this.size/c.resolution,d= -0,g=String(a).split(""),e=g.length,f=[],a=0;a0)for(l=0;l2;){if(k--<=0){console.log("Warning, unable to triangulate polygon!");if(d)return h;return e}i=l;g<=i&&(i=0);l=i+1;g<=l&&(l=0);m=l+1;g<=m&&(m=0);var o;a:{o=a;var p=i,q=l,n=m,t=g,u=f,v=void 0,r=void 0,z=void 0, -E=void 0,N=void 0,A=void 0,J=void 0,x=void 0,w=void 0,r=o[u[p]].x,z=o[u[p]].y,E=o[u[q]].x,N=o[u[q]].y,A=o[u[n]].x,J=o[u[n]].y;if(1.0E-10>(E-r)*(J-z)-(N-z)*(A-r))o=!1;else{for(v=0;v=0&&S>=0&&L>=0){o=!1;break a}}o= -!0}}if(o){e.push([a[f[i]],a[f[l]],a[f[m]]]);h.push([f[i],f[l],f[m]]);i=l;for(m=l+1;m0)for(k=0;k2;){if(m--<=0){console.log("Warning, unable to triangulate polygon!");if(d)return h;return e}i=k;g<=i&&(i=0);k=i+1;g<=k&&(k=0);l=k+1;g<=l&&(l=0);var o;a:{o=a;var n=i,s=k,p=l,u=g,v=f,y=void 0,q=void 0,t=void 0, +w=void 0,z=void 0,L=void 0,J=void 0,I=void 0,D=void 0,q=o[v[n]].x,t=o[v[n]].y,w=o[v[s]].x,z=o[v[s]].y,L=o[v[p]].x,J=o[v[p]].y;if(1.0E-10>(w-q)*(J-t)-(z-t)*(L-q))o=!1;else{for(y=0;y=0&&R>=0&&M>=0){o=!1;break a}}o= +!0}}if(o){e.push([a[f[i]],a[f[k]],a[f[l]]]);h.push([f[i],f[k],f[l]]);i=k;for(l=k+1;l0;)this.smooth(a)}; -THREE.SubdivisionModifier.prototype.smooth=function(a){function c(a,b,c,d,h,i){var k=new THREE.Face4(a,b,c,d,null,h.color,h.material);if(f.useOldVertexColors){k.vertexColors=[];for(var l,n,m,p=0;p<4;p++){m=i[p];l=new THREE.Color;l.setRGB(0,0,0);for(var q=0;q>7)-127;d|=(f&127)<<16|e<<8;if(d==0&&h==-127)return 0;return(1-2*(g>>7))*(1+d*Math.pow(2,-23))*Math.pow(2,h)}function g(a,b){var c=m(a,b),d=m(a,b+1),e=m(a,b+2);return(m(a,b+3)<<24)+(e<<16)+(d<<8)+c}function i(a,b){var c=m(a,b);return(m(a,b+1)<<8)+c}function l(a,b){var c=m(a,b);return c>127?c-256:c}function m(a,b){return a.charCodeAt(b)&255}function k(b){var c, -d,e;c=g(a,b);d=g(a,b+N);e=g(a,b+A);b=i(a,b+J);u.faces.push(new THREE.Face3(c,d,e,null,null,b))}function o(b){var c,d,e,f,j,k,l;c=g(a,b);d=g(a,b+N);e=g(a,b+A);f=i(a,b+J);j=g(a,b+x);k=g(a,b+w);l=g(a,b+D);var b=z[k*3],n=z[k*3+1];k=z[k*3+2];var m=z[l*3],p=z[l*3+1];l=z[l*3+2];u.faces.push(new THREE.Face3(c,d,e,[new THREE.Vector3(z[j*3],z[j*3+1],z[j*3+2]),new THREE.Vector3(b,n,k),new THREE.Vector3(m,p,l)],null,f))}function p(b){var c,d,e,f;c=g(a,b);d=g(a,b+M);e=g(a,b+S);f=g(a,b+ca);b=i(a,b+L);u.faces.push(new THREE.Face4(c, -d,e,f,null,null,b))}function q(b){var c,d,e,f,k,l,n,m,p;c=g(a,b);d=g(a,b+M);e=g(a,b+S);f=g(a,b+ca);k=i(a,b+L);l=g(a,b+P);n=g(a,b+j);m=g(a,b+ea);p=g(a,b+ha);var b=z[n*3],o=z[n*3+1];n=z[n*3+2];var Q=z[m*3],G=z[m*3+1];m=z[m*3+2];var H=z[p*3],q=z[p*3+1];p=z[p*3+2];u.faces.push(new THREE.Face4(c,d,e,f,[new THREE.Vector3(z[l*3],z[l*3+1],z[l*3+2]),new THREE.Vector3(b,o,n),new THREE.Vector3(Q,G,m),new THREE.Vector3(H,q,p)],null,k))}function n(b){var c,d,e,f;c=g(a,b);d=g(a,b+F);e=g(a,b+B);b=E[c*2];f=E[c*2+ -1];c=E[d*2];var i=u.faceVertexUvs[0];d=E[d*2+1];var j=E[e*2];e=E[e*2+1];var k=[];k.push(new THREE.UV(b,f));k.push(new THREE.UV(c,d));k.push(new THREE.UV(j,e));i.push(k)}function t(b){var c,d,e,f,i,j;c=g(a,b);d=g(a,b+R);e=g(a,b+Y);f=g(a,b+O);b=E[c*2];i=E[c*2+1];c=E[d*2];j=E[d*2+1];d=E[e*2];var k=u.faceVertexUvs[0];e=E[e*2+1];var l=E[f*2];f=E[f*2+1];var n=[];n.push(new THREE.UV(b,i));n.push(new THREE.UV(c,j));n.push(new THREE.UV(d,e));n.push(new THREE.UV(l,f));k.push(n)}var u=this,v=0,r,z=[],E=[],N, -A,J,x,w,D,M,S,ca,L,P,j,ea,ha,F,B,R,Y,O,ga,$,X,aa,ba,V;THREE.Geometry.call(this);THREE.Loader.prototype.initMaterials(u,d,b);r={signature:a.substr(v,8),header_bytes:m(a,v+8),vertex_coordinate_bytes:m(a,v+9),normal_coordinate_bytes:m(a,v+10),uv_coordinate_bytes:m(a,v+11),vertex_index_bytes:m(a,v+12),normal_index_bytes:m(a,v+13),uv_index_bytes:m(a,v+14),material_index_bytes:m(a,v+15),nvertices:g(a,v+16),nnormals:g(a,v+16+4),nuvs:g(a,v+16+8),ntri_flat:g(a,v+16+12),ntri_smooth:g(a,v+16+16),ntri_flat_uv:g(a, -v+16+20),ntri_smooth_uv:g(a,v+16+24),nquad_flat:g(a,v+16+28),nquad_smooth:g(a,v+16+32),nquad_flat_uv:g(a,v+16+36),nquad_smooth_uv:g(a,v+16+40)};v+=r.header_bytes;N=r.vertex_index_bytes;A=r.vertex_index_bytes*2;J=r.vertex_index_bytes*3;x=r.vertex_index_bytes*3+r.material_index_bytes;w=r.vertex_index_bytes*3+r.material_index_bytes+r.normal_index_bytes;D=r.vertex_index_bytes*3+r.material_index_bytes+r.normal_index_bytes*2;M=r.vertex_index_bytes;S=r.vertex_index_bytes*2;ca=r.vertex_index_bytes*3;L=r.vertex_index_bytes* -4;P=r.vertex_index_bytes*4+r.material_index_bytes;j=r.vertex_index_bytes*4+r.material_index_bytes+r.normal_index_bytes;ea=r.vertex_index_bytes*4+r.material_index_bytes+r.normal_index_bytes*2;ha=r.vertex_index_bytes*4+r.material_index_bytes+r.normal_index_bytes*3;F=r.uv_index_bytes;B=r.uv_index_bytes*2;R=r.uv_index_bytes;Y=r.uv_index_bytes*2;O=r.uv_index_bytes*3;b=r.vertex_index_bytes*3+r.material_index_bytes;V=r.vertex_index_bytes*4+r.material_index_bytes;ga=r.ntri_flat*b;$=r.ntri_smooth*(b+r.normal_index_bytes* -3);X=r.ntri_flat_uv*(b+r.uv_index_bytes*3);aa=r.ntri_smooth_uv*(b+r.normal_index_bytes*3+r.uv_index_bytes*3);ba=r.nquad_flat*V;b=r.nquad_smooth*(V+r.normal_index_bytes*4);V=r.nquad_flat_uv*(V+r.uv_index_bytes*4);v+=function(b){for(var d,e,g,h=r.vertex_coordinate_bytes*3,i=b+r.nvertices*h;b=0){o=i.invBindMatrices[n];j.invBindMatrix=o;j.skinningMatrix=new THREE.Matrix4;j.skinningMatrix.multiply(j.world,o);j.weights=[];for(o=0;o1){j=new THREE.MeshFaceMaterial;for(h=0;h1?b.add(j):b=j}}b.name=a.id||"";a.matrix.decompose(b.position,b.rotation, -b.scale);for(f=0;f1?c[1].substr(0,b):"0";c[1].length=0,g=e.indexOf("(")>=0,h;if(f)d=e.split("."),e=d.shift(),d.shift();else if(g){h=e.split("(");e=h.shift(); -for(d=0;db){l=j.output[i];break}g=l!==void 0?l instanceof THREE.Matrix4? -g.multiply(g,l):g.multiply(g,h.matrix):g.multiply(g,h.matrix)}else g=g.multiply(g,h.matrix);b=g;c.push({time:a,pos:[b.n14,b.n24,b.n34],rotq:[0,0,0,1],scl:[1,1,1]})}this.keys=c}this.updateMatrix();return this};k.prototype.updateMatrix=function(){this.matrix.identity();for(var a=0;a>7)-127;d|=(f&127)<<16|e<<8;if(d==0&&h==-127)return 0;return(1-2*(g>>7))*(1+d*Math.pow(2,-23))*Math.pow(2,h)}function g(a,b){var c=l(a,b),d=l(a,b+1),e=l(a,b+2);return(l(a,b+3)<<24)+(e<<16)+(d<<8)+c}function i(a,b){var c=l(a,b);return(l(a,b+1)<<8)+c}function k(a,b){var c=l(a,b);return c>127?c-256:c}function l(a,b){return a.charCodeAt(b)&255}function m(b){var c, +d,e;c=g(a,b);d=g(a,b+z);e=g(a,b+L);b=i(a,b+J);v.faces.push(new THREE.Face3(c,d,e,null,null,b))}function o(b){var c,d,e,f,j,k,l;c=g(a,b);d=g(a,b+z);e=g(a,b+L);f=i(a,b+J);j=g(a,b+I);k=g(a,b+D);l=g(a,b+C);var b=t[k*3],m=t[k*3+1];k=t[k*3+2];var n=t[l*3],o=t[l*3+1];l=t[l*3+2];v.faces.push(new THREE.Face3(c,d,e,[new THREE.Vector3(t[j*3],t[j*3+1],t[j*3+2]),new THREE.Vector3(b,m,k),new THREE.Vector3(n,o,l)],null,f))}function n(b){var c,d,e,f;c=g(a,b);d=g(a,b+P);e=g(a,b+R);f=g(a,b+fa);b=i(a,b+M);v.faces.push(new THREE.Face4(c, +d,e,f,null,null,b))}function s(b){var c,d,e,f,j,k,l,m,n;c=g(a,b);d=g(a,b+P);e=g(a,b+R);f=g(a,b+fa);j=i(a,b+M);k=g(a,b+N);l=g(a,b+ga);m=g(a,b+ka);n=g(a,b+Z);var b=t[l*3],o=t[l*3+1];l=t[l*3+2];var x=t[m*3],p=t[m*3+1];m=t[m*3+2];var E=t[n*3],q=t[n*3+1];n=t[n*3+2];v.faces.push(new THREE.Face4(c,d,e,f,[new THREE.Vector3(t[k*3],t[k*3+1],t[k*3+2]),new THREE.Vector3(b,o,l),new THREE.Vector3(x,p,m),new THREE.Vector3(E,q,n)],null,j))}function p(b){var c,d,e,f;c=g(a,b);d=g(a,b+F);e=g(a,b+B);b=w[c*2];f=w[c*2+ +1];c=w[d*2];var i=v.faceVertexUvs[0];d=w[d*2+1];var j=w[e*2];e=w[e*2+1];var k=[];k.push(new THREE.UV(b,f));k.push(new THREE.UV(c,d));k.push(new THREE.UV(j,e));i.push(k)}function u(b){var c,d,e,f,i,k;c=g(a,b);d=g(a,b+Q);e=g(a,b+O);f=g(a,b+j);b=w[c*2];i=w[c*2+1];c=w[d*2];k=w[d*2+1];d=w[e*2];var l=v.faceVertexUvs[0];e=w[e*2+1];var m=w[f*2];f=w[f*2+1];var n=[];n.push(new THREE.UV(b,i));n.push(new THREE.UV(c,k));n.push(new THREE.UV(d,e));n.push(new THREE.UV(m,f));l.push(n)}var v=this,y=0,q,t=[],w=[],z, +L,J,I,D,C,P,R,fa,M,N,ga,ka,Z,F,B,Q,O,j,ha,aa,V,ba,U,ea;THREE.Geometry.call(this);THREE.Loader.prototype.initMaterials(v,d,b);q={signature:a.substr(y,8),header_bytes:l(a,y+8),vertex_coordinate_bytes:l(a,y+9),normal_coordinate_bytes:l(a,y+10),uv_coordinate_bytes:l(a,y+11),vertex_index_bytes:l(a,y+12),normal_index_bytes:l(a,y+13),uv_index_bytes:l(a,y+14),material_index_bytes:l(a,y+15),nvertices:g(a,y+16),nnormals:g(a,y+16+4),nuvs:g(a,y+16+8),ntri_flat:g(a,y+16+12),ntri_smooth:g(a,y+16+16),ntri_flat_uv:g(a, +y+16+20),ntri_smooth_uv:g(a,y+16+24),nquad_flat:g(a,y+16+28),nquad_smooth:g(a,y+16+32),nquad_flat_uv:g(a,y+16+36),nquad_smooth_uv:g(a,y+16+40)};y+=q.header_bytes;z=q.vertex_index_bytes;L=q.vertex_index_bytes*2;J=q.vertex_index_bytes*3;I=q.vertex_index_bytes*3+q.material_index_bytes;D=q.vertex_index_bytes*3+q.material_index_bytes+q.normal_index_bytes;C=q.vertex_index_bytes*3+q.material_index_bytes+q.normal_index_bytes*2;P=q.vertex_index_bytes;R=q.vertex_index_bytes*2;fa=q.vertex_index_bytes*3;M=q.vertex_index_bytes* +4;N=q.vertex_index_bytes*4+q.material_index_bytes;ga=q.vertex_index_bytes*4+q.material_index_bytes+q.normal_index_bytes;ka=q.vertex_index_bytes*4+q.material_index_bytes+q.normal_index_bytes*2;Z=q.vertex_index_bytes*4+q.material_index_bytes+q.normal_index_bytes*3;F=q.uv_index_bytes;B=q.uv_index_bytes*2;Q=q.uv_index_bytes;O=q.uv_index_bytes*2;j=q.uv_index_bytes*3;b=q.vertex_index_bytes*3+q.material_index_bytes;ea=q.vertex_index_bytes*4+q.material_index_bytes;ha=q.ntri_flat*b;aa=q.ntri_smooth*(b+q.normal_index_bytes* +3);V=q.ntri_flat_uv*(b+q.uv_index_bytes*3);ba=q.ntri_smooth_uv*(b+q.normal_index_bytes*3+q.uv_index_bytes*3);U=q.nquad_flat*ea;b=q.nquad_smooth*(ea+q.normal_index_bytes*4);ea=q.nquad_flat_uv*(ea+q.uv_index_bytes*4);y+=function(b){for(var d,e,g,h=q.vertex_coordinate_bytes*3,i=b+q.nvertices*h;b=0){p=i.invBindMatrices[m];j.invBindMatrix=p;j.skinningMatrix=new THREE.Matrix4;j.skinningMatrix.multiply(j.world,p);j.weights=[];for(p=0;p1){j=new THREE.MeshFaceMaterial;for(h=0;h1?b.add(j):b=j}}b.name=a.id||"";a.matrix.decompose(b.position,b.rotation, +b.scale);for(f=0;f1?c[1].substr(0,b):"0";c[1].length=0,g=e.indexOf("(")>=0,h;if(f)d=e.split("."),e=d.shift(),d.shift();else if(g){h=e.split("(");e=h.shift(); +for(d=0;db){k=j.output[i];break}g=k!==void 0?k instanceof THREE.Matrix4? +g.multiply(g,k):g.multiply(g,h.matrix):g.multiply(g,h.matrix)}else g=g.multiply(g,h.matrix);b=g;c.push({time:a,pos:[b.n14,b.n24,b.n34],rotq:[0,0,0,1],scl:[1,1,1]})}this.keys=c}this.updateMatrix();return this};m.prototype.updateMatrix=function(){this.matrix.identity();for(var a=0;a0&&(this[c.nodeName]=parseFloat(d[0].textContent))}}this.create();return this};w.prototype.create=function(){var a= -{},b=this.transparency!==void 0&&this.transparency<1,c;for(c in this)switch(c){case "ambient":case "emission":case "diffuse":case "specular":var d=this[c];if(d instanceof x)if(d.isTexture()){if(this.effect.sampler&&this.effect.surface&&this.effect.sampler.source==this.effect.surface.sid&&(d=C[this.effect.surface.init_from]))a.map=THREE.ImageUtils.loadTexture(sa+d.init_from),a.map.wrapS=THREE.RepeatWrapping,a.map.wrapT=THREE.RepeatWrapping,a.map.repeat.x=1,a.map.repeat.y=-1}else c=="diffuse"?a.color= -d.color.getHex():b||(a[c]=d.color.getHex());break;case "shininess":case "reflectivity":a[c]=this[c];break;case "transparency":if(b)a.transparent=!0,a.opacity=this[c],b=!0}a.shading=xa;return this.material=new THREE.MeshLambertMaterial(a)};D.prototype.parse=function(a){for(var b=0;b=0,d=a.indexOf("(")>=0,e,f;if(c)b=a.split("."),a=b.shift(),f=b.shift();else if(d){e=a.split("("); -a=e.shift();for(b=0;b0&&(this[c.nodeName]=parseFloat(d[0].textContent))}}this.create();return this};D.prototype.create=function(){var a= +{},b=this.transparency!==void 0&&this.transparency<1,c;for(c in this)switch(c){case "ambient":case "emission":case "diffuse":case "specular":var d=this[c];if(d instanceof I)if(d.isTexture()){if(this.effect.sampler&&this.effect.surface&&this.effect.sampler.source==this.effect.surface.sid&&(d=ca[this.effect.surface.init_from]))a.map=THREE.ImageUtils.loadTexture(va+d.init_from),a.map.wrapS=THREE.RepeatWrapping,a.map.wrapT=THREE.RepeatWrapping,a.map.repeat.x=1,a.map.repeat.y=-1}else c=="diffuse"?a.color= +d.color.getHex():b||(a[c]=d.color.getHex());break;case "shininess":case "reflectivity":a[c]=this[c];break;case "transparency":if(b)a.transparent=!0,a.opacity=this[c],b=!0}a.shading=Aa;return this.material=new THREE.MeshLambertMaterial(a)};C.prototype.parse=function(a){for(var b=0;b=0,d=a.indexOf("(")>=0,e,f;if(c)b=a.split("."),a=b.shift(),f=b.shift();else if(d){e=a.split("("); +a=e.shift();for(b=0;b1&&(ca=new THREE.MeshFaceMaterial);a=new THREE.Mesh(w,ca);a.name=p;a.position.set(E[0],E[1],E[2]);A?(a.quaternion.set(A[0],A[1],A[2],A[3]),a.useQuaternion=!0):a.rotation.set(N[0],N[1],N[2]);a.scale.set(J[0],J[1],J[2]);a.visible=v.visible;B.scene.add(a);B.objects[p]=a;if(v.meshCollider){var b=THREE.CollisionUtils.MeshColliderWBox(a);B.scene.collisions.colliders.push(b)}if(v.castsShadow)b=new THREE.ShadowVolume(w),B.scene.add(b), -b.position=a.position,b.rotation=a.rotation,b.scale=a.scale;v.trigger&&v.trigger.toLowerCase()!="none"&&(b={type:v.trigger,object:v},B.triggers[a.name]=b)}}else E=v.position,N=v.rotation,A=v.quaternion,J=v.scale,A=0,a=new THREE.Object3D,a.name=p,a.position.set(E[0],E[1],E[2]),A?(a.quaternion.set(A[0],A[1],A[2],A[3]),a.useQuaternion=!0):a.rotation.set(N[0],N[1],N[2]),a.scale.set(J[0],J[1],J[2]),a.visible=v.visible!==void 0?v.visible:!1,B.scene.add(a),B.objects[p]=a,B.empties[p]=a,v.trigger&&v.trigger.toLowerCase()!= -"none"&&(b={type:v.trigger,object:v},B.triggers[a.name]=b)}function i(a){return function(c){B.geometries[a]=c;h();j-=1;b.onLoadComplete();m()}}function l(a){return function(b){B.geometries[a]=b}}function m(){b.callbackProgress({totalModels:ha,totalTextures:F,loadedModels:ha-j,loadedTextures:F-ea},B);b.onLoadProgress();j==0&&ea==0&&c(B)}var k,o,p,q,n,t,u,v,r,z,E,N,A,J,x,w,D,M,S,ca,L,P,j,ea,ha,F,B;L=a.data;S=new THREE.BinaryLoader;P=new THREE.JSONLoader;ea=j=0;B={scene:new THREE.Scene,geometries:{}, -materials:{},textures:{},objects:{},cameras:{},lights:{},fogs:{},triggers:{},empties:{}};a=!1;for(p in L.objects)if(v=L.objects[p],v.meshCollider){a=!0;break}if(a)B.scene.collisions=new THREE.CollisionSystem;if(L.transform){a=L.transform.position;r=L.transform.rotation;var R=L.transform.scale;a&&B.scene.position.set(a[0],a[1],a[2]);r&&B.scene.rotation.set(r[0],r[1],r[2]);R&&B.scene.scale.set(R[0],R[1],R[2]);(a||r||R)&&B.scene.updateMatrix()}a=function(){ea-=1;m();b.onLoadComplete()};for(n in L.cameras)r= -L.cameras[n],r.type=="perspective"?D=new THREE.PerspectiveCamera(r.fov,r.aspect,r.near,r.far):r.type=="ortho"&&(D=new THREE.OrthographicCamera(r.left,r.right,r.top,r.bottom,r.near,r.far)),E=r.position,r=r.target,D.position.set(E[0],E[1],E[2]),D.target=new THREE.Vector3(r[0],r[1],r[2]),B.cameras[n]=D;for(q in L.lights)r=L.lights[q],n=r.color!==void 0?r.color:16777215,D=r.intensity!==void 0?r.intensity:1,r.type=="directional"?(E=r.direction,z=new THREE.DirectionalLight(n,D),z.position.set(E[0],E[1], -E[2]),z.position.normalize()):r.type=="point"?(E=r.position,z=r.distance,z=new THREE.PointLight(n,D,z),z.position.set(E[0],E[1],E[2])):r.type=="ambient"&&(z=new THREE.AmbientLight(n)),B.scene.add(z),B.lights[q]=z;for(t in L.fogs)q=L.fogs[t],q.type=="linear"?M=new THREE.Fog(0,q.near,q.far):q.type=="exp2"&&(M=new THREE.FogExp2(0,q.density)),r=q.color,M.color.setRGB(r[0],r[1],r[2]),B.fogs[t]=M;if(B.cameras&&L.defaults.camera)B.currentCamera=B.cameras[L.defaults.camera];if(B.fogs&&L.defaults.fog)B.scene.fog= -B.fogs[L.defaults.fog];r=L.defaults.bgcolor;B.bgColor=new THREE.Color;B.bgColor.setRGB(r[0],r[1],r[2]);B.bgColorAlpha=L.defaults.bgalpha;for(k in L.geometries)if(t=L.geometries[k],t.type=="bin_mesh"||t.type=="ascii_mesh")j+=1,b.onLoadStart();ha=j;for(k in L.geometries)t=L.geometries[k],t.type=="cube"?(w=new THREE.CubeGeometry(t.width,t.height,t.depth,t.segmentsWidth,t.segmentsHeight,t.segmentsDepth,null,t.flipped,t.sides),B.geometries[k]=w):t.type=="plane"?(w=new THREE.PlaneGeometry(t.width,t.height, -t.segmentsWidth,t.segmentsHeight),B.geometries[k]=w):t.type=="sphere"?(w=new THREE.SphereGeometry(t.radius,t.segmentsWidth,t.segmentsHeight),B.geometries[k]=w):t.type=="cylinder"?(w=new THREE.CylinderGeometry(t.topRad,t.botRad,t.height,t.radSegs,t.heightSegs),B.geometries[k]=w):t.type=="torus"?(w=new THREE.TorusGeometry(t.radius,t.tube,t.segmentsR,t.segmentsT),B.geometries[k]=w):t.type=="icosahedron"?(w=new THREE.IcosahedronGeometry(t.subdivisions),B.geometries[k]=w):t.type=="bin_mesh"?S.load(d(t.url, -L.urlBaseType),i(k)):t.type=="ascii_mesh"?P.load(d(t.url,L.urlBaseType),i(k)):t.type=="embedded_mesh"&&(t=L.embeds[t.id])&&P.createModel(t,l(k),"");for(u in L.textures)if(k=L.textures[u],k.url instanceof Array){ea+=k.url.length;for(S=0;S1&&(fa=new THREE.MeshFaceMaterial);a=new THREE.Mesh(D,fa);a.name=n;a.position.set(w[0],w[1],w[2]);L?(a.quaternion.set(L[0],L[1],L[2],L[3]),a.useQuaternion=!0):a.rotation.set(z[0],z[1],z[2]);a.scale.set(J[0],J[1],J[2]);a.visible=y.visible;B.scene.add(a);B.objects[n]=a;if(y.meshCollider){var b=THREE.CollisionUtils.MeshColliderWBox(a);B.scene.collisions.colliders.push(b)}if(y.castsShadow)b=new THREE.ShadowVolume(D),B.scene.add(b), +b.position=a.position,b.rotation=a.rotation,b.scale=a.scale;y.trigger&&y.trigger.toLowerCase()!="none"&&(b={type:y.trigger,object:y},B.triggers[a.name]=b)}}else w=y.position,z=y.rotation,L=y.quaternion,J=y.scale,L=0,a=new THREE.Object3D,a.name=n,a.position.set(w[0],w[1],w[2]),L?(a.quaternion.set(L[0],L[1],L[2],L[3]),a.useQuaternion=!0):a.rotation.set(z[0],z[1],z[2]),a.scale.set(J[0],J[1],J[2]),a.visible=y.visible!==void 0?y.visible:!1,B.scene.add(a),B.objects[n]=a,B.empties[n]=a,y.trigger&&y.trigger.toLowerCase()!= +"none"&&(b={type:y.trigger,object:y},B.triggers[a.name]=b)}function i(a){return function(c){B.geometries[a]=c;h();ga-=1;b.onLoadComplete();l()}}function k(a){return function(b){B.geometries[a]=b}}function l(){b.callbackProgress({totalModels:Z,totalTextures:F,loadedModels:Z-ga,loadedTextures:F-ka},B);b.onLoadProgress();ga==0&&ka==0&&c(B)}var m,o,n,s,p,u,v,y,q,t,w,z,L,J,I,D,C,P,R,fa,M,N,ga,ka,Z,F,B;M=a.data;R=new THREE.BinaryLoader;N=new THREE.JSONLoader;ka=ga=0;B={scene:new THREE.Scene,geometries:{}, +materials:{},textures:{},objects:{},cameras:{},lights:{},fogs:{},triggers:{},empties:{}};a=!1;for(n in M.objects)if(y=M.objects[n],y.meshCollider){a=!0;break}if(a)B.scene.collisions=new THREE.CollisionSystem;if(M.transform){a=M.transform.position;q=M.transform.rotation;var Q=M.transform.scale;a&&B.scene.position.set(a[0],a[1],a[2]);q&&B.scene.rotation.set(q[0],q[1],q[2]);Q&&B.scene.scale.set(Q[0],Q[1],Q[2]);(a||q||Q)&&B.scene.updateMatrix()}a=function(){ka-=1;l();b.onLoadComplete()};for(p in M.cameras)q= +M.cameras[p],q.type=="perspective"?C=new THREE.PerspectiveCamera(q.fov,q.aspect,q.near,q.far):q.type=="ortho"&&(C=new THREE.OrthographicCamera(q.left,q.right,q.top,q.bottom,q.near,q.far)),w=q.position,q=q.target,C.position.set(w[0],w[1],w[2]),C.target=new THREE.Vector3(q[0],q[1],q[2]),B.cameras[p]=C;for(s in M.lights)q=M.lights[s],p=q.color!==void 0?q.color:16777215,C=q.intensity!==void 0?q.intensity:1,q.type=="directional"?(w=q.direction,t=new THREE.DirectionalLight(p,C),t.position.set(w[0],w[1], +w[2]),t.position.normalize()):q.type=="point"?(w=q.position,t=q.distance,t=new THREE.PointLight(p,C,t),t.position.set(w[0],w[1],w[2])):q.type=="ambient"&&(t=new THREE.AmbientLight(p)),B.scene.add(t),B.lights[s]=t;for(u in M.fogs)s=M.fogs[u],s.type=="linear"?P=new THREE.Fog(0,s.near,s.far):s.type=="exp2"&&(P=new THREE.FogExp2(0,s.density)),q=s.color,P.color.setRGB(q[0],q[1],q[2]),B.fogs[u]=P;if(B.cameras&&M.defaults.camera)B.currentCamera=B.cameras[M.defaults.camera];if(B.fogs&&M.defaults.fog)B.scene.fog= +B.fogs[M.defaults.fog];q=M.defaults.bgcolor;B.bgColor=new THREE.Color;B.bgColor.setRGB(q[0],q[1],q[2]);B.bgColorAlpha=M.defaults.bgalpha;for(m in M.geometries)if(u=M.geometries[m],u.type=="bin_mesh"||u.type=="ascii_mesh")ga+=1,b.onLoadStart();Z=ga;for(m in M.geometries)u=M.geometries[m],u.type=="cube"?(D=new THREE.CubeGeometry(u.width,u.height,u.depth,u.segmentsWidth,u.segmentsHeight,u.segmentsDepth,null,u.flipped,u.sides),B.geometries[m]=D):u.type=="plane"?(D=new THREE.PlaneGeometry(u.width,u.height, +u.segmentsWidth,u.segmentsHeight),B.geometries[m]=D):u.type=="sphere"?(D=new THREE.SphereGeometry(u.radius,u.segmentsWidth,u.segmentsHeight),B.geometries[m]=D):u.type=="cylinder"?(D=new THREE.CylinderGeometry(u.topRad,u.botRad,u.height,u.radSegs,u.heightSegs),B.geometries[m]=D):u.type=="torus"?(D=new THREE.TorusGeometry(u.radius,u.tube,u.segmentsR,u.segmentsT),B.geometries[m]=D):u.type=="icosahedron"?(D=new THREE.IcosahedronGeometry(u.subdivisions),B.geometries[m]=D):u.type=="bin_mesh"?R.load(d(u.url, +M.urlBaseType),i(m)):u.type=="ascii_mesh"?N.load(d(u.url,M.urlBaseType),i(m)):u.type=="embedded_mesh"&&(u=M.embeds[u.id])&&N.createModel(u,k(m),"");for(v in M.textures)if(m=M.textures[v],m.url instanceof Array){ka+=m.url.length;for(R=0;R=57344&&(c-=2048);c++;for(var b=new Float32Array(8*c),d=1,g=0;g<8;g++){for(var e=0,f=0;f>1^-(h&1);b[8*f+g]=e}d+=c}c=a.length-d;e=new Uint16Array(c);for(g=f=0;g=this.maxCount-3&&h(this)};this.begin= -function(){this.count=0;this.hasNormal=this.hasPos=!1};this.end=function(a){if(this.count!==0){for(var c=this.count*3;cthis.size-1&&(i=this.size-1);var o=Math.floor(l-h);o<1&&(o=1);l=Math.floor(l+h);l>this.size-1&&(l=this.size-1);var p=Math.floor(m-h);p<1&&(p=1);h=Math.floor(m+h); -h>this.size-1&&(h=this.size-1);for(var q,n,t,u,v,r;k0&&(this.field[t+q]+=u)}}};this.addPlaneX=function(a,c){var g,e,f,h,i,l=this.size,m=this.yd,k=this.zd,o=this.field,p=l*Math.sqrt(a/c);p>l&&(p=l);for(g=0;g0)for(e=0;em&&(q=m);for(e=0;e0){i=e*k;for(g=0;gm&&(q=m);for(f=0;f0){i=o*f;for(e=0;ethis.size-1&&(i=this.size-1);var o=Math.floor(k-h);o<1&&(o=1);k=Math.floor(k+h);k>this.size-1&&(k=this.size-1);var n=Math.floor(l-h);n<1&&(n=1);h=Math.floor(l+h); +h>this.size-1&&(h=this.size-1);for(var s,p,u,v,y,q;m0&&(this.field[u+s]+=v)}}};this.addPlaneX=function(a,c){var g,e,f,h,i,k=this.size,l=this.yd,m=this.zd,o=this.field,n=k*Math.sqrt(a/c);n>k&&(n=k);for(g=0;g0)for(e=0;el&&(s=l);for(e=0;e0){i=e*m;for(g=0;gl&&(s=l);for(f=0;f0){i=o*f;for(e=0;ee?this.hits.push(g):this.hits.unshift(g),e=d;return this.hits}; THREE.CollisionSystem.prototype.rayCastNearest=function(a){var c=this.rayCastAll(a);if(c.length==0)return null;for(var b=0;c[b]instanceof THREE.MeshCollider;){var d=this.rayMesh(a,c[b]);if(d.distc.length)return null;return c[b]}; THREE.CollisionSystem.prototype.rayCast=function(a,c){if(c instanceof THREE.PlaneCollider)return this.rayPlane(a,c);else if(c instanceof THREE.SphereCollider)return this.raySphere(a,c);else if(c instanceof THREE.BoxCollider)return this.rayBox(a,c);else if(c instanceof THREE.MeshCollider&&c.box)return this.rayBox(a,c.box)}; -THREE.CollisionSystem.prototype.rayMesh=function(a,c){for(var b=this.makeRayLocal(a,c.mesh),d=Number.MAX_VALUE,g,e=0;e=h*g))return Number.MAX_VALUE;f/=h;h=THREE.CollisionSystem.__v3;h.copy(a.direction);h.multiplyScalar(f);h.addSelf(a.origin);Math.abs(e.x)> Math.abs(e.y)?Math.abs(e.x)>Math.abs(e.z)?(a=h.y-c.y,e=b.y-c.y,g=d.y-c.y,h=h.z-c.z,b=b.z-c.z,d=d.z-c.z):(a=h.x-c.x,e=b.x-c.x,g=d.x-c.x,h=h.y-c.y,b=b.y-c.y,d=d.y-c.y):Math.abs(e.y)>Math.abs(e.z)?(a=h.x-c.x,e=b.x-c.x,g=d.x-c.x,h=h.z-c.z,b=b.z-c.z,d=d.z-c.z):(a=h.x-c.x,e=b.x-c.x,g=d.x-c.x,h=h.y-c.y,b=b.y-c.y,d=d.y-c.y);c=e*d-b*g;if(c==0)return Number.MAX_VALUE;c=1/c;d=(a*d-h*g)*c;if(!(d>=0))return Number.MAX_VALUE;c*=e*h-b*a;if(!(c>=0))return Number.MAX_VALUE;if(!(1-d-c>=0))return Number.MAX_VALUE;return f}; THREE.CollisionSystem.prototype.makeRayLocal=function(a,c){var b=THREE.CollisionSystem.__m;b.getInverse(c.matrixWorld);var d=THREE.CollisionSystem.__r;d.origin.copy(a.origin);d.direction.copy(a.direction);b.multiplyVector3(d.origin);b.rotateAxis(d.direction);d.direction.normalize();return d}; -THREE.CollisionSystem.prototype.rayBox=function(a,c){var b;c.dynamic&&c.mesh&&c.mesh.matrixWorld?b=this.makeRayLocal(a,c.mesh):(b=THREE.CollisionSystem.__r,b.origin.copy(a.origin),b.direction.copy(a.direction));var d=0,g=0,e=0,f=0,h=0,i=0,l=!0;b.origin.xc.max.x&&(d=c.max.x-b.origin.x,d/=b.direction.x,l=!1,f=1);b.origin.yc.max.y&&(g=c.max.y-b.origin.y,g/=b.direction.y, -l=!1,h=1);b.origin.zc.max.z&&(e=c.max.z-b.origin.z,e/=b.direction.z,l=!1,i=1);if(l)return-1;l=0;g>d&&(l=1,d=g);e>d&&(l=2,d=e);switch(l){case 0:h=b.origin.y+b.direction.y*d;if(hc.max.y)return Number.MAX_VALUE;b=b.origin.z+b.direction.z*d;if(bc.max.z)return Number.MAX_VALUE;c.normal.set(f,0,0);break;case 1:f=b.origin.x+b.direction.x*d;if(fc.max.x)return Number.MAX_VALUE;b=b.origin.z+b.direction.z* +THREE.CollisionSystem.prototype.rayBox=function(a,c){var b;c.dynamic&&c.mesh&&c.mesh.matrixWorld?b=this.makeRayLocal(a,c.mesh):(b=THREE.CollisionSystem.__r,b.origin.copy(a.origin),b.direction.copy(a.direction));var d=0,g=0,e=0,f=0,h=0,i=0,k=!0;b.origin.xc.max.x&&(d=c.max.x-b.origin.x,d/=b.direction.x,k=!1,f=1);b.origin.yc.max.y&&(g=c.max.y-b.origin.y,g/=b.direction.y, +k=!1,h=1);b.origin.zc.max.z&&(e=c.max.z-b.origin.z,e/=b.direction.z,k=!1,i=1);if(k)return-1;k=0;g>d&&(k=1,d=g);e>d&&(k=2,d=e);switch(k){case 0:h=b.origin.y+b.direction.y*d;if(hc.max.y)return Number.MAX_VALUE;b=b.origin.z+b.direction.z*d;if(bc.max.z)return Number.MAX_VALUE;c.normal.set(f,0,0);break;case 1:f=b.origin.x+b.direction.x*d;if(fc.max.x)return Number.MAX_VALUE;b=b.origin.z+b.direction.z* d;if(bc.max.z)return Number.MAX_VALUE;c.normal.set(0,h,0);break;case 2:f=b.origin.x+b.direction.x*d;if(fc.max.x)return Number.MAX_VALUE;h=b.origin.y+b.direction.y*d;if(hc.max.y)return Number.MAX_VALUE;c.normal.set(0,0,i)}return d};THREE.CollisionSystem.prototype.rayPlane=function(a,c){var b=a.direction.dot(c.normal),d=c.point.dot(c.normal);if(b<0)b=(d-a.origin.dot(c.normal))/b;else return Number.MAX_VALUE;return b>0?b:Number.MAX_VALUE}; THREE.CollisionSystem.prototype.raySphere=function(a,c){var b=c.center.clone().subSelf(a.origin);if(b.lengthSq=0)return Math.abs(d)-Math.sqrt(b);return Number.MAX_VALUE};THREE.CollisionSystem.__v1=new THREE.Vector3;THREE.CollisionSystem.__v2=new THREE.Vector3;THREE.CollisionSystem.__v3=new THREE.Vector3;THREE.CollisionSystem.__nr=new THREE.Vector3;THREE.CollisionSystem.__m=new THREE.Matrix4; THREE.CollisionSystem.__r=new THREE.Ray;THREE.CollisionUtils={};THREE.CollisionUtils.MeshOBB=function(a){a.geometry.computeBoundingBox();var c=a.geometry.boundingBox,b=new THREE.Vector3(c.x[0],c.y[0],c.z[0]),c=new THREE.Vector3(c.x[1],c.y[1],c.z[1]),b=new THREE.BoxCollider(b,c);b.mesh=a;return b};THREE.CollisionUtils.MeshAABB=function(a){var c=THREE.CollisionUtils.MeshOBB(a);c.min.addSelf(a.position);c.max.addSelf(a.position);c.dynamic=!1;return c}; THREE.CollisionUtils.MeshColliderWBox=function(a){return new THREE.MeshCollider(a,THREE.CollisionUtils.MeshOBB(a))}; -if(THREE.WebGLRenderer)THREE.AnaglyphWebGLRenderer=function(a){THREE.WebGLRenderer.call(this,a);this.autoUpdateScene=!1;var c=this,b=this.setSize,d=this.render,g=new THREE.PerspectiveCamera,e=new THREE.PerspectiveCamera,f=new THREE.Matrix4,h=new THREE.Matrix4,i,l,m,k;g.matrixAutoUpdate=e.matrixAutoUpdate=!1;var a={minFilter:THREE.LinearFilter,magFilter:THREE.NearestFilter,format:THREE.RGBAFormat},o=new THREE.WebGLRenderTarget(512,512,a),p=new THREE.WebGLRenderTarget(512,512,a),q=new THREE.PerspectiveCamera(53, -1,1,1E4);q.position.z=2;var a=new THREE.ShaderMaterial({uniforms:{mapLeft:{type:"t",value:0,texture:o},mapRight:{type:"t",value:1,texture:p}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform sampler2D mapLeft;\nuniform sampler2D mapRight;\nvarying vec2 vUv;\nvoid main() {\nvec4 colorL, colorR;\nvec2 uv = vUv;\ncolorL = texture2D( mapLeft, uv );\ncolorR = texture2D( mapRight, uv );\ngl_FragColor = vec4( colorL.g * 0.7 + colorL.b * 0.3, colorR.g, colorR.b, colorL.a + colorR.a ) * 1.1;\n}"}), -n=new THREE.Scene;n.add(new THREE.Mesh(new THREE.PlaneGeometry(2,2),a));n.add(q);this.setSize=function(a,d){b.call(c,a,d);o.width=a;o.height=d;p.width=a;p.height=d};this.render=function(a,b){a.updateMatrixWorld();if(i!==b.aspect||l!==b.near||m!==b.far||k!==b.fov){i=b.aspect;l=b.near;m=b.far;k=b.fov;var v=b.projectionMatrix.clone(),r=125/30*0.5,z=r*l/125,E=l*Math.tan(k*Math.PI/360),N;f.n14=r;h.n14=-r;r=-E*i+z;N=E*i+z;v.n11=2*l/(N-r);v.n13=(N+r)/(N-r);g.projectionMatrix.copy(v);r=-E*i-z;N=E*i-z;v.n11= -2*l/(N-r);v.n13=(N+r)/(N-r);e.projectionMatrix.copy(v)}g.matrixWorld.copy(b.matrixWorld).multiplySelf(h);g.position.copy(b.position);g.near=b.near;g.far=b.far;d.call(c,a,g,o,!0);e.matrixWorld.copy(b.matrixWorld).multiplySelf(f);e.position.copy(b.position);e.near=b.near;e.far=b.far;d.call(c,a,e,p,!0);n.updateMatrixWorld();d.call(c,n,q)}}; +if(THREE.WebGLRenderer)THREE.AnaglyphWebGLRenderer=function(a){THREE.WebGLRenderer.call(this,a);this.autoUpdateScene=!1;var c=this,b=this.setSize,d=this.render,g=new THREE.PerspectiveCamera,e=new THREE.PerspectiveCamera,f=new THREE.Matrix4,h=new THREE.Matrix4,i,k,l,m;g.matrixAutoUpdate=e.matrixAutoUpdate=!1;var a={minFilter:THREE.LinearFilter,magFilter:THREE.NearestFilter,format:THREE.RGBAFormat},o=new THREE.WebGLRenderTarget(512,512,a),n=new THREE.WebGLRenderTarget(512,512,a),s=new THREE.PerspectiveCamera(53, +1,1,1E4);s.position.z=2;var a=new THREE.ShaderMaterial({uniforms:{mapLeft:{type:"t",value:0,texture:o},mapRight:{type:"t",value:1,texture:n}},vertexShader:"varying vec2 vUv;\nvoid main() {\nvUv = vec2( uv.x, 1.0 - uv.y );\ngl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}",fragmentShader:"uniform sampler2D mapLeft;\nuniform sampler2D mapRight;\nvarying vec2 vUv;\nvoid main() {\nvec4 colorL, colorR;\nvec2 uv = vUv;\ncolorL = texture2D( mapLeft, uv );\ncolorR = texture2D( mapRight, uv );\ngl_FragColor = vec4( colorL.g * 0.7 + colorL.b * 0.3, colorR.g, colorR.b, colorL.a + colorR.a ) * 1.1;\n}"}), +p=new THREE.Scene;p.add(new THREE.Mesh(new THREE.PlaneGeometry(2,2),a));p.add(s);this.setSize=function(a,d){b.call(c,a,d);o.width=a;o.height=d;n.width=a;n.height=d};this.render=function(a,b){a.updateMatrixWorld();if(i!==b.aspect||k!==b.near||l!==b.far||m!==b.fov){i=b.aspect;k=b.near;l=b.far;m=b.fov;var y=b.projectionMatrix.clone(),q=125/30*0.5,t=q*k/125,w=k*Math.tan(m*Math.PI/360),z;f.n14=q;h.n14=-q;q=-w*i+t;z=w*i+t;y.n11=2*k/(z-q);y.n13=(z+q)/(z-q);g.projectionMatrix.copy(y);q=-w*i-t;z=w*i-t;y.n11= +2*k/(z-q);y.n13=(z+q)/(z-q);e.projectionMatrix.copy(y)}g.matrixWorld.copy(b.matrixWorld).multiplySelf(h);g.position.copy(b.position);g.near=b.near;g.far=b.far;d.call(c,a,g,o,!0);e.matrixWorld.copy(b.matrixWorld).multiplySelf(f);e.position.copy(b.position);e.near=b.near;e.far=b.far;d.call(c,a,e,n,!0);p.updateMatrixWorld();d.call(c,p,s)}}; if(THREE.WebGLRenderer)THREE.CrosseyedWebGLRenderer=function(a){THREE.WebGLRenderer.call(this,a);this.autoClear=!1;var c=this,b=this.setSize,d=this.render,g,e,f=new THREE.PerspectiveCamera;f.target=new THREE.Vector3(0,0,0);var h=new THREE.PerspectiveCamera;h.target=new THREE.Vector3(0,0,0);c.separation=10;if(a&&a.separation!==void 0)c.separation=a.separation;this.setSize=function(a,d){b.call(c,a,d);g=a/2;e=d};this.render=function(a,b){this.clear();f.fov=b.fov;f.aspect=0.5*b.aspect;f.near=b.near;f.far= b.far;f.updateProjectionMatrix();f.position.copy(b.position);f.target.copy(b.target);f.translateX(c.separation);f.lookAt(f.target);h.projectionMatrix=f.projectionMatrix;h.position.copy(b.position);h.target.copy(b.target);h.translateX(-c.separation);h.lookAt(h.target);this.setViewport(0,0,g,e);d.call(c,a,f);this.setViewport(g,0,g,e);d.call(c,a,h,!1)}}; diff --git a/build/custom/ThreeWebGL.js b/build/custom/ThreeWebGL.js index 66fbbd03..e695e70b 100644 --- a/build/custom/ThreeWebGL.js +++ b/build/custom/ThreeWebGL.js @@ -1,7 +1,7 @@ // ThreeWebGL.js r46dev - http://github.com/mrdoob/three.js var THREE=THREE||{};if(!self.Int32Array)self.Int32Array=Array,self.Float32Array=Array;THREE.Color=function(a){a!==void 0&&this.setHex(a);return this}; -THREE.Color.prototype={constructor:THREE.Color,r:1,g:1,b:1,copy:function(a){this.r=a.r;this.g=a.g;this.b=a.b;return this},copyGammaToLinear:function(a){this.r=a.r*a.r;this.g=a.g*a.g;this.b=a.b*a.b;return this},copyLinearToGamma:function(a){this.r=Math.sqrt(a.r);this.g=Math.sqrt(a.g);this.b=Math.sqrt(a.b);return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSV:function(a,b,c){var e,g,f;if(c===0)this.r=this.g=this.b=0;else switch(e=Math.floor(a*6),g=a*6-e,a=c*(1-b),f=c*(1- -b*g),b=c*(1-b*(1-g)),e){case 1:this.r=f;this.g=c;this.b=a;break;case 2:this.r=a;this.g=c;this.b=b;break;case 3:this.r=a;this.g=f;this.b=c;break;case 4:this.r=b;this.g=a;this.b=c;break;case 5:this.r=c;this.g=a;this.b=f;break;case 6:case 0:this.r=c,this.g=b,this.b=a}return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},getHex:function(){return~~(this.r*255)<<16^~~(this.g*255)<<8^~~(this.b*255)},getContextStyle:function(){return"rgb("+ +THREE.Color.prototype={constructor:THREE.Color,r:1,g:1,b:1,copy:function(a){this.r=a.r;this.g=a.g;this.b=a.b;return this},copyGammaToLinear:function(a){this.r=a.r*a.r;this.g=a.g*a.g;this.b=a.b*a.b;return this},copyLinearToGamma:function(a){this.r=Math.sqrt(a.r);this.g=Math.sqrt(a.g);this.b=Math.sqrt(a.b);return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSV:function(a,b,c){var e,f,g;if(c===0)this.r=this.g=this.b=0;else switch(e=Math.floor(a*6),f=a*6-e,a=c*(1-b),g=c*(1- +b*f),b=c*(1-b*(1-f)),e){case 1:this.r=g;this.g=c;this.b=a;break;case 2:this.r=a;this.g=c;this.b=b;break;case 3:this.r=a;this.g=g;this.b=c;break;case 4:this.r=b;this.g=a;this.b=c;break;case 5:this.r=c;this.g=a;this.b=g;break;case 6:case 0:this.r=c,this.g=b,this.b=a}return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},getHex:function(){return~~(this.r*255)<<16^~~(this.g*255)<<8^~~(this.b*255)},getContextStyle:function(){return"rgb("+ Math.floor(this.r*255)+","+Math.floor(this.g*255)+","+Math.floor(this.b*255)+")"},clone:function(){return(new THREE.Color).setRGB(this.r,this.g,this.b)}};THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; THREE.Vector2.prototype={constructor:THREE.Vector2,set:function(a,b){this.x=a;this.y=b;return this},copy:function(a){this.x=a.x;this.y=a.y;return this},clone:function(){return new THREE.Vector2(this.x,this.y)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this}, divideScalar:function(a){a?(this.x/=a,this.y/=a):this.set(0,0);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.lengthSq())},normalize:function(){return this.divideScalar(this.length())},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,a=this.y-a.y;return b*b+a*a},setLength:function(a){return this.normalize().multiplyScalar(a)}, @@ -14,87 +14,87 @@ Math.abs(b)>1.0E-5?(this.x=Math.atan2(-a.n23/b,a.n33/b),this.z=Math.atan2(-a.n12 THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,e){this.x=a;this.y=b;this.z=c;this.w=e;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w!==void 0?a.w:1},clone:function(){return new THREE.Vector4(this.x,this.y,this.z,this.w)},add:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addSelf:function(a){this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},sub:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z- b.z;this.w=a.w-b.w;return this},subSelf:function(a){this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;this.w*=a;return this},divideScalar:function(a){a?(this.x/=a,this.y/=a,this.z/=a,this.w/=a):(this.z=this.y=this.x=0,this.w=1);return this},negate:function(){return this.multiplyScalar(-1)},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.dot(this)},length:function(){return Math.sqrt(this.lengthSq())}, normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.normalize().multiplyScalar(a)},lerpSelf:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this}};THREE.Ray=function(a,b){this.origin=a||new THREE.Vector3;this.direction=b||new THREE.Vector3}; -THREE.Ray.prototype={constructor:THREE.Ray,intersectScene:function(a){return this.intersectObjects(a.children)},intersectObjects:function(a){var b,c,e=[];b=0;for(c=a.length;b=0&&C>=0&&u+C<1}for(var e=new THREE.Vector3,g=new THREE.Vector3,f=new THREE.Vector3,h,i,q,m,k,r,u,C,B,D=[],G=0,qa=a.children.length;Ga.scale.x)return[];B={distance:G,point:a.position, -face:null,object:a};D.push(B)}else if(a instanceof THREE.Mesh){G=b(this.origin,this.direction,a.matrixWorld.getPosition());if(G===null||G>a.geometry.boundingSphere.radius*Math.max(a.scale.x,Math.max(a.scale.y,a.scale.z)))return D;var N,ka,ma,Q,ca,F,K,X,I=a.geometry,U=I.vertices;a.matrixRotationWorld.extractRotation(a.matrixWorld);G=0;for(qa=I.faces.length;G0:F<0)))if(F=ca.dot((new THREE.Vector3).sub(N,K))/F,K=K.addSelf(X.multiplyScalar(F)),B instanceof THREE.Face3)c(K,N,ka,ma)&&(B={distance:this.origin.distanceTo(K),point:K,face:B, -object:a},D.push(B));else if(B instanceof THREE.Face4&&(c(K,N,ka,Q)||c(K,ka,ma,Q)))B={distance:this.origin.distanceTo(K),point:K,face:B,object:a},D.push(B)}return D}}; -THREE.Rectangle=function(){function a(){f=e-b;h=g-c}var b,c,e,g,f,h,i=!0;this.getX=function(){return b};this.getY=function(){return c};this.getWidth=function(){return f};this.getHeight=function(){return h};this.getLeft=function(){return b};this.getTop=function(){return c};this.getRight=function(){return e};this.getBottom=function(){return g};this.set=function(f,h,k,r){i=!1;b=f;c=h;e=k;g=r;a()};this.addPoint=function(f,h){i?(i=!1,b=f,c=h,e=f,g=h):(b=bf?e:f,g=g>h?g:h);a()};this.add3Points= -function(f,h,k,r,u,C){i?(i=!1,b=fk?f>u?f:u:k>u?k:u,g=h>r?h>C?h:C:r>C?r:C):(b=fk?f>u?f>e?f:e:u>e?u:e:k>u?k>e?k:e:u>e?u:e,g=h>r?h>C?h>g?h:g:C>g?C:g:r>C?r>g?r:g:C>g?C:g);a()};this.addRectangle=function(f){i?(i=!1,b=f.getLeft(),c=f.getTop(),e=f.getRight(),g=f.getBottom()):(b=bf.getRight()?e:f.getRight(),g=g> -f.getBottom()?g:f.getBottom());a()};this.inflate=function(f){b-=f;c-=f;e+=f;g+=f;a()};this.minSelf=function(f){b=b>f.getLeft()?b:f.getLeft();c=c>f.getTop()?c:f.getTop();e=e=0&&Math.min(g,a.getBottom())-Math.max(c,a.getTop())>=0};this.empty=function(){i=!0;g=e=c=b=0;a()};this.isEmpty=function(){return i}}; -THREE.Math={clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=0&&B>=0&&t+B<1}for(var e=new THREE.Vector3,f=new THREE.Vector3,g=new THREE.Vector3,h,i,o,r,j,q,t,B,G,L=[],N=0,ka=a.children.length;Na.scale.x)return[];G={distance:N,point:a.position, +face:null,object:a};L.push(G)}else if(a instanceof THREE.Mesh){N=b(this.origin,this.direction,a.matrixWorld.getPosition());if(N===null||N>a.geometry.boundingSphere.radius*Math.max(a.scale.x,Math.max(a.scale.y,a.scale.z)))return L;var P,U,Y,E,M,C,D,V,ca=a.geometry,Z=ca.vertices;a.matrixRotationWorld.extractRotation(a.matrixWorld);N=0;for(ka=ca.faces.length;N0:C<0)))if(C=M.dot((new THREE.Vector3).sub(P,D))/C,D=D.addSelf(V.multiplyScalar(C)),G instanceof THREE.Face3)c(D,P,U,Y)&&(G={distance:this.origin.distanceTo(D),point:D,face:G,object:a}, +L.push(G));else if(G instanceof THREE.Face4&&(c(D,P,U,E)||c(D,U,Y,E)))G={distance:this.origin.distanceTo(D),point:D,face:G,object:a},L.push(G)}return L}}; +THREE.Rectangle=function(){function a(){g=e-b;h=f-c}var b,c,e,f,g,h,i=!0;this.getX=function(){return b};this.getY=function(){return c};this.getWidth=function(){return g};this.getHeight=function(){return h};this.getLeft=function(){return b};this.getTop=function(){return c};this.getRight=function(){return e};this.getBottom=function(){return f};this.set=function(g,h,j,q){i=!1;b=g;c=h;e=j;f=q;a()};this.addPoint=function(g,h){i?(i=!1,b=g,c=h,e=g,f=h):(b=bg?e:g,f=f>h?f:h);a()};this.add3Points= +function(g,h,j,q,t,B){i?(i=!1,b=gj?g>t?g:t:j>t?j:t,f=h>q?h>B?h:B:q>B?q:B):(b=gj?g>t?g>e?g:e:t>e?t:e:j>t?j>e?j:e:t>e?t:e,f=h>q?h>B?h>f?h:f:B>f?B:f:q>B?q>f?q:f:B>f?B:f);a()};this.addRectangle=function(g){i?(i=!1,b=g.getLeft(),c=g.getTop(),e=g.getRight(),f=g.getBottom()):(b=bg.getRight()?e:g.getRight(),f=f> +g.getBottom()?f:g.getBottom());a()};this.inflate=function(g){b-=g;c-=g;e+=g;f+=g;a()};this.minSelf=function(g){b=b>g.getLeft()?b:g.getLeft();c=c>g.getTop()?c:g.getTop();e=e=0&&Math.min(f,a.getBottom())-Math.max(c,a.getTop())>=0};this.empty=function(){i=!0;f=e=c=b=0;a()};this.isEmpty=function(){return i}}; +THREE.Math={clamp:function(a,b,c){return ac?c:a},clampBottom:function(a,b){return a=0&&f>=0&&g>=0&&h>=0?!0:d<0&&f<0||g<0&&h<0?!1:(d<0?c=Math.max(c,d/(d-f)):f<0&&(e=Math.min(e,d/(d-f))),g<0?c=Math.max(c,g/(g-h)):h<0&&(e=Math.min(e,g/(g-h))),eh&&i.positionScreen.z< -d;ra=0;for(ca=Fa.length;ra0&&F.z<1))h=ma[ka]=ma[ka]||new THREE.RenderableParticle,ka++,N=h,N.x=F.x/F.w,N.y=F.y/F.w,N.z=F.z,N.rotation=O.rotation.z,N.scale.x=O.scale.x*Math.abs(N.x-(F.x+f.projectionMatrix.n11)/(F.w+f.projectionMatrix.n14)),N.scale.y= -O.scale.y*Math.abs(N.y-(F.y+f.projectionMatrix.n22)/(F.w+f.projectionMatrix.n24)),N.material=O.material,Q.elements.push(N);g&&Q.elements.sort(c);return Q}};THREE.Quaternion=function(a,b,c,e){this.set(a||0,b||0,c||0,e!==void 0?e:1)}; -THREE.Quaternion.prototype={constructor:THREE.Quaternion,set:function(a,b,c,e){this.x=a;this.y=b;this.z=c;this.w=e;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w;return this},setFromEuler:function(a){var b=Math.PI/360,c=a.x*b,e=a.y*b,g=a.z*b,a=Math.cos(e),e=Math.sin(e),b=Math.cos(-g),g=Math.sin(-g),f=Math.cos(c),c=Math.sin(c),h=a*b,i=e*g;this.w=h*f-i*c;this.x=h*c+i*f;this.y=e*b*f+a*g*c;this.z=a*g*f-e*b*c;return this},setFromAxisAngle:function(a,b){var c=b/2,e=Math.sin(c); +THREE.Projector=function(){function a(){var a=h[g]=h[g]||new THREE.RenderableObject;g++;return a}function b(){var a=r[o]=r[o]||new THREE.RenderableVertex;o++;return a}function c(a,b){return b.z-a.z}function e(a,b){var c=0,e=1,g=a.z+a.w,f=b.z+b.w,h=-a.z+a.w,i=-b.z+b.w;return g>=0&&f>=0&&h>=0&&i>=0?!0:g<0&&f<0||h<0&&i<0?!1:(g<0?c=Math.max(c,g/(g-f)):f<0&&(e=Math.min(e,g/(g-f))),h<0?c=Math.max(c,h/(h-i)):i<0&&(e=Math.min(e,h/(h-i))),eh&&i.positionScreen.z0&&C.z<1))h=Y[U]=Y[U]||new THREE.RenderableParticle,U++,P=h,P.x=C.x/C.w,P.y=C.y/C.w,P.z=C.z,P.rotation=S.rotation.z,P.scale.x=S.scale.x*Math.abs(P.x-(C.x+g.projectionMatrix.n11)/(C.w+g.projectionMatrix.n14)),P.scale.y=S.scale.y*Math.abs(P.y-(C.y+g.projectionMatrix.n22)/(C.w+g.projectionMatrix.n24)),P.material= +S.material,E.elements.push(P);f&&E.elements.sort(c);return E}};THREE.Quaternion=function(a,b,c,e){this.set(a||0,b||0,c||0,e!==void 0?e:1)}; +THREE.Quaternion.prototype={constructor:THREE.Quaternion,set:function(a,b,c,e){this.x=a;this.y=b;this.z=c;this.w=e;return this},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=a.w;return this},setFromEuler:function(a){var b=Math.PI/360,c=a.x*b,e=a.y*b,f=a.z*b,a=Math.cos(e),e=Math.sin(e),b=Math.cos(-f),f=Math.sin(-f),g=Math.cos(c),c=Math.sin(c),h=a*b,i=e*f;this.w=h*g-i*c;this.x=h*c+i*g;this.y=e*b*g+a*f*c;this.z=a*f*g-e*b*c;return this},setFromAxisAngle:function(a,b){var c=b/2,e=Math.sin(c); this.x=a.x*e;this.y=a.y*e;this.z=a.z*e;this.w=Math.cos(c);return this},setFromRotationMatrix:function(a){var b=Math.pow(a.determinant(),1/3);this.w=Math.sqrt(Math.max(0,b+a.n11+a.n22+a.n33))/2;this.x=Math.sqrt(Math.max(0,b+a.n11-a.n22-a.n33))/2;this.y=Math.sqrt(Math.max(0,b-a.n11+a.n22-a.n33))/2;this.z=Math.sqrt(Math.max(0,b-a.n11-a.n22+a.n33))/2;this.x=a.n32-a.n23<0?-Math.abs(this.x):Math.abs(this.x);this.y=a.n13-a.n31<0?-Math.abs(this.y):Math.abs(this.y);this.z=a.n21-a.n12<0?-Math.abs(this.z):Math.abs(this.z); this.normalize();return this},calculateW:function(){this.w=-Math.sqrt(Math.abs(1-this.x*this.x-this.y*this.y-this.z*this.z));return this},inverse:function(){this.x*=-1;this.y*=-1;this.z*=-1;return this},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},normalize:function(){var a=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);a===0?this.w=this.z=this.y=this.x=0:(a=1/a,this.x*=a,this.y*=a,this.z*=a,this.w*=a);return this},multiplySelf:function(a){var b= -this.x,c=this.y,e=this.z,g=this.w,f=a.x,h=a.y,i=a.z,a=a.w;this.x=b*a+g*f+c*i-e*h;this.y=c*a+g*h+e*f-b*i;this.z=e*a+g*i+b*h-c*f;this.w=g*a-b*f-c*h-e*i;return this},multiply:function(a,b){this.x=a.x*b.w+a.y*b.z-a.z*b.y+a.w*b.x;this.y=-a.x*b.z+a.y*b.w+a.z*b.x+a.w*b.y;this.z=a.x*b.y-a.y*b.x+a.z*b.w+a.w*b.z;this.w=-a.x*b.x-a.y*b.y-a.z*b.z+a.w*b.w;return this},multiplyVector3:function(a,b){b||(b=a);var c=a.x,e=a.y,g=a.z,f=this.x,h=this.y,i=this.z,q=this.w,m=q*c+h*g-i*e,k=q*e+i*c-f*g,r=q*g+f*e-h*c,c=-f* -c-h*e-i*g;b.x=m*q+c*-f+k*-i-r*-h;b.y=k*q+c*-h+r*-f-m*-i;b.z=r*q+c*-i+m*-h-k*-f;return b}}; -THREE.Quaternion.slerp=function(a,b,c,e){var g=a.w*b.w+a.x*b.x+a.y*b.y+a.z*b.z;g<0?(c.w=-b.w,c.x=-b.x,c.y=-b.y,c.z=-b.z,g=-g):c.copy(b);if(Math.abs(g)>=1)return c.w=a.w,c.x=a.x,c.y=a.y,c.z=a.z,c;var f=Math.acos(g),g=Math.sqrt(1-g*g);if(Math.abs(g)<0.0010)return c.w=0.5*(a.w+b.w),c.x=0.5*(a.x+b.x),c.y=0.5*(a.y+b.y),c.z=0.5*(a.z+b.z),c;b=Math.sin((1-e)*f)/g;e=Math.sin(e*f)/g;c.w=a.w*b+c.w*e;c.x=a.x*b+c.x*e;c.y=a.y*b+c.y*e;c.z=a.z*b+c.z*e;return c};THREE.Vertex=function(a){this.position=a||new THREE.Vector3}; -THREE.Face3=function(a,b,c,e,g,f){this.a=a;this.b=b;this.c=c;this.normal=e instanceof THREE.Vector3?e:new THREE.Vector3;this.vertexNormals=e instanceof Array?e:[];this.color=g instanceof THREE.Color?g:new THREE.Color;this.vertexColors=g instanceof Array?g:[];this.vertexTangents=[];this.materialIndex=f;this.centroid=new THREE.Vector3}; -THREE.Face4=function(a,b,c,e,g,f,h){this.a=a;this.b=b;this.c=c;this.d=e;this.normal=g instanceof THREE.Vector3?g:new THREE.Vector3;this.vertexNormals=g instanceof Array?g:[];this.color=f instanceof THREE.Color?f:new THREE.Color;this.vertexColors=f instanceof Array?f:[];this.vertexTangents=[];this.materialIndex=h;this.centroid=new THREE.Vector3};THREE.UV=function(a,b){this.u=a||0;this.v=b||0}; +this.x,c=this.y,e=this.z,f=this.w,g=a.x,h=a.y,i=a.z,a=a.w;this.x=b*a+f*g+c*i-e*h;this.y=c*a+f*h+e*g-b*i;this.z=e*a+f*i+b*h-c*g;this.w=f*a-b*g-c*h-e*i;return this},multiply:function(a,b){this.x=a.x*b.w+a.y*b.z-a.z*b.y+a.w*b.x;this.y=-a.x*b.z+a.y*b.w+a.z*b.x+a.w*b.y;this.z=a.x*b.y-a.y*b.x+a.z*b.w+a.w*b.z;this.w=-a.x*b.x-a.y*b.y-a.z*b.z+a.w*b.w;return this},multiplyVector3:function(a,b){b||(b=a);var c=a.x,e=a.y,f=a.z,g=this.x,h=this.y,i=this.z,o=this.w,r=o*c+h*f-i*e,j=o*e+i*c-g*f,q=o*f+g*e-h*c,c=-g* +c-h*e-i*f;b.x=r*o+c*-g+j*-i-q*-h;b.y=j*o+c*-h+q*-g-r*-i;b.z=q*o+c*-i+r*-h-j*-g;return b}}; +THREE.Quaternion.slerp=function(a,b,c,e){var f=a.w*b.w+a.x*b.x+a.y*b.y+a.z*b.z;f<0?(c.w=-b.w,c.x=-b.x,c.y=-b.y,c.z=-b.z,f=-f):c.copy(b);if(Math.abs(f)>=1)return c.w=a.w,c.x=a.x,c.y=a.y,c.z=a.z,c;var g=Math.acos(f),f=Math.sqrt(1-f*f);if(Math.abs(f)<0.0010)return c.w=0.5*(a.w+b.w),c.x=0.5*(a.x+b.x),c.y=0.5*(a.y+b.y),c.z=0.5*(a.z+b.z),c;b=Math.sin((1-e)*g)/f;e=Math.sin(e*g)/f;c.w=a.w*b+c.w*e;c.x=a.x*b+c.x*e;c.y=a.y*b+c.y*e;c.z=a.z*b+c.z*e;return c};THREE.Vertex=function(a){this.position=a||new THREE.Vector3}; +THREE.Face3=function(a,b,c,e,f,g){this.a=a;this.b=b;this.c=c;this.normal=e instanceof THREE.Vector3?e:new THREE.Vector3;this.vertexNormals=e instanceof Array?e:[];this.color=f instanceof THREE.Color?f:new THREE.Color;this.vertexColors=f instanceof Array?f:[];this.vertexTangents=[];this.materialIndex=g;this.centroid=new THREE.Vector3}; +THREE.Face4=function(a,b,c,e,f,g,h){this.a=a;this.b=b;this.c=c;this.d=e;this.normal=f instanceof THREE.Vector3?f:new THREE.Vector3;this.vertexNormals=f instanceof Array?f:[];this.color=g instanceof THREE.Color?g:new THREE.Color;this.vertexColors=g instanceof Array?g:[];this.vertexTangents=[];this.materialIndex=h;this.centroid=new THREE.Vector3};THREE.UV=function(a,b){this.u=a||0;this.v=b||0}; THREE.UV.prototype={constructor:THREE.UV,set:function(a,b){this.u=a;this.v=b;return this},copy:function(a){this.u=a.u;this.v=a.v;return this},clone:function(){return new THREE.UV(this.u,this.v)}}; THREE.Geometry=function(){this.id=THREE.GeometryCount++;this.vertices=[];this.colors=[];this.materials=[];this.faces=[];this.faceUvs=[[]];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphColors=[];this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.dynamic=this.hasTangents=!1}; -THREE.Geometry.prototype={constructor:THREE.Geometry,applyMatrix:function(a){var b=new THREE.Matrix4;b.extractRotation(a,new THREE.Vector3(1,1,1));for(var c=0,e=this.vertices.length;c0){this.boundingBox={x:[this.vertices[0].position.x,this.vertices[0].position.x], -y:[this.vertices[0].position.y,this.vertices[0].position.y],z:[this.vertices[0].position.z,this.vertices[0].position.z]};for(var b=1,c=this.vertices.length;bthis.boundingBox.x[1])this.boundingBox.x[1]=a.position.x;if(a.position.ythis.boundingBox.y[1])this.boundingBox.y[1]=a.position.y;if(a.position.z< -this.boundingBox.z[0])this.boundingBox.z[0]=a.position.z;else if(a.position.z>this.boundingBox.z[1])this.boundingBox.z[1]=a.position.z}}},computeBoundingSphere:function(){for(var a=0,b=0,c=this.vertices.length;bthis.points.length-2?f:f+1;c[3]=f>this.points.length-3?f:f+2;m=this.points[c[0]];k=this.points[c[1]]; -r=this.points[c[2]];u=this.points[c[3]];i=h*h;q=h*i;e.x=b(m.x,k.x,r.x,u.x,h,i,q);e.y=b(m.y,k.y,r.y,u.y,h,i,q);e.z=b(m.z,k.z,r.z,u.z,h,i,q);return e};this.getControlPointsArray=function(){var a,b,c=this.points.length,e=[];for(a=0;a0){this.boundingBox={x:[this.vertices[0].position.x,this.vertices[0].position.x],y:[this.vertices[0].position.y, +this.vertices[0].position.y],z:[this.vertices[0].position.z,this.vertices[0].position.z]};for(var b=1,c=this.vertices.length;bthis.boundingBox.x[1])this.boundingBox.x[1]=a.position.x;if(a.position.ythis.boundingBox.y[1])this.boundingBox.y[1]=a.position.y;if(a.position.zthis.boundingBox.z[1])this.boundingBox.z[1]=a.position.z}}},computeBoundingSphere:function(){for(var a=0,b=0,c=this.vertices.length;bthis.points.length-2?g:g+1;c[3]=g>this.points.length-3?g:g+2;r=this.points[c[0]];j=this.points[c[1]]; +q=this.points[c[2]];t=this.points[c[3]];i=h*h;o=h*i;e.x=b(r.x,j.x,q.x,t.x,h,i,o);e.y=b(r.y,j.y,q.y,t.y,h,i,o);e.z=b(r.z,j.z,q.z,t.z,h,i,o);return e};this.getControlPointsArray=function(){var a,b,c=this.points.length,e=[];for(a=0;a1){a.matrixWorldInverse.getInverse(a.matrixWorld);a=a.matrixWorldInverse;a=-(a.n31*this.position.x+a.n32*this.position.y+a.n33*this.position.z+a.n34);this.LODs[0].object3D.visible=!0;for(var b=1;b=this.LODs[b].visibleAtDistance)this.LODs[b-1].object3D.visible=!1,this.LODs[b].object3D.visible=!0;else break;for(;b= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) {\n#ifdef SHADOWMAP_SOFT\nfloat shadow = 0.0;\nfor ( float y = -1.25; y <= 1.25; y += 1.25 )\nfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\nvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadow += 1.0;\n}\nshadow /= 9.0;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( shadowDarkness );\n#endif\n}\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n#endif",shadowmap_vertex:"#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );\n}\n#endif",alphatest_fragment:"#ifdef ALPHATEST\nif ( gl_FragColor.a < ALPHATEST ) discard;\n#endif",linear_to_gamma_fragment:"#ifdef GAMMA_OUTPUT\ngl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n#endif"}; -THREE.UniformsUtils={merge:function(a){var b,c,e,g={};for(b=0;b=0)return a.geometry.materials[b.materialIndex]}function e(a,b,c){var e,f,g,h,n=a.vertices;h=n.length;var A=a.colors,i=A.length,l=a.__vertexArray,p=a.__colorArray,k=a.__sortArray,v=a.__dirtyVertices,q=a.__dirtyColors,m=a.__webglCustomAttributesList;if(c.sortParticles){Aa.multiplySelf(c.matrixWorld);for(e=0;e=0)a&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglVertexBuffer),d.vertexAttribPointer(b.position,3,d.FLOAT,!1,0,0));else if(h.morphTargetBase){c=e.program.attributes;h.morphTargetBase!==-1?(d.bindBuffer(d.ARRAY_BUFFER,f.__webglMorphTargetsBuffers[h.morphTargetBase]), -d.vertexAttribPointer(c.position,3,d.FLOAT,!1,0,0)):c.position>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglVertexBuffer),d.vertexAttribPointer(c.position,3,d.FLOAT,!1,0,0));if(h.morphTargetForcedOrder.length){i=0;var A=h.morphTargetForcedOrder;for(n=h.morphTargetInfluences;ik&&(l=p,k=n[l]);d.bindBuffer(d.ARRAY_BUFFER,f.__webglMorphTargetsBuffers[l]);d.vertexAttribPointer(c["morphTarget"+i],3,d.FLOAT,!1,0,0);h.__webglMorphTargetInfluences[i]=k;A[l]=1;k=-1;i++}}e.program.uniforms.morphTargetInfluences!==null&&d.uniform1fv(e.program.uniforms.morphTargetInfluences,h.__webglMorphTargetInfluences)}if(a){if(f.__webglCustomAttributesList){i= -0;for(n=f.__webglCustomAttributesList.length;i=0&&(d.bindBuffer(d.ARRAY_BUFFER,c.buffer),d.vertexAttribPointer(b[c.buffer.belongsToAttribute],c.size,d.FLOAT,!1,0,0))}b.color>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglColorBuffer),d.vertexAttribPointer(b.color,3,d.FLOAT,!1,0,0));b.normal>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglNormalBuffer),d.vertexAttribPointer(b.normal,3,d.FLOAT,!1,0,0));b.tangent>=0&&(d.bindBuffer(d.ARRAY_BUFFER, -f.__webglTangentBuffer),d.vertexAttribPointer(b.tangent,4,d.FLOAT,!1,0,0));b.uv>=0&&(f.__webglUVBuffer?(d.bindBuffer(d.ARRAY_BUFFER,f.__webglUVBuffer),d.vertexAttribPointer(b.uv,2,d.FLOAT,!1,0,0),d.enableVertexAttribArray(b.uv)):d.disableVertexAttribArray(b.uv));b.uv2>=0&&(f.__webglUV2Buffer?(d.bindBuffer(d.ARRAY_BUFFER,f.__webglUV2Buffer),d.vertexAttribPointer(b.uv2,2,d.FLOAT,!1,0,0),d.enableVertexAttribArray(b.uv2)):d.disableVertexAttribArray(b.uv2));e.skinning&&b.skinVertexA>=0&&b.skinVertexB>= -0&&b.skinIndex>=0&&b.skinWeight>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinVertexABuffer),d.vertexAttribPointer(b.skinVertexA,4,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinVertexBBuffer),d.vertexAttribPointer(b.skinVertexB,4,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinIndicesBuffer),d.vertexAttribPointer(b.skinIndex,4,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinWeightsBuffer),d.vertexAttribPointer(b.skinWeight,4,d.FLOAT,!1,0,0))}h instanceof THREE.Mesh?(e.wireframe? -(e=e.wireframeLinewidth,e!==za&&(d.lineWidth(e),za=e),a&&d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,f.__webglLineBuffer),d.drawElements(d.LINES,f.__webglLineCount,d.UNSIGNED_SHORT,0)):(a&&d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,f.__webglFaceBuffer),d.drawElements(d.TRIANGLES,f.__webglFaceCount,d.UNSIGNED_SHORT,0)),M.info.render.calls++,M.info.render.vertices+=f.__webglFaceCount,M.info.render.faces+=f.__webglFaceCount/3):h instanceof THREE.Line?(h=h.type===THREE.LineStrip?d.LINE_STRIP:d.LINES,e=e.linewidth,e!== -za&&(d.lineWidth(e),za=e),d.drawArrays(h,0,f.__webglLineCount),M.info.render.calls++):h instanceof THREE.ParticleSystem?(d.drawArrays(d.POINTS,0,f.__webglParticleCount),M.info.render.calls++):h instanceof THREE.Ribbon&&(d.drawArrays(d.TRIANGLE_STRIP,0,f.__webglVertexCount),M.info.render.calls++)}}function h(a,b,c){if(!a.__webglVertexBuffer)a.__webglVertexBuffer=d.createBuffer();if(!a.__webglNormalBuffer)a.__webglNormalBuffer=d.createBuffer();a.hasPos&&(d.bindBuffer(d.ARRAY_BUFFER,a.__webglVertexBuffer), -d.bufferData(d.ARRAY_BUFFER,a.positionArray,d.DYNAMIC_DRAW),d.enableVertexAttribArray(b.attributes.position),d.vertexAttribPointer(b.attributes.position,3,d.FLOAT,!1,0,0));if(a.hasNormal){d.bindBuffer(d.ARRAY_BUFFER,a.__webglNormalBuffer);if(c===THREE.FlatShading){var e,f,g,h,n,i,k,l,p,m,v=a.count*3;for(m=0;m=0)b=b.geometry.materials[d],b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}else if(b=c)b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}function D(a,b){return b.z-a.z}function G(a){var b,c,e,k=0,T,m,n,A,R,l,p=a.lights;oa||(oa=new THREE.PerspectiveCamera(M.shadowCameraFov,M.shadowMapWidth/M.shadowMapHeight,M.shadowCameraNear,M.shadowCameraFar));b=0;for(c= -p.length;b=0;c--)a[c].object===b&&a.splice(c,1)}function ca(a,b,c){a.push({buffer:b, -object:c,opaque:null,transparent:null})}function F(a){if(a!==O){switch(a){case THREE.AdditiveBlending:d.blendEquation(d.FUNC_ADD);d.blendFunc(d.SRC_ALPHA,d.ONE);break;case THREE.SubtractiveBlending:d.blendEquation(d.FUNC_ADD);d.blendFunc(d.ZERO,d.ONE_MINUS_SRC_COLOR);break;case THREE.MultiplyBlending:d.blendEquation(d.FUNC_ADD);d.blendFunc(d.ZERO,d.SRC_COLOR);break;default:d.blendEquationSeparate(d.FUNC_ADD,d.FUNC_ADD),d.blendFuncSeparate(d.SRC_ALPHA,d.ONE_MINUS_SRC_ALPHA,d.ONE,d.ONE_MINUS_SRC_ALPHA)}O= -a}}function K(a,b,c){(c.width&c.width-1)===0&&(c.height&c.height-1)===0?(d.texParameteri(a,d.TEXTURE_WRAP_S,ja(b.wrapS)),d.texParameteri(a,d.TEXTURE_WRAP_T,ja(b.wrapT)),d.texParameteri(a,d.TEXTURE_MAG_FILTER,ja(b.magFilter)),d.texParameteri(a,d.TEXTURE_MIN_FILTER,ja(b.minFilter)),d.generateMipmap(a)):(d.texParameteri(a,d.TEXTURE_WRAP_S,d.CLAMP_TO_EDGE),d.texParameteri(a,d.TEXTURE_WRAP_T,d.CLAMP_TO_EDGE),d.texParameteri(a,d.TEXTURE_MAG_FILTER,wa(b.magFilter)),d.texParameteri(a,d.TEXTURE_MIN_FILTER, -wa(b.minFilter)))}function X(a,b){if(a.needsUpdate){if(!a.__webglInit)a.__webglInit=!0,a.__webglTexture=d.createTexture(),M.info.memory.textures++;d.activeTexture(d.TEXTURE0+b);d.bindTexture(d.TEXTURE_2D,a.__webglTexture);a instanceof THREE.DataTexture?d.texImage2D(d.TEXTURE_2D,0,ja(a.format),a.image.width,a.image.height,0,ja(a.format),d.UNSIGNED_BYTE,a.image.data):d.texImage2D(d.TEXTURE_2D,0,d.RGBA,d.RGBA,d.UNSIGNED_BYTE,a.image);K(d.TEXTURE_2D,a,a.image);a.needsUpdate=!1}else d.activeTexture(d.TEXTURE0+ -b),d.bindTexture(d.TEXTURE_2D,a.__webglTexture)}function I(a,b){d.bindRenderbuffer(d.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(d.renderbufferStorage(d.RENDERBUFFER,d.DEPTH_COMPONENT16,b.width,b.height),d.framebufferRenderbuffer(d.FRAMEBUFFER,d.DEPTH_ATTACHMENT,d.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(d.renderbufferStorage(d.RENDERBUFFER,d.DEPTH_STENCIL,b.width,b.height),d.framebufferRenderbuffer(d.FRAMEBUFFER,d.DEPTH_STENCIL_ATTACHMENT,d.RENDERBUFFER,a)):d.renderbufferStorage(d.RENDERBUFFER, -d.RGBA4,b.width,b.height)}function U(a){var b=a instanceof THREE.WebGLRenderTargetCube;if(a&&!a.__webglFramebuffer){if(a.depthBuffer===void 0)a.depthBuffer=!0;if(a.stencilBuffer===void 0)a.stencilBuffer=!0;a.__webglTexture=d.createTexture();if(b){a.__webglFramebuffer=[];a.__webglRenderbuffer=[];d.bindTexture(d.TEXTURE_CUBE_MAP,a.__webglTexture);K(d.TEXTURE_CUBE_MAP,a,a);for(var c=0;c<6;c++){a.__webglFramebuffer[c]=d.createFramebuffer();a.__webglRenderbuffer[c]=d.createRenderbuffer();d.texImage2D(d.TEXTURE_CUBE_MAP_POSITIVE_X+ -c,0,ja(a.format),a.width,a.height,0,ja(a.format),ja(a.type),null);var e=a,f=d.TEXTURE_CUBE_MAP_POSITIVE_X+c;d.bindFramebuffer(d.FRAMEBUFFER,a.__webglFramebuffer[c]);d.framebufferTexture2D(d.FRAMEBUFFER,d.COLOR_ATTACHMENT0,f,e.__webglTexture,0);I(a.__webglRenderbuffer[c],a)}}else a.__webglFramebuffer=d.createFramebuffer(),a.__webglRenderbuffer=d.createRenderbuffer(),d.bindTexture(d.TEXTURE_2D,a.__webglTexture),K(d.TEXTURE_2D,a,a),d.texImage2D(d.TEXTURE_2D,0,ja(a.format),a.width,a.height,0,ja(a.format), -ja(a.type),null),c=d.TEXTURE_2D,d.bindFramebuffer(d.FRAMEBUFFER,a.__webglFramebuffer),d.framebufferTexture2D(d.FRAMEBUFFER,d.COLOR_ATTACHMENT0,c,a.__webglTexture,0),d.bindRenderbuffer(d.RENDERBUFFER,a.__webglRenderbuffer),I(a.__webglRenderbuffer,a);b?d.bindTexture(d.TEXTURE_CUBE_MAP,null):d.bindTexture(d.TEXTURE_2D,null);d.bindRenderbuffer(d.RENDERBUFFER,null);d.bindFramebuffer(d.FRAMEBUFFER,null)}a?(b=b?a.__webglFramebuffer[a.activeCubeFace]:a.__webglFramebuffer,c=a.width,a=a.height,f=e=0):(b=null, -c=La,a=Ha,e=xa,f=Qa);b!==ia&&(d.bindFramebuffer(d.FRAMEBUFFER,b),d.viewport(e,f,c,a),ia=b)}function $(a){a instanceof THREE.WebGLRenderTargetCube?(d.bindTexture(d.TEXTURE_CUBE_MAP,a.__webglTexture),d.generateMipmap(d.TEXTURE_CUBE_MAP),d.bindTexture(d.TEXTURE_CUBE_MAP,null)):(d.bindTexture(d.TEXTURE_2D,a.__webglTexture),d.generateMipmap(d.TEXTURE_2D),d.bindTexture(d.TEXTURE_2D,null))}function la(a,b){var c;a==="fragment"?c=d.createShader(d.FRAGMENT_SHADER):a==="vertex"&&(c=d.createShader(d.VERTEX_SHADER)); -d.shaderSource(c,b);d.compileShader(c);if(!d.getShaderParameter(c,d.COMPILE_STATUS))return console.error(d.getShaderInfoLog(c)),console.error(b),null;return c}function wa(a){switch(a){case THREE.NearestFilter:case THREE.NearestMipMapNearestFilter:case THREE.NearestMipMapLinearFilter:return d.NEAREST;default:return d.LINEAR}}function ja(a){switch(a){case THREE.RepeatWrapping:return d.REPEAT;case THREE.ClampToEdgeWrapping:return d.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return d.MIRRORED_REPEAT; -case THREE.NearestFilter:return d.NEAREST;case THREE.NearestMipMapNearestFilter:return d.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return d.NEAREST_MIPMAP_LINEAR;case THREE.LinearFilter:return d.LINEAR;case THREE.LinearMipMapNearestFilter:return d.LINEAR_MIPMAP_NEAREST;case THREE.LinearMipMapLinearFilter:return d.LINEAR_MIPMAP_LINEAR;case THREE.ByteType:return d.BYTE;case THREE.UnsignedByteType:return d.UNSIGNED_BYTE;case THREE.ShortType:return d.SHORT;case THREE.UnsignedShortType:return d.UNSIGNED_SHORT; -case THREE.IntType:return d.INT;case THREE.UnsignedShortType:return d.UNSIGNED_INT;case THREE.FloatType:return d.FLOAT;case THREE.AlphaFormat:return d.ALPHA;case THREE.RGBFormat:return d.RGB;case THREE.RGBAFormat:return d.RGBA;case THREE.LuminanceFormat:return d.LUMINANCE;case THREE.LuminanceAlphaFormat:return d.LUMINANCE_ALPHA}return 0}var M=this,d,Da=[],Pa=null,ia=null,ra=-1,W=null,pa=0,fa=null,sa=null,O=null,na=null,ta=null,Ea=null,Ia=null,Fa=null,za=null,xa=0,Qa=0,La=0,Ha=0,ua=[new THREE.Vector4, -new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4],Aa=new THREE.Matrix4,Ma=new Float32Array(16),Na=new Float32Array(16),Ga=new THREE.Vector4,Sa={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[]}},a=a||{},Ba=a.canvas!==void 0?a.canvas:document.createElement("canvas"),S=a.stencil!==void 0?a.stencil:!0,Xa=a.preserveDrawingBuffer!==void 0?a.preserveDrawingBuffer:!1,Ya=a.antialias!==void 0?a.antialias: -!1,va=a.clearColor!==void 0?new THREE.Color(a.clearColor):new THREE.Color(0),Ca=a.clearAlpha!==void 0?a.clearAlpha:0,Ra=a.maxLights!==void 0?a.maxLights:4;this.info={memory:{programs:0,geometries:0,textures:0},render:{calls:0,vertices:0,faces:0}};this.maxMorphTargets=8;this.domElement=Ba;this.autoUpdateScene=this.autoUpdateObjects=this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.physicallyBasedShading=this.gammaOutput=this.gammaInput=!1;this.shadowMapBias= -0.0039;this.shadowMapDarkness=0.5;this.shadowMapHeight=this.shadowMapWidth=512;this.shadowCameraNear=1;this.shadowCameraFar=5E3;this.shadowCameraFov=50;this.shadowMap=[];this.shadowMapEnabled=!1;this.shadowMapSoft=this.shadowMapAutoUpdate=!0;var oa,Ka=[],a=THREE.ShaderLib.depthRGBA,Va=THREE.UniformsUtils.clone(a.uniforms),Oa=new THREE.ShaderMaterial({fragmentShader:a.fragmentShader,vertexShader:a.vertexShader,uniforms:Va}),Ta=new THREE.ShaderMaterial({fragmentShader:a.fragmentShader,vertexShader:a.vertexShader, -uniforms:Va,morphTargets:!0});Oa._shadowPass=!0;Ta._shadowPass=!0;try{if(!(d=Ba.getContext("experimental-webgl",{antialias:Ya,stencil:S,preserveDrawingBuffer:Xa})))throw"Error creating WebGL context.";console.log(navigator.userAgent+" | "+d.getParameter(d.VERSION)+" | "+d.getParameter(d.VENDOR)+" | "+d.getParameter(d.RENDERER)+" | "+d.getParameter(d.SHADING_LANGUAGE_VERSION))}catch(Za){console.error(Za)}d.clearColor(0,0,0,1);d.clearDepth(1);d.clearStencil(0);d.enable(d.DEPTH_TEST);d.depthFunc(d.LEQUAL); -d.frontFace(d.CCW);d.cullFace(d.BACK);d.enable(d.CULL_FACE);d.enable(d.BLEND);d.blendEquation(d.FUNC_ADD);d.blendFunc(d.SRC_ALPHA,d.ONE_MINUS_SRC_ALPHA);d.clearColor(va.r,va.g,va.b,Ca);this.context=d;var Wa=d.getParameter(d.MAX_VERTEX_TEXTURE_IMAGE_UNITS)>0,z={};z.vertices=new Float32Array(16);z.faces=new Uint16Array(6);S=0;z.vertices[S++]=-1;z.vertices[S++]=-1;z.vertices[S++]=0;z.vertices[S++]=1;z.vertices[S++]=1;z.vertices[S++]=-1;z.vertices[S++]=1;z.vertices[S++]=1;z.vertices[S++]=1;z.vertices[S++]= -1;z.vertices[S++]=1;z.vertices[S++]=0;z.vertices[S++]=-1;z.vertices[S++]=1;z.vertices[S++]=0;S=z.vertices[S++]=0;z.faces[S++]=0;z.faces[S++]=1;z.faces[S++]=2;z.faces[S++]=0;z.faces[S++]=2;z.faces[S++]=3;z.vertexBuffer=d.createBuffer();z.elementBuffer=d.createBuffer();d.bindBuffer(d.ARRAY_BUFFER,z.vertexBuffer);d.bufferData(d.ARRAY_BUFFER,z.vertices,d.STATIC_DRAW);d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,z.elementBuffer);d.bufferData(d.ELEMENT_ARRAY_BUFFER,z.faces,d.STATIC_DRAW);z.program=d.createProgram(); -d.attachShader(z.program,la("fragment",THREE.ShaderLib.sprite.fragmentShader));d.attachShader(z.program,la("vertex",THREE.ShaderLib.sprite.vertexShader));d.linkProgram(z.program);z.attributes={};z.uniforms={};z.attributes.position=d.getAttribLocation(z.program,"position");z.attributes.uv=d.getAttribLocation(z.program,"uv");z.uniforms.uvOffset=d.getUniformLocation(z.program,"uvOffset");z.uniforms.uvScale=d.getUniformLocation(z.program,"uvScale");z.uniforms.rotation=d.getUniformLocation(z.program,"rotation"); -z.uniforms.scale=d.getUniformLocation(z.program,"scale");z.uniforms.alignment=d.getUniformLocation(z.program,"alignment");z.uniforms.color=d.getUniformLocation(z.program,"color");z.uniforms.map=d.getUniformLocation(z.program,"map");z.uniforms.opacity=d.getUniformLocation(z.program,"opacity");z.uniforms.useScreenCoordinates=d.getUniformLocation(z.program,"useScreenCoordinates");z.uniforms.affectedByDistance=d.getUniformLocation(z.program,"affectedByDistance");z.uniforms.screenPosition=d.getUniformLocation(z.program, -"screenPosition");z.uniforms.modelViewMatrix=d.getUniformLocation(z.program,"modelViewMatrix");z.uniforms.projectionMatrix=d.getUniformLocation(z.program,"projectionMatrix");var Ua=!1;this.setSize=function(a,b){Ba.width=a;Ba.height=b;this.setViewport(0,0,Ba.width,Ba.height)};this.setViewport=function(a,b,c,e){xa=a;Qa=b;La=c;Ha=e;d.viewport(xa,Qa,La,Ha)};this.setScissor=function(a,b,c,e){d.scissor(a,b,c,e)};this.enableScissorTest=function(a){a?d.enable(d.SCISSOR_TEST):d.disable(d.SCISSOR_TEST)};this.setClearColorHex= -function(a,b){va.setHex(a);Ca=b;d.clearColor(va.r,va.g,va.b,Ca)};this.setClearColor=function(a,b){va.copy(a);Ca=b;d.clearColor(va.r,va.g,va.b,Ca)};this.getClearColor=function(){return va};this.getClearAlpha=function(){return Ca};this.clear=function(a,b,c){var e=0;if(a===void 0||a)e|=d.COLOR_BUFFER_BIT;if(b===void 0||b)e|=d.DEPTH_BUFFER_BIT;if(c===void 0||c)e|=d.STENCIL_BUFFER_BIT;d.clear(e)};this.getContext=function(){return d};this.deallocateObject=function(a){if(a.__webglInit)if(a.__webglInit=!1, -delete a._modelViewMatrix,delete a._normalMatrixArray,delete a._modelViewMatrixArray,delete a._objectMatrixArray,a instanceof THREE.Mesh)for(var b in a.geometry.geometryGroups){var c=a.geometry.geometryGroups[b];d.deleteBuffer(c.__webglVertexBuffer);d.deleteBuffer(c.__webglNormalBuffer);d.deleteBuffer(c.__webglTangentBuffer);d.deleteBuffer(c.__webglColorBuffer);d.deleteBuffer(c.__webglUVBuffer);d.deleteBuffer(c.__webglUV2Buffer);d.deleteBuffer(c.__webglSkinVertexABuffer);d.deleteBuffer(c.__webglSkinVertexBBuffer); -d.deleteBuffer(c.__webglSkinIndicesBuffer);d.deleteBuffer(c.__webglSkinWeightsBuffer);d.deleteBuffer(c.__webglFaceBuffer);d.deleteBuffer(c.__webglLineBuffer);if(c.numMorphTargets)for(var e=0,f=c.numMorphTargets;e=0&&d.enableVertexAttribArray(v.position);v.color>=0&&d.enableVertexAttribArray(v.color);v.normal>=0&&d.enableVertexAttribArray(v.normal); -v.tangent>=0&&d.enableVertexAttribArray(v.tangent);a.skinning&&v.skinVertexA>=0&&v.skinVertexB>=0&&v.skinIndex>=0&&v.skinWeight>=0&&(d.enableVertexAttribArray(v.skinVertexA),d.enableVertexAttribArray(v.skinVertexB),d.enableVertexAttribArray(v.skinIndex),d.enableVertexAttribArray(v.skinWeight));if(a.attributes)for(g in a.attributes)v[g]!==void 0&&v[g]>=0&&d.enableVertexAttribArray(v[g]);if(a.morphTargets)for(g=a.numSupportedMorphTargets=0;g=0&&(d.enableVertexAttribArray(v[r]), -a.numSupportedMorphTargets++);a.uniformsList=[];for(f in a.uniforms)a.uniformsList.push([a.uniforms[f],f])};this.clearTarget=function(a,b,c,d){U(a);this.clear(b,c,d)};this.updateShadowMap=function(a,b){G(a,b)};this.render=function(a,b,c,e){var z,T,Ja,n,A,R,l,p=a.lights,Q=a.fog;ra=-1;this.autoUpdateObjects&&this.initWebGLObjects(a);this.shadowMapEnabled&&this.shadowMapAutoUpdate&&G(a,b);M.info.render.calls=0;M.info.render.vertices=0;M.info.render.faces=0;b.parent===void 0&&(console.warn("DEPRECATED: Camera hasn't been added to a Scene. Adding it..."), -a.add(b));this.autoUpdateScene&&a.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);b.matrixWorldInverse.flattenToArray(Na);b.projectionMatrix.flattenToArray(Ma);Aa.multiply(b.projectionMatrix,b.matrixWorldInverse);r(Aa);U(c);(this.autoClear||e)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);Ja=a.__webglObjects.length;for(e=0;e=0;e--)if(A=a.__webglObjects[e],A.render&&(R=A.object,l=A.buffer,T=A.opaque))i(R),q(T.depthTest),m(T.depthWrite),k(T.polygonOffset,T.polygonOffsetFactor, -T.polygonOffsetUnits),f(b,p,Q,T,l,R);for(e=0;e65535&&(v[p].counter+=1,z=v[p].hash+"_"+v[p].counter,k.geometryGroups[z]===void 0&&(k.geometryGroups[z]= -{faces3:[],faces4:[],materialIndex:r,vertices:0,numMorphTargets:u})),q instanceof THREE.Face3?k.geometryGroups[z].faces3.push(m):k.geometryGroups[z].faces4.push(m),k.geometryGroups[z].vertices+=l;k.geometryGroupsList=[];m=void 0;for(m in k.geometryGroups)k.geometryGroups[m].id=pa++,k.geometryGroupsList.push(k.geometryGroups[m])}for(h in i.geometryGroups)if(k=i.geometryGroups[h],!k.__webglVertexBuffer){m=k;m.__webglVertexBuffer=d.createBuffer();m.__webglNormalBuffer=d.createBuffer();m.__webglTangentBuffer= -d.createBuffer();m.__webglColorBuffer=d.createBuffer();m.__webglUVBuffer=d.createBuffer();m.__webglUV2Buffer=d.createBuffer();m.__webglSkinVertexABuffer=d.createBuffer();m.__webglSkinVertexBBuffer=d.createBuffer();m.__webglSkinIndicesBuffer=d.createBuffer();m.__webglSkinWeightsBuffer=d.createBuffer();m.__webglFaceBuffer=d.createBuffer();m.__webglLineBuffer=d.createBuffer();if(m.numMorphTargets){q=n=void 0;m.__webglMorphTargetsBuffers=[];n=0;for(q=m.numMorphTargets;n0||l.faceVertexUvs.length>0)k.__uvArray=new Float32Array(m*2);if(l.faceUvs.length>1||l.faceVertexUvs.length>1)k.__uv2Array=new Float32Array(m*2)}if(r.geometry.skinWeights.length&&r.geometry.skinIndices.length)k.__skinVertexAArray=new Float32Array(m*4),k.__skinVertexBArray=new Float32Array(m*4),k.__skinIndexArray=new Float32Array(m*4),k.__skinWeightArray=new Float32Array(m*4);k.__faceArray=new Uint16Array(q*3); -k.__lineArray=new Uint16Array(p*2);if(k.numMorphTargets){k.__morphTargetsArrays=[];r=0;for(l=k.numMorphTargets;r=0;i--)g[i]===h&&g.splice(i,1)}else(f instanceof THREE.MarchingCubes||f.immediateRenderCallback)&&Q(g.__webglObjectsImmediate,f);f.__webglActive=!1;a.__objectsRemoved.splice(0,1)}f=0;for(g=a.__webglObjects.length;f0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglSkinVertexABuffer),d.bufferData(d.ARRAY_BUFFER,Y,q),d.bindBuffer(d.ARRAY_BUFFER,n.__webglSkinVertexBBuffer),d.bufferData(d.ARRAY_BUFFER,Z,q),d.bindBuffer(d.ARRAY_BUFFER, -n.__webglSkinIndicesBuffer),d.bufferData(d.ARRAY_BUFFER,F,q),d.bindBuffer(d.ARRAY_BUFFER,n.__webglSkinWeightsBuffer),d.bufferData(d.ARRAY_BUFFER,ha,q))}if(sa&&K){l=0;for(p=v.length;l0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglColorBuffer),d.bufferData(d.ARRAY_BUFFER,I,q))}if(ra&&$.hasTangents){l=0;for(p=v.length;l0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglUVBuffer),d.bufferData(d.ARRAY_BUFFER,fa,q))}if(oa&&va&&W){l=0;for(p=v.length;l0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglUV2Buffer),d.bufferData(d.ARRAY_BUFFER,o,q))}if(X){l= -0;for(p=v.length;l=0)return a.geometry.materials[b.materialIndex]}function e(a,b,c){var e,g,f,h,n=a.vertices;h=n.length;var Q=a.colors,i=Q.length,l=a.__vertexArray,p=a.__colorArray,j=a.__sortArray,z=a.__dirtyVertices,o=a.__dirtyColors,r=a.__webglCustomAttributesList;if(c.sortParticles){za.multiplySelf(c.matrixWorld);for(e=0;e=0)a&&(d.bindBuffer(d.ARRAY_BUFFER, +f.__webglVertexBuffer),d.vertexAttribPointer(b.position,3,d.FLOAT,!1,0,0));else if(g.morphTargetBase){c=e.program.attributes;g.morphTargetBase!==-1?(d.bindBuffer(d.ARRAY_BUFFER,f.__webglMorphTargetsBuffers[g.morphTargetBase]),d.vertexAttribPointer(c.position,3,d.FLOAT,!1,0,0)):c.position>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglVertexBuffer),d.vertexAttribPointer(c.position,3,d.FLOAT,!1,0,0));if(g.morphTargetForcedOrder.length){h=0;var i=g.morphTargetForcedOrder;for(n=g.morphTargetInfluences;hj&&(l=p,j=n[l]);d.bindBuffer(d.ARRAY_BUFFER,f.__webglMorphTargetsBuffers[l]);d.vertexAttribPointer(c["morphTarget"+h],3,d.FLOAT,!1,0,0);g.__webglMorphTargetInfluences[h]= +j;i[l]=1;j=-1;h++}}e.program.uniforms.morphTargetInfluences!==null&&d.uniform1fv(e.program.uniforms.morphTargetInfluences,g.__webglMorphTargetInfluences)}if(a){if(f.__webglCustomAttributesList){h=0;for(n=f.__webglCustomAttributesList.length;h=0&&(d.bindBuffer(d.ARRAY_BUFFER,c.buffer),d.vertexAttribPointer(b[c.buffer.belongsToAttribute],c.size,d.FLOAT,!1,0,0))}b.color>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglColorBuffer),d.vertexAttribPointer(b.color, +3,d.FLOAT,!1,0,0));b.normal>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglNormalBuffer),d.vertexAttribPointer(b.normal,3,d.FLOAT,!1,0,0));b.tangent>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglTangentBuffer),d.vertexAttribPointer(b.tangent,4,d.FLOAT,!1,0,0));b.uv>=0&&(f.__webglUVBuffer?(d.bindBuffer(d.ARRAY_BUFFER,f.__webglUVBuffer),d.vertexAttribPointer(b.uv,2,d.FLOAT,!1,0,0),d.enableVertexAttribArray(b.uv)):d.disableVertexAttribArray(b.uv));b.uv2>=0&&(f.__webglUV2Buffer?(d.bindBuffer(d.ARRAY_BUFFER,f.__webglUV2Buffer), +d.vertexAttribPointer(b.uv2,2,d.FLOAT,!1,0,0),d.enableVertexAttribArray(b.uv2)):d.disableVertexAttribArray(b.uv2));e.skinning&&b.skinVertexA>=0&&b.skinVertexB>=0&&b.skinIndex>=0&&b.skinWeight>=0&&(d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinVertexABuffer),d.vertexAttribPointer(b.skinVertexA,4,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinVertexBBuffer),d.vertexAttribPointer(b.skinVertexB,4,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinIndicesBuffer),d.vertexAttribPointer(b.skinIndex, +4,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,f.__webglSkinWeightsBuffer),d.vertexAttribPointer(b.skinWeight,4,d.FLOAT,!1,0,0))}g instanceof THREE.Mesh?(e.wireframe?(e=e.wireframeLinewidth,e!==Ja&&(d.lineWidth(e),Ja=e),a&&d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,f.__webglLineBuffer),d.drawElements(d.LINES,f.__webglLineCount,d.UNSIGNED_SHORT,0)):(a&&d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,f.__webglFaceBuffer),d.drawElements(d.TRIANGLES,f.__webglFaceCount,d.UNSIGNED_SHORT,0)),F.info.render.calls++,F.info.render.vertices+= +f.__webglFaceCount,F.info.render.faces+=f.__webglFaceCount/3):g instanceof THREE.Line?(g=g.type===THREE.LineStrip?d.LINE_STRIP:d.LINES,e=e.linewidth,e!==Ja&&(d.lineWidth(e),Ja=e),d.drawArrays(g,0,f.__webglLineCount),F.info.render.calls++):g instanceof THREE.ParticleSystem?(d.drawArrays(d.POINTS,0,f.__webglParticleCount),F.info.render.calls++):g instanceof THREE.Ribbon&&(d.drawArrays(d.TRIANGLE_STRIP,0,f.__webglVertexCount),F.info.render.calls++)}}function h(a){ta[0].set(a.n41-a.n11,a.n42-a.n12,a.n43- +a.n13,a.n44-a.n14);ta[1].set(a.n41+a.n11,a.n42+a.n12,a.n43+a.n13,a.n44+a.n14);ta[2].set(a.n41+a.n21,a.n42+a.n22,a.n43+a.n23,a.n44+a.n24);ta[3].set(a.n41-a.n21,a.n42-a.n22,a.n43-a.n23,a.n44-a.n24);ta[4].set(a.n41-a.n31,a.n42-a.n32,a.n43-a.n33,a.n44-a.n34);ta[5].set(a.n41+a.n31,a.n42+a.n32,a.n43+a.n33,a.n44+a.n34);for(var b,a=0;a<6;a++)b=ta[a],b.divideScalar(Math.sqrt(b.x*b.x+b.y*b.y+b.z*b.z))}function i(a){for(var b=a.matrixWorld,d=-a.geometry.boundingSphere.radius*Math.max(a.scale.x,Math.max(a.scale.y, +a.scale.z)),c=0;c<6;c++)if(a=ta[c].x*b.n14+ta[c].y*b.n24+ta[c].z*b.n34+ta[c].w,a<=d)return!1;return!0}function o(a,b){return b.z-a.z}function r(a){var b,c,e,j=0,W,xa,n,Q,R,l,p=a.lights;pa||(pa=new THREE.PerspectiveCamera(F.shadowCameraFov,F.shadowMapWidth/F.shadowMapHeight,F.shadowCameraNear,F.shadowCameraFar));b=0;for(c=p.length;b=0)b=b.geometry.materials[d],b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}else if(b=c)b.transparent?(a.transparent=b,a.opaque=null):(a.opaque=b,a.transparent=null)}function t(a,b){var c,e,f;c=s.attributes;var g=s.uniforms,h=Ea/Ha,n,i=[],j=Ha*0.5,l=Ea*0.5,p=!0;d.useProgram(s.program); +S=s.program;qa=Na=sa=-1;Ra||(d.enableVertexAttribArray(s.attributes.position),d.enableVertexAttribArray(s.attributes.uv),Ra=!0);d.disable(d.CULL_FACE);d.enable(d.BLEND);d.depthMask(!0);d.bindBuffer(d.ARRAY_BUFFER,s.vertexBuffer);d.vertexAttribPointer(c.position,2,d.FLOAT,!1,16,0);d.vertexAttribPointer(c.uv,2,d.FLOAT,!1,16,8);d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,s.elementBuffer);d.uniformMatrix4fv(g.projectionMatrix,!1,La);d.activeTexture(d.TEXTURE0);d.uniform1i(g.map,0);c=0;for(e=a.__webglSprites.length;c< +e;c++)if(f=a.__webglSprites[c],f.visible&&f.opacity!==0)f.useScreenCoordinates?f.z=-f.position.z:(f._modelViewMatrix.multiplyToArray(b.matrixWorldInverse,f.matrixWorld,f._modelViewMatrixArray),f.z=-f._modelViewMatrix.n34);a.__webglSprites.sort(o);c=0;for(e=a.__webglSprites.length;c=0;d--)a[d].object===b&&a.splice(d,1)}function ka(a,b,c,e,f){e.program||F.initMaterial(e,b,c,f);if(e.morphTargets&&!f.__webglMorphTargetInfluences){f.__webglMorphTargetInfluences=new Float32Array(F.maxMorphTargets);for(var g=0,h=F.maxMorphTargets;g0;this.getContext=function(){return d};this.supportsVertexTextures=function(){return Wa};this.setSize=function(a,b){ua.width=a;ua.height=b;this.setViewport(0,0,ua.width,ua.height)};this.setViewport=function(a,b,c,e){Pa=a;Qa=b;Ha=c;Ea=e;d.viewport(Pa,Qa,Ha,Ea)};this.setScissor=function(a,b,c,e){d.scissor(a,b,c,e)};this.enableScissorTest=function(a){a?d.enable(d.SCISSOR_TEST):d.disable(d.SCISSOR_TEST)}; +this.setClearColorHex=function(a,b){O.setHex(a);ma=b;d.clearColor(O.r,O.g,O.b,ma)};this.setClearColor=function(a,b){O.copy(a);ma=b;d.clearColor(O.r,O.g,O.b,ma)};this.getClearColor=function(){return O};this.getClearAlpha=function(){return ma};this.clear=function(a,b,c){var e=0;if(a===void 0||a)e|=d.COLOR_BUFFER_BIT;if(b===void 0||b)e|=d.DEPTH_BUFFER_BIT;if(c===void 0||c)e|=d.STENCIL_BUFFER_BIT;d.clear(e)};this.clearTarget=function(a,b,c,d){ba(a);this.clear(b,c,d)};this.deallocateObject=function(a){if(a.__webglInit)if(a.__webglInit= +!1,delete a._modelViewMatrix,delete a._normalMatrixArray,delete a._modelViewMatrixArray,delete a._objectMatrixArray,a instanceof THREE.Mesh)for(var b in a.geometry.geometryGroups){var c=a.geometry.geometryGroups[b];d.deleteBuffer(c.__webglVertexBuffer);d.deleteBuffer(c.__webglNormalBuffer);d.deleteBuffer(c.__webglTangentBuffer);d.deleteBuffer(c.__webglColorBuffer);d.deleteBuffer(c.__webglUVBuffer);d.deleteBuffer(c.__webglUV2Buffer);d.deleteBuffer(c.__webglSkinVertexABuffer);d.deleteBuffer(c.__webglSkinVertexBBuffer); +d.deleteBuffer(c.__webglSkinIndicesBuffer);d.deleteBuffer(c.__webglSkinWeightsBuffer);d.deleteBuffer(c.__webglFaceBuffer);d.deleteBuffer(c.__webglLineBuffer);if(c.numMorphTargets)for(var e=0,f=c.numMorphTargets;e=0;e--)if(Q=a.__webglObjects[e],Q.render&&(R=Q.object,l=Q.buffer,W=Q.opaque))U(R),Y(W.depthTest),E(W.depthWrite),M(W.polygonOffset,W.polygonOffsetFactor,W.polygonOffsetUnits),g(b,p,B,W,l,R);for(e=0;e65535&&(z[p].counter+=1,s=z[p].hash+"_"+z[p].counter,j.geometryGroups[s]===void 0&&(j.geometryGroups[s]={faces3:[],faces4:[],materialIndex:q,vertices:0,numMorphTargets:t})),r instanceof THREE.Face3?j.geometryGroups[s].faces3.push(o):j.geometryGroups[s].faces4.push(o),j.geometryGroups[s].vertices+= +l;j.geometryGroupsList=[];o=void 0;for(o in j.geometryGroups)j.geometryGroups[o].id=Ia++,j.geometryGroupsList.push(j.geometryGroups[o])}for(h in i.geometryGroups)if(j=i.geometryGroups[h],!j.__webglVertexBuffer){o=j;o.__webglVertexBuffer=d.createBuffer();o.__webglNormalBuffer=d.createBuffer();o.__webglTangentBuffer=d.createBuffer();o.__webglColorBuffer=d.createBuffer();o.__webglUVBuffer=d.createBuffer();o.__webglUV2Buffer=d.createBuffer();o.__webglSkinVertexABuffer=d.createBuffer();o.__webglSkinVertexBBuffer= +d.createBuffer();o.__webglSkinIndicesBuffer=d.createBuffer();o.__webglSkinWeightsBuffer=d.createBuffer();o.__webglFaceBuffer=d.createBuffer();o.__webglLineBuffer=d.createBuffer();if(o.numMorphTargets){r=n=void 0;o.__webglMorphTargetsBuffers=[];n=0;for(r=o.numMorphTargets;n0||l.faceVertexUvs.length>0)j.__uvArray=new Float32Array(o* +2);if(l.faceUvs.length>1||l.faceVertexUvs.length>1)j.__uv2Array=new Float32Array(o*2)}if(q.geometry.skinWeights.length&&q.geometry.skinIndices.length)j.__skinVertexAArray=new Float32Array(o*4),j.__skinVertexBArray=new Float32Array(o*4),j.__skinIndexArray=new Float32Array(o*4),j.__skinWeightArray=new Float32Array(o*4);j.__faceArray=new Uint16Array(r*3);j.__lineArray=new Uint16Array(p*2);if(j.numMorphTargets){j.__morphTargetsArrays=[];q=0;for(l=j.numMorphTargets;q=0;i--)g[i]===h&&g.splice(i,1)}else(f instanceof THREE.MarchingCubes||f.immediateRenderCallback)&&N(g.__webglObjectsImmediate,f);f.__webglActive=!1;a.__objectsRemoved.splice(0,1)}f=0;for(g=a.__webglObjects.length;f0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglSkinVertexABuffer),d.bufferData(d.ARRAY_BUFFER,$,r),d.bindBuffer(d.ARRAY_BUFFER,n.__webglSkinVertexBBuffer),d.bufferData(d.ARRAY_BUFFER,aa,r),d.bindBuffer(d.ARRAY_BUFFER,n.__webglSkinIndicesBuffer),d.bufferData(d.ARRAY_BUFFER,H,r),d.bindBuffer(d.ARRAY_BUFFER,n.__webglSkinWeightsBuffer),d.bufferData(d.ARRAY_BUFFER, +ia,r))}if(ua&&P){l=0;for(p=z.length;l0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglColorBuffer),d.bufferData(d.ARRAY_BUFFER,fa,r))}if(ta&&ba.hasTangents){l=0;for(p=z.length;l0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglUVBuffer),d.bufferData(d.ARRAY_BUFFER,ja,r))}if(ma&&wa&&ca){l=0;for(p=z.length;l0&&(d.bindBuffer(d.ARRAY_BUFFER,n.__webglUV2Buffer),d.bufferData(d.ARRAY_BUFFER,m,r))}if(Z){l=0;for(p=z.length;l=0&&d.enableVertexAttribArray(q.position);q.color>=0&&d.enableVertexAttribArray(q.color);q.normal>=0&&d.enableVertexAttribArray(q.normal); +q.tangent>=0&&d.enableVertexAttribArray(q.tangent);a.skinning&&q.skinVertexA>=0&&q.skinVertexB>=0&&q.skinIndex>=0&&q.skinWeight>=0&&(d.enableVertexAttribArray(q.skinVertexA),d.enableVertexAttribArray(q.skinVertexB),d.enableVertexAttribArray(q.skinIndex),d.enableVertexAttribArray(q.skinWeight));if(a.attributes)for(g in a.attributes)q[g]!==void 0&&q[g]>=0&&d.enableVertexAttribArray(q[g]);if(a.morphTargets)for(g=a.numSupportedMorphTargets=0;g=0&&(d.enableVertexAttribArray(q[t]), +a.numSupportedMorphTargets++);a.uniformsList=[];for(f in a.uniforms)a.uniformsList.push([a.uniforms[f],f])};this.setFaceCulling=function(a,b){a?(!b||b==="ccw"?d.frontFace(d.CCW):d.frontFace(d.CW),a==="back"?d.cullFace(d.BACK):a==="front"?d.cullFace(d.FRONT):d.cullFace(d.FRONT_AND_BACK),d.enable(d.CULL_FACE)):d.disable(d.CULL_FACE)}}; THREE.WebGLRenderTarget=function(a,b,c){this.width=a;this.height=b;c=c||{};this.wrapS=c.wrapS!==void 0?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=c.wrapT!==void 0?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=c.magFilter!==void 0?c.magFilter:THREE.LinearFilter;this.minFilter=c.minFilter!==void 0?c.minFilter:THREE.LinearMipMapLinearFilter;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1);this.format=c.format!==void 0?c.format:THREE.RGBAFormat;this.type=c.type!==void 0?c.type: THREE.UnsignedByteType;this.depthBuffer=c.depthBuffer!==void 0?c.depthBuffer:!0;this.stencilBuffer=c.stencilBuffer!==void 0?c.stencilBuffer:!0}; THREE.WebGLRenderTarget.prototype.clone=function(){var a=new THREE.WebGLRenderTarget(this.width,this.height);a.wrapS=this.wrapS;a.wrapT=this.wrapT;a.magFilter=this.magFilter;a.minFilter=this.minFilter;a.offset.copy(this.offset);a.repeat.copy(this.repeat);a.format=this.format;a.type=this.type;a.depthBuffer=this.depthBuffer;a.stencilBuffer=this.stencilBuffer;return a};THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeCubeFace=0}; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 487cb6e4..a19d566a 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -7,103 +7,35 @@ THREE.WebGLRenderer = function ( parameters ) { - // By default you can use just up to 4 directional / point lights total. - // ANGLE implementation (Chrome/Firefox on Windows) is bound to - // 10 varying vectors due to DirectX9 limitation. + // constructor parameters - var _this = this, - _gl, _programs = [], - _currentProgram = null, - _currentFramebuffer = null, - _currentMaterialId = -1, - _currentGeometryGroupHash = null, - _geometryGroupCounter = 0, - - // gl state cache - - _oldDoubleSided = null, - _oldFlipSided = null, - _oldBlending = null, - _oldDepthTest = null, - _oldDepthWrite = null, - _oldPolygonOffset = null, - _oldPolygonOffsetFactor = null, - _oldPolygonOffsetUnits = null, - _oldLineWidth = null, - _cullEnabled = true, - - _viewportX = 0, - _viewportY = 0, - _viewportWidth = 0, - _viewportHeight = 0, - - // camera matrices caches - - _frustum = [ - new THREE.Vector4(), - new THREE.Vector4(), - new THREE.Vector4(), - new THREE.Vector4(), - new THREE.Vector4(), - new THREE.Vector4() - ], - - _projScreenMatrix = new THREE.Matrix4(), - _projectionMatrixArray = new Float32Array( 16 ), - _viewMatrixArray = new Float32Array( 16 ), - - _vector3 = new THREE.Vector4(), - - // light arrays cache - - _lights = { - - ambient: [ 0, 0, 0 ], - directional: { length: 0, colors: new Array(), positions: new Array() }, - point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() } - - }, - - // parameters - - parameters = parameters || {}, + var parameters = parameters || {}, _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ), + _stencil = parameters.stencil !== undefined ? parameters.stencil : true, - _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, _antialias = parameters.antialias !== undefined ? parameters.antialias : false, + _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, + _clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ), _clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0, + _maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4; - this.info = { + // public properties - memory: { - - programs: 0, - geometries: 0, - textures: 0 - - }, - - render: { - - calls: 0, - vertices: 0, - faces: 0 - - } - - }; - - this.maxMorphTargets = 8; this.domElement = _canvas; + this.context = null; + + // clearing this.autoClear = true; this.autoClearColor = true; this.autoClearDepth = true; this.autoClearStencil = true; + // scene graph + this.sortObjects = true; this.autoUpdateObjects = true; @@ -132,135 +64,130 @@ THREE.WebGLRenderer = function ( parameters ) { this.shadowMapAutoUpdate = true; this.shadowMapSoft = true; - var _cameraLight, _shadowMatrix = []; + // morphs - var depthShader = THREE.ShaderLib[ "depthRGBA" ]; - var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms ); + this.maxMorphTargets = 8; - var _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } ); + // info - var _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } ); + this.info = { - _depthMaterial._shadowPass = true; - _depthMaterialMorph._shadowPass = true; + memory: { - // Init GL + programs: 0, + geometries: 0, + textures: 0 - try { + }, - if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) { + render: { - throw 'Error creating WebGL context.'; + calls: 0, + vertices: 0, + faces: 0 } - console.log( - navigator.userAgent + " | " + - _gl.getParameter( _gl.VERSION ) + " | " + - _gl.getParameter( _gl.VENDOR ) + " | " + - _gl.getParameter( _gl.RENDERER ) + " | " + - _gl.getParameter( _gl.SHADING_LANGUAGE_VERSION ) - ); + }; - } catch ( error ) { + // internal properties - console.error( error ); + var _this = this, - } + _gl, - _gl.clearColor( 0, 0, 0, 1 ); - _gl.clearDepth( 1 ); - _gl.clearStencil( 0 ); + _programs = [], - _gl.enable( _gl.DEPTH_TEST ); - _gl.depthFunc( _gl.LEQUAL ); + // internal state cache - _gl.frontFace( _gl.CCW ); - _gl.cullFace( _gl.BACK ); - _gl.enable( _gl.CULL_FACE ); + _currentProgram = null, + _currentFramebuffer = null, + _currentMaterialId = -1, + _currentGeometryGroupHash = null, + _geometryGroupCounter = 0, - _gl.enable( _gl.BLEND ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA ); + // GL state cache - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + _oldDoubleSided = null, + _oldFlipSided = null, + _oldBlending = null, + _oldDepthTest = null, + _oldDepthWrite = null, + _oldPolygonOffset = null, + _oldPolygonOffsetFactor = null, + _oldPolygonOffsetUnits = null, + _oldLineWidth = null, - _cullEnabled = true; + _viewportX = 0, + _viewportY = 0, + _viewportWidth = 0, + _viewportHeight = 0, - // + // frustum cache + + _frustum = [ + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4(), + new THREE.Vector4() + ], + + // camera matrices cache + + _projScreenMatrix = new THREE.Matrix4(), + _projectionMatrixArray = new Float32Array( 16 ), + _viewMatrixArray = new Float32Array( 16 ), + + _vector3 = new THREE.Vector4(), + + // light arrays cache + + _lights = { + + ambient: [ 0, 0, 0 ], + directional: { length: 0, colors: new Array(), positions: new Array() }, + point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() } + + }; + + // shadow maps + + var _cameraLight, _shadowMatrix = []; + var _depthMaterial, _depthMaterialMorph; + + // sprites + + var _sprite = {}; + var _spriteAttributesEnabled = false; + + // initialize + + _gl = initGL(); + + setDefaultGLState(); + + initSprites(); + initShadowmaps(); this.context = _gl; var _supportsVertexTextures = ( maxVertexTextures() > 0 ); - // prepare sprites + // API - var _sprite = {}; + this.getContext = function () { - _sprite.vertices = new Float32Array( 8 + 8 ); - _sprite.faces = new Uint16Array( 6 ); + return _gl; - var i = 0; + }; - _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1; // vertex 0 - _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 1; // uv 0 + this.supportsVertexTextures = function () { - _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = -1; // vertex 1 - _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // uv 1 + return _supportsVertexTextures; - _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // vertex 2 - _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 0; // uv 2 - - _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1; // vertex 3 - _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 0; // uv 3 - - i = 0; - - _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2; - _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3; - - _sprite.vertexBuffer = _gl.createBuffer(); - _sprite.elementBuffer = _gl.createBuffer(); - - _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW ); - - _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer ); - _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW ); - - - _sprite.program = _gl.createProgram(); - _gl.attachShader( _sprite.program, getShader( "fragment", THREE.ShaderLib.sprite.fragmentShader ) ); - _gl.attachShader( _sprite.program, getShader( "vertex", THREE.ShaderLib.sprite.vertexShader ) ); - _gl.linkProgram( _sprite.program ); - - _sprite.attributes = {}; - _sprite.uniforms = {}; - - _sprite.attributes.position = _gl.getAttribLocation ( _sprite.program, "position" ); - _sprite.attributes.uv = _gl.getAttribLocation ( _sprite.program, "uv" ); - - _sprite.uniforms.uvOffset = _gl.getUniformLocation( _sprite.program, "uvOffset" ); - _sprite.uniforms.uvScale = _gl.getUniformLocation( _sprite.program, "uvScale" ); - - _sprite.uniforms.rotation = _gl.getUniformLocation( _sprite.program, "rotation" ); - _sprite.uniforms.scale = _gl.getUniformLocation( _sprite.program, "scale" ); - _sprite.uniforms.alignment = _gl.getUniformLocation( _sprite.program, "alignment" ); - - _sprite.uniforms.color = _gl.getUniformLocation( _sprite.program, "color" ); - _sprite.uniforms.map = _gl.getUniformLocation( _sprite.program, "map" ); - _sprite.uniforms.opacity = _gl.getUniformLocation( _sprite.program, "opacity" ); - - _sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" ); - _sprite.uniforms.affectedByDistance = _gl.getUniformLocation( _sprite.program, "affectedByDistance" ); - _sprite.uniforms.screenPosition = _gl.getUniformLocation( _sprite.program, "screenPosition" ); - _sprite.uniforms.modelViewMatrix = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" ); - _sprite.uniforms.projectionMatrix = _gl.getUniformLocation( _sprite.program, "projectionMatrix" ); - - //_gl.enableVertexAttribArray( _sprite.attributes.position ); - //_gl.enableVertexAttribArray( _sprite.attributes.uv ); - - var _spriteAttributesEnabled = false; + }; this.setSize = function ( width, height ) { @@ -295,6 +222,8 @@ THREE.WebGLRenderer = function ( parameters ) { }; + // Clearing + this.setClearColorHex = function ( hex, alpha ) { _clearColor.setHex( hex ); @@ -337,12 +266,15 @@ THREE.WebGLRenderer = function ( parameters ) { }; - this.getContext = function () { + this.clearTarget = function ( renderTarget, color, depth, stencil ) { - return _gl; + setRenderTarget( renderTarget ); + this.clear( color, depth, stencil ); }; + // Deallocation + this.deallocateObject = function ( object ) { if ( ! object.__webglInit ) return; @@ -390,152 +322,19 @@ THREE.WebGLRenderer = function ( parameters ) { }; - // + // Rendering - function setupLights( program, lights ) { + this.updateShadowMap = function ( scene, camera ) { - var l, ll, light, n, - r = 0, g = 0, b = 0, - color, position, intensity, distance, - - zlights = _lights, - - dcolors = zlights.directional.colors, - dpositions = zlights.directional.positions, - - pcolors = zlights.point.colors, - ppositions = zlights.point.positions, - pdistances = zlights.point.distances, - - dlength = 0, - plength = 0, - - doffset = 0, - poffset = 0; - - for ( l = 0, ll = lights.length; l < ll; l ++ ) { - - light = lights[ l ]; - color = light.color; - - position = light.position; - intensity = light.intensity; - distance = light.distance; - - if ( light instanceof THREE.AmbientLight ) { - - if ( _this.gammaInput ) { - - r += color.r * color.r; - g += color.g * color.g; - b += color.b * color.b; - - } else { - - r += color.r; - g += color.g; - b += color.b; - - } - - } else if ( light instanceof THREE.DirectionalLight ) { - - doffset = dlength * 3; - - if ( _this.gammaInput ) { - - dcolors[ doffset ] = color.r * color.r * intensity * intensity; - dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity; - dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity; - - } else { - - dcolors[ doffset ] = color.r * intensity; - dcolors[ doffset + 1 ] = color.g * intensity; - dcolors[ doffset + 2 ] = color.b * intensity; - - } - - dpositions[ doffset ] = position.x; - dpositions[ doffset + 1 ] = position.y; - dpositions[ doffset + 2 ] = position.z; - - dlength += 1; - - } else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight - - doffset = dlength * 3; - - if ( _this.gammaInput ) { - - dcolors[ doffset ] = color.r * color.r * intensity * intensity; - dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity; - dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity; - - } else { - - dcolors[ doffset ] = color.r * intensity; - dcolors[ doffset + 1 ] = color.g * intensity; - dcolors[ doffset + 2 ] = color.b * intensity; - - } - - n = 1 / position.length(); - - dpositions[ doffset ] = position.x * n; - dpositions[ doffset + 1 ] = position.y * n; - dpositions[ doffset + 2 ] = position.z * n; - - dlength += 1; - - } else if( light instanceof THREE.PointLight ) { - - poffset = plength * 3; - - if ( _this.gammaInput ) { - - pcolors[ poffset ] = color.r * color.r * intensity * intensity; - pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity; - pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity; - - } else { - - pcolors[ poffset ] = color.r * intensity; - pcolors[ poffset + 1 ] = color.g * intensity; - pcolors[ poffset + 2 ] = color.b * intensity; - - } - - ppositions[ poffset ] = position.x; - ppositions[ poffset + 1 ] = position.y; - ppositions[ poffset + 2 ] = position.z; - - pdistances[ plength ] = distance; - - plength += 1; - - } - - } - - // null eventual remains from removed lights - // (this is to avoid if in shader) - - for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0; - for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0; - - zlights.point.length = plength; - zlights.directional.length = dlength; - - zlights.ambient[ 0 ] = r; - zlights.ambient[ 1 ] = g; - zlights.ambient[ 2 ] = b; + renderShadowMap( scene, camera ); }; + // Internal functions + // Buffer allocation - function createParticleBuffers( geometry ) { + function createParticleBuffers ( geometry ) { geometry.__webglVertexBuffer = _gl.createBuffer(); geometry.__webglColorBuffer = _gl.createBuffer(); @@ -544,7 +343,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function createLineBuffers( geometry ) { + function createLineBuffers ( geometry ) { geometry.__webglVertexBuffer = _gl.createBuffer(); geometry.__webglColorBuffer = _gl.createBuffer(); @@ -553,7 +352,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function createRibbonBuffers( geometry ) { + function createRibbonBuffers ( geometry ) { geometry.__webglVertexBuffer = _gl.createBuffer(); geometry.__webglColorBuffer = _gl.createBuffer(); @@ -562,7 +361,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function createMeshBuffers( geometryGroup ) { + function createMeshBuffers ( geometryGroup ) { geometryGroup.__webglVertexBuffer = _gl.createBuffer(); geometryGroup.__webglNormalBuffer = _gl.createBuffer(); @@ -599,7 +398,7 @@ THREE.WebGLRenderer = function ( parameters ) { // Buffer deallocation - function deleteParticleBuffers( geometry ) { + function deleteParticleBuffers ( geometry ) { _gl.deleteBuffer( geometry.__webglVertexBuffer ); _gl.deleteBuffer( geometry.__webglColorBuffer ); @@ -608,7 +407,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function deleteLineBuffers( geometry ) { + function deleteLineBuffers ( geometry ) { _gl.deleteBuffer( geometry.__webglVertexBuffer ); _gl.deleteBuffer( geometry.__webglColorBuffer ); @@ -617,7 +416,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function deleteRibbonBuffers( geometry ) { + function deleteRibbonBuffers ( geometry ) { _gl.deleteBuffer( geometry.__webglVertexBuffer ); _gl.deleteBuffer( geometry.__webglColorBuffer ); @@ -626,7 +425,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function deleteMeshBuffers( geometryGroup ) { + function deleteMeshBuffers ( geometryGroup ) { _gl.deleteBuffer( geometryGroup.__webglVertexBuffer ); _gl.deleteBuffer( geometryGroup.__webglNormalBuffer ); @@ -657,7 +456,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - // + // Buffer initialization function initCustomAttributes ( geometry, object ) { @@ -707,21 +506,6 @@ THREE.WebGLRenderer = function ( parameters ) { }; - // - - function initLineBuffers ( geometry, object ) { - - var nvertices = geometry.vertices.length; - - geometry.__vertexArray = new Float32Array( nvertices * 3 ); - geometry.__colorArray = new Float32Array( nvertices * 3 ); - - geometry.__webglLineCount = nvertices; - - initCustomAttributes ( geometry, object ); - - }; - function initParticleBuffers ( geometry, object ) { var nvertices = geometry.vertices.length; @@ -737,6 +521,19 @@ THREE.WebGLRenderer = function ( parameters ) { }; + function initLineBuffers ( geometry, object ) { + + var nvertices = geometry.vertices.length; + + geometry.__vertexArray = new Float32Array( nvertices * 3 ); + geometry.__colorArray = new Float32Array( nvertices * 3 ); + + geometry.__webglLineCount = nvertices; + + initCustomAttributes ( geometry, object ); + + }; + function initRibbonBuffers ( geometry ) { var nvertices = geometry.vertices.length; @@ -748,22 +545,6 @@ THREE.WebGLRenderer = function ( parameters ) { }; - // - - function getBufferMaterial( object, geometryGroup ) { - - if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) { - - return object.material; - - } else if ( geometryGroup.materialIndex >= 0 ) { - - return object.geometry.materials[ geometryGroup.materialIndex ]; - - } - - }; - function initMeshBuffers ( geometryGroup, object ) { var geometry = object.geometry, @@ -910,6 +691,606 @@ THREE.WebGLRenderer = function ( parameters ) { }; + function getBufferMaterial( object, geometryGroup ) { + + if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) { + + return object.material; + + } else if ( geometryGroup.materialIndex >= 0 ) { + + return object.geometry.materials[ geometryGroup.materialIndex ]; + + } + + }; + + function materialNeedsSmoothNormals ( material ) { + + return material && material.shading !== undefined && material.shading === THREE.SmoothShading; + + }; + + function bufferGuessNormalType ( material ) { + + // only MeshBasicMaterial and MeshDepthMaterial don't need normals + + if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) { + + return false; + + } + + if ( materialNeedsSmoothNormals( material ) ) { + + return THREE.SmoothShading; + + } else { + + return THREE.FlatShading; + + } + + }; + + function bufferGuessVertexColorType ( material ) { + + if ( material.vertexColors ) { + + return material.vertexColors; + + } + + return false; + + }; + + function bufferGuessUVType ( material ) { + + // material must use some texture to require uvs + + if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) { + + return true; + + } + + return false; + + }; + + // Buffer setting + + function setParticleBuffers ( geometry, hint, object ) { + + var v, c, vertex, offset, index, color, + + vertices = geometry.vertices, + vl = vertices.length, + + colors = geometry.colors, + cl = colors.length, + + vertexArray = geometry.__vertexArray, + colorArray = geometry.__colorArray, + + sortArray = geometry.__sortArray, + + dirtyVertices = geometry.__dirtyVertices, + dirtyElements = geometry.__dirtyElements, + dirtyColors = geometry.__dirtyColors, + + customAttributes = geometry.__webglCustomAttributesList, + i, il, + a, ca, cal, value, + customAttribute; + + if ( object.sortParticles ) { + + _projScreenMatrix.multiplySelf( object.matrixWorld ); + + for ( v = 0; v < vl; v ++ ) { + + vertex = vertices[ v ].position; + + _vector3.copy( vertex ); + _projScreenMatrix.multiplyVector3( _vector3 ); + + sortArray[ v ] = [ _vector3.z, v ]; + + } + + sortArray.sort( function( a, b ) { return b[ 0 ] - a[ 0 ]; } ); + + for ( v = 0; v < vl; v ++ ) { + + vertex = vertices[ sortArray[v][1] ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + for ( c = 0; c < cl; c ++ ) { + + offset = c * 3; + + color = colors[ sortArray[c][1] ]; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + if ( customAttributes ) { + + for ( i = 0, il = customAttributes.length; i < il; i ++ ) { + + customAttribute = customAttributes[ i ]; + + if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue; + + offset = 0; + + cal = customAttribute.value.length; + + if ( customAttribute.size === 1 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + index = sortArray[ ca ][ 1 ]; + + customAttribute.array[ ca ] = customAttribute.value[ index ]; + + } + + } else if ( customAttribute.size === 2 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + index = sortArray[ ca ][ 1 ]; + + value = customAttribute.value[ index ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + + offset += 2; + + } + + } else if ( customAttribute.size === 3 ) { + + if ( customAttribute.type === "c" ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + index = sortArray[ ca ][ 1 ]; + + value = customAttribute.value[ index ]; + + customAttribute.array[ offset ] = value.r; + customAttribute.array[ offset + 1 ] = value.g; + customAttribute.array[ offset + 2 ] = value.b; + + offset += 3; + + } + + } else { + + for ( ca = 0; ca < cal; ca ++ ) { + + index = sortArray[ ca ][ 1 ]; + + value = customAttribute.value[ index ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + customAttribute.array[ offset + 2 ] = value.z; + + offset += 3; + + } + + } + + } else if ( customAttribute.size === 4 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + index = sortArray[ ca ][ 1 ]; + + value = customAttribute.value[ index ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + customAttribute.array[ offset + 2 ] = value.z; + customAttribute.array[ offset + 3 ] = value.w; + + offset += 4; + + } + + } + + } + + } + + } else { + + if ( dirtyVertices ) { + + for ( v = 0; v < vl; v ++ ) { + + vertex = vertices[ v ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + } + + if ( dirtyColors ) { + + for ( c = 0; c < cl; c ++ ) { + + color = colors[ c ]; + + offset = c * 3; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + } + + if ( customAttributes ) { + + for ( i = 0, il = customAttributes.length; i < il; i ++ ) { + + customAttribute = customAttributes[ i ]; + + if ( customAttribute.needsUpdate && + ( customAttribute.boundTo === undefined || + customAttribute.boundTo === "vertices") ) { + + cal = customAttribute.value.length; + + offset = 0; + + if ( customAttribute.size === 1 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + customAttribute.array[ ca ] = customAttribute.value[ ca ]; + + } + + } else if ( customAttribute.size === 2 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + + offset += 2; + + } + + } else if ( customAttribute.size === 3 ) { + + if ( customAttribute.type === "c" ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.r; + customAttribute.array[ offset + 1 ] = value.g; + customAttribute.array[ offset + 2 ] = value.b; + + offset += 3; + + } + + } else { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + customAttribute.array[ offset + 2 ] = value.z; + + offset += 3; + + } + + } + + } else if ( customAttribute.size === 4 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + customAttribute.array[ offset + 2 ] = value.z; + customAttribute.array[ offset + 3 ] = value.w; + + offset += 4; + + } + + } + + } + + } + + } + + } + + if ( dirtyVertices || object.sortParticles ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + + } + + if ( dirtyColors || object.sortParticles ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + + } + + if ( customAttributes ) { + + for ( i = 0, il = customAttributes.length; i < il; i ++ ) { + + customAttribute = customAttributes[ i ]; + + if ( customAttribute.needsUpdate || object.sortParticles ) { + + _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint ); + + } + + } + + } + + + }; + + function setLineBuffers ( geometry, hint ) { + + var v, c, vertex, offset, color, + + vertices = geometry.vertices, + colors = geometry.colors, + vl = vertices.length, + cl = colors.length, + + vertexArray = geometry.__vertexArray, + colorArray = geometry.__colorArray, + + dirtyVertices = geometry.__dirtyVertices, + dirtyColors = geometry.__dirtyColors, + + customAttributes = geometry.__webglCustomAttributesList, + + i, il, + a, ca, cal, value, + customAttribute; + + if ( dirtyVertices ) { + + for ( v = 0; v < vl; v ++ ) { + + vertex = vertices[ v ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + + } + + if ( dirtyColors ) { + + for ( c = 0; c < cl; c ++ ) { + + color = colors[ c ]; + + offset = c * 3; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + + } + + if ( customAttributes ) { + + for ( i = 0, il = customAttributes.length; i < il; i ++ ) { + + customAttribute = customAttributes[ i ]; + + if ( customAttribute.needsUpdate && + ( customAttribute.boundTo === undefined || + customAttribute.boundTo === "vertices" ) ) { + + offset = 0; + + cal = customAttribute.value.length; + + if ( customAttribute.size === 1 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + customAttribute.array[ ca ] = customAttribute.value[ ca ]; + + } + + } else if ( customAttribute.size === 2 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + + offset += 2; + + } + + } else if ( customAttribute.size === 3 ) { + + if ( customAttribute.type === "c" ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.r; + customAttribute.array[ offset + 1 ] = value.g; + customAttribute.array[ offset + 2 ] = value.b; + + offset += 3; + + } + + } else { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + customAttribute.array[ offset + 2 ] = value.z; + + offset += 3; + + } + + } + + } else if ( customAttribute.size === 4 ) { + + for ( ca = 0; ca < cal; ca ++ ) { + + value = customAttribute.value[ ca ]; + + customAttribute.array[ offset ] = value.x; + customAttribute.array[ offset + 1 ] = value.y; + customAttribute.array[ offset + 2 ] = value.z; + customAttribute.array[ offset + 3 ] = value.w; + + offset += 4; + + } + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint ); + + } + + } + + } + + }; + + function setRibbonBuffers ( geometry, hint ) { + + var v, c, vertex, offset, color, + + vertices = geometry.vertices, + colors = geometry.colors, + vl = vertices.length, + cl = colors.length, + + vertexArray = geometry.__vertexArray, + colorArray = geometry.__colorArray, + + dirtyVertices = geometry.__dirtyVertices, + dirtyColors = geometry.__dirtyColors; + + if ( dirtyVertices ) { + + for ( v = 0; v < vl; v ++ ) { + + vertex = vertices[ v ].position; + + offset = v * 3; + + vertexArray[ offset ] = vertex.x; + vertexArray[ offset + 1 ] = vertex.y; + vertexArray[ offset + 2 ] = vertex.z; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + + } + + if ( dirtyColors ) { + + for ( c = 0; c < cl; c ++ ) { + + color = colors[ c ]; + + offset = c * 3; + + colorArray[ offset ] = color.r; + colorArray[ offset + 1 ] = color.g; + colorArray[ offset + 2 ] = color.b; + + } + + _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + + } + + }; + function setMeshBuffers( geometryGroup, object, hint, dispose ) { if ( ! geometryGroup.__inittedArrays ) { @@ -2434,991 +2815,82 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function setLineBuffers ( geometry, hint ) { + // Buffer rendering - var v, c, vertex, offset, color, + function renderBufferImmediate ( object, program, shading ) { - vertices = geometry.vertices, - colors = geometry.colors, - vl = vertices.length, - cl = colors.length, + if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer(); + if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer(); - vertexArray = geometry.__vertexArray, - colorArray = geometry.__colorArray, + if ( object.hasPos ) { - dirtyVertices = geometry.__dirtyVertices, - dirtyColors = geometry.__dirtyColors, - - customAttributes = geometry.__webglCustomAttributesList, - - i, il, - a, ca, cal, value, - customAttribute; - - if ( dirtyVertices ) { - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ v ].position; - - offset = v * 3; - - vertexArray[ offset ] = vertex.x; - vertexArray[ offset + 1 ] = vertex.y; - vertexArray[ offset + 2 ] = vertex.z; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); + _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); + _gl.enableVertexAttribArray( program.attributes.position ); + _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 ); } - if ( dirtyColors ) { + if ( object.hasNormal ) { - for ( c = 0; c < cl; c ++ ) { + _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer ); - color = colors[ c ]; + if ( shading === THREE.FlatShading ) { - offset = c * 3; + var nx, ny, nz, + nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz, + normalArray, + i, il = object.count * 3; - colorArray[ offset ] = color.r; - colorArray[ offset + 1 ] = color.g; - colorArray[ offset + 2 ] = color.b; + for( i = 0; i < il; i += 9 ) { - } + normalArray = object.normalArray; - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); + nax = normalArray[ i ]; + nay = normalArray[ i + 1 ]; + naz = normalArray[ i + 2 ]; - } + nbx = normalArray[ i + 3 ]; + nby = normalArray[ i + 4 ]; + nbz = normalArray[ i + 5 ]; - if ( customAttributes ) { + ncx = normalArray[ i + 6 ]; + ncy = normalArray[ i + 7 ]; + ncz = normalArray[ i + 8 ]; - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { + nx = ( nax + nbx + ncx ) / 3; + ny = ( nay + nby + ncy ) / 3; + nz = ( naz + nbz + ncz ) / 3; - customAttribute = customAttributes[ i ]; + normalArray[ i ] = nx; + normalArray[ i + 1 ] = ny; + normalArray[ i + 2 ] = nz; - if ( customAttribute.needsUpdate && - ( customAttribute.boundTo === undefined || - customAttribute.boundTo === "vertices" ) ) { + normalArray[ i + 3 ] = nx; + normalArray[ i + 4 ] = ny; + normalArray[ i + 5 ] = nz; - offset = 0; - - cal = customAttribute.value.length; - - if ( customAttribute.size === 1 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - customAttribute.array[ ca ] = customAttribute.value[ ca ]; - - } - - } else if ( customAttribute.size === 2 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - - offset += 2; - - } - - } else if ( customAttribute.size === 3 ) { - - if ( customAttribute.type === "c" ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.r; - customAttribute.array[ offset + 1 ] = value.g; - customAttribute.array[ offset + 2 ] = value.b; - - offset += 3; - - } - - } else { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - - offset += 3; - - } - - } - - } else if ( customAttribute.size === 4 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - customAttribute.array[ offset + 3 ] = value.w; - - offset += 4; - - } - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint ); + normalArray[ i + 6 ] = nx; + normalArray[ i + 7 ] = ny; + normalArray[ i + 8 ] = nz; } } + _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); + _gl.enableVertexAttribArray( program.attributes.normal ); + _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); + } + _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); + + object.count = 0; + }; - function setRibbonBuffers ( geometry, hint ) { - - var v, c, vertex, offset, color, - - vertices = geometry.vertices, - colors = geometry.colors, - vl = vertices.length, - cl = colors.length, - - vertexArray = geometry.__vertexArray, - colorArray = geometry.__colorArray, - - dirtyVertices = geometry.__dirtyVertices, - dirtyColors = geometry.__dirtyColors; - - if ( dirtyVertices ) { - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ v ].position; - - offset = v * 3; - - vertexArray[ offset ] = vertex.x; - vertexArray[ offset + 1 ] = vertex.y; - vertexArray[ offset + 2 ] = vertex.z; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); - - } - - if ( dirtyColors ) { - - for ( c = 0; c < cl; c ++ ) { - - color = colors[ c ]; - - offset = c * 3; - - colorArray[ offset ] = color.r; - colorArray[ offset + 1 ] = color.g; - colorArray[ offset + 2 ] = color.b; - - } - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); - - } - - }; - - function setParticleBuffers ( geometry, hint, object ) { - - var v, c, vertex, offset, index, color, - - vertices = geometry.vertices, - vl = vertices.length, - - colors = geometry.colors, - cl = colors.length, - - vertexArray = geometry.__vertexArray, - colorArray = geometry.__colorArray, - - sortArray = geometry.__sortArray, - - dirtyVertices = geometry.__dirtyVertices, - dirtyElements = geometry.__dirtyElements, - dirtyColors = geometry.__dirtyColors, - - customAttributes = geometry.__webglCustomAttributesList, - i, il, - a, ca, cal, value, - customAttribute; - - if ( object.sortParticles ) { - - _projScreenMatrix.multiplySelf( object.matrixWorld ); - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ v ].position; - - _vector3.copy( vertex ); - _projScreenMatrix.multiplyVector3( _vector3 ); - - sortArray[ v ] = [ _vector3.z, v ]; - - } - - sortArray.sort( function( a, b ) { return b[ 0 ] - a[ 0 ]; } ); - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ sortArray[v][1] ].position; - - offset = v * 3; - - vertexArray[ offset ] = vertex.x; - vertexArray[ offset + 1 ] = vertex.y; - vertexArray[ offset + 2 ] = vertex.z; - - } - - for ( c = 0; c < cl; c ++ ) { - - offset = c * 3; - - color = colors[ sortArray[c][1] ]; - - colorArray[ offset ] = color.r; - colorArray[ offset + 1 ] = color.g; - colorArray[ offset + 2 ] = color.b; - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue; - - offset = 0; - - cal = customAttribute.value.length; - - if ( customAttribute.size === 1 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - customAttribute.array[ ca ] = customAttribute.value[ index ]; - - } - - } else if ( customAttribute.size === 2 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - - offset += 2; - - } - - } else if ( customAttribute.size === 3 ) { - - if ( customAttribute.type === "c" ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.r; - customAttribute.array[ offset + 1 ] = value.g; - customAttribute.array[ offset + 2 ] = value.b; - - offset += 3; - - } - - } else { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - - offset += 3; - - } - - } - - } else if ( customAttribute.size === 4 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - index = sortArray[ ca ][ 1 ]; - - value = customAttribute.value[ index ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - customAttribute.array[ offset + 3 ] = value.w; - - offset += 4; - - } - - } - - } - - } - - } else { - - if ( dirtyVertices ) { - - for ( v = 0; v < vl; v ++ ) { - - vertex = vertices[ v ].position; - - offset = v * 3; - - vertexArray[ offset ] = vertex.x; - vertexArray[ offset + 1 ] = vertex.y; - vertexArray[ offset + 2 ] = vertex.z; - - } - - } - - if ( dirtyColors ) { - - for ( c = 0; c < cl; c ++ ) { - - color = colors[ c ]; - - offset = c * 3; - - colorArray[ offset ] = color.r; - colorArray[ offset + 1 ] = color.g; - colorArray[ offset + 2 ] = color.b; - - } - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( customAttribute.needsUpdate && - ( customAttribute.boundTo === undefined || - customAttribute.boundTo === "vertices") ) { - - cal = customAttribute.value.length; - - offset = 0; - - if ( customAttribute.size === 1 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - customAttribute.array[ ca ] = customAttribute.value[ ca ]; - - } - - } else if ( customAttribute.size === 2 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - - offset += 2; - - } - - } else if ( customAttribute.size === 3 ) { - - if ( customAttribute.type === "c" ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.r; - customAttribute.array[ offset + 1 ] = value.g; - customAttribute.array[ offset + 2 ] = value.b; - - offset += 3; - - } - - } else { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - - offset += 3; - - } - - } - - } else if ( customAttribute.size === 4 ) { - - for ( ca = 0; ca < cal; ca ++ ) { - - value = customAttribute.value[ ca ]; - - customAttribute.array[ offset ] = value.x; - customAttribute.array[ offset + 1 ] = value.y; - customAttribute.array[ offset + 2 ] = value.z; - customAttribute.array[ offset + 3 ] = value.w; - - offset += 4; - - } - - } - - } - - } - - } - - } - - if ( dirtyVertices || object.sortParticles ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint ); - - } - - if ( dirtyColors || object.sortParticles ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint ); - - } - - if ( customAttributes ) { - - for ( i = 0, il = customAttributes.length; i < il; i ++ ) { - - customAttribute = customAttributes[ i ]; - - if ( customAttribute.needsUpdate || object.sortParticles ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint ); - - } - - } - - } - - - }; - - function setMaterialShaders( material, shaders ) { - - material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms ); - material.vertexShader = shaders.vertexShader; - material.fragmentShader = shaders.fragmentShader; - - }; - - function refreshUniformsCommon( uniforms, material ) { - - uniforms.opacity.value = material.opacity; - - if ( _this.gammaInput ) { - - uniforms.diffuse.value.copyGammaToLinear( material.color ); - - } else { - - uniforms.diffuse.value = material.color; - - } - - uniforms.map.texture = material.map; - - if ( material.map ) { - - uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y ); - - } - - uniforms.lightMap.texture = material.lightMap; - - uniforms.envMap.texture = material.envMap; - uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1; - - if ( _this.gammaInput ) { - - //uniforms.reflectivity.value = material.reflectivity * material.reflectivity; - uniforms.reflectivity.value = material.reflectivity; - - } else { - - uniforms.reflectivity.value = material.reflectivity; - - } - - uniforms.refractionRatio.value = material.refractionRatio; - uniforms.combine.value = material.combine; - uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping; - - }; - - function refreshUniformsLine( uniforms, material ) { - - uniforms.diffuse.value = material.color; - uniforms.opacity.value = material.opacity; - - }; - - function refreshUniformsParticle( uniforms, material ) { - - uniforms.psColor.value = material.color; - uniforms.opacity.value = material.opacity; - uniforms.size.value = material.size; - uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this. - - uniforms.map.texture = material.map; - - }; - - function refreshUniformsFog( uniforms, fog ) { - - uniforms.fogColor.value = fog.color; - - if ( fog instanceof THREE.Fog ) { - - uniforms.fogNear.value = fog.near; - uniforms.fogFar.value = fog.far; - - } else if ( fog instanceof THREE.FogExp2 ) { - - uniforms.fogDensity.value = fog.density; - - } - - }; - - function refreshUniformsPhong( uniforms, material ) { - - uniforms.shininess.value = material.shininess; - - if ( _this.gammaInput ) { - - uniforms.ambient.value.copyGammaToLinear( material.ambient ); - uniforms.specular.value.copyGammaToLinear( material.specular ); - - } else { - - uniforms.ambient.value = material.ambient; - uniforms.specular.value = material.specular; - - } - - }; - - function refreshUniformsLambert( uniforms, material ) { - - if ( _this.gammaInput ) { - - uniforms.ambient.value.copyGammaToLinear( material.ambient ); - - } else { - - uniforms.ambient.value = material.ambient; - - } - - }; - - function refreshUniformsLights( uniforms, lights ) { - - uniforms.enableLighting.value = lights.directional.length + lights.point.length; - uniforms.ambientLightColor.value = lights.ambient; - - uniforms.directionalLightColor.value = lights.directional.colors; - uniforms.directionalLightDirection.value = lights.directional.positions; - - uniforms.pointLightColor.value = lights.point.colors; - uniforms.pointLightPosition.value = lights.point.positions; - uniforms.pointLightDistance.value = lights.point.distances; - - }; - - function refreshUniformsShadow( uniforms, material ) { - - if ( uniforms.shadowMatrix ) { - - for ( var i = 0; i < _shadowMatrix.length; i ++ ) { - - uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ]; - uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ]; - - - } - - uniforms.shadowDarkness.value = _this.shadowMapDarkness; - uniforms.shadowBias.value = _this.shadowMapBias; - - } - - }; - - this.initMaterial = function ( material, lights, fog, object ) { - - var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID; - - if ( material instanceof THREE.MeshDepthMaterial ) { - - shaderID = 'depth'; - - } else if ( material instanceof THREE.MeshNormalMaterial ) { - - shaderID = 'normal'; - - } else if ( material instanceof THREE.MeshBasicMaterial ) { - - shaderID = 'basic'; - - } else if ( material instanceof THREE.MeshLambertMaterial ) { - - shaderID = 'lambert'; - - } else if ( material instanceof THREE.MeshPhongMaterial ) { - - shaderID = 'phong'; - - } else if ( material instanceof THREE.LineBasicMaterial ) { - - shaderID = 'basic'; - - } else if ( material instanceof THREE.ParticleBasicMaterial ) { - - shaderID = 'particle_basic'; - - } - - if ( shaderID ) { - - setMaterialShaders( material, THREE.ShaderLib[ shaderID ] ); - - } - - // heuristics to create shader parameters according to lights in the scene - // (not to blow over maxLights budget) - - maxLightCount = allocateLights( lights ); - - maxShadows = allocateShadows( lights ); - - maxBones = allocateBones( object ); - - parameters = { - - map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap, - vertexColors: material.vertexColors, - fog: fog, useFog: material.fog, - sizeAttenuation: material.sizeAttenuation, - skinning: material.skinning, - morphTargets: material.morphTargets, - maxMorphTargets: this.maxMorphTargets, - maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point, - maxBones: maxBones, - shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow, - shadowMapSoft: this.shadowMapSoft, - shadowMapWidth: this.shadowMapWidth, - shadowMapHeight: this.shadowMapHeight, - maxShadows: maxShadows, - alphaTest: material.alphaTest, - metal: material.metal, - perPixel: material.perPixel - - }; - - material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters ); - - var attributes = material.program.attributes; - - if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position ); - if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color ); - if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal ); - if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent ); - - if ( material.skinning && - attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 && - attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) { - - _gl.enableVertexAttribArray( attributes.skinVertexA ); - _gl.enableVertexAttribArray( attributes.skinVertexB ); - _gl.enableVertexAttribArray( attributes.skinIndex ); - _gl.enableVertexAttribArray( attributes.skinWeight ); - - } - - if ( material.attributes ) { - - for ( a in material.attributes ) { - - if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] ); - - } - - } - - if ( material.morphTargets ) { - - material.numSupportedMorphTargets = 0; - - var id, base = "morphTarget"; - - for ( i = 0; i < this.maxMorphTargets; i ++ ) { - - id = base + i; - - if ( attributes[ id ] >= 0 ) { - - _gl.enableVertexAttribArray( attributes[ id ] ); - material.numSupportedMorphTargets ++; - - } - - } - - } - - material.uniformsList = []; - - for ( u in material.uniforms ) { - - material.uniformsList.push( [ material.uniforms[ u ], u ] ); - - } - - }; - - function setProgram( camera, lights, fog, material, object ) { - - if ( ! material.program ) { - - _this.initMaterial( material, lights, fog, object ); - - } - - if ( material.morphTargets ) { - - if ( ! object.__webglMorphTargetInfluences ) { - - object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets ); - - for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) { - - object.__webglMorphTargetInfluences[ i ] = 0; - - } - - } - - } - - var refreshMaterial = false; - - var program = material.program, - p_uniforms = program.uniforms, - m_uniforms = material.uniforms; - - if ( program !== _currentProgram ) { - - _gl.useProgram( program ); - _currentProgram = program; - - refreshMaterial = true; - - } - - if ( material.id !== _currentMaterialId ) { - - _currentMaterialId = material.id; - refreshMaterial = true; - - } - - if ( refreshMaterial ) { - - _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray ); - - // refresh uniforms common to several materials - - if ( fog && material.fog ) { - - refreshUniformsFog( m_uniforms, fog ); - - } - - if ( material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshLambertMaterial || - material.lights ) { - - setupLights( program, lights ); - refreshUniformsLights( m_uniforms, _lights ); - - } - - if ( material instanceof THREE.MeshBasicMaterial || - material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.MeshPhongMaterial ) { - - refreshUniformsCommon( m_uniforms, material ); - - } - - // refresh single material specific uniforms - - if ( material instanceof THREE.LineBasicMaterial ) { - - refreshUniformsLine( m_uniforms, material ); - - } else if ( material instanceof THREE.ParticleBasicMaterial ) { - - refreshUniformsParticle( m_uniforms, material ); - - } else if ( material instanceof THREE.MeshPhongMaterial ) { - - refreshUniformsPhong( m_uniforms, material ); - - } else if ( material instanceof THREE.MeshLambertMaterial ) { - - refreshUniformsLambert( m_uniforms, material ); - - } else if ( material instanceof THREE.MeshDepthMaterial ) { - - m_uniforms.mNear.value = camera.near; - m_uniforms.mFar.value = camera.far; - m_uniforms.opacity.value = material.opacity; - - } else if ( material instanceof THREE.MeshNormalMaterial ) { - - m_uniforms.opacity.value = material.opacity; - - } - - if ( object.receiveShadow && ! material._shadowPass ) { - - refreshUniformsShadow( m_uniforms, material ); - - } - - // load common uniforms - - loadUniformsGeneric( program, material.uniformsList ); - - // load material specific uniforms - // (shader material also gets them for the sake of genericity) - - if ( material instanceof THREE.ShaderMaterial || - material instanceof THREE.MeshPhongMaterial || - material.envMap ) { - - if( p_uniforms.cameraPosition !== null ) { - - _gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z ); - - } - - } - - if ( material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.ShaderMaterial || - material.skinning ) { - - if( p_uniforms.viewMatrix !== null ) { - - _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray ); - - } - - } - - if ( material.skinning ) { - - loadUniformsSkinning( p_uniforms, object ); - - } - - } - - loadUniformsMatrices( p_uniforms, object ); - - if ( material instanceof THREE.ShaderMaterial || - material.envMap || - material.skinning || - object.receiveShadow ) { - - if ( p_uniforms.objectMatrix !== null ) { - - _gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray ); - - } - - } - - return program; - - }; - - function renderBuffer( camera, lights, fog, material, geometryGroup, object ) { + function renderBuffer ( camera, lights, fog, material, geometryGroup, object ) { if ( material.opacity === 0 ) return; @@ -3626,7 +3098,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function setupMorphTargets( material, geometryGroup, object ) { + function setupMorphTargets ( material, geometryGroup, object ) { // set base @@ -3715,189 +3187,9 @@ THREE.WebGLRenderer = function ( parameters ) { } + // Frustum - function renderBufferImmediate( object, program, shading ) { - - if ( ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer(); - if ( ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer(); - - if ( object.hasPos ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer ); - _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW ); - _gl.enableVertexAttribArray( program.attributes.position ); - _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 ); - - } - - if ( object.hasNormal ) { - - _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer ); - - if ( shading === THREE.FlatShading ) { - - var nx, ny, nz, - nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz, - normalArray, - i, il = object.count * 3; - - for( i = 0; i < il; i += 9 ) { - - normalArray = object.normalArray; - - nax = normalArray[ i ]; - nay = normalArray[ i + 1 ]; - naz = normalArray[ i + 2 ]; - - nbx = normalArray[ i + 3 ]; - nby = normalArray[ i + 4 ]; - nbz = normalArray[ i + 5 ]; - - ncx = normalArray[ i + 6 ]; - ncy = normalArray[ i + 7 ]; - ncz = normalArray[ i + 8 ]; - - nx = ( nax + nbx + ncx ) / 3; - ny = ( nay + nby + ncy ) / 3; - nz = ( naz + nbz + ncz ) / 3; - - normalArray[ i ] = nx; - normalArray[ i + 1 ] = ny; - normalArray[ i + 2 ] = nz; - - normalArray[ i + 3 ] = nx; - normalArray[ i + 4 ] = ny; - normalArray[ i + 5 ] = nz; - - normalArray[ i + 6 ] = nx; - normalArray[ i + 7 ] = ny; - normalArray[ i + 8 ] = nz; - - } - - } - - _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW ); - _gl.enableVertexAttribArray( program.attributes.normal ); - _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 ); - - } - - _gl.drawArrays( _gl.TRIANGLES, 0, object.count ); - - object.count = 0; - - }; - - function setLineWidth( width ) { - - if ( width !== _oldLineWidth ) { - - _gl.lineWidth( width ); - - _oldLineWidth = width; - - } - - }; - - function setObjectFaces( object ) { - - if ( _oldDoubleSided !== object.doubleSided ) { - - if( object.doubleSided ) { - - _gl.disable( _gl.CULL_FACE ); - - } else { - - _gl.enable( _gl.CULL_FACE ); - - } - - _oldDoubleSided = object.doubleSided; - - } - - if ( _oldFlipSided !== object.flipSided ) { - - if( object.flipSided ) { - - _gl.frontFace( _gl.CW ); - - } else { - - _gl.frontFace( _gl.CCW ); - - } - - _oldFlipSided = object.flipSided; - - } - - }; - - function setDepthTest( depthTest ) { - - if ( _oldDepthTest !== depthTest ) { - - if( depthTest ) { - - _gl.enable( _gl.DEPTH_TEST ); - - } else { - - _gl.disable( _gl.DEPTH_TEST ); - - } - - _oldDepthTest = depthTest; - - } - - }; - - function setDepthWrite( depthWrite ) { - - if ( _oldDepthWrite !== depthWrite ) { - - _gl.depthMask( depthWrite ); - _oldDepthWrite = depthWrite; - - } - - }; - - function setPolygonOffset ( polygonoffset, factor, units ) { - - if ( _oldPolygonOffset !== polygonoffset ) { - - if ( polygonoffset ) { - - _gl.enable( _gl.POLYGON_OFFSET_FILL ); - - } else { - - _gl.disable( _gl.POLYGON_OFFSET_FILL ); - - } - - _oldPolygonOffset = polygonoffset; - - } - - if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) { - - _gl.polygonOffset( factor, units ); - - _oldPolygonOffsetFactor = factor; - _oldPolygonOffsetUnits = units; - - } - - }; - - function computeFrustum( m ) { + function computeFrustum ( m ) { _frustum[ 0 ].set( m.n41 - m.n11, m.n42 - m.n12, m.n43 - m.n13, m.n44 - m.n14 ); _frustum[ 1 ].set( m.n41 + m.n11, m.n42 + m.n12, m.n43 + m.n13, m.n44 + m.n14 ); @@ -3917,7 +3209,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function isInFrustum( object ) { + function isInFrustum ( object ) { var distance, matrix = object.matrixWorld, radius = - object.geometry.boundingSphere.radius * Math.max( object.scale.x, Math.max( object.scale.y, object.scale.z ) ); @@ -3933,309 +3225,16 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function addToFixedArray( where, what ) { - where.list[ where.count ] = what; - where.count += 1; - - }; - - function unrollImmediateBufferMaterial( globject ) { - - var object = globject.object, - material = object.material; - - if ( material.transparent ) { - - globject.transparent = material; - globject.opaque = null; - - } else { - - globject.opaque = material; - globject.transparent = null; - - } - - }; - - function unrollBufferMaterial( globject ) { - - var object = globject.object, - buffer = globject.buffer, - material, materialIndex, meshMaterial; - - meshMaterial = object.material; - - if ( meshMaterial instanceof THREE.MeshFaceMaterial ) { - - materialIndex = buffer.materialIndex; - - if ( materialIndex >= 0 ) { - - material = object.geometry.materials[ materialIndex ]; - - if ( material.transparent ) { - - globject.transparent = material; - globject.opaque = null; - - } else { - - globject.opaque = material; - globject.transparent = null; - - } - - } - - } else { - - material = meshMaterial; - - if ( material ) { - - if ( material.transparent ) { - - globject.transparent = material; - globject.opaque = null; - - } else { - - globject.opaque = material; - globject.transparent = null; - - } - - } - - } - - }; - - function painterSort( a, b ) { + function painterSort ( a, b ) { return b.z - a.z; }; - function renderShadowMap( scene, camera ) { + // Rendering - var i, il, light, - j = 0, - shadowMap, shadowMatrix, - oil, - material, - program, buffer, - o, ol, webglObject, object, - lights = scene.lights, - fog = null; - - if ( ! _cameraLight ) { - - _cameraLight = new THREE.PerspectiveCamera( _this.shadowCameraFov, _this.shadowMapWidth / _this.shadowMapHeight, _this.shadowCameraNear, _this.shadowCameraFar ); - - } - - for ( i = 0, il = lights.length; i < il; i ++ ) { - - light = lights[ i ]; - - if ( light instanceof THREE.SpotLight && light.castShadow ) { - - _currentMaterialId = -1; - - if ( ! _this.shadowMap[ j ] ) { - - var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat }; - _this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars ); - - } - - if ( ! _shadowMatrix[ j ] ) { - - _shadowMatrix[ j ] = new THREE.Matrix4(); - - } - - shadowMap = _this.shadowMap[ j ]; - shadowMatrix = _shadowMatrix[ j ]; - - _cameraLight.position.copy( light.position ); - _cameraLight.lookAt( light.target.position ); - - if ( _cameraLight.parent == null ) { - - console.warn( "Camera is not on the Scene. Adding it..." ); - scene.add( _cameraLight ); - - } - - if ( this.autoUpdateScene ) scene.updateMatrixWorld(); - - _cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld ); - - // compute shadow matrix - - shadowMatrix.set( 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 0.5, 0.5, - 0.0, 0.0, 0.0, 1.0 ); - - shadowMatrix.multiplySelf( _cameraLight.projectionMatrix ); - shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse ); - - // render shadow map - - _cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray ); - _cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray ); - - _projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse ); - computeFrustum( _projScreenMatrix ); - - setRenderTarget( shadowMap ); - - // using arbitrary clear color in depth pass - // creates variance in shadows - - _gl.clearColor( 1, 1, 1, 1 ); - //_gl.clearColor( 0, 0, 0, 1 ); - - _this.clear(); - - _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); - - - // set matrices & frustum culling - - ol = scene.__webglObjects.length; - oil = scene.__webglObjectsImmediate.length; - - for ( o = 0; o < ol; o ++ ) { - - webglObject = scene.__webglObjects[ o ]; - object = webglObject.object; - - if ( object.visible && object.castShadow ) { - - if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) { - - object.matrixWorld.flattenToArray( object._objectMatrixArray ); - - setupMatrices( object, _cameraLight, false ); - - webglObject.render = true; - - } else { - - webglObject.render = false; - - } - - } else { - - webglObject.render = false; - - } - - } - - setDepthTest( true ); - setBlending( THREE.NormalBlending ); // maybe blending should be just disabled? - - //_gl.cullFace( _gl.FRONT ); - - for ( o = 0; o < ol; o ++ ) { - - webglObject = scene.__webglObjects[ o ]; - - if ( webglObject.render ) { - - object = webglObject.object; - buffer = webglObject.buffer; - - setObjectFaces( object ); - - if ( object.customDepthMaterial ) { - - material = object.customDepthMaterial; - - } else if ( object.geometry.morphTargets.length ) { - - material = _depthMaterialMorph; - - } else { - - material = _depthMaterial; - - } - - renderBuffer( _cameraLight, lights, fog, material, buffer, object ); - - } - - } - - - for ( o = 0; o < oil; o ++ ) { - - webglObject = scene.__webglObjectsImmediate[ o ]; - object = webglObject.object; - - if ( object.visible && object.castShadow ) { - - if( object.matrixAutoUpdate ) { - - object.matrixWorld.flattenToArray( object._objectMatrixArray ); - - } - - _currentGeometryGroupHash = -1; - - setupMatrices( object, _cameraLight, false ); - - setObjectFaces( object ); - - program = setProgram( _cameraLight, lights, fog, _depthMaterial, object ); - - if ( object.immediateRenderCallback ) { - - object.immediateRenderCallback( program, _gl, _frustum ); - - } else { - - object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } ); - - } - - } - - } - - //_gl.cullFace( _gl.BACK ); - - j ++; - - } - - } - - }; - - this.clearTarget = function ( renderTarget, color, depth, stencil ) { - - setRenderTarget( renderTarget ); - this.clear( color, depth, stencil ); - - }; - - this.updateShadowMap = function ( scene, camera ) { - - renderShadowMap( scene, camera ); - - }; - - this.render = function( scene, camera, renderTarget, forceClear ) { + this.render = function ( scene, camera, renderTarget, forceClear ) { var i, program, material, o, ol, oil, webglObject, object, buffer, @@ -4561,12 +3560,283 @@ THREE.WebGLRenderer = function ( parameters ) { }; - /* - * Render sprites - * - */ + function renderShadowMap ( scene, camera ) { - function renderSprites( scene, camera ) { + var i, il, light, + j = 0, + shadowMap, shadowMatrix, + oil, + material, + program, buffer, + o, ol, webglObject, object, + lights = scene.lights, + fog = null; + + if ( ! _cameraLight ) { + + _cameraLight = new THREE.PerspectiveCamera( _this.shadowCameraFov, _this.shadowMapWidth / _this.shadowMapHeight, _this.shadowCameraNear, _this.shadowCameraFar ); + + } + + for ( i = 0, il = lights.length; i < il; i ++ ) { + + light = lights[ i ]; + + if ( light instanceof THREE.SpotLight && light.castShadow ) { + + _currentMaterialId = -1; + + if ( ! _this.shadowMap[ j ] ) { + + var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat }; + _this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars ); + + } + + if ( ! _shadowMatrix[ j ] ) { + + _shadowMatrix[ j ] = new THREE.Matrix4(); + + } + + shadowMap = _this.shadowMap[ j ]; + shadowMatrix = _shadowMatrix[ j ]; + + _cameraLight.position.copy( light.position ); + _cameraLight.lookAt( light.target.position ); + + if ( _cameraLight.parent == null ) { + + console.warn( "Camera is not on the Scene. Adding it..." ); + scene.add( _cameraLight ); + + } + + if ( this.autoUpdateScene ) scene.updateMatrixWorld(); + + _cameraLight.matrixWorldInverse.getInverse( _cameraLight.matrixWorld ); + + // compute shadow matrix + + shadowMatrix.set( 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0 ); + + shadowMatrix.multiplySelf( _cameraLight.projectionMatrix ); + shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse ); + + // render shadow map + + _cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray ); + _cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray ); + + _projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse ); + computeFrustum( _projScreenMatrix ); + + setRenderTarget( shadowMap ); + + // using arbitrary clear color in depth pass + // creates variance in shadows + + _gl.clearColor( 1, 1, 1, 1 ); + //_gl.clearColor( 0, 0, 0, 1 ); + + _this.clear(); + + _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + + + // set matrices & frustum culling + + ol = scene.__webglObjects.length; + oil = scene.__webglObjectsImmediate.length; + + for ( o = 0; o < ol; o ++ ) { + + webglObject = scene.__webglObjects[ o ]; + object = webglObject.object; + + if ( object.visible && object.castShadow ) { + + if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || isInFrustum( object ) ) { + + object.matrixWorld.flattenToArray( object._objectMatrixArray ); + + setupMatrices( object, _cameraLight, false ); + + webglObject.render = true; + + } else { + + webglObject.render = false; + + } + + } else { + + webglObject.render = false; + + } + + } + + setDepthTest( true ); + setBlending( THREE.NormalBlending ); // maybe blending should be just disabled? + + //_gl.cullFace( _gl.FRONT ); + + for ( o = 0; o < ol; o ++ ) { + + webglObject = scene.__webglObjects[ o ]; + + if ( webglObject.render ) { + + object = webglObject.object; + buffer = webglObject.buffer; + + setObjectFaces( object ); + + if ( object.customDepthMaterial ) { + + material = object.customDepthMaterial; + + } else if ( object.geometry.morphTargets.length ) { + + material = _depthMaterialMorph; + + } else { + + material = _depthMaterial; + + } + + renderBuffer( _cameraLight, lights, fog, material, buffer, object ); + + } + + } + + + for ( o = 0; o < oil; o ++ ) { + + webglObject = scene.__webglObjectsImmediate[ o ]; + object = webglObject.object; + + if ( object.visible && object.castShadow ) { + + if( object.matrixAutoUpdate ) { + + object.matrixWorld.flattenToArray( object._objectMatrixArray ); + + } + + _currentGeometryGroupHash = -1; + + setupMatrices( object, _cameraLight, false ); + + setObjectFaces( object ); + + program = setProgram( _cameraLight, lights, fog, _depthMaterial, object ); + + if ( object.immediateRenderCallback ) { + + object.immediateRenderCallback( program, _gl, _frustum ); + + } else { + + object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } ); + + } + + } + + } + + //_gl.cullFace( _gl.BACK ); + + j ++; + + } + + } + + }; + + function unrollImmediateBufferMaterial ( globject ) { + + var object = globject.object, + material = object.material; + + if ( material.transparent ) { + + globject.transparent = material; + globject.opaque = null; + + } else { + + globject.opaque = material; + globject.transparent = null; + + } + + }; + + function unrollBufferMaterial ( globject ) { + + var object = globject.object, + buffer = globject.buffer, + material, materialIndex, meshMaterial; + + meshMaterial = object.material; + + if ( meshMaterial instanceof THREE.MeshFaceMaterial ) { + + materialIndex = buffer.materialIndex; + + if ( materialIndex >= 0 ) { + + material = object.geometry.materials[ materialIndex ]; + + if ( material.transparent ) { + + globject.transparent = material; + globject.opaque = null; + + } else { + + globject.opaque = material; + globject.transparent = null; + + } + + } + + } else { + + material = meshMaterial; + + if ( material ) { + + if ( material.transparent ) { + + globject.transparent = material; + globject.opaque = null; + + } else { + + globject.opaque = material; + globject.transparent = null; + + } + + } + + } + + }; + + function renderSprites ( scene, camera ) { var o, ol, object; var attributes = _sprite.attributes; @@ -4703,17 +3973,81 @@ THREE.WebGLRenderer = function ( parameters ) { } - function setupMatrices( object, camera, computeNormalMatrix ) { + // Geometry splitting - object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray ); + function sortFacesByMaterial ( geometry ) { - if ( computeNormalMatrix ) { + var f, fl, face, materialIndex, vertices, + materialHash, groupHash, + hash_map = {}; - THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray ); + var numMorphTargets = geometry.morphTargets.length; + + geometry.geometryGroups = {}; + + for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) { + + face = geometry.faces[ f ]; + materialIndex = face.materialIndex; + + materialHash = ( materialIndex !== undefined ) ? materialIndex : -1; + + if ( hash_map[ materialHash ] === undefined ) { + + hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 }; + + } + + groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter; + + if ( geometry.geometryGroups[ groupHash ] === undefined ) { + + geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets }; + + } + + vertices = face instanceof THREE.Face3 ? 3 : 4; + + if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) { + + hash_map[ materialHash ].counter += 1; + groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter; + + if ( geometry.geometryGroups[ groupHash ] === undefined ) { + + geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets }; + + } + + } + + if ( face instanceof THREE.Face3 ) { + + geometry.geometryGroups[ groupHash ].faces3.push( f ); + + } else { + + geometry.geometryGroups[ groupHash ].faces4.push( f ); + + } + + geometry.geometryGroups[ groupHash ].vertices += vertices; } - } + geometry.geometryGroupsList = []; + + for ( var g in geometry.geometryGroups ) { + + geometry.geometryGroups[ g ].id = _geometryGroupCounter ++; + + geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] ); + + } + + }; + + // Objects refresh this.initWebGLObjects = function ( scene ) { @@ -4749,7 +4083,9 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function addObject( object, scene ) { + // Objects adding + + function addObject ( object, scene ) { var g, geometry, geometryGroup; @@ -4883,29 +4219,34 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function areCustomAttributesDirty( material ) { + function addBuffer ( objlist, buffer, object ) { - for ( var a in material.attributes ) { - - if ( material.attributes[ a ].needsUpdate ) return true; - - } - - return false; + objlist.push( + { + buffer: buffer, + object: object, + opaque: null, + transparent: null + } + ); }; - function clearCustomAttributes( material ) { + function addBufferImmediate ( objlist, object ) { - for ( var a in material.attributes ) { - - material.attributes[ a ].needsUpdate = false; - - } + objlist.push( + { + object: object, + opaque: null, + transparent: null + } + ); }; - function updateObject( object ) { + // Objects updates + + function updateObject ( object ) { var geometry = object.geometry, geometryGroup, customAttributesDirty, material; @@ -4991,35 +4332,33 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function removeInstances( objlist, object ) { + // Objects updates - custom attributes check - for ( var o = objlist.length - 1; o >= 0; o -- ) { + function areCustomAttributesDirty ( material ) { - if ( objlist[ o ].object === object ) { + for ( var a in material.attributes ) { - objlist.splice( o, 1 ); + if ( material.attributes[ a ].needsUpdate ) return true; - } + } + + return false; + + }; + + function clearCustomAttributes ( material ) { + + for ( var a in material.attributes ) { + + material.attributes[ a ].needsUpdate = false; } }; - function removeInstancesDirect( objlist, object ) { + // Objects removal - for ( var o = objlist.length - 1; o >= 0; o -- ) { - - if ( objlist[ o ] === object ) { - - objlist.splice( o, 1 ); - - } - - } - - }; - - function removeObject( object, scene ) { + function removeObject ( object, scene ) { if ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem || @@ -5042,103 +4381,843 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function sortFacesByMaterial( geometry ) { + function removeInstances ( objlist, object ) { - var f, fl, face, materialIndex, vertices, - materialHash, groupHash, - hash_map = {}; + for ( var o = objlist.length - 1; o >= 0; o -- ) { - var numMorphTargets = geometry.morphTargets.length; + if ( objlist[ o ].object === object ) { - geometry.geometryGroups = {}; - - for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) { - - face = geometry.faces[ f ]; - materialIndex = face.materialIndex; - - materialHash = ( materialIndex !== undefined ) ? materialIndex : -1; - - if ( hash_map[ materialHash ] === undefined ) { - - hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 }; + objlist.splice( o, 1 ); } - groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter; + } - if ( geometry.geometryGroups[ groupHash ] === undefined ) { + }; - geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets }; + function removeInstancesDirect ( objlist, object ) { + + for ( var o = objlist.length - 1; o >= 0; o -- ) { + + if ( objlist[ o ] === object ) { + + objlist.splice( o, 1 ); } - vertices = face instanceof THREE.Face3 ? 3 : 4; + } - if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) { + }; - hash_map[ materialHash ].counter += 1; - groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter; + // Materials - if ( geometry.geometryGroups[ groupHash ] === undefined ) { + this.initMaterial = function ( material, lights, fog, object ) { - geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets }; + var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID; + + if ( material instanceof THREE.MeshDepthMaterial ) { + + shaderID = 'depth'; + + } else if ( material instanceof THREE.MeshNormalMaterial ) { + + shaderID = 'normal'; + + } else if ( material instanceof THREE.MeshBasicMaterial ) { + + shaderID = 'basic'; + + } else if ( material instanceof THREE.MeshLambertMaterial ) { + + shaderID = 'lambert'; + + } else if ( material instanceof THREE.MeshPhongMaterial ) { + + shaderID = 'phong'; + + } else if ( material instanceof THREE.LineBasicMaterial ) { + + shaderID = 'basic'; + + } else if ( material instanceof THREE.ParticleBasicMaterial ) { + + shaderID = 'particle_basic'; + + } + + if ( shaderID ) { + + setMaterialShaders( material, THREE.ShaderLib[ shaderID ] ); + + } + + // heuristics to create shader parameters according to lights in the scene + // (not to blow over maxLights budget) + + maxLightCount = allocateLights( lights ); + + maxShadows = allocateShadows( lights ); + + maxBones = allocateBones( object ); + + parameters = { + + map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap, + vertexColors: material.vertexColors, + fog: fog, useFog: material.fog, + sizeAttenuation: material.sizeAttenuation, + skinning: material.skinning, + morphTargets: material.morphTargets, + maxMorphTargets: this.maxMorphTargets, + maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point, + maxBones: maxBones, + shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow, + shadowMapSoft: this.shadowMapSoft, + shadowMapWidth: this.shadowMapWidth, + shadowMapHeight: this.shadowMapHeight, + maxShadows: maxShadows, + alphaTest: material.alphaTest, + metal: material.metal, + perPixel: material.perPixel + + }; + + material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters ); + + var attributes = material.program.attributes; + + if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position ); + if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color ); + if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal ); + if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent ); + + if ( material.skinning && + attributes.skinVertexA >=0 && attributes.skinVertexB >= 0 && + attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) { + + _gl.enableVertexAttribArray( attributes.skinVertexA ); + _gl.enableVertexAttribArray( attributes.skinVertexB ); + _gl.enableVertexAttribArray( attributes.skinIndex ); + _gl.enableVertexAttribArray( attributes.skinWeight ); + + } + + if ( material.attributes ) { + + for ( a in material.attributes ) { + + if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] ); + + } + + } + + if ( material.morphTargets ) { + + material.numSupportedMorphTargets = 0; + + var id, base = "morphTarget"; + + for ( i = 0; i < this.maxMorphTargets; i ++ ) { + + id = base + i; + + if ( attributes[ id ] >= 0 ) { + + _gl.enableVertexAttribArray( attributes[ id ] ); + material.numSupportedMorphTargets ++; } } - if ( face instanceof THREE.Face3 ) { - - geometry.geometryGroups[ groupHash ].faces3.push( f ); - - } else { - - geometry.geometryGroups[ groupHash ].faces4.push( f ); - - } - - geometry.geometryGroups[ groupHash ].vertices += vertices; - } - geometry.geometryGroupsList = []; + material.uniformsList = []; - for ( var g in geometry.geometryGroups ) { + for ( u in material.uniforms ) { - geometry.geometryGroups[ g ].id = _geometryGroupCounter ++; - - geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] ); + material.uniformsList.push( [ material.uniforms[ u ], u ] ); } }; - function addBuffer( objlist, buffer, object ) { + function setMaterialShaders ( material, shaders ) { - objlist.push( - { - buffer: buffer, - object: object, - opaque: null, - transparent: null - } - ); + material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms ); + material.vertexShader = shaders.vertexShader; + material.fragmentShader = shaders.fragmentShader; }; - function addBufferImmediate( objlist, object ) { + function setProgram ( camera, lights, fog, material, object ) { + + if ( ! material.program ) { + + _this.initMaterial( material, lights, fog, object ); + + } + + if ( material.morphTargets ) { + + if ( ! object.__webglMorphTargetInfluences ) { + + object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets ); + + for ( var i = 0, il = _this.maxMorphTargets; i < il; i ++ ) { + + object.__webglMorphTargetInfluences[ i ] = 0; + + } - objlist.push( - { - object: object, - opaque: null, - transparent: null } - ); + + } + + var refreshMaterial = false; + + var program = material.program, + p_uniforms = program.uniforms, + m_uniforms = material.uniforms; + + if ( program !== _currentProgram ) { + + _gl.useProgram( program ); + _currentProgram = program; + + refreshMaterial = true; + + } + + if ( material.id !== _currentMaterialId ) { + + _currentMaterialId = material.id; + refreshMaterial = true; + + } + + if ( refreshMaterial ) { + + _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray ); + + // refresh uniforms common to several materials + + if ( fog && material.fog ) { + + refreshUniformsFog( m_uniforms, fog ); + + } + + if ( material instanceof THREE.MeshPhongMaterial || + material instanceof THREE.MeshLambertMaterial || + material.lights ) { + + setupLights( program, lights ); + refreshUniformsLights( m_uniforms, _lights ); + + } + + if ( material instanceof THREE.MeshBasicMaterial || + material instanceof THREE.MeshLambertMaterial || + material instanceof THREE.MeshPhongMaterial ) { + + refreshUniformsCommon( m_uniforms, material ); + + } + + // refresh single material specific uniforms + + if ( material instanceof THREE.LineBasicMaterial ) { + + refreshUniformsLine( m_uniforms, material ); + + } else if ( material instanceof THREE.ParticleBasicMaterial ) { + + refreshUniformsParticle( m_uniforms, material ); + + } else if ( material instanceof THREE.MeshPhongMaterial ) { + + refreshUniformsPhong( m_uniforms, material ); + + } else if ( material instanceof THREE.MeshLambertMaterial ) { + + refreshUniformsLambert( m_uniforms, material ); + + } else if ( material instanceof THREE.MeshDepthMaterial ) { + + m_uniforms.mNear.value = camera.near; + m_uniforms.mFar.value = camera.far; + m_uniforms.opacity.value = material.opacity; + + } else if ( material instanceof THREE.MeshNormalMaterial ) { + + m_uniforms.opacity.value = material.opacity; + + } + + if ( object.receiveShadow && ! material._shadowPass ) { + + refreshUniformsShadow( m_uniforms, material ); + + } + + // load common uniforms + + loadUniformsGeneric( program, material.uniformsList ); + + // load material specific uniforms + // (shader material also gets them for the sake of genericity) + + if ( material instanceof THREE.ShaderMaterial || + material instanceof THREE.MeshPhongMaterial || + material.envMap ) { + + if( p_uniforms.cameraPosition !== null ) { + + _gl.uniform3f( p_uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z ); + + } + + } + + if ( material instanceof THREE.MeshPhongMaterial || + material instanceof THREE.MeshLambertMaterial || + material instanceof THREE.ShaderMaterial || + material.skinning ) { + + if( p_uniforms.viewMatrix !== null ) { + + _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray ); + + } + + } + + if ( material.skinning ) { + + loadUniformsSkinning( p_uniforms, object ); + + } + + } + + loadUniformsMatrices( p_uniforms, object ); + + if ( material instanceof THREE.ShaderMaterial || + material.envMap || + material.skinning || + object.receiveShadow ) { + + if ( p_uniforms.objectMatrix !== null ) { + + _gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray ); + + } + + } + + return program; }; + // Uniforms (refresh uniforms objects) + + function refreshUniformsCommon ( uniforms, material ) { + + uniforms.opacity.value = material.opacity; + + if ( _this.gammaInput ) { + + uniforms.diffuse.value.copyGammaToLinear( material.color ); + + } else { + + uniforms.diffuse.value = material.color; + + } + + uniforms.map.texture = material.map; + + if ( material.map ) { + + uniforms.offsetRepeat.value.set( material.map.offset.x, material.map.offset.y, material.map.repeat.x, material.map.repeat.y ); + + } + + uniforms.lightMap.texture = material.lightMap; + + uniforms.envMap.texture = material.envMap; + uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1; + + if ( _this.gammaInput ) { + + //uniforms.reflectivity.value = material.reflectivity * material.reflectivity; + uniforms.reflectivity.value = material.reflectivity; + + } else { + + uniforms.reflectivity.value = material.reflectivity; + + } + + uniforms.refractionRatio.value = material.refractionRatio; + uniforms.combine.value = material.combine; + uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping; + + }; + + function refreshUniformsLine ( uniforms, material ) { + + uniforms.diffuse.value = material.color; + uniforms.opacity.value = material.opacity; + + }; + + function refreshUniformsParticle ( uniforms, material ) { + + uniforms.psColor.value = material.color; + uniforms.opacity.value = material.opacity; + uniforms.size.value = material.size; + uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this. + + uniforms.map.texture = material.map; + + }; + + function refreshUniformsFog ( uniforms, fog ) { + + uniforms.fogColor.value = fog.color; + + if ( fog instanceof THREE.Fog ) { + + uniforms.fogNear.value = fog.near; + uniforms.fogFar.value = fog.far; + + } else if ( fog instanceof THREE.FogExp2 ) { + + uniforms.fogDensity.value = fog.density; + + } + + }; + + function refreshUniformsPhong ( uniforms, material ) { + + uniforms.shininess.value = material.shininess; + + if ( _this.gammaInput ) { + + uniforms.ambient.value.copyGammaToLinear( material.ambient ); + uniforms.specular.value.copyGammaToLinear( material.specular ); + + } else { + + uniforms.ambient.value = material.ambient; + uniforms.specular.value = material.specular; + + } + + }; + + function refreshUniformsLambert ( uniforms, material ) { + + if ( _this.gammaInput ) { + + uniforms.ambient.value.copyGammaToLinear( material.ambient ); + + } else { + + uniforms.ambient.value = material.ambient; + + } + + }; + + function refreshUniformsLights ( uniforms, lights ) { + + uniforms.enableLighting.value = lights.directional.length + lights.point.length; + uniforms.ambientLightColor.value = lights.ambient; + + uniforms.directionalLightColor.value = lights.directional.colors; + uniforms.directionalLightDirection.value = lights.directional.positions; + + uniforms.pointLightColor.value = lights.point.colors; + uniforms.pointLightPosition.value = lights.point.positions; + uniforms.pointLightDistance.value = lights.point.distances; + + }; + + function refreshUniformsShadow ( uniforms, material ) { + + if ( uniforms.shadowMatrix ) { + + for ( var i = 0; i < _shadowMatrix.length; i ++ ) { + + uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ]; + uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ]; + + + } + + uniforms.shadowDarkness.value = _this.shadowMapDarkness; + uniforms.shadowBias.value = _this.shadowMapBias; + + } + + }; + + // Uniforms (load to GPU) + + function loadUniformsSkinning ( uniforms, object ) { + + _gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray ); + _gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices ); + + }; + + + function loadUniformsMatrices ( uniforms, object ) { + + _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray ); + + if ( uniforms.normalMatrix ) { + + _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray ); + + } + + }; + + function loadUniformsGeneric ( program, uniforms ) { + + var uniform, value, type, location, texture, i, il, j, jl, offset; + + for( j = 0, jl = uniforms.length; j < jl; j ++ ) { + + location = program.uniforms[ uniforms[ j ][ 1 ] ]; + if ( !location ) continue; + + uniform = uniforms[ j ][ 0 ]; + + type = uniform.type; + value = uniform.value; + + // single integer + + if( type === "i" ) { + + _gl.uniform1i( location, value ); + + // single float + + } else if( type === "f" ) { + + _gl.uniform1f( location, value ); + + // single THREE.Vector2 + + } else if( type === "v2" ) { + + _gl.uniform2f( location, value.x, value.y ); + + // single THREE.Vector3 + + } else if( type === "v3" ) { + + _gl.uniform3f( location, value.x, value.y, value.z ); + + // single THREE.Vector4 + + } else if( type === "v4" ) { + + _gl.uniform4f( location, value.x, value.y, value.z, value.w ); + + // single THREE.Color + + } else if( type === "c" ) { + + _gl.uniform3f( location, value.r, value.g, value.b ); + + // flat array of floats (JS or typed array) + + } else if( type === "fv1" ) { + + _gl.uniform1fv( location, value ); + + // flat array of floats with 3 x N size (JS or typed array) + + } else if( type === "fv" ) { + + _gl.uniform3fv( location, value ); + + // array of THREE.Vector3 + + } else if( type === "v3v" ) { + + if ( ! uniform._array ) { + + uniform._array = new Float32Array( 3 * value.length ); + + } + + for ( i = 0, il = value.length; i < il; i ++ ) { + + offset = i * 3; + + uniform._array[ offset ] = value[ i ].x; + uniform._array[ offset + 1 ] = value[ i ].y; + uniform._array[ offset + 2 ] = value[ i ].z; + + } + + _gl.uniform3fv( location, uniform._array ); + + // single THREE.Matrix4 + + } else if( type === "m4" ) { + + if ( ! uniform._array ) { + + uniform._array = new Float32Array( 16 ); + + } + + value.flattenToArray( uniform._array ); + _gl.uniformMatrix4fv( location, false, uniform._array ); + + // array of THREE.Matrix4 + + } else if( type === "m4v" ) { + + if ( ! uniform._array ) { + + uniform._array = new Float32Array( 16 * value.length ); + + } + + for ( i = 0, il = value.length; i < il; i ++ ) { + + value[ i ].flattenToArrayOffset( uniform._array, i * 16 ); + + } + + _gl.uniformMatrix4fv( location, false, uniform._array ); + + + // single THREE.Texture (2d or cube) + + } else if( type === "t" ) { + + _gl.uniform1i( location, value ); + + texture = uniform.texture; + + if ( !texture ) continue; + + if ( texture.image instanceof Array && texture.image.length === 6 ) { + + setCubeTexture( texture, value ); + + } else if ( texture instanceof THREE.WebGLRenderTargetCube ) { + + setCubeTextureDynamic( texture, value ); + + } else { + + setTexture( texture, value ); + + } + + // array of THREE.Texture (2d) + + } else if( type === "tv" ) { + + if ( ! uniform._array ) { + + uniform._array = []; + + for( i = 0, il = uniform.texture.length; i < il; i ++ ) { + + uniform._array[ i ] = value + i; + + } + + } + + _gl.uniform1iv( location, uniform._array ); + + for( i = 0, il = uniform.texture.length; i < il; i ++ ) { + + texture = uniform.texture[ i ]; + + if ( !texture ) continue; + + setTexture( texture, uniform._array[ i ] ); + + } + + } + + } + + }; + + function setupMatrices ( object, camera, computeNormalMatrix ) { + + object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray ); + + if ( computeNormalMatrix ) { + + THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray ); + + } + + } + + function setupLights ( program, lights ) { + + var l, ll, light, n, + r = 0, g = 0, b = 0, + color, position, intensity, distance, + + zlights = _lights, + + dcolors = zlights.directional.colors, + dpositions = zlights.directional.positions, + + pcolors = zlights.point.colors, + ppositions = zlights.point.positions, + pdistances = zlights.point.distances, + + dlength = 0, + plength = 0, + + doffset = 0, + poffset = 0; + + for ( l = 0, ll = lights.length; l < ll; l ++ ) { + + light = lights[ l ]; + color = light.color; + + position = light.position; + intensity = light.intensity; + distance = light.distance; + + if ( light instanceof THREE.AmbientLight ) { + + if ( _this.gammaInput ) { + + r += color.r * color.r; + g += color.g * color.g; + b += color.b * color.b; + + } else { + + r += color.r; + g += color.g; + b += color.b; + + } + + } else if ( light instanceof THREE.DirectionalLight ) { + + doffset = dlength * 3; + + if ( _this.gammaInput ) { + + dcolors[ doffset ] = color.r * color.r * intensity * intensity; + dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity; + dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity; + + } else { + + dcolors[ doffset ] = color.r * intensity; + dcolors[ doffset + 1 ] = color.g * intensity; + dcolors[ doffset + 2 ] = color.b * intensity; + + } + + dpositions[ doffset ] = position.x; + dpositions[ doffset + 1 ] = position.y; + dpositions[ doffset + 2 ] = position.z; + + dlength += 1; + + } else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight + + doffset = dlength * 3; + + if ( _this.gammaInput ) { + + dcolors[ doffset ] = color.r * color.r * intensity * intensity; + dcolors[ doffset + 1 ] = color.g * color.g * intensity * intensity; + dcolors[ doffset + 2 ] = color.b * color.b * intensity * intensity; + + } else { + + dcolors[ doffset ] = color.r * intensity; + dcolors[ doffset + 1 ] = color.g * intensity; + dcolors[ doffset + 2 ] = color.b * intensity; + + } + + n = 1 / position.length(); + + dpositions[ doffset ] = position.x * n; + dpositions[ doffset + 1 ] = position.y * n; + dpositions[ doffset + 2 ] = position.z * n; + + dlength += 1; + + } else if( light instanceof THREE.PointLight ) { + + poffset = plength * 3; + + if ( _this.gammaInput ) { + + pcolors[ poffset ] = color.r * color.r * intensity * intensity; + pcolors[ poffset + 1 ] = color.g * color.g * intensity * intensity; + pcolors[ poffset + 2 ] = color.b * color.b * intensity * intensity; + + } else { + + pcolors[ poffset ] = color.r * intensity; + pcolors[ poffset + 1 ] = color.g * intensity; + pcolors[ poffset + 2 ] = color.b * intensity; + + } + + ppositions[ poffset ] = position.x; + ppositions[ poffset + 1 ] = position.y; + ppositions[ poffset + 2 ] = position.z; + + pdistances[ plength ] = distance; + + plength += 1; + + } + + } + + // null eventual remains from removed lights + // (this is to avoid if in shader) + + for ( l = dlength * 3, ll = dcolors.length; l < ll; l ++ ) dcolors[ l ] = 0.0; + for ( l = plength * 3, ll = pcolors.length; l < ll; l ++ ) pcolors[ l ] = 0.0; + + zlights.point.length = plength; + zlights.directional.length = dlength; + + zlights.ambient[ 0 ] = r; + zlights.ambient[ 1 ] = g; + zlights.ambient[ 2 ] = b; + + }; + + // GL state setting + this.setFaceCulling = function ( cullFace, frontFace ) { if ( cullFace ) { @@ -5177,19 +5256,163 @@ THREE.WebGLRenderer = function ( parameters ) { }; - this.supportsVertexTextures = function () { + function setLineWidth ( width ) { - return _supportsVertexTextures; + if ( width !== _oldLineWidth ) { + + _gl.lineWidth( width ); + + _oldLineWidth = width; + + } }; - function maxVertexTextures() { + function setObjectFaces ( object ) { - return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); + if ( _oldDoubleSided !== object.doubleSided ) { + + if( object.doubleSided ) { + + _gl.disable( _gl.CULL_FACE ); + + } else { + + _gl.enable( _gl.CULL_FACE ); + + } + + _oldDoubleSided = object.doubleSided; + + } + + if ( _oldFlipSided !== object.flipSided ) { + + if( object.flipSided ) { + + _gl.frontFace( _gl.CW ); + + } else { + + _gl.frontFace( _gl.CCW ); + + } + + _oldFlipSided = object.flipSided; + + } }; - function buildProgram( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) { + function setDepthTest ( depthTest ) { + + if ( _oldDepthTest !== depthTest ) { + + if( depthTest ) { + + _gl.enable( _gl.DEPTH_TEST ); + + } else { + + _gl.disable( _gl.DEPTH_TEST ); + + } + + _oldDepthTest = depthTest; + + } + + }; + + function setDepthWrite ( depthWrite ) { + + if ( _oldDepthWrite !== depthWrite ) { + + _gl.depthMask( depthWrite ); + _oldDepthWrite = depthWrite; + + } + + }; + + function setPolygonOffset ( polygonoffset, factor, units ) { + + if ( _oldPolygonOffset !== polygonoffset ) { + + if ( polygonoffset ) { + + _gl.enable( _gl.POLYGON_OFFSET_FILL ); + + } else { + + _gl.disable( _gl.POLYGON_OFFSET_FILL ); + + } + + _oldPolygonOffset = polygonoffset; + + } + + if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) { + + _gl.polygonOffset( factor, units ); + + _oldPolygonOffsetFactor = factor; + _oldPolygonOffsetUnits = units; + + } + + }; + + function setBlending ( blending ) { + + if ( blending !== _oldBlending ) { + + switch ( blending ) { + + case THREE.AdditiveBlending: + + _gl.blendEquation( _gl.FUNC_ADD ); + _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); + + break; + + case THREE.SubtractiveBlending: + + // TODO: Find blendFuncSeparate() combination + + _gl.blendEquation( _gl.FUNC_ADD ); + _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR ); + + break; + + case THREE.MultiplyBlending: + + // TODO: Find blendFuncSeparate() combination + + _gl.blendEquation( _gl.FUNC_ADD ); + _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR ); + + break; + + default: + + _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD ); + _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA ); + + break; + + } + + _oldBlending = blending; + + } + + }; + + // Shaders + + function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) { var p, pl, program, code; var chunks = []; @@ -5418,247 +5641,66 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function loadUniformsSkinning( uniforms, object ) { + // Shader parameters cache - _gl.uniformMatrix4fv( uniforms.cameraInverseMatrix, false, _viewMatrixArray ); - _gl.uniformMatrix4fv( uniforms.boneGlobalMatrices, false, object.boneMatrices ); + function cacheUniformLocations ( program, identifiers ) { - }; + var i, l, id; + for( i = 0, l = identifiers.length; i < l; i++ ) { - function loadUniformsMatrices( uniforms, object ) { - - _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray ); - - if ( uniforms.normalMatrix ) { - - _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrixArray ); + id = identifiers[ i ]; + program.uniforms[ id ] = _gl.getUniformLocation( program, id ); } }; - function loadUniformsGeneric( program, uniforms ) { + function cacheAttributeLocations ( program, identifiers ) { - var uniform, value, type, location, texture, i, il, j, jl, offset; + var i, l, id; - for( j = 0, jl = uniforms.length; j < jl; j ++ ) { + for( i = 0, l = identifiers.length; i < l; i++ ) { - location = program.uniforms[ uniforms[ j ][ 1 ] ]; - if ( !location ) continue; - - uniform = uniforms[ j ][ 0 ]; - - type = uniform.type; - value = uniform.value; - - // single integer - - if( type === "i" ) { - - _gl.uniform1i( location, value ); - - // single float - - } else if( type === "f" ) { - - _gl.uniform1f( location, value ); - - // single THREE.Vector2 - - } else if( type === "v2" ) { - - _gl.uniform2f( location, value.x, value.y ); - - // single THREE.Vector3 - - } else if( type === "v3" ) { - - _gl.uniform3f( location, value.x, value.y, value.z ); - - // single THREE.Vector4 - - } else if( type === "v4" ) { - - _gl.uniform4f( location, value.x, value.y, value.z, value.w ); - - // single THREE.Color - - } else if( type === "c" ) { - - _gl.uniform3f( location, value.r, value.g, value.b ); - - // flat array of floats (JS or typed array) - - } else if( type === "fv1" ) { - - _gl.uniform1fv( location, value ); - - // flat array of floats with 3 x N size (JS or typed array) - - } else if( type === "fv" ) { - - _gl.uniform3fv( location, value ); - - // array of THREE.Vector3 - - } else if( type === "v3v" ) { - - if ( ! uniform._array ) { - - uniform._array = new Float32Array( 3 * value.length ); - - } - - for ( i = 0, il = value.length; i < il; i ++ ) { - - offset = i * 3; - - uniform._array[ offset ] = value[ i ].x; - uniform._array[ offset + 1 ] = value[ i ].y; - uniform._array[ offset + 2 ] = value[ i ].z; - - } - - _gl.uniform3fv( location, uniform._array ); - - // single THREE.Matrix4 - - } else if( type === "m4" ) { - - if ( ! uniform._array ) { - - uniform._array = new Float32Array( 16 ); - - } - - value.flattenToArray( uniform._array ); - _gl.uniformMatrix4fv( location, false, uniform._array ); - - // array of THREE.Matrix4 - - } else if( type === "m4v" ) { - - if ( ! uniform._array ) { - - uniform._array = new Float32Array( 16 * value.length ); - - } - - for ( i = 0, il = value.length; i < il; i ++ ) { - - value[ i ].flattenToArrayOffset( uniform._array, i * 16 ); - - } - - _gl.uniformMatrix4fv( location, false, uniform._array ); - - - // single THREE.Texture (2d or cube) - - } else if( type === "t" ) { - - _gl.uniform1i( location, value ); - - texture = uniform.texture; - - if ( !texture ) continue; - - if ( texture.image instanceof Array && texture.image.length === 6 ) { - - setCubeTexture( texture, value ); - - } else if ( texture instanceof THREE.WebGLRenderTargetCube ) { - - setCubeTextureDynamic( texture, value ); - - } else { - - setTexture( texture, value ); - - } - - // array of THREE.Texture (2d) - - } else if( type === "tv" ) { - - if ( ! uniform._array ) { - - uniform._array = []; - - for( i = 0, il = uniform.texture.length; i < il; i ++ ) { - - uniform._array[ i ] = value + i; - - } - - } - - _gl.uniform1iv( location, uniform._array ); - - for( i = 0, il = uniform.texture.length; i < il; i ++ ) { - - texture = uniform.texture[ i ]; - - if ( !texture ) continue; - - setTexture( texture, uniform._array[ i ] ); - - } - - } + id = identifiers[ i ]; + program.attributes[ id ] = _gl.getAttribLocation( program, id ); } }; - function setBlending( blending ) { + function getShader ( type, string ) { - if ( blending !== _oldBlending ) { + var shader; - switch ( blending ) { + if ( type === "fragment" ) { - case THREE.AdditiveBlending: + shader = _gl.createShader( _gl.FRAGMENT_SHADER ); - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); + } else if ( type === "vertex" ) { - break; - - case THREE.SubtractiveBlending: - - // TODO: Find blendFuncSeparate() combination - - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR ); - - break; - - case THREE.MultiplyBlending: - - // TODO: Find blendFuncSeparate() combination - - _gl.blendEquation( _gl.FUNC_ADD ); - _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR ); - - break; - - default: - - _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD ); - _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA ); - - break; - - } - - _oldBlending = blending; + shader = _gl.createShader( _gl.VERTEX_SHADER ); } + _gl.shaderSource( shader, string ); + _gl.compileShader( shader ); + + if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) { + + console.error( _gl.getShaderInfoLog( shader ) ); + console.error( string ); + return null; + + } + + return shader; + }; - function setTextureParameters( textureType, texture, image ) { + // Textures + + function setTextureParameters ( textureType, texture, image ) { if ( isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ) ) { @@ -5682,7 +5724,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function setTexture( texture, slot ) { + function setTexture ( texture, slot ) { if ( texture.needsUpdate ) { @@ -5721,7 +5763,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function setCubeTexture( texture, slot ) { + function setCubeTexture ( texture, slot ) { if ( texture.image.length === 6 ) { @@ -5757,21 +5799,23 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function setCubeTextureDynamic( texture, slot ) { + function setCubeTextureDynamic ( texture, slot ) { _gl.activeTexture( _gl.TEXTURE0 + slot ); _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture ); }; - function setupFrameBuffer( framebuffer, renderTarget, textureTarget ) { + // Render targets + + function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) { _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 ); }; - function setupRenderBuffer( renderbuffer, renderTarget ) { + function setupRenderBuffer ( renderbuffer, renderTarget ) { _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer ); @@ -5799,7 +5843,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function setRenderTarget( renderTarget ) { + function setRenderTarget ( renderTarget ) { var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); @@ -5911,7 +5955,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function updateRenderTargetMipmap( renderTarget ) { + function updateRenderTargetMipmap ( renderTarget ) { if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) { @@ -5929,64 +5973,9 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function cacheUniformLocations( program, identifiers ) { - - var i, l, id; - - for( i = 0, l = identifiers.length; i < l; i++ ) { - - id = identifiers[ i ]; - program.uniforms[ id ] = _gl.getUniformLocation( program, id ); - - } - - }; - - function cacheAttributeLocations( program, identifiers ) { - - var i, l, id; - - for( i = 0, l = identifiers.length; i < l; i++ ) { - - id = identifiers[ i ]; - program.attributes[ id ] = _gl.getAttribLocation( program, id ); - - } - - }; - - function getShader( type, string ) { - - var shader; - - if ( type === "fragment" ) { - - shader = _gl.createShader( _gl.FRAGMENT_SHADER ); - - } else if ( type === "vertex" ) { - - shader = _gl.createShader( _gl.VERTEX_SHADER ); - - } - - _gl.shaderSource( shader, string ); - _gl.compileShader( shader ); - - if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) { - - console.error( _gl.getShaderInfoLog( shader ) ); - console.error( string ); - return null; - - } - - return shader; - - }; - // fallback filters for non-power-of-2 textures - function filterFallback( f ) { + function filterFallback ( f ) { switch ( f ) { @@ -6005,7 +5994,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function paramThreeToGL( p ) { + function paramThreeToGL ( p ) { switch ( p ) { @@ -6041,67 +6030,15 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function isPowerOfTwo( value ) { + function isPowerOfTwo ( value ) { return ( value & ( value - 1 ) ) === 0; }; - function materialNeedsSmoothNormals( material ) { + // Allocations - return material && material.shading !== undefined && material.shading === THREE.SmoothShading; - - }; - - function bufferGuessVertexColorType( material ) { - - if ( material.vertexColors ) { - - return material.vertexColors; - - } - - return false; - - }; - - function bufferGuessNormalType( material ) { - - // only MeshBasicMaterial and MeshDepthMaterial don't need normals - - if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) { - - return false; - - } - - if ( materialNeedsSmoothNormals( material ) ) { - - return THREE.SmoothShading; - - } else { - - return THREE.FlatShading; - - } - - }; - - function bufferGuessUVType( material ) { - - // material must use some texture to require uvs - - if ( material.map || material.lightMap || material instanceof THREE.ShaderMaterial ) { - - return true; - - } - - return false; - - }; - - function allocateBones( object ) { + function allocateBones ( object ) { // default for when object is not specified // ( for example when prebuilding shader @@ -6123,7 +6060,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function allocateLights( lights ) { + function allocateLights ( lights ) { var l, ll, light, dirLights, pointLights, maxDirLights, maxPointLights; dirLights = pointLights = maxDirLights = maxPointLights = 0; @@ -6154,7 +6091,7 @@ THREE.WebGLRenderer = function ( parameters ) { }; - function allocateShadows( lights ) { + function allocateShadows ( lights ) { var l, ll, light, maxShadows = 0; @@ -6170,36 +6107,142 @@ THREE.WebGLRenderer = function ( parameters ) { }; + function maxVertexTextures () { - /* DEBUG - function getGLParams() { + return _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); - var params = { - - 'MAX_VARYING_VECTORS': _gl.getParameter( _gl.MAX_VARYING_VECTORS ), - 'MAX_VERTEX_ATTRIBS': _gl.getParameter( _gl.MAX_VERTEX_ATTRIBS ), - - 'MAX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ), - 'MAX_VERTEX_TEXTURE_IMAGE_UNITS': _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ), - 'MAX_COMBINED_TEXTURE_IMAGE_UNITS' : _gl.getParameter( _gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS ), - - 'MAX_VERTEX_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS ), - 'MAX_FRAGMENT_UNIFORM_VECTORS': _gl.getParameter( _gl.MAX_FRAGMENT_UNIFORM_VECTORS ) - } - - return params; }; - function dumpObject( obj ) { + // Initialization - var p, str = ""; - for ( p in obj ) { + function initSprites () { - str += p + ": " + obj[p] + "\n"; + _sprite.vertices = new Float32Array( 8 + 8 ); + _sprite.faces = new Uint16Array( 6 ); + + var i = 0; + + _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1; // vertex 0 + _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 1; // uv 0 + + _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = -1; // vertex 1 + _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // uv 1 + + _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 1; // vertex 2 + _sprite.vertices[ i++ ] = 1; _sprite.vertices[ i++ ] = 0; // uv 2 + + _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1; // vertex 3 + _sprite.vertices[ i++ ] = 0; _sprite.vertices[ i++ ] = 0; // uv 3 + + i = 0; + + _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2; + _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3; + + _sprite.vertexBuffer = _gl.createBuffer(); + _sprite.elementBuffer = _gl.createBuffer(); + + _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer ); + _gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW ); + + _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer ); + _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW ); + + _sprite.program = _gl.createProgram(); + _gl.attachShader( _sprite.program, getShader( "fragment", THREE.ShaderLib.sprite.fragmentShader ) ); + _gl.attachShader( _sprite.program, getShader( "vertex", THREE.ShaderLib.sprite.vertexShader ) ); + _gl.linkProgram( _sprite.program ); + + _sprite.attributes = {}; + _sprite.uniforms = {}; + + _sprite.attributes.position = _gl.getAttribLocation ( _sprite.program, "position" ); + _sprite.attributes.uv = _gl.getAttribLocation ( _sprite.program, "uv" ); + + _sprite.uniforms.uvOffset = _gl.getUniformLocation( _sprite.program, "uvOffset" ); + _sprite.uniforms.uvScale = _gl.getUniformLocation( _sprite.program, "uvScale" ); + + _sprite.uniforms.rotation = _gl.getUniformLocation( _sprite.program, "rotation" ); + _sprite.uniforms.scale = _gl.getUniformLocation( _sprite.program, "scale" ); + _sprite.uniforms.alignment = _gl.getUniformLocation( _sprite.program, "alignment" ); + + _sprite.uniforms.color = _gl.getUniformLocation( _sprite.program, "color" ); + _sprite.uniforms.map = _gl.getUniformLocation( _sprite.program, "map" ); + _sprite.uniforms.opacity = _gl.getUniformLocation( _sprite.program, "opacity" ); + + _sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" ); + _sprite.uniforms.affectedByDistance = _gl.getUniformLocation( _sprite.program, "affectedByDistance" ); + _sprite.uniforms.screenPosition = _gl.getUniformLocation( _sprite.program, "screenPosition" ); + _sprite.uniforms.modelViewMatrix = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" ); + _sprite.uniforms.projectionMatrix = _gl.getUniformLocation( _sprite.program, "projectionMatrix" ); + + //_gl.enableVertexAttribArray( _sprite.attributes.position ); + //_gl.enableVertexAttribArray( _sprite.attributes.uv ); + + }; + + function initShadowmaps () { + + var depthShader = THREE.ShaderLib[ "depthRGBA" ]; + var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms ); + + _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } ); + _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } ); + + _depthMaterial._shadowPass = true; + _depthMaterialMorph._shadowPass = true; + + } + + function initGL () { + + var gl; + + try { + + if ( ! ( gl = _canvas.getContext( 'experimental-webgl', { antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) { + + throw 'Error creating WebGL context.'; + + } + + console.log( + navigator.userAgent + " | " + + gl.getParameter( gl.VERSION ) + " | " + + gl.getParameter( gl.VENDOR ) + " | " + + gl.getParameter( gl.RENDERER ) + " | " + + gl.getParameter( gl.SHADING_LANGUAGE_VERSION ) + ); + + } catch ( error ) { + + console.error( error ); } - return str; - } - */ + return gl; + + }; + + function setDefaultGLState () { + + _gl.clearColor( 0, 0, 0, 1 ); + _gl.clearDepth( 1 ); + _gl.clearStencil( 0 ); + + _gl.enable( _gl.DEPTH_TEST ); + _gl.depthFunc( _gl.LEQUAL ); + + _gl.frontFace( _gl.CCW ); + _gl.cullFace( _gl.BACK ); + _gl.enable( _gl.CULL_FACE ); + + _gl.enable( _gl.BLEND ); + _gl.blendEquation( _gl.FUNC_ADD ); + _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA ); + + _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha ); + + }; + };