h;h++)g[h]=!X.autoScaleCubemaps||d||e?e?a.image[h].image:a.image[h]:D(a.image[h],da.maxCubemapSize);var k=z(g[0]),l=L(a.format),m=L(a.type);x(r.TEXTURE_CUBE_MAP,a,k);for(h=0;6>h;h++)if(d)for(var n,p=g[h].mipmaps,q=0,s=p.length;q<s;q++)n=p[q],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<K.getCompressedTextureFormats().indexOf(l)?K.compressedTexImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,q,l,
n.width,n.height,0,n.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()"):K.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,q,l,n.width,n.height,0,l,m,n.data);else e?K.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,g[h].width,g[h].height,0,l,m,g[h].data):K.texImage2D(r.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,l,m,g[h]);a.generateMipmaps&&k&&r.generateMipmap(r.TEXTURE_CUBE_MAP);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}else K.activeTexture(r.TEXTURE0+
b),K.bindTexture(r.TEXTURE_CUBE_MAP,c.__image__webglTextureCube)}function B(a,b){K.activeTexture(r.TEXTURE0+b);K.bindTexture(r.TEXTURE_CUBE_MAP,U.get(a).__webglTexture)}function G(a,b,c,d){var e=L(b.texture.format),g=L(b.texture.type);K.texImage2D(d,0,e,b.width,b.height,0,e,g,null);r.bindFramebuffer(r.FRAMEBUFFER,a);r.framebufferTexture2D(r.FRAMEBUFFER,c,d,U.get(b.texture).__webglTexture,0);r.bindFramebuffer(r.FRAMEBUFFER,null)}function F(a,b){r.bindRenderbuffer(r.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?
(r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_COMPONENT16,b.width,b.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_ATTACHMENT,r.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_STENCIL,b.width,b.height),r.framebufferRenderbuffer(r.FRAMEBUFFER,r.DEPTH_STENCIL_ATTACHMENT,r.RENDERBUFFER,a)):r.renderbufferStorage(r.RENDERBUFFER,r.RGBA4,b.width,b.height);r.bindRenderbuffer(r.RENDERBUFFER,null)}function H(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||
a===THREE.NearestMipMapLinearFilter?r.NEAREST:r.LINEAR}function L(a){var b;if(a===THREE.RepeatWrapping)return r.REPEAT;if(a===THREE.ClampToEdgeWrapping)return r.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return r.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return r.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return r.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return r.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return r.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return r.LINEAR_MIPMAP_NEAREST;
if(a===THREE.LinearMipMapLinearFilter)return r.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return r.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return r.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return r.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return r.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return r.BYTE;if(a===THREE.ShortType)return r.SHORT;if(a===THREE.UnsignedShortType)return r.UNSIGNED_SHORT;if(a===THREE.IntType)return r.INT;if(a===THREE.UnsignedIntType)return r.UNSIGNED_INT;
if(a===THREE.FloatType)return r.FLOAT;b=V.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return r.ALPHA;if(a===THREE.RGBFormat)return r.RGB;if(a===THREE.RGBAFormat)return r.RGBA;if(a===THREE.LuminanceFormat)return r.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return r.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return r.FUNC_ADD;if(a===THREE.SubtractEquation)return r.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return r.FUNC_REVERSE_SUBTRACT;
if(a===THREE.ZeroFactor)return r.ZERO;if(a===THREE.OneFactor)return r.ONE;if(a===THREE.SrcColorFactor)return r.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return r.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return r.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return r.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return r.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return r.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return r.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return r.ONE_MINUS_DST_COLOR;
if(a===THREE.SrcAlphaSaturateFactor)return r.SRC_ALPHA_SATURATE;b=V.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=V.get("WEBGL_compressed_texture_pvrtc");if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=V.get("WEBGL_compressed_texture_etc1");if(null!==b&&a===THREE.RGB_ETC1_Format)return b.COMPRESSED_RGB_ETC1_WEBGL;b=V.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT;if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",
THREE.REVISION);a=a||{};var A=void 0!==a.canvas?a.canvas:document.createElement("canvas"),N=void 0!==a.context?a.context:null,M=void 0!==a.alpha?a.alpha:!1,I=void 0!==a.depth?a.depth:!0,O=void 0!==a.stencil?a.stencil:!0,Q=void 0!==a.antialias?a.antialias:!1,P=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,T=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,J=[],C=[],Z=-1,S=[],Y=-1,$=new Float32Array(8),ja=[],ea=[];this.domElement=A;this.context=null;this.sortObjects=this.autoClearStencil=
this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.physicallyCorrectLights=this.gammaOutput=this.gammaInput=!1;this.toneMapping=THREE.LinearToneMapping;this.toneMappingWhitePoint=this.toneMappingExposure=1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;var X=this,ha=null,ca=null,ua=null,ra=-1,na="",ma=null,qa=new THREE.Vector4,Aa=null,ka=new THREE.Vector4,ta=0,ba=new THREE.Color(0),ga=0,va=A.width,wa=A.height,aa=1,ya=new THREE.Vector4(0,0,va,
wa),Ba=!1,la=new THREE.Vector4(0,0,va,wa),za=new THREE.Frustum,sa=new THREE.Matrix4,W=new THREE.Vector3,R={hash:"",ambient:[0,0,0],directional:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotShadowMap:[],spotShadowMatrix:[],point:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],shadows:[],shadowsPointLight:0},ia={geometries:0,textures:0},fa={calls:0,vertices:0,faces:0,points:0};this.info={render:fa,memory:ia,programs:null};var r;try{M={alpha:M,depth:I,stencil:O,antialias:Q,premultipliedAlpha:P,
preserveDrawingBuffer:T};r=N||A.getContext("webgl",M)||A.getContext("experimental-webgl",M);if(null===r){if(null!==A.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}void 0===r.getShaderPrecisionFormat&&(r.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});A.addEventListener("webglcontextlost",e,!1)}catch(Da){console.error("THREE.WebGLRenderer: "+Da)}var V=new THREE.WebGLExtensions(r);V.get("OES_texture_float");
V.get("OES_texture_float_linear");V.get("OES_texture_half_float");V.get("OES_texture_half_float_linear");V.get("OES_standard_derivatives");V.get("ANGLE_instanced_arrays");V.get("OES_element_index_uint")&&(THREE.BufferGeometry.MaxIndex=4294967296);var da=new THREE.WebGLCapabilities(r,V,a),K=new THREE.WebGLState(r,V,L),U=new THREE.WebGLProperties,pa=new THREE.WebGLObjects(r,U,this.info),oa=new THREE.WebGLPrograms(this,da),xa=new THREE.WebGLLights;this.info.programs=oa.programs;var Ea=new THREE.WebGLBufferRenderer(r,
V,fa),Fa=new THREE.WebGLIndexedBufferRenderer(r,V,fa);c();this.context=r;this.capabilities=da;this.extensions=V;this.properties=U;this.state=K;var Ca=new THREE.WebGLShadowMap(this,R,pa);this.shadowMap=Ca;var Ga=new THREE.SpritePlugin(this,ja),Ha=new THREE.LensFlarePlugin(this,ea);this.getContext=function(){return r};this.getContextAttributes=function(){return r.getContextAttributes()};this.forceContextLoss=function(){V.get("WEBGL_lose_context").loseContext()};this.getMaxAnisotropy=function(){var a;
return function(){if(void 0!==a)return a;var b=V.get("EXT_texture_filter_anisotropic");return a=null!==b?r.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT):0}}();this.getPrecision=function(){return da.precision};this.getPixelRatio=function(){return aa};this.setPixelRatio=function(a){void 0!==a&&(aa=a,this.setSize(la.z,la.w,!1))};this.getSize=function(){return{width:va,height:wa}};this.setSize=function(a,b,c){va=a;wa=b;A.width=a*aa;A.height=b*aa;!1!==c&&(A.style.width=a+"px",A.style.height=b+"px");this.setViewport(0,
0,a,b)};this.setViewport=function(a,b,c,d){K.viewport(la.set(a,b,c,d))};this.setScissor=function(a,b,c,d){K.scissor(ya.set(a,b,c,d))};this.setScissorTest=function(a){K.setScissorTest(Ba=a)};this.getClearColor=function(){return ba};this.setClearColor=function(a,c){ba.set(a);ga=void 0!==c?c:1;b(ba.r,ba.g,ba.b,ga)};this.getClearAlpha=function(){return ga};this.setClearAlpha=function(a){ga=a;b(ba.r,ba.g,ba.b,ga)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=r.COLOR_BUFFER_BIT;if(void 0===b||
b)d|=r.DEPTH_BUFFER_BIT;if(void 0===c||c)d|=r.STENCIL_BUFFER_BIT;r.clear(d)};this.clearColor=function(){this.clear(!0,!1,!1)};this.clearDepth=function(){this.clear(!1,!0,!1)};this.clearStencil=function(){this.clear(!1,!1,!0)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){A.removeEventListener("webglcontextlost",e,!1)};this.renderBufferImmediate=function(a,b,c){K.initAttributes();var d=U.get(a);a.hasPositions&&!d.position&&
(d.position=r.createBuffer());a.hasNormals&&!d.normal&&(d.normal=r.createBuffer());a.hasUvs&&!d.uv&&(d.uv=r.createBuffer());a.hasColors&&!d.color&&(d.color=r.createBuffer());b=b.getAttributes();a.hasPositions&&(r.bindBuffer(r.ARRAY_BUFFER,d.position),r.bufferData(r.ARRAY_BUFFER,a.positionArray,r.DYNAMIC_DRAW),K.enableAttribute(b.position),r.vertexAttribPointer(b.position,3,r.FLOAT,!1,0,0));if(a.hasNormals){r.bindBuffer(r.ARRAY_BUFFER,d.normal);if("MeshPhongMaterial"!==c.type&&"MeshStandardMaterial"!==
c.type&&c.shading===THREE.FlatShading)for(var e=0,g=3*a.count;e<g;e+=9){var f=a.normalArray,h=(f[e+0]+f[e+3]+f[e+6])/3,k=(f[e+1]+f[e+4]+f[e+7])/3,l=(f[e+2]+f[e+5]+f[e+8])/3;f[e+0]=h;f[e+1]=k;f[e+2]=l;f[e+3]=h;f[e+4]=k;f[e+5]=l;f[e+6]=h;f[e+7]=k;f[e+8]=l}r.bufferData(r.ARRAY_BUFFER,a.normalArray,r.DYNAMIC_DRAW);K.enableAttribute(b.normal);r.vertexAttribPointer(b.normal,3,r.FLOAT,!1,0,0)}a.hasUvs&&c.map&&(r.bindBuffer(r.ARRAY_BUFFER,d.uv),r.bufferData(r.ARRAY_BUFFER,a.uvArray,r.DYNAMIC_DRAW),K.enableAttribute(b.uv),
r.vertexAttribPointer(b.uv,2,r.FLOAT,!1,0,0));a.hasColors&&c.vertexColors!==THREE.NoColors&&(r.bindBuffer(r.ARRAY_BUFFER,d.color),r.bufferData(r.ARRAY_BUFFER,a.colorArray,r.DYNAMIC_DRAW),K.enableAttribute(b.color),r.vertexAttribPointer(b.color,3,r.FLOAT,!1,0,0));K.disableUnusedAttributes();r.drawArrays(r.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,b,c,d,e,g){v(d);var f=t(a,b,d,e),h=!1;a=c.id+"_"+f.id+"_"+d.wireframe;a!==na&&(na=a,h=!0);b=e.morphTargetInfluences;if(void 0!==
b){a=[];for(var k=0,h=b.length;k<h;k++){var m=b[k];a.push([m,k])}a.sort(l);8<a.length&&(a.length=8);for(var n=c.morphAttributes,k=0,h=a.length;k<h;k++)m=a[k],$[k]=m[0],0!==m[0]?(b=m[1],!0===d.morphTargets&&n.position&&c.addAttribute("morphTarget"+k,n.position[b]),!0===d.morphNormals&&n.normal&&c.addAttribute("morphNormal"+k,n.normal[b])):(!0===d.morphTargets&&c.removeAttribute("morphTarget"+k),!0===d.morphNormals&&c.removeAttribute("morphNormal"+k));a=f.getUniforms();null!==a.morphTargetInfluences&&
r.uniform1fv(a.morphTargetInfluences,$);h=!0}b=c.index;k=c.attributes.position;!0===d.wireframe&&(b=pa.getWireframeAttribute(c));null!==b?(a=Fa,a.setIndex(b)):a=Ea;if(h){a:{var h=void 0,p;if(c instanceof THREE.InstancedBufferGeometry&&(p=V.get("ANGLE_instanced_arrays"),null===p)){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");break a}void 0===h&&(h=0);K.initAttributes();var m=c.attributes,
f=f.getAttributes(),n=d.defaultAttributeValues,q;for(q in f){var s=f[q];if(0<=s){var u=m[q];if(void 0!==u){var x=u.itemSize,w=pa.getAttributeBuffer(u);if(u instanceof THREE.InterleavedBufferAttribute){var E=u.data,z=E.stride,u=u.offset;E instanceof THREE.InstancedInterleavedBuffer?(K.enableAttributeAndDivisor(s,E.meshPerAttribute,p),void 0===c.maxInstancedCount&&(c.maxInstancedCount=E.meshPerAttribute*E.count)):K.enableAttribute(s);r.bindBuffer(r.ARRAY_BUFFER,w);r.vertexAttribPointer(s,x,r.FLOAT,
!1,z*E.array.BYTES_PER_ELEMENT,(h*z+u)*E.array.BYTES_PER_ELEMENT)}else u instanceof THREE.InstancedBufferAttribute?(K.enableAttributeAndDivisor(s,u.meshPerAttribute,p),void 0===c.maxInstancedCount&&(c.maxInstancedCount=u.meshPerAttribute*u.count)):K.enableAttribute(s),r.bindBuffer(r.ARRAY_BUFFER,w),r.vertexAttribPointer(s,x,r.FLOAT,!1,0,h*x*4)}else if(void 0!==n&&(x=n[q],void 0!==x))switch(x.length){case 2:r.vertexAttrib2fv(s,x);break;case 3:r.vertexAttrib3fv(s,x);break;case 4:r.vertexAttrib4fv(s,
x);break;default:r.vertexAttrib1fv(s,x)}}}K.disableUnusedAttributes()}null!==b&&r.bindBuffer(r.ELEMENT_ARRAY_BUFFER,pa.getAttributeBuffer(b))}p=Infinity;null!==b?p=b.count:void 0!==k&&(p=k.count);q=c.drawRange.start;b=c.drawRange.count;k=null!==g?g.start:0;h=null!==g?g.count:Infinity;g=Math.max(0,q,k);p=Math.min(0+p,q+b,k+h)-1;p=Math.max(0,p-g+1);if(e instanceof THREE.Mesh)if(!0===d.wireframe)K.setLineWidth(d.wireframeLinewidth*(null===ca?aa:1)),a.setMode(r.LINES);else switch(e.drawMode){case THREE.TrianglesDrawMode:a.setMode(r.TRIANGLES);
break;case THREE.TriangleStripDrawMode:a.setMode(r.TRIANGLE_STRIP);break;case THREE.TriangleFanDrawMode:a.setMode(r.TRIANGLE_FAN)}else e instanceof THREE.Line?(d=d.linewidth,void 0===d&&(d=1),K.setLineWidth(d*(null===ca?aa:1)),e instanceof THREE.LineSegments?a.setMode(r.LINES):a.setMode(r.LINE_STRIP)):e instanceof THREE.Points&&a.setMode(r.POINTS);c instanceof THREE.InstancedBufferGeometry?0<c.maxInstancedCount&&a.renderInstances(c,g,p):a.render(g,p)};this.render=function(a,b,c,d){if(!1===b instanceof
THREE.Camera)console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");else{var e=a.fog;na="";ra=-1;ma=null;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);sa.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);za.setFromMatrix(sa);J.length=0;Y=Z=-1;ja.length=0;ea.length=0;q(a,b);C.length=Z+1;S.length=Y+1;!0===X.sortObjects&&(C.sort(p),S.sort(n));var g=J,f,h,k,l=0,m=0,s=0,t,v,x,w=b.matrixWorldInverse,
$=0,E=0,y=0,D=0,B=0;f=R.shadowsPointLight=0;for(h=g.length;f<h;f++)if(k=g[f],t=k.color,v=k.intensity,x=k.distance,k instanceof THREE.AmbientLight)l+=t.r*v,m+=t.g*v,s+=t.b*v;else if(k instanceof THREE.DirectionalLight){var A=xa.get(k);A.color.copy(k.color).multiplyScalar(k.intensity);A.direction.setFromMatrixPosition(k.matrixWorld);W.setFromMatrixPosition(k.target.matrixWorld);A.direction.sub(W);A.direction.transformDirection(w);if(A.shadow=k.castShadow)A.shadowBias=k.shadow.bias,A.shadowRadius=k.shadow.radius,
A.shadowMapSize=k.shadow.mapSize,R.shadows[B++]=k;R.directionalShadowMap[$]=k.shadow.map;R.directionalShadowMatrix[$]=k.shadow.matrix;R.directional[$++]=A}else if(k instanceof THREE.SpotLight){A=xa.get(k);A.position.setFromMatrixPosition(k.matrixWorld);A.position.applyMatrix4(w);A.color.copy(t).multiplyScalar(v);A.distance=x;A.direction.setFromMatrixPosition(k.matrixWorld);W.setFromMatrixPosition(k.target.matrixWorld);A.direction.sub(W);A.direction.transformDirection(w);A.coneCos=Math.cos(k.angle);
A.penumbraCos=Math.cos(k.angle*(1-k.penumbra));A.decay=0===k.distance?0:k.decay;if(A.shadow=k.castShadow)A.shadowBias=k.shadow.bias,A.shadowRadius=k.shadow.radius,A.shadowMapSize=k.shadow.mapSize,R.shadows[B++]=k;R.spotShadowMap[y]=k.shadow.map;R.spotShadowMatrix[y]=k.shadow.matrix;R.spot[y++]=A}else if(k instanceof THREE.PointLight){A=xa.get(k);A.position.setFromMatrixPosition(k.matrixWorld);A.position.applyMatrix4(w);A.color.copy(k.color).multiplyScalar(k.intensity);A.distance=k.distance;A.decay=
0===k.distance?0:k.decay;if(A.shadow=k.castShadow)A.shadowBias=k.shadow.bias,A.shadowRadius=k.shadow.radius,A.shadowMapSize=k.shadow.mapSize,R.shadows[B++]=k;R.pointShadowMap[E]=k.shadow.map;void 0===R.pointShadowMatrix[E]&&(R.pointShadowMatrix[E]=new THREE.Matrix4);W.setFromMatrixPosition(k.matrixWorld).negate();R.pointShadowMatrix[E].identity().setPosition(W);R.point[E++]=A}else k instanceof THREE.HemisphereLight&&(A=xa.get(k),A.direction.setFromMatrixPosition(k.matrixWorld),A.direction.transformDirection(w),
A.direction.normalize(),A.skyColor.copy(k.color).multiplyScalar(v),A.groundColor.copy(k.groundColor).multiplyScalar(v),R.hemi[D++]=A);R.ambient[0]=l;R.ambient[1]=m;R.ambient[2]=s;R.directional.length=$;R.spot.length=y;R.point.length=E;R.hemi.length=D;R.shadows.length=B;R.hash=$+","+E+","+y+","+D+","+B;Ca.render(a,b);fa.calls=0;fa.vertices=0;fa.faces=0;fa.points=0;void 0===c&&(c=null);this.setRenderTarget(c);(this.autoClear||d)&&this.clear(this.autoClearColor,this.autoClearDepth,this.autoClearStencil);
a.overrideMaterial?(d=a.overrideMaterial,u(C,b,e,d),u(S,b,e,d)):(K.setBlending(THREE.NoBlending),u(C,b,e),u(S,b,e));Ga.render(a,b);Ha.render(a,b,ka);c&&(a=c.texture,a.generateMipmaps&&z(c)&&a.minFilter!==THREE.NearestFilter&&a.minFilter!==THREE.LinearFilter&&(a=c instanceof THREE.WebGLRenderTargetCube?r.TEXTURE_CUBE_MAP:r.TEXTURE_2D,c=U.get(c.texture).__webglTexture,K.bindTexture(a,c),r.generateMipmap(a),K.bindTexture(a,null)));K.setDepthTest(!0);K.setDepthWrite(!0);K.setColorWrite(!0)}};this.setFaceCulling=
function(a,b){a===THREE.CullFaceNone?K.disable(r.CULL_FACE):(b===THREE.FrontFaceDirectionCW?r.frontFace(r.CW):r.frontFace(r.CCW),a===THREE.CullFaceBack?r.cullFace(r.BACK):a===THREE.CullFaceFront?r.cullFace(r.FRONT):r.cullFace(r.FRONT_AND_BACK),K.enable(r.CULL_FACE))};this.setTexture=function(a,b){var c=U.get(a);if(0<a.version&&c.__version!==a.version){var d=a.image;if(void 0===d)console.warn("THREE.WebGLRenderer: Texture marked for update but image is undefined",a);else if(!1===d.complete)console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete",
a);else{void 0===c.__webglInit&&(c.__webglInit=!0,a.addEventListener("dispose",f),c.__webglTexture=r.createTexture(),ia.textures++);K.activeTexture(r.TEXTURE0+b);K.bindTexture(r.TEXTURE_2D,c.__webglTexture);r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,a.flipY);r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,a.premultiplyAlpha);r.pixelStorei(r.UNPACK_ALIGNMENT,a.unpackAlignment);var e=D(a.image,da.maxTextureSize);if((a.wrapS!==THREE.ClampToEdgeWrapping||a.wrapT!==THREE.ClampToEdgeWrapping||a.minFilter!==THREE.NearestFilter&&
a.minFilter!==THREE.LinearFilter)&&!1===z(e))if(d=e,d instanceof HTMLImageElement||d instanceof HTMLCanvasElement){var g=document.createElement("canvas");g.width=THREE.Math.nearestPowerOfTwo(d.width);g.height=THREE.Math.nearestPowerOfTwo(d.height);g.getContext("2d").drawImage(d,0,0,g.width,g.height);console.warn("THREE.WebGLRenderer: image is not power of two ("+d.width+"x"+d.height+"). Resized to "+g.width+"x"+g.height,d);e=g}else e=d;var d=z(e),g=L(a.format),h=L(a.type);x(r.TEXTURE_2D,a,d);var k=
a.mipmaps;if(a instanceof THREE.DataTexture)if(0<k.length&&d){for(var l=0,m=k.length;l<m;l++)e=k[l],K.texImage2D(r.TEXTURE_2D,l,g,e.width,e.height,0,g,h,e.data);a.generateMipmaps=!1}else K.texImage2D(r.TEXTURE_2D,0,g,e.width,e.height,0,g,h,e.data);else if(a instanceof THREE.CompressedTexture)for(l=0,m=k.length;l<m;l++)e=k[l],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<K.getCompressedTextureFormats().indexOf(g)?K.compressedTexImage2D(r.TEXTURE_2D,l,g,e.width,e.height,0,e.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):
K.texImage2D(r.TEXTURE_2D,l,g,e.width,e.height,0,g,h,e.data);else if(0<k.length&&d){l=0;for(m=k.length;lf;f++)b.__webglFramebuffer[f]=r.createFramebuffer()}else b.__webglFramebuffer=r.createFramebuffer();if(d){K.bindTexture(r.TEXTURE_CUBE_MAP,c.__webglTexture);x(r.TEXTURE_CUBE_MAP,a.texture,e);for(f=
0;6>f;f++)G(b.__webglFramebuffer[f],a,r.COLOR_ATTACHMENT0,r.TEXTURE_CUBE_MAP_POSITIVE_X+f);a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_CUBE_MAP);K.bindTexture(r.TEXTURE_CUBE_MAP,null)}else K.bindTexture(r.TEXTURE_2D,c.__webglTexture),x(r.TEXTURE_2D,a.texture,e),G(b.__webglFramebuffer,a,r.COLOR_ATTACHMENT0,r.TEXTURE_2D),a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_2D),K.bindTexture(r.TEXTURE_2D,null);if(a.depthBuffer){b=U.get(a);if(a instanceof THREE.WebGLRenderTargetCube)for(b.__webglDepthbuffer=
[],c=0;6>c;c++)r.bindFramebuffer(r.FRAMEBUFFER,b.__webglFramebuffer[c]),b.__webglDepthbuffer[c]=r.createRenderbuffer(),F(b.__webglDepthbuffer[c],a);else r.bindFramebuffer(r.FRAMEBUFFER,b.__webglFramebuffer),b.__webglDepthbuffer=r.createRenderbuffer(),F(b.__webglDepthbuffer,a);r.bindFramebuffer(r.FRAMEBUFFER,null)}}b=a instanceof THREE.WebGLRenderTargetCube;a?(c=U.get(a),c=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,qa.copy(a.scissor),Aa=a.scissorTest,ka.copy(a.viewport)):(c=null,
qa.copy(ya).multiplyScalar(aa),Aa=Ba,ka.copy(la).multiplyScalar(aa));ua!==c&&(r.bindFramebuffer(r.FRAMEBUFFER,c),ua=c);K.scissor(qa);K.setScissorTest(Aa);K.viewport(ka);b&&(b=U.get(a.texture),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,b.__webglTexture,a.activeMipMapLevel))};this.readRenderTargetPixels=function(a,b,c,d,e,g){if(!1===a instanceof THREE.WebGLRenderTarget)console.error(“THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.”);
else{var f=U.get(a).__webglFramebuffer;if(f){var h=!1;f!==ua&&(r.bindFramebuffer(r.FRAMEBUFFER,f),h=!0);try{var k=a.texture;k.format!==THREE.RGBAFormat&&L(k.format)!==r.getParameter(r.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error(“THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.”):k.type===THREE.UnsignedByteType||L(k.type)===r.getParameter(r.IMPLEMENTATION_COLOR_READ_TYPE)||k.type===THREE.FloatType&&V.get(“WEBGL_color_buffer_float”)||k.type===
THREE.HalfFloatType&&V.get(“EXT_color_buffer_half_float”)?r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE?r.readPixels(b,c,d,e,L(k.format),L(k.type),g):console.error(“THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.”):console.error(“THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.”)}finally{h&&r.bindFramebuffer(r.FRAMEBUFFER,ua)}}}}};
THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;this.scissor=new THREE.Vector4(0,0,a,b);this.scissorTest=!1;this.viewport=new THREE.Vector4(0,0,a,b);c=c||{};void 0===c.minFilter&&(c.minFilter=THREE.LinearFilter);this.texture=new THREE.Texture(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0};
THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;return this},dispose:function(){this.dispatchEvent({type:”dispose”})}};
THREE.EventDispatcher.prototype.apply(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeMipMapLevel=this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube;
THREE.WebGLBufferRenderer=function(a,b,c){var d;this.setMode=function(a){d=a};this.render=function(b,f){a.drawArrays(d,b,f);c.calls++;c.vertices+=f;d===a.TRIANGLES&&(c.faces+=f/3)};this.renderInstances=function(e){var f=b.get(“ANGLE_instanced_arrays”);if(null===f)console.error(“THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.”);else{var g=e.attributes.position,h=0,h=g instanceof THREE.InterleavedBufferAttribute?g.data.count:
g.count;f.drawArraysInstancedANGLE(d,0,h,e.maxInstancedCount);c.calls++;c.vertices+=h*e.maxInstancedCount;d===a.TRIANGLES&&(c.faces+=e.maxInstancedCount*h/3)}}};
THREE.WebGLIndexedBufferRenderer=function(a,b,c){var d,e,f;this.setMode=function(a){d=a};this.setIndex=function(c){c.array instanceof Uint32Array&&b.get(“OES_element_index_uint”)?(e=a.UNSIGNED_INT,f=4):(e=a.UNSIGNED_SHORT,f=2)};this.render=function(b,h){a.drawElements(d,h,e,b*f);c.calls++;c.vertices+=h;d===a.TRIANGLES&&(c.faces+=h/3)};this.renderInstances=function(g,h,k){var l=b.get(“ANGLE_instanced_arrays”);null===l?console.error(“THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.”):
(l.drawElementsInstancedANGLE(d,k,e,h*f,g.maxInstancedCount),c.calls++,c.vertices+=k*g.maxInstancedCount,d===a.TRIANGLES&&(c.faces+=g.maxInstancedCount*k/3))}};
THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c])return b[c];var d;switch(c){case “EXT_texture_filter_anisotropic”:d=a.getExtension(“EXT_texture_filter_anisotropic”)||a.getExtension(“MOZ_EXT_texture_filter_anisotropic”)||a.getExtension(“WEBKIT_EXT_texture_filter_anisotropic”);break;case “WEBGL_compressed_texture_s3tc”:d=a.getExtension(“WEBGL_compressed_texture_s3tc”)||a.getExtension(“MOZ_WEBGL_compressed_texture_s3tc”)||a.getExtension(“WEBKIT_WEBGL_compressed_texture_s3tc”);
break;case “WEBGL_compressed_texture_pvrtc”:d=a.getExtension(“WEBGL_compressed_texture_pvrtc”)||a.getExtension(“WEBKIT_WEBGL_compressed_texture_pvrtc”);break;case “WEBGL_compressed_texture_etc1”:d=a.getExtension(“WEBGL_compressed_texture_etc1”);break;default:d=a.getExtension(c)}null===d&&console.warn(“THREE.WebGLRenderer: “+c+” extension not supported.”);return b[c]=d}};
THREE.WebGLCapabilities=function(a,b,c){function d(b){if(“highp”===b){if(0<a.getShaderPrecisionFormat(a.VERTEX_SHADER,a.HIGH_FLOAT).precision&&0<a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.HIGH_FLOAT).precision)return"highp";b="mediump"}return"mediump"===b&&0<a.getShaderPrecisionFormat(a.VERTEX_SHADER,a.MEDIUM_FLOAT).precision&&0<a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.MEDIUM_FLOAT).precision?"mediump":"lowp"}this.getMaxPrecision=d;this.precision=void 0!==c.precision?c.precision:"highp";
this.logarithmicDepthBuffer=void 0!==c.logarithmicDepthBuffer?c.logarithmicDepthBuffer:!1;this.maxTextures=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS);this.maxVertexTextures=a.getParameter(a.MAX_VERTEX_TEXTURE_IMAGE_UNITS);this.maxTextureSize=a.getParameter(a.MAX_TEXTURE_SIZE);this.maxCubemapSize=a.getParameter(a.MAX_CUBE_MAP_TEXTURE_SIZE);this.maxAttributes=a.getParameter(a.MAX_VERTEX_ATTRIBS);this.maxVertexUniforms=a.getParameter(a.MAX_VERTEX_UNIFORM_VECTORS);this.maxVaryings=a.getParameter(a.MAX_VARYING_VECTORS);
this.maxFragmentUniforms=a.getParameter(a.MAX_FRAGMENT_UNIFORM_VECTORS);this.vertexTextures=0c){var d=b;b=c;c=d}d=a[b];return void 0===d?(a[b]=[c],!0):-1===d.indexOf(c)?(d.push(c),!0):!1}var f=new THREE.WebGLGeometries(a,b,c);this.getAttributeBuffer=function(a){return a instanceof THREE.InterleavedBufferAttribute?b.get(a.data).__webglBuffer:b.get(a).__webglBuffer};this.getWireframeAttribute=
function(c){var f=b.get(c);if(void 0!==f.wireframe)return f.wireframe;var k=[],l=c.index,p=c.attributes;c=p.position;if(null!==l)for(var p={},l=l.array,n=0,m=l.length;n<m;n+=3){var q=l[n+0],u=l[n+1],v=l[n+2];e(p,q,u)&&k.push(q,u);e(p,u,v)&&k.push(u,v);e(p,v,q)&&k.push(v,q)}else for(l=p.position.array,n=0,m=l.length/3-1;n<m;n+=3)q=n+0,u=n+1,v=n+2,k.push(q,u,u,v,v,q);k=new THREE.BufferAttribute(new (65535<c.count?Uint32Array:Uint16Array)(k),1);d(k,a.ELEMENT_ARRAY_BUFFER);return f.wireframe=k};this.update=
function(b){var c=f.get(b);b.geometry instanceof THREE.Geometry&&c.updateFromObject(b);b=c.index;var e=c.attributes;null!==b&&d(b,a.ELEMENT_ARRAY_BUFFER);for(var l in e)d(e[l],a.ARRAY_BUFFER);b=c.morphAttributes;for(l in b)for(var e=b[l],p=0,n=e.length;p<n;p++)d(e[p],a.ARRAY_BUFFER);return c}};
THREE.WebGLProgram=function(){function a(a){switch(a){case THREE.LinearEncoding:return["Linear","( value )"];case THREE.sRGBEncoding:return["sRGB","( value )"];case THREE.RGBEEncoding:return["RGBE","( value )"];case THREE.RGBM7Encoding:return["RGBM","( value, 7.0 )"];case THREE.RGBM16Encoding:return["RGBM","( value, 16.0 )"];case THREE.RGBDEncoding:return["RGBD","( value, 256.0 )"];case THREE.GammaEncoding:return["Gamma","( value, float( GAMMA_FACTOR ) )"];default:throw Error("unsupported encoding: "+
a);}}function b(b,c){var d=a(c);return"vec4 "+b+"( vec4 value ) { return "+d[0]+"ToLinear"+d[1]+"; }"}function c(b,c){var d=a(c);return"vec4 "+b+"( vec4 value ) { return LinearTo"+d[0]+d[1]+"; }"}function d(a,b){var c;switch(b){case THREE.LinearToneMapping:c="Linear";break;case THREE.ReinhardToneMapping:c="Reinhard";break;case THREE.Uncharted2ToneMapping:c="Uncharted2";break;case THREE.CineonToneMapping:c="OptimizedCineon";break;default:throw Error("unsupported toneMapping: "+b);}return"vec3 "+a+
"( vec3 color ) { return "+c+"ToneMapping( color ); }"}function e(a,b,c){a=a||{};return[a.derivatives||b.envMapCubeUV||b.bumpMap||b.normalMap||b.flatShading?"#extension GL_OES_standard_derivatives : enable":"",(a.fragDepth||b.logarithmicDepthBuffer)&&c.get("EXT_frag_depth")?"#extension GL_EXT_frag_depth : enable":"",a.drawBuffers&&c.get("WEBGL_draw_buffers")?"#extension GL_EXT_draw_buffers : require":"",(a.shaderTextureLOD||b.envMap)&&c.get("EXT_shader_texture_lod")?"#extension GL_EXT_shader_texture_lod : enable":
""].filter(g).join("\n")}function f(a){var b=[],c;for(c in a){var d=a[c];!1!==d&&b.push("#define "+c+" "+d)}return b.join("\n")}function g(a){return""!==a}function h(a,b){return a.replace(/NUM_DIR_LIGHTS/g,b.numDirLights).replace(/NUM_SPOT_LIGHTS/g,b.numSpotLights).replace(/NUM_POINT_LIGHTS/g,b.numPointLights).replace(/NUM_HEMI_LIGHTS/g,b.numHemiLights)}function k(a){return a.replace(/#include +/g,function(a,b){var c=THREE.ShaderChunk[b];if(void 0===c)throw Error(“Can not resolve #include “);return k(c)})}function l(a){return a.replace(/for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,b,c,d){a="";for(b=parseInt(b);b<parseInt(c);b++)a+=d.replace(/\[ i \]/g,"[ "+b+" ]");return a})}var p=0,n=/^([\w\d_]+)\.([\w\d_]+)$/,m=/^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/,q=/^([\w\d_]+)\[0\]$/;return function(a,v,t,s){var w=a.context,E=t.extensions,x=t.defines,D=t.__webglShader.vertexShader,z=t.__webglShader.fragmentShader,y="SHADOWMAP_TYPE_BASIC";s.shadowMapType===
THREE.PCFShadowMap?y="SHADOWMAP_TYPE_PCF":s.shadowMapType===THREE.PCFSoftShadowMap&&(y="SHADOWMAP_TYPE_PCF_SOFT");var B="ENVMAP_TYPE_CUBE",G="ENVMAP_MODE_REFLECTION",F="ENVMAP_BLENDING_MULTIPLY";if(s.envMap){switch(t.envMap.mapping){case THREE.CubeReflectionMapping:case THREE.CubeRefractionMapping:B="ENVMAP_TYPE_CUBE";break;case THREE.CubeUVReflectionMapping:case THREE.CubeUVRefractionMapping:B="ENVMAP_TYPE_CUBE_UV";break;case THREE.EquirectangularReflectionMapping:case THREE.EquirectangularRefractionMapping:B=
"ENVMAP_TYPE_EQUIREC";break;case THREE.SphericalReflectionMapping:B="ENVMAP_TYPE_SPHERE"}switch(t.envMap.mapping){case THREE.CubeRefractionMapping:case THREE.EquirectangularRefractionMapping:G="ENVMAP_MODE_REFRACTION"}switch(t.combine){case THREE.MultiplyOperation:F="ENVMAP_BLENDING_MULTIPLY";break;case THREE.MixOperation:F="ENVMAP_BLENDING_MIX";break;case THREE.AddOperation:F="ENVMAP_BLENDING_ADD"}}var H=0<a.gammaFactor?a.gammaFactor:1,E=e(E,s,a.extensions),L=f(x),A=w.createProgram();t instanceof
THREE.RawShaderMaterial?a=x="":(x=["precision "+s.precision+" float;","precision "+s.precision+" int;","#define SHADER_NAME "+t.__webglShader.name,L,s.supportsVertexTextures?"#define VERTEX_TEXTURES":"","#define GAMMA_FACTOR "+H,"#define MAX_BONES "+s.maxBones,s.map?"#define USE_MAP":"",s.envMap?"#define USE_ENVMAP":"",s.envMap?"#define "+G:"",s.lightMap?"#define USE_LIGHTMAP":"",s.aoMap?"#define USE_AOMAP":"",s.emissiveMap?"#define USE_EMISSIVEMAP":"",s.bumpMap?"#define USE_BUMPMAP":"",s.normalMap?
"#define USE_NORMALMAP":"",s.displacementMap&&s.supportsVertexTextures?"#define USE_DISPLACEMENTMAP":"",s.specularMap?"#define USE_SPECULARMAP":"",s.roughnessMap?"#define USE_ROUGHNESSMAP":"",s.metalnessMap?"#define USE_METALNESSMAP":"",s.alphaMap?"#define USE_ALPHAMAP":"",s.vertexColors?"#define USE_COLOR":"",s.flatShading?"#define FLAT_SHADED":"",s.skinning?"#define USE_SKINNING":"",s.useVertexTexture?"#define BONE_TEXTURE":"",s.morphTargets?"#define USE_MORPHTARGETS":"",s.morphNormals&&!1===s.flatShading?
"#define USE_MORPHNORMALS":"",s.doubleSided?"#define DOUBLE_SIDED":"",s.flipSided?"#define FLIP_SIDED":"",s.shadowMapEnabled?"#define USE_SHADOWMAP":"",s.shadowMapEnabled?"#define "+y:"",0<s.pointLightShadows?"#define POINT_LIGHT_SHADOWS":"",s.sizeAttenuation?"#define USE_SIZEATTENUATION":"",s.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",s.logarithmicDepthBuffer&&a.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;",
"uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_COLOR","\tattribute vec3 color;","#endif","#ifdef USE_MORPHTARGETS","\tattribute vec3 morphTarget0;","\tattribute vec3 morphTarget1;","\tattribute vec3 morphTarget2;","\tattribute vec3 morphTarget3;","\t#ifdef USE_MORPHNORMALS","\t\tattribute vec3 morphNormal0;","\t\tattribute vec3 morphNormal1;",
"\t\tattribute vec3 morphNormal2;","\t\tattribute vec3 morphNormal3;","\t#else","\t\tattribute vec3 morphTarget4;","\t\tattribute vec3 morphTarget5;","\t\tattribute vec3 morphTarget6;","\t\tattribute vec3 morphTarget7;","\t#endif","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(g).join("\n"),a=[E,"precision "+s.precision+" float;","precision "+s.precision+" int;","#define SHADER_NAME "+t.__webglShader.name,L,s.alphaTest?"#define ALPHATEST "+
s.alphaTest:"","#define GAMMA_FACTOR "+H,s.useFog&&s.fog?"#define USE_FOG":"",s.useFog&&s.fogExp?"#define FOG_EXP2":"",s.map?"#define USE_MAP":"",s.envMap?"#define USE_ENVMAP":"",s.envMap?"#define "+B:"",s.envMap?"#define "+G:"",s.envMap?"#define "+F:"",s.lightMap?"#define USE_LIGHTMAP":"",s.aoMap?"#define USE_AOMAP":"",s.emissiveMap?"#define USE_EMISSIVEMAP":"",s.bumpMap?"#define USE_BUMPMAP":"",s.normalMap?"#define USE_NORMALMAP":"",s.specularMap?"#define USE_SPECULARMAP":"",s.roughnessMap?"#define USE_ROUGHNESSMAP":
"",s.metalnessMap?"#define USE_METALNESSMAP":"",s.alphaMap?"#define USE_ALPHAMAP":"",s.vertexColors?"#define USE_COLOR":"",s.flatShading?"#define FLAT_SHADED":"",s.doubleSided?"#define DOUBLE_SIDED":"",s.flipSided?"#define FLIP_SIDED":"",s.shadowMapEnabled?"#define USE_SHADOWMAP":"",s.shadowMapEnabled?"#define "+y:"",0<s.pointLightShadows?"#define POINT_LIGHT_SHADOWS":"",s.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",s.physicallyCorrectLights?"#define PHYSICALLY_CORRECT_LIGHTS":"",s.logarithmicDepthBuffer?
"#define USE_LOGDEPTHBUF":"",s.logarithmicDepthBuffer&&a.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"",s.envMap&&a.extensions.get("EXT_shader_texture_lod")?"#define TEXTURE_LOD_EXT":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;",s.toneMapping!==THREE.NoToneMapping?"#define TONE_MAPPING":"",s.toneMapping!==THREE.NoToneMapping?THREE.ShaderChunk.tonemapping_pars_fragment:"",s.toneMapping!==THREE.NoToneMapping?d("toneMapping",s.toneMapping):"",s.outputEncoding||s.mapEncoding||
s.envMapEncoding||s.emissiveMapEncoding?THREE.ShaderChunk.encodings_pars_fragment:"",s.mapEncoding?b("mapTexelToLinear",s.mapEncoding):"",s.envMapEncoding?b("envMapTexelToLinear",s.envMapEncoding):"",s.emissiveMapEncoding?b("emissiveMapTexelToLinear",s.emissiveMapEncoding):"",s.outputEncoding?c("linearToOutputTexel",s.outputEncoding):"","\n"].filter(g).join("\n"));D=k(D,s);D=h(D,s);z=k(z,s);z=h(z,s);!1===t instanceof THREE.ShaderMaterial&&(D=l(D),z=l(z));z=a+z;D=THREE.WebGLShader(w,w.VERTEX_SHADER,
x+D);z=THREE.WebGLShader(w,w.FRAGMENT_SHADER,z);w.attachShader(A,D);w.attachShader(A,z);void 0!==t.index0AttributeName?w.bindAttribLocation(A,0,t.index0AttributeName):!0===s.morphTargets&&w.bindAttribLocation(A,0,"position");w.linkProgram(A);s=w.getProgramInfoLog(A);y=w.getShaderInfoLog(D);B=w.getShaderInfoLog(z);F=G=!0;if(!1===w.getProgramParameter(A,w.LINK_STATUS))G=!1,console.error("THREE.WebGLProgram: shader error: ",w.getError(),"gl.VALIDATE_STATUS",w.getProgramParameter(A,w.VALIDATE_STATUS),
"gl.getProgramInfoLog",s,y,B);else if(""!==s)console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",s);else if(""===y||""===B)F=!1;F&&(this.diagnostics={runnable:G,material:t,programLog:s,vertexShader:{log:y,prefix:x},fragmentShader:{log:B,prefix:a}});w.deleteShader(D);w.deleteShader(z);var N;this.getUniforms=function(){if(void 0===N){for(var a={},b=w.getProgramParameter(A,w.ACTIVE_UNIFORMS),c=0;c<b;c++){var d=w.getActiveUniform(A,c).name,e=w.getUniformLocation(A,d),g=n.exec(d);if(g){var d=g[1],
g=g[2],f=a[d];f||(f=a[d]={});f[g]=e}else if(g=m.exec(d)){var f=g[1],d=g[2],g=g[3],h=a[f];h||(h=a[f]=[]);(f=h[d])||(f=h[d]={});f[g]=e}else(g=q.exec(d))?(f=g[1],a[f]=e):a[d]=e}N=a}return N};var M;this.getAttributes=function(){if(void 0===M){for(var a={},b=w.getProgramParameter(A,w.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=w.getActiveAttrib(A,c).name;a[d]=w.getAttribLocation(A,d)}M=a}return M};this.destroy=function(){w.deleteProgram(A);this.program=void 0};Object.defineProperties(this,{uniforms:{get:function(){console.warn("THREE.WebGLProgram: .uniforms is now .getUniforms().");
return this.getUniforms()}},attributes:{get:function(){console.warn("THREE.WebGLProgram: .attributes is now .getAttributes().");return this.getAttributes()}}});this.id=p++;this.code=v;this.usedTimes=1;this.program=A;this.vertexShader=D;this.fragmentShader=z;return this}}();
THREE.WebGLPrograms=function(a,b){function c(a,b){var c;a?a instanceof THREE.Texture?c=a.encoding:a instanceof THREE.WebGLRenderTarget&&(c=a.texture.encoding):c=THREE.LinearEncoding;c===THREE.LinearEncoding&&b&&(c=THREE.GammaEncoding);return c}var d=[],e={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshStandardMaterial:"standard",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points"},
f="precision supportsVertexTextures map mapEncoding envMap envMapMode envMapEncoding lightMap aoMap emissiveMap emissiveMapEncoding bumpMap normalMap displacementMap specularMap roughnessMap metalnessMap alphaMap combine vertexColors fog useFog fogExp flatShading sizeAttenuation logarithmicDepthBuffer skinning maxBones useVertexTexture morphTargets morphNormals maxMorphTargets maxMorphNormals premultipliedAlpha numDirLights numPointLights numSpotLights numHemiLights shadowMapEnabled pointLightShadows toneMapping physicallyCorrectLights shadowMapType alphaTest doubleSided flipSided".split(" ");
this.getParameters=function(d,f,k,l){var p=e[d.type],n;b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture?n=1024:(n=Math.floor((b.maxVertexUniforms-20)/4),void 0!==l&&l instanceof THREE.SkinnedMesh&&(n=Math.min(l.skeleton.bones.length,n),n<l.skeleton.bones.length&&console.warn("WebGLRenderer: too many bones – "+l.skeleton.bones.length+", this GPU supports just "+n+" (try OpenGL instead of ANGLE)")));var m=a.getPrecision();null!==d.precision&&(m=b.getMaxPrecision(d.precision),m!==d.precision&&
console.warn("THREE.WebGLProgram.getParameters:",d.precision,"not supported, using",m,"instead."));return{shaderID:p,precision:m,supportsVertexTextures:b.vertexTextures,outputEncoding:c(a.getCurrentRenderTarget(),a.gammaOutput),map:!!d.map,mapEncoding:c(d.map,a.gammaInput),envMap:!!d.envMap,envMapMode:d.envMap&&d.envMap.mapping,envMapEncoding:c(d.envMap,a.gammaInput),envMapCubeUV:!!d.envMap&&(d.envMap.mapping===THREE.CubeUVReflectionMapping||d.envMap.mapping===THREE.CubeUVRefractionMapping),lightMap:!!d.lightMap,
aoMap:!!d.aoMap,emissiveMap:!!d.emissiveMap,emissiveMapEncoding:c(d.emissiveMap,a.gammaInput),bumpMap:!!d.bumpMap,normalMap:!!d.normalMap,displacementMap:!!d.displacementMap,roughnessMap:!!d.roughnessMap,metalnessMap:!!d.metalnessMap,specularMap:!!d.specularMap,alphaMap:!!d.alphaMap,combine:d.combine,vertexColors:d.vertexColors,fog:k,useFog:d.fog,fogExp:k instanceof THREE.FogExp2,flatShading:d.shading===THREE.FlatShading,sizeAttenuation:d.sizeAttenuation,logarithmicDepthBuffer:b.logarithmicDepthBuffer,
skinning:d.skinning,maxBones:n,useVertexTexture:b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture,morphTargets:d.morphTargets,morphNormals:d.morphNormals,maxMorphTargets:a.maxMorphTargets,maxMorphNormals:a.maxMorphNormals,numDirLights:f.directional.length,numPointLights:f.point.length,numSpotLights:f.spot.length,numHemiLights:f.hemi.length,pointLightShadows:f.shadowsPointLight,shadowMapEnabled:a.shadowMap.enabled&&l.receiveShadow&&0<f.shadows.length,shadowMapType:a.shadowMap.type,
toneMapping:a.toneMapping,physicallyCorrectLights:a.physicallyCorrectLights,premultipliedAlpha:d.premultipliedAlpha,alphaTest:d.alphaTest,doubleSided:d.side===THREE.DoubleSide,flipSided:d.side===THREE.BackSide}};this.getProgramCode=function(a,b){var c=[];b.shaderID?c.push(b.shaderID):(c.push(a.fragmentShader),c.push(a.vertexShader));if(void 0!==a.defines)for(var d in a.defines)c.push(d),c.push(a.defines[d]);for(d=0;d<f.length;d++){var e=f[d];c.push(e);c.push(b[e])}return c.join()};this.acquireProgram=
function(b,c,e){for(var f,p=0,n=d.length;p<n;p++){var m=d[p];if(m.code===e){f=m;++f.usedTimes;break}}void 0===f&&(f=new THREE.WebGLProgram(a,e,b,c),d.push(f));return f};this.releaseProgram=function(a){if(0===–a.usedTimes){var b=d.indexOf(a);d[b]=d[d.length-1];d.pop();a.destroy()}};this.programs=d};THREE.WebGLProperties=function(){var a={};this.get=function(b){b=b.uuid;var c=a[b];void 0===c&&(c={},a[b]=c);return c};this.delete=function(b){delete a[b.uuid]};this.clear=function(){a={}}};
THREE.WebGLShader=function(){function a(a){a=a.split("\n");for(var c=0;c<a.length;c++)a[c]=c+1+": "+a[c];return a.join("\n")}return function(b,c,d){var e=b.createShader(c);b.shaderSource(e,d);b.compileShader(e);!1===b.getShaderParameter(e,b.COMPILE_STATUS)&&console.error("THREE.WebGLShader: Shader couldn't compile.");""!==b.getShaderInfoLog(e)&&console.warn("THREE.WebGLShader: gl.getShaderInfoLog()",c===b.VERTEX_SHADER?"vertex":"fragment",b.getShaderInfoLog(e),a(d));return e}}();
THREE.WebGLShadowMap=function(a,b,c){function d(a,b,c,d){var e=a.geometry,f=null,f=q,g=a.customDepthMaterial;c&&(f=u,g=a.customDistanceMaterial);g?f=g:(a=a instanceof THREE.SkinnedMesh&&b.skinning,g=0,void 0!==e.morphTargets&&0<e.morphTargets.length&&b.morphTargets&&(g|=1),a&&(g|=2),f=f[g]);f.visible=b.visible;f.wireframe=b.wireframe;f.wireframeLinewidth=b.wireframeLinewidth;c&&void 0!==f.uniforms.lightPos&&f.uniforms.lightPos.value.copy(d);return f}function e(a,b,c){if(!1!==a.visible){a.layers.test(b.layers)&&
(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)&&a.castShadow&&(!1===a.frustumCulled||!0===h.intersectsObject(a))&&!0===a.material.visible&&(a.modelViewMatrix.multiplyMatrices(c.matrixWorldInverse,a.matrixWorld),m.push(a));a=a.children;for(var d=0,f=a.length;d<f;d++)e(a[d],b,c)}}for(var f=a.context,g=a.state,h=new THREE.Frustum,k=new THREE.Matrix4,l=new THREE.Vector2,p=new THREE.Vector3,n=new THREE.Vector3,m=[],q=Array(4),u=Array(4),v=[new THREE.Vector3(1,0,0),new THREE.Vector3(-1,
0,0),new THREE.Vector3(0,0,1),new THREE.Vector3(0,0,-1),new THREE.Vector3(0,1,0),new THREE.Vector3(0,-1,0)],t=[new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,1,0),new THREE.Vector3(0,0,1),new THREE.Vector3(0,0,-1)],s=[new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4,new THREE.Vector4],w=THREE.ShaderLib.depthRGBA,E=THREE.UniformsUtils.clone(w.uniforms),x=THREE.ShaderLib.distanceRGBA,D=THREE.UniformsUtils.clone(x.uniforms),
z=0;4!==z;++z){var y=0!==(z&1),B=0!==(z&2),G=new THREE.ShaderMaterial({uniforms:E,vertexShader:w.vertexShader,fragmentShader:w.fragmentShader,morphTargets:y,skinning:B});q[z]=G;y=new THREE.ShaderMaterial({defines:{USE_SHADOWMAP:""},uniforms:D,vertexShader:x.vertexShader,fragmentShader:x.fragmentShader,morphTargets:y,skinning:B});u[z]=y}var F=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=THREE.PCFShadowMap;this.cullFace=THREE.CullFaceFront;this.render=function(q,u){var x,w,
E=b.shadows;if(0!==E.length&&!1!==F.enabled&&(!1!==F.autoUpdate||!1!==F.needsUpdate)){g.clearColor(1,1,1,1);g.disable(f.BLEND);g.enable(f.CULL_FACE);f.frontFace(f.CCW);f.cullFace(F.cullFace===THREE.CullFaceFront?f.FRONT:f.BACK);g.setDepthTest(!0);g.setScissorTest(!1);for(var z=0,y=E.length;z<y;z++){var D=E[z],B=D.shadow,G=B.camera;l.copy(B.mapSize);if(D instanceof THREE.PointLight){x=6;w=!0;var J=l.x,C=l.y;s[0].set(2*J,C,J,C);s[1].set(0,C,J,C);s[2].set(3*J,C,J,C);s[3].set(J,C,J,C);s[4].set(3*J,0,
J,C);s[5].set(J,0,J,C);l.x*=4;l.y*=2}else x=1,w=!1;null===B.map&&(B.map=new THREE.WebGLRenderTarget(l.x,l.y,{minFilter:THREE.NearestFilter,magFilter:THREE.NearestFilter,format:THREE.RGBAFormat}),D instanceof THREE.SpotLight&&(G.aspect=l.x/l.y),G.updateProjectionMatrix());J=B.map;B=B.matrix;n.setFromMatrixPosition(D.matrixWorld);G.position.copy(n);a.setRenderTarget(J);a.clear();for(J=0;J<x;J++){w?(p.copy(G.position),p.add(v[J]),G.up.copy(t[J]),G.lookAt(p),g.viewport(s[J])):(p.setFromMatrixPosition(D.target.matrixWorld),
G.lookAt(p));G.updateMatrixWorld();G.matrixWorldInverse.getInverse(G.matrixWorld);B.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1);B.multiply(G.projectionMatrix);B.multiply(G.matrixWorldInverse);k.multiplyMatrices(G.projectionMatrix,G.matrixWorldInverse);h.setFromMatrix(k);m.length=0;e(q,u,G);for(var C=0,Z=m.length;C<Z;C++){var S=m[C],Y=c.update(S),$=S.material;if($ instanceof THREE.MultiMaterial)for(var ja=Y.groups,$=$.materials,ea=0,X=ja.length;ea<X;ea++){var ha=ja[ea],ca=$[ha.materialIndex];!0===ca.visible&&
(ca=d(S,ca,w,n),a.renderBufferDirect(G,null,Y,ca,S,ha))}else ca=d(S,$,w,n),a.renderBufferDirect(G,null,Y,ca,S,null)}}}x=a.getClearColor();w=a.getClearAlpha();a.setClearColor(x,w);g.enable(f.BLEND);F.cullFace===THREE.CullFaceFront&&f.cullFace(f.BACK);F.needsUpdate=!1}}};
THREE.WebGLState=function(a,b,c){var d=this,e=new THREE.Vector4,f=new Uint8Array(16),g=new Uint8Array(16),h=new Uint8Array(16),k={},l=null,p=null,n=null,m=null,q=null,u=null,v=null,t=null,s=!1,w=null,E=null,x=null,D=null,z=null,y=null,B=null,G=null,F=null,H=null,L=null,A=null,N=null,M=null,I=null,O=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),Q=void 0,P={},T=new THREE.Vector4,J=null,C=null,Z=new THREE.Vector4,S=new THREE.Vector4,Y=a.createTexture();a.bindTexture(a.TEXTURE_2D,Y);a.texParameteri(a.TEXTURE_2D,
a.TEXTURE_MIN_FILTER,a.LINEAR);a.texImage2D(a.TEXTURE_2D,0,a.RGB,1,1,0,a.RGB,a.UNSIGNED_BYTE,new Uint8Array(3));this.init=function(){this.clearColor(0,0,0,1);this.clearDepth(1);this.clearStencil(0);this.enable(a.DEPTH_TEST);a.depthFunc(a.LEQUAL);a.frontFace(a.CCW);a.cullFace(a.BACK);this.enable(a.CULL_FACE);this.enable(a.BLEND);a.blendEquation(a.FUNC_ADD);a.blendFunc(a.SRC_ALPHA,a.ONE_MINUS_SRC_ALPHA)};this.initAttributes=function(){for(var a=0,b=f.length;a<b;a++)f[a]=0};this.enableAttribute=function(c){f[c]=
1;0===g[c]&&(a.enableVertexAttribArray(c),g[c]=1);0!==h[c]&&(b.get("ANGLE_instanced_arrays").vertexAttribDivisorANGLE(c,0),h[c]=0)};this.enableAttributeAndDivisor=function(b,c,d){f[b]=1;0===g[b]&&(a.enableVertexAttribArray(b),g[b]=1);h[b]!==c&&(d.vertexAttribDivisorANGLE(b,c),h[b]=c)};this.disableUnusedAttributes=function(){for(var b=0,c=g.length;b<c;b++)g[b]!==f[b]&&(a.disableVertexAttribArray(b),g[b]=0)};this.enable=function(b){!0!==k[b]&&(a.enable(b),k[b]=!0)};this.disable=function(b){!1!==k[b]&&
(a.disable(b),k[b]=!1)};this.getCompressedTextureFormats=function(){if(null===l&&(l=[],b.get("WEBGL_compressed_texture_pvrtc")||b.get("WEBGL_compressed_texture_s3tc")||b.get("WEBGL_compressed_texture_etc1")))for(var c=a.getParameter(a.COMPRESSED_TEXTURE_FORMATS),d=0;d<c.length;d++)l.push(c[d]);return l};this.setBlending=function(b,d,e,f,g,h,k,l){b===THREE.NoBlending?this.disable(a.BLEND):this.enable(a.BLEND);if(b!==p||l!==s)b===THREE.AdditiveBlending?l?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),
a.blendFuncSeparate(a.ONE,a.ONE,a.ONE,a.ONE)):(a.blendEquation(a.FUNC_ADD),a.blendFunc(a.SRC_ALPHA,a.ONE)):b===THREE.SubtractiveBlending?l?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ZERO,a.ZERO,a.ONE_MINUS_SRC_COLOR,a.ONE_MINUS_SRC_ALPHA)):(a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.ONE_MINUS_SRC_COLOR)):b===THREE.MultiplyBlending?l?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ZERO,a.ZERO,a.SRC_COLOR,a.SRC_ALPHA)):(a.blendEquation(a.FUNC_ADD),
a.blendFunc(a.ZERO,a.SRC_COLOR)):l?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ONE,a.ONE_MINUS_SRC_ALPHA,a.ONE,a.ONE_MINUS_SRC_ALPHA)):(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.SRC_ALPHA,a.ONE_MINUS_SRC_ALPHA,a.ONE,a.ONE_MINUS_SRC_ALPHA)),p=b,s=l;if(b===THREE.CustomBlending){g=g||d;h=h||e;k=k||f;if(d!==n||g!==u)a.blendEquationSeparate(c(d),c(g)),n=d,u=g;if(e!==m||f!==q||h!==v||k!==t)a.blendFuncSeparate(c(e),c(f),c(h),c(k)),m=e,q=f,v=h,t=k}else t=
v=u=q=m=n=null};this.setDepthFunc=function(b){if(w!==b){if(b)switch(b){case THREE.NeverDepth:a.depthFunc(a.NEVER);break;case THREE.AlwaysDepth:a.depthFunc(a.ALWAYS);break;case THREE.LessDepth:a.depthFunc(a.LESS);break;case THREE.LessEqualDepth:a.depthFunc(a.LEQUAL);break;case THREE.EqualDepth:a.depthFunc(a.EQUAL);break;case THREE.GreaterEqualDepth:a.depthFunc(a.GEQUAL);break;case THREE.GreaterDepth:a.depthFunc(a.GREATER);break;case THREE.NotEqualDepth:a.depthFunc(a.NOTEQUAL);break;default:a.depthFunc(a.LEQUAL)}else a.depthFunc(a.LEQUAL);
w=b}};this.setDepthTest=function(b){b?this.enable(a.DEPTH_TEST):this.disable(a.DEPTH_TEST)};this.setDepthWrite=function(b){E!==b&&(a.depthMask(b),E=b)};this.setColorWrite=function(b){x!==b&&(a.colorMask(b,b,b,b),x=b)};this.setStencilFunc=function(b,c,d){if(z!==b||y!==c||B!==d)a.stencilFunc(b,c,d),z=b,y=c,B=d};this.setStencilOp=function(b,c,d){if(G!==b||F!==c||H!==d)a.stencilOp(b,c,d),G=b,F=c,H=d};this.setStencilTest=function(b){b?this.enable(a.STENCIL_TEST):this.disable(a.STENCIL_TEST)};this.setStencilWrite=
function(b){D!==b&&(a.stencilMask(b),D=b)};this.setFlipSided=function(b){L!==b&&(b?a.frontFace(a.CW):a.frontFace(a.CCW),L=b)};this.setLineWidth=function(b){b!==A&&(a.lineWidth(b),A=b)};this.setPolygonOffset=function(b,c,d){b?this.enable(a.POLYGON_OFFSET_FILL):this.disable(a.POLYGON_OFFSET_FILL);!b||N===c&&M===d||(a.polygonOffset(c,d),N=c,M=d)};this.getScissorTest=function(){return I};this.setScissorTest=function(b){(I=b)?this.enable(a.SCISSOR_TEST):this.disable(a.SCISSOR_TEST)};this.activeTexture=
function(b){void 0===b&&(b=a.TEXTURE0+O-1);Q!==b&&(a.activeTexture(b),Q=b)};this.bindTexture=function(b,c){void 0===Q&&d.activeTexture();var e=P[Q];void 0===e&&(e={type:void 0,texture:void 0},P[Q]=e);if(e.type!==b||e.texture!==c)a.bindTexture(b,c||Y),e.type=b,e.texture=c};this.compressedTexImage2D=function(){try{a.compressedTexImage2D.apply(a,arguments)}catch(b){console.error(b)}};this.texImage2D=function(){try{a.texImage2D.apply(a,arguments)}catch(b){console.error(b)}};this.clearColor=function(b,
c,d,f){e.set(b,c,d,f);!1===T.equals(e)&&(a.clearColor(b,c,d,f),T.copy(e))};this.clearDepth=function(b){J!==b&&(a.clearDepth(b),J=b)};this.clearStencil=function(b){C!==b&&(a.clearStencil(b),C=b)};this.scissor=function(b){!1===Z.equals(b)&&(a.scissor(b.x,b.y,b.z,b.w),Z.copy(b))};this.viewport=function(b){!1===S.equals(b)&&(a.viewport(b.x,b.y,b.z,b.w),S.copy(b))};this.reset=function(){for(var b=0;b<g.length;b++)1===g[b]&&(a.disableVertexAttribArray(b),g[b]=0);k={};l=null;Q=void 0;P={};L=D=E=x=p=null}};
THREE.LensFlarePlugin=function(a,b){var c,d,e,f,g,h,k,l,p,n,m=a.context,q=a.state,u,v,t,s,w,E;this.render=function(x,D,z){if(0!==b.length){x=new THREE.Vector3;var y=z.w/z.z,B=.5*z.z,G=.5*z.w,F=16/z.w,H=new THREE.Vector2(F*y,F),L=new THREE.Vector3(1,1,0),A=new THREE.Vector2(1,1);if(void 0===t){var F=new Float32Array([-1,-1,0,0,1,-1,1,0,1,1,1,1,-1,1,0,1]),N=new Uint16Array([0,1,2,0,2,3]);u=m.createBuffer();v=m.createBuffer();m.bindBuffer(m.ARRAY_BUFFER,u);m.bufferData(m.ARRAY_BUFFER,F,m.STATIC_DRAW);
m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,v);m.bufferData(m.ELEMENT_ARRAY_BUFFER,N,m.STATIC_DRAW);w=m.createTexture();E=m.createTexture();q.bindTexture(m.TEXTURE_2D,w);m.texImage2D(m.TEXTURE_2D,0,m.RGB,16,16,0,m.RGB,m.UNSIGNED_BYTE,null);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.NEAREST);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.NEAREST);q.bindTexture(m.TEXTURE_2D,
E);m.texImage2D(m.TEXTURE_2D,0,m.RGBA,16,16,0,m.RGBA,m.UNSIGNED_BYTE,null);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_S,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_WRAP_T,m.CLAMP_TO_EDGE);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MAG_FILTER,m.NEAREST);m.texParameteri(m.TEXTURE_2D,m.TEXTURE_MIN_FILTER,m.NEAREST);var F=(s=0<m.getParameter(m.MAX_VERTEX_TEXTURE_IMAGE_UNITS))?{vertexShader:"uniform lowp int renderType;\nuniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nuniform sampler2D occlusionMap;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif ( renderType == 2 ) {\nvec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\nvVisibility = visibility.r / 9.0;\nvVisibility *= 1.0 – visibility.g / 9.0;\nvVisibility *= visibility.b / 9.0;\nvVisibility *= 1.0 – visibility.a / 9.0;\npos.x = cos( rotation ) * position.x – sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",
fragmentShader:"uniform lowp int renderType;\nuniform sampler2D map;\nuniform float opacity;\nuniform vec3 color;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nif ( renderType == 0 ) {\ngl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\n} else if ( renderType == 1 ) {\ngl_FragColor = texture2D( map, vUV );\n} else {\nvec4 texture = texture2D( map, vUV );\ntexture.a *= opacity * vVisibility;\ngl_FragColor = texture;\ngl_FragColor.rgb *= color;\n}\n}"}:{vertexShader:"uniform lowp int renderType;\nuniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif ( renderType == 2 ) {\npos.x = cos( rotation ) * position.x – sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",
fragmentShader:"precision mediump float;\nuniform lowp int renderType;\nuniform sampler2D map;\nuniform sampler2D occlusionMap;\nuniform float opacity;\nuniform vec3 color;\nvarying vec2 vUV;\nvoid main() {\nif ( renderType == 0 ) {\ngl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );\n} else if ( renderType == 1 ) {\ngl_FragColor = texture2D( map, vUV );\n} else {\nfloat visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a;\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a;\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a;\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;\nvisibility = ( 1.0 – visibility / 4.0 );\nvec4 texture = texture2D( map, vUV );\ntexture.a *= opacity * visibility;\ngl_FragColor = texture;\ngl_FragColor.rgb *= color;\n}\n}"},
N=m.createProgram(),M=m.createShader(m.FRAGMENT_SHADER),I=m.createShader(m.VERTEX_SHADER),O="precision "+a.getPrecision()+" float;\n";m.shaderSource(M,O+F.fragmentShader);m.shaderSource(I,O+F.vertexShader);m.compileShader(M);m.compileShader(I);m.attachShader(N,M);m.attachShader(N,I);m.linkProgram(N);t=N;p=m.getAttribLocation(t,"position");n=m.getAttribLocation(t,"uv");c=m.getUniformLocation(t,"renderType");d=m.getUniformLocation(t,"map");e=m.getUniformLocation(t,"occlusionMap");f=m.getUniformLocation(t,
"opacity");g=m.getUniformLocation(t,"color");h=m.getUniformLocation(t,"scale");k=m.getUniformLocation(t,"rotation");l=m.getUniformLocation(t,"screenPosition")}m.useProgram(t);q.initAttributes();q.enableAttribute(p);q.enableAttribute(n);q.disableUnusedAttributes();m.uniform1i(e,0);m.uniform1i(d,1);m.bindBuffer(m.ARRAY_BUFFER,u);m.vertexAttribPointer(p,2,m.FLOAT,!1,16,0);m.vertexAttribPointer(n,2,m.FLOAT,!1,16,8);m.bindBuffer(m.ELEMENT_ARRAY_BUFFER,v);q.disable(m.CULL_FACE);q.setDepthWrite(!1);N=0;
for(M=b.length;N<M;N++)if(F=16/z.w,H.set(F*y,F),I=b[N],x.set(I.matrixWorld.elements[12],I.matrixWorld.elements[13],I.matrixWorld.elements[14]),x.applyMatrix4(D.matrixWorldInverse),x.applyProjection(D.projectionMatrix),L.copy(x),A.x=L.x*B+B,A.y=L.y*G+G,s||0<A.x&&A.x<z.z&&0<A.y&&A.y<z.w){q.activeTexture(m.TEXTURE0);q.bindTexture(m.TEXTURE_2D,null);q.activeTexture(m.TEXTURE1);q.bindTexture(m.TEXTURE_2D,w);m.copyTexImage2D(m.TEXTURE_2D,0,m.RGB,z.x+A.x-8,z.y+A.y-8,16,16,0);m.uniform1i(c,0);m.uniform2f(h,
H.x,H.y);m.uniform3f(l,L.x,L.y,L.z);q.disable(m.BLEND);q.enable(m.DEPTH_TEST);m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0);q.activeTexture(m.TEXTURE0);q.bindTexture(m.TEXTURE_2D,E);m.copyTexImage2D(m.TEXTURE_2D,0,m.RGBA,z.x+A.x-8,z.y+A.y-8,16,16,0);m.uniform1i(c,1);q.disable(m.DEPTH_TEST);q.activeTexture(m.TEXTURE1);q.bindTexture(m.TEXTURE_2D,w);m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0);I.positionScreen.copy(L);I.customUpdateCallback?I.customUpdateCallback(I):I.updateLensFlares();m.uniform1i(c,
2);q.enable(m.BLEND);for(var O=0,Q=I.lensFlares.length;O<Q;O++){var P=I.lensFlares[O];.001<P.opacity&&.001<P.scale&&(L.x=P.x,L.y=P.y,L.z=P.z,F=P.size*P.scale/z.w,H.x=F*y,H.y=F,m.uniform3f(l,L.x,L.y,L.z),m.uniform2f(h,H.x,H.y),m.uniform1f(k,P.rotation),m.uniform1f(f,P.opacity),m.uniform3f(g,P.color.r,P.color.g,P.color.b),q.setBlending(P.blending,P.blendEquation,P.blendSrc,P.blendDst),a.setTexture(P.texture,1),m.drawElements(m.TRIANGLES,6,m.UNSIGNED_SHORT,0))}}q.enable(m.CULL_FACE);q.enable(m.DEPTH_TEST);
q.setDepthWrite(!0);a.resetGLState()}}};
THREE.SpritePlugin=function(a,b){var c,d,e,f,g,h,k,l,p,n,m,q,u,v,t,s,w;function E(a,b){return a.renderOrder!==b.renderOrder?a.renderOrder-b.renderOrder:a.z!==b.z?b.z-a.z:b.id-a.id}var x=a.context,D=a.state,z,y,B,G,F=new THREE.Vector3,H=new THREE.Quaternion,L=new THREE.Vector3;this.render=function(A,N){if(0!==b.length){if(void 0===B){var M=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),I=new Uint16Array([0,1,2,0,2,3]);z=x.createBuffer();y=x.createBuffer();x.bindBuffer(x.ARRAY_BUFFER,
z);x.bufferData(x.ARRAY_BUFFER,M,x.STATIC_DRAW);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,y);x.bufferData(x.ELEMENT_ARRAY_BUFFER,I,x.STATIC_DRAW);var M=x.createProgram(),I=x.createShader(x.VERTEX_SHADER),O=x.createShader(x.FRAGMENT_SHADER);x.shaderSource(I,["precision "+a.getPrecision()+" float;","uniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform float rotation;\nuniform vec2 scale;\nuniform vec2 uvOffset;\nuniform vec2 uvScale;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uvOffset + uv * uvScale;\nvec2 alignedPosition = position * scale;\nvec2 rotatedPosition;\nrotatedPosition.x = cos( rotation ) * alignedPosition.x – sin( rotation ) * alignedPosition.y;\nrotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\nvec4 finalPosition;\nfinalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\nfinalPosition.xy += rotatedPosition;\nfinalPosition = projectionMatrix * finalPosition;\ngl_Position = finalPosition;\n}"].join("\n"));
x.shaderSource(O,["precision "+a.getPrecision()+" float;","uniform vec3 color;\nuniform sampler2D map;\nuniform float opacity;\nuniform int fogType;\nuniform vec3 fogColor;\nuniform float fogDensity;\nuniform float fogNear;\nuniform float fogFar;\nuniform float alphaTest;\nvarying vec2 vUV;\nvoid main() {\nvec4 texture = texture2D( map, vUV );\nif ( texture.a 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfogFactor = exp2( – fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 – clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}”].join(“\n”));
x.compileShader(I);x.compileShader(O);x.attachShader(M,I);x.attachShader(M,O);x.linkProgram(M);B=M;s=x.getAttribLocation(B,”position”);w=x.getAttribLocation(B,”uv”);c=x.getUniformLocation(B,”uvOffset”);d=x.getUniformLocation(B,”uvScale”);e=x.getUniformLocation(B,”rotation”);f=x.getUniformLocation(B,”scale”);g=x.getUniformLocation(B,”color”);h=x.getUniformLocation(B,”map”);k=x.getUniformLocation(B,”opacity”);l=x.getUniformLocation(B,”modelViewMatrix”);p=x.getUniformLocation(B,”projectionMatrix”);n=
x.getUniformLocation(B,”fogType”);m=x.getUniformLocation(B,”fogDensity”);q=x.getUniformLocation(B,”fogNear”);u=x.getUniformLocation(B,”fogFar”);v=x.getUniformLocation(B,”fogColor”);t=x.getUniformLocation(B,”alphaTest”);M=document.createElement(“canvas”);M.width=8;M.height=8;I=M.getContext(“2d”);I.fillStyle=”white”;I.fillRect(0,0,8,8);G=new THREE.Texture(M);G.needsUpdate=!0}x.useProgram(B);D.initAttributes();D.enableAttribute(s);D.enableAttribute(w);D.disableUnusedAttributes();D.disable(x.CULL_FACE);
D.enable(x.BLEND);x.bindBuffer(x.ARRAY_BUFFER,z);x.vertexAttribPointer(s,2,x.FLOAT,!1,16,0);x.vertexAttribPointer(w,2,x.FLOAT,!1,16,8);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,y);x.uniformMatrix4fv(p,!1,N.projectionMatrix.elements);D.activeTexture(x.TEXTURE0);x.uniform1i(h,0);I=M=0;(O=A.fog)?(x.uniform3f(v,O.color.r,O.color.g,O.color.b),O instanceof THREE.Fog?(x.uniform1f(q,O.near),x.uniform1f(u,O.far),x.uniform1i(n,1),I=M=1):O instanceof THREE.FogExp2&&(x.uniform1f(m,O.density),x.uniform1i(n,2),I=M=2)):
(x.uniform1i(n,0),I=M=0);for(var O=0,Q=b.length;O<Q;O++){var P=b[O];P.modelViewMatrix.multiplyMatrices(N.matrixWorldInverse,P.matrixWorld);P.z=-P.modelViewMatrix.elements[14]}b.sort(E);for(var T=[],O=0,Q=b.length;O<Q;O++){var P=b[O],J=P.material;x.uniform1f(t,J.alphaTest);x.uniformMatrix4fv(l,!1,P.modelViewMatrix.elements);P.matrixWorld.decompose(F,H,L);T[0]=L.x;T[1]=L.y;P=0;A.fog&&J.fog&&(P=I);M!==P&&(x.uniform1i(n,P),M=P);null!==J.map?(x.uniform2f(c,J.map.offset.x,J.map.offset.y),x.uniform2f(d,
J.map.repeat.x,J.map.repeat.y)):(x.uniform2f(c,0,0),x.uniform2f(d,1,1));x.uniform1f(k,J.opacity);x.uniform3f(g,J.color.r,J.color.g,J.color.b);x.uniform1f(e,J.rotation);x.uniform2fv(f,T);D.setBlending(J.blending,J.blendEquation,J.blendSrc,J.blendDst);D.setDepthTest(J.depthTest);D.setDepthWrite(J.depthWrite);J.map&&J.map.image&&J.map.image.width?a.setTexture(J.map,0):a.setTexture(G,0);x.drawElements(x.TRIANGLES,6,x.UNSIGNED_SHORT,0)}D.enable(x.CULL_FACE);a.resetGLState()}}};
Object.defineProperties(THREE.Box2.prototype,{empty:{value:function(){console.warn("THREE.Box2: .empty() has been renamed to .isEmpty().");return this.isEmpty()}},isIntersectionBox:{value:function(a){console.warn("THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)}}});
Object.defineProperties(THREE.Box3.prototype,{empty:{value:function(){console.warn("THREE.Box3: .empty() has been renamed to .isEmpty().");return this.isEmpty()}},isIntersectionBox:{value:function(a){console.warn("THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)}},isIntersectionSphere:{value:function(a){console.warn("THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().");return this.intersectsSphere(a)}}});
Object.defineProperties(THREE.Matrix3.prototype,{multiplyVector3:{value:function(a){console.warn("THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.");return a.applyMatrix3(this)}},multiplyVector3Array:{value:function(a){console.warn("THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.");return this.applyToVector3Array(a)}}});
Object.defineProperties(THREE.Matrix4.prototype,{extractPosition:{value:function(a){console.warn("THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().");return this.copyPosition(a)}},setRotationFromQuaternion:{value:function(a){console.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().");return this.makeRotationFromQuaternion(a)}},multiplyVector3:{value:function(a){console.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.");
return a.applyProjection(this)}},multiplyVector4:{value:function(a){console.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)}},multiplyVector3Array:{value:function(a){console.warn("THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.");return this.applyToVector3Array(a)}},rotateAxis:{value:function(a){console.warn("THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.");
a.transformDirection(this)}},crossVector:{value:function(a){console.warn("THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)}},translate:{value:function(a){console.error("THREE.Matrix4: .translate() has been removed.")}},rotateX:{value:function(a){console.error("THREE.Matrix4: .rotateX() has been removed.")}},rotateY:{value:function(a){console.error("THREE.Matrix4: .rotateY() has been removed.")}},rotateZ:{value:function(a){console.error("THREE.Matrix4: .rotateZ() has been removed.")}},
rotateByAxis:{value:function(a,b){console.error("THREE.Matrix4: .rotateByAxis() has been removed.")}}});Object.defineProperties(THREE.Plane.prototype,{isIntersectionLine:{value:function(a){console.warn("THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().");return this.intersectsLine(a)}}});
Object.defineProperties(THREE.Quaternion.prototype,{multiplyVector3:{value:function(a){console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.");return a.applyQuaternion(this)}}});
Object.defineProperties(THREE.Ray.prototype,{isIntersectionBox:{value:function(a){console.warn("THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)}},isIntersectionPlane:{value:function(a){console.warn("THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().");return this.intersectsPlane(a)}},isIntersectionSphere:{value:function(a){console.warn("THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().");return this.intersectsSphere(a)}}});
Object.defineProperties(THREE.Vector3.prototype,{setEulerFromRotationMatrix:{value:function(){console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")}},setEulerFromQuaternion:{value:function(){console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")}},getPositionFromMatrix:{value:function(a){console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");
return this.setFromMatrixPosition(a)}},getScaleFromMatrix:{value:function(a){console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)}},getColumnFromMatrix:{value:function(a,b){console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(a,b)}}});
THREE.Face4=function(a,b,c,d,e,f,g){console.warn("THREE.Face4 has been removed. A THREE.Face3 will be created instead.");return new THREE.Face3(a,b,c,e,f,g)};THREE.Vertex=function(a,b,c){console.warn("THREE.Vertex has been removed. Use THREE.Vector3 instead.");return new THREE.Vector3(a,b,c)};
Object.defineProperties(THREE.Object3D.prototype,{eulerOrder:{get:function(){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");return this.rotation.order},set:function(a){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");this.rotation.order=a}},getChildByName:{value:function(a){console.warn("THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().");return this.getObjectByName(a)}},renderDepth:{set:function(a){console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.")}},
translate:{value:function(a,b){console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.");return this.translateOnAxis(b,a)}},useQuaternion:{get:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set:function(a){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")}}});
Object.defineProperties(THREE,{PointCloud:{value:function(a,b){console.warn("THREE.PointCloud has been renamed to THREE.Points.");return new THREE.Points(a,b)}},ParticleSystem:{value:function(a,b){console.warn("THREE.ParticleSystem has been renamed to THREE.Points.");return new THREE.Points(a,b)}}});
Object.defineProperties(THREE.Light.prototype,{onlyShadow:{set:function(a){console.warn("THREE.Light: .onlyShadow has been removed.")}},shadowCameraFov:{set:function(a){console.warn("THREE.Light: .shadowCameraFov is now .shadow.camera.fov.");this.shadow.camera.fov=a}},shadowCameraLeft:{set:function(a){console.warn("THREE.Light: .shadowCameraLeft is now .shadow.camera.left.");this.shadow.camera.left=a}},shadowCameraRight:{set:function(a){console.warn("THREE.Light: .shadowCameraRight is now .shadow.camera.right.");
this.shadow.camera.right=a}},shadowCameraTop:{set:function(a){console.warn("THREE.Light: .shadowCameraTop is now .shadow.camera.top.");this.shadow.camera.top=a}},shadowCameraBottom:{set:function(a){console.warn("THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.");this.shadow.camera.bottom=a}},shadowCameraNear:{set:function(a){console.warn("THREE.Light: .shadowCameraNear is now .shadow.camera.near.");this.shadow.camera.near=a}},shadowCameraFar:{set:function(a){console.warn("THREE.Light: .shadowCameraFar is now .shadow.camera.far.");
this.shadow.camera.far=a}},shadowCameraVisible:{set:function(a){console.warn("THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.")}},shadowBias:{set:function(a){console.warn("THREE.Light: .shadowBias is now .shadow.bias.");this.shadow.bias=a}},shadowDarkness:{set:function(a){console.warn("THREE.Light: .shadowDarkness has been removed.")}},shadowMapWidth:{set:function(a){console.warn("THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.");
this.shadow.mapSize.width=a}},shadowMapHeight:{set:function(a){console.warn("THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.");this.shadow.mapSize.height=a}}});Object.defineProperties(THREE.BufferAttribute.prototype,{length:{get:function(){console.warn("THREE.BufferAttribute: .length has been deprecated. Please use .count.");return this.array.length}}});
Object.defineProperties(THREE.BufferGeometry.prototype,{drawcalls:{get:function(){console.error("THREE.BufferGeometry: .drawcalls has been renamed to .groups.");return this.groups}},offsets:{get:function(){console.warn("THREE.BufferGeometry: .offsets has been renamed to .groups.");return this.groups}},addIndex:{value:function(a){console.warn("THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().");this.setIndex(a)}},addDrawCall:{value:function(a,b,c){void 0!==c&&console.warn("THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.");
console.warn("THREE.BufferGeometry: .addDrawCall() is now .addGroup().");this.addGroup(a,b)}},clearDrawCalls:{value:function(){console.warn("THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().");this.clearGroups()}},computeTangents:{value:function(){console.warn("THREE.BufferGeometry: .computeTangents() has been removed.")}},computeOffsets:{value:function(){console.warn("THREE.BufferGeometry: .computeOffsets() has been removed.")}}});
Object.defineProperties(THREE.Material.prototype,{wrapAround:{get:function(){console.warn("THREE."+this.type+": .wrapAround has been removed.")},set:function(a){console.warn("THREE."+this.type+": .wrapAround has been removed.")}},wrapRGB:{get:function(){console.warn("THREE."+this.type+": .wrapRGB has been removed.");return new THREE.Color}}});
Object.defineProperties(THREE,{PointCloudMaterial:{value:function(a){console.warn("THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.");return new THREE.PointsMaterial(a)}},ParticleBasicMaterial:{value:function(a){console.warn("THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.");return new THREE.PointsMaterial(a)}},ParticleSystemMaterial:{value:function(a){console.warn("THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.");return new THREE.PointsMaterial(a)}}});
Object.defineProperties(THREE.MeshPhongMaterial.prototype,{metal:{get:function(){console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.");return!1},set:function(a){console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead")}}});
Object.defineProperties(THREE.ShaderMaterial.prototype,{derivatives:{get:function(){console.warn("THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.");return this.extensions.derivatives},set:function(a){console.warn("THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.");this.extensions.derivatives=a}}});
Object.defineProperties(THREE.WebGLRenderer.prototype,{supportsFloatTextures:{value:function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");return this.extensions.get("OES_texture_float")}},supportsHalfFloatTextures:{value:function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return this.extensions.get("OES_texture_half_float")}},supportsStandardDerivatives:{value:function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");
return this.extensions.get("OES_standard_derivatives")}},supportsCompressedTextureS3TC:{value:function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");return this.extensions.get("WEBGL_compressed_texture_s3tc")}},supportsCompressedTexturePVRTC:{value:function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return this.extensions.get("WEBGL_compressed_texture_pvrtc")}},
supportsBlendMinMax:{value:function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return this.extensions.get("EXT_blend_minmax")}},supportsVertexTextures:{value:function(){return this.capabilities.vertexTextures}},supportsInstancedArrays:{value:function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");return this.extensions.get("ANGLE_instanced_arrays")}},enableScissorTest:{value:function(a){console.warn("THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().");
this.setScissorTest(a)}},initMaterial:{value:function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")}},addPrePlugin:{value:function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")}},addPostPlugin:{value:function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}},updateShadowMap:{value:function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}},shadowMapEnabled:{get:function(){return this.shadowMap.enabled},
set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");this.shadowMap.enabled=a}},shadowMapType:{get:function(){return this.shadowMap.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");this.shadowMap.type=a}},shadowMapCullFace:{get:function(){return this.shadowMap.cullFace},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");this.shadowMap.cullFace=a}}});
Object.defineProperties(THREE.WebGLRenderTarget.prototype,{wrapS:{get:function(){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");return this.texture.wrapS},set:function(a){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");this.texture.wrapS=a}},wrapT:{get:function(){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");return this.texture.wrapT},set:function(a){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");this.texture.wrapT=
a}},magFilter:{get:function(){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");return this.texture.magFilter},set:function(a){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");this.texture.magFilter=a}},minFilter:{get:function(){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");return this.texture.minFilter},set:function(a){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");this.texture.minFilter=
a}},anisotropy:{get:function(){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");return this.texture.anisotropy},set:function(a){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");this.texture.anisotropy=a}},offset:{get:function(){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");return this.texture.offset},set:function(a){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");this.texture.offset=
a}},repeat:{get:function(){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");return this.texture.repeat},set:function(a){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");this.texture.repeat=a}},format:{get:function(){console.warn("THREE.WebGLRenderTarget: .format is now .texture.format.");return this.texture.format},set:function(a){console.warn("THREE.WebGLRenderTarget: .format is now .texture.format.");this.texture.format=a}},type:{get:function(){console.warn("THREE.WebGLRenderTarget: .type is now .texture.type.");
return this.texture.type},set:function(a){console.warn("THREE.WebGLRenderTarget: .type is now .texture.type.");this.texture.type=a}},generateMipmaps:{get:function(){console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.");return this.texture.generateMipmaps},set:function(a){console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.");this.texture.generateMipmaps=a}}});
THREE.GeometryUtils={merge:function(a,b,c){console.warn("THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.");var d;b instanceof THREE.Mesh&&(b.matrixAutoUpdate&&b.updateMatrix(),d=b.matrix,b=b.geometry);a.merge(b,d,c)},center:function(a){console.warn("THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.");return a.center()}};
THREE.ImageUtils={crossOrigin:void 0,loadTexture:function(a,b,c,d){console.warn("THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.");var e=new THREE.TextureLoader;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,d);b&&(a.mapping=b);return a},loadTextureCube:function(a,b,c,d){console.warn("THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.");var e=new THREE.CubeTextureLoader;e.setCrossOrigin(this.crossOrigin);a=e.load(a,
c,void 0,d);b&&(a.mapping=b);return a},loadCompressedTexture:function(){console.error("THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.")},loadCompressedTextureCube:function(){console.error("THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.")}};
THREE.Projector=function(){console.error("THREE.Projector has been moved to /examples/js/renderers/Projector.js.");this.projectVector=function(a,b){console.warn("THREE.Projector: .projectVector() is now vector.project().");a.project(b)};this.unprojectVector=function(a,b){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");a.unproject(b)};this.pickingRay=function(a,b){console.error("THREE.Projector: .pickingRay() is now raycaster.setFromCamera().")}};
THREE.CanvasRenderer=function(){console.error("THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js");this.domElement=document.createElement("canvas");this.clear=function(){};this.render=function(){};this.setClearColor=function(){};this.setSize=function(){}};THREE.MeshFaceMaterial=THREE.MultiMaterial;
THREE.CurveUtils={tangentQuadraticBezier:function(a,b,c,d){return 2*(1-a)*(c-b)+2*a*(d-c)},tangentCubicBezier:function(a,b,c,d,e){return-3*b*(1-a)*(1-a)+3*c*(1-a)*(1-a)-6*a*c*(1-a)+6*a*d*(1-a)-3*a*a*d+3*a*a*e},tangentSpline:function(a,b,c,d,e){return 6*a*a-6*a+(3*a*a-4*a+1)+(-6*a*a+6*a)+(3*a*a-2*a)},interpolate:function(a,b,c,d,e){a=.5*(c-a);d=.5*(d-b);var f=e*e;return(2*b-2*c+a+d)*e*f+(-3*b+3*c-2*a-d)*f+a*e+b}};
THREE.SceneUtils={createMultiMaterialObject:function(a,b){for(var c=new THREE.Group,d=0,e=b.length;d<e;d++)c.add(new THREE.Mesh(a,b[d]));return c},detach:function(a,b,c){a.applyMatrix(b.matrixWorld);b.remove(a);c.add(a)},attach:function(a,b,c){var d=new THREE.Matrix4;d.getInverse(c.matrixWorld);a.applyMatrix(d);b.remove(a);c.add(a)}};
THREE.ShapeUtils={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;ec)return null;var d=[],e=[],f=[],g,h,k;if(0<THREE.ShapeUtils.area(a))for(h=0;h<c;h++)e[h]=h;else for(h=0;h<c;h++)e[h]=c-1-h;var l=2*c;for(h=c-1;2=l–){console.warn(“THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()”);break}g=h;c<=g&&(g=0);h=g+1;c<=h&&(h=0);k=h+1;c(q-n)*(t-m)-(u-m)*(v-n))p=!1;else{var E=void 0,x=void 0,D=void 0,z=void 0,y=void 0,B=void 0,G=void 0,F=void 0,H=void 0,L=void 0,H=F=G=w=s=void 0,E=v-q,x=t-u,D=n-v,z=m-t,y=q-n,B=u-m;for(p=0;p=-Number.EPSILON&&
F>=-Number.EPSILON&&G>=-Number.EPSILON)){p=!1;break a}p=!0}}if(p){d.push([a[e[g]],a[e[h]],a[e[k]]]);f.push([e[g],e[h],e[k]]);g=h;for(k=h+1;k<c;g++,k++)e[g]=e[k];c–;l=2*c}}return b?f:d}}(),triangulateShape:function(a,b){function c(a,b,c){return a.x!==b.x?a.x<b.x?a.x<=c.x&&c.x<=b.x:b.x<=c.x&&c.x<=a.x:a.y<b.y?a.y<=c.y&&c.y<=b.y:b.y<=c.y&&c.yNumber.EPSILON){if(0B||B>
y)return[];k=l*n-k*p;if(0>k||k>y)return[]}else{if(0<B||B<y)return[];k=l*n-k*p;if(0<k||k<y)return[]}if(0===k)return!f||0!==B&&B!==y?[a]:[];if(k===y)return!f||0!==B&&B!==y?[b]:[];if(0===B)return[d];if(B===y)return[e];f=k/y;return[{x:a.x+f*g,y:a.y+f*h}]}if(0!==B||l*n!==k*p)return[];h=0===g&&0===h;k=0===k&&0===l;if(h&&k)return a.x!==d.x||a.y!==d.y?[]:[a];if(h)return c(d,e,a)?[a]:[];if(k)return c(a,b,d)?[d]:[];0!==g?(a.x<b.x?(g=a,k=a.x,h=b,a=b.x):(g=b,k=b.x,h=a,a=a.x),d.x<e.x?(b=d,y=d.x,l=e,d=e.x):(b=
e,y=e.x,l=d,d=d.x)):(a.y<b.y?(g=a,k=a.y,h=b,a=b.y):(g=b,k=b.y,h=a,a=a.y),d.y<e.y?(b=d,y=d.y,l=e,d=e.y):(b=e,y=e.y,l=d,d=d.y));return k<=y?a<y?[]:a===y?f?[]:[b]:ad?[]:k===d?f?[]:[g]:aNumber.EPSILON?(b=g*c-d*b,0<a?0<=e&&0<=b:0<=e||0<=b):0<e}var f,g,h,k,l,p={};h=a.concat();f=0;for(g=b.length;f<g;f++)Array.prototype.push.apply(h,b[f]);f=0;for(g=
h.length;ff&&(f=d);var g=a+1;g>d&&(g=0);d=e(h[a],h[f],h[g],k[b]);if(!d)return!1;d=k.length-1;f=b-1;0>f&&(f=d);g=b+1;g>d&&(g=0);return(d=e(k[b],k[f],k[g],h[a]))?!0:!1}function f(a,b){var c,e;for(c=0;c<h.length;c++)if(e=c+1,e%=h.length,e=d(a,b,h[c],h[e],!0),0<e.length)return!0;return!1}function g(a,c){var e,f,h,k;for(e=0;e<l.length;e++)for(f=b[l[e]],
h=0;h<f.length;h++)if(k=h+1,k%=f.length,k=d(a,c,f[h],f[k],!0),0<k.length)return!0;return!1}var h=a.concat(),k,l=[],n,p,z,y,B,G=[],F,H,L,A=0;for(n=b.length;A<n;A++)l.push(A);F=0;for(var N=2*l.length;0N){console.log(“Infinite Loop! Holes left:”+l.length+”, Probably Hole outside Shape!”);break}for(p=F;p<h.length;p++){z=h[p];n=-1;for(A=0;A<l.length;A++)if(y=l[A],B=z.x+":"+z.y+":"+y,void 0===G[B]){k=b[y];for(H=0;H<k.length;H++)if(y=k[H],c(p,H)&&!f(z,y)&&!g(z,y)){n=H;l.splice(A,1);
F=h.slice(0,p+1);y=h.slice(p);H=k.slice(n);L=k.slice(0,n+1);h=F.concat(H).concat(L).concat(y);F=p;break}if(0<=n)break;G[B]=!0}if(0<=n)break}}return h}(a,b);var n=THREE.ShapeUtils.triangulate(f,!1);f=0;for(g=n.length;fh;h++)l=k[h].x+”:”+k[h].y,l=p[l],void 0!==l&&(k[h]=l);return n.concat()},isClockWise:function(a){return 0>THREE.ShapeUtils.area(a)},b2:function(){return function(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}}(),b3:function(){return function(a,b,c,d,e){var f=
1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}}()};THREE.Curve=function(){};
THREE.Curve.prototype={constructor:THREE.Curve,getPoint:function(a){console.warn(“THREE.Curve: Warning, getPoint() not implemented!”);return null},getPointAt:function(a){a=this.getUtoTmapping(a);return this.getPoint(a)},getPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPoint(b/a));return c},getSpacedPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPointAt(b/a));return c},getLength:function(){var a=this.getLengths();return a[a.length-1]},getLengths:function(a){a||
(a=this.__arcLengthDivisions?this.__arcLengthDivisions:200);if(this.cacheArcLengths&&this.cacheArcLengths.length===a+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;var b=[],c,d=this.getPoint(0),e,f=0;b.push(0);for(e=1;e<=a;e++)c=this.getPoint(e/a),f+=c.distanceTo(d),b.push(f),d=c;return this.cacheArcLengths=b},updateArcLengths:function(){this.needsUpdate=!0;this.getLengths()},getUtoTmapping:function(a,b){var c=this.getLengths(),d=0,e=c.length,f;f=b?b:a*c[e-1];for(var g=0,h=e-
1,k;gk)g=d+1;else if(0b&&(b=0);1<a&&(a=1);b=this.getPoint(b);return this.getPoint(a).clone().sub(b).normalize()},getTangentAt:function(a){a=this.getUtoTmapping(a);return this.getTangent(a)}};
THREE.Curve.create=function(a,b){a.prototype=Object.create(THREE.Curve.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};THREE.CurvePath=function(){this.curves=[];this.autoClose=!1};THREE.CurvePath.prototype=Object.create(THREE.Curve.prototype);THREE.CurvePath.prototype.constructor=THREE.CurvePath;THREE.CurvePath.prototype.add=function(a){this.curves.push(a)};
THREE.CurvePath.prototype.closePath=function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);a.equals(b)||this.curves.push(new THREE.LineCurve(b,a))};THREE.CurvePath.prototype.getPoint=function(a){for(var b=a*this.getLength(),c=this.getCurveLengths(),d=0;d=b)return a=this.curves[d],b=1-(c[d]-b)/a.getLength(),a.getPointAt(b);d++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]};
THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;c<d;c++)b+=this.curves[c].getLength(),a.push(b);return this.cacheLengths=a};THREE.CurvePath.prototype.createPointsGeometry=function(a){a=this.getPoints(a);return this.createGeometry(a)};THREE.CurvePath.prototype.createSpacedPointsGeometry=function(a){a=this.getSpacedPoints(a);return this.createGeometry(a)};
THREE.CurvePath.prototype.createGeometry=function(a){for(var b=new THREE.Geometry,c=0,d=a.length;c<d;c++){var e=a[c];b.vertices.push(new THREE.Vector3(e.x,e.y,e.z||0))}return b};THREE.Font=function(a){this.data=a};
THREE.Font.prototype={constructor:THREE.Font,generateShapes:function(a,b,c){void 0===b&&(b=100);void 0===c&&(c=4);var d=this.data;a=String(a).split("");var e=b/d.resolution,f=0;b=[];for(var g=0;g<a.length;g++){var h;h=e;var k=f,l=d.glyphs[a[g]]||d.glyphs["?"];if(l){var p=new THREE.Path,n=[],m=THREE.ShapeUtils.b2,q=THREE.ShapeUtils.b3,u=void 0,v=void 0,t=v=u=void 0,s=void 0,w=void 0,E=void 0,x=void 0,D=void 0,s=void 0;if(l.o)for(var z=l._cachedOutline||(l._cachedOutline=l.o.split(" ")),y=0,B=z.length;y<
B;)switch(z[y++]){case "m":u=z[y++]*h+k;v=z[y++]*h;p.moveTo(u,v);break;case "l":u=z[y++]*h+k;v=z[y++]*h;p.lineTo(u,v);break;case "q":u=z[y++]*h+k;v=z[y++]*h;w=z[y++]*h+k;E=z[y++]*h;p.quadraticCurveTo(w,E,u,v);if(s=n[n.length-1])for(var t=s.x,s=s.y,G=1;G<=c;G++){var F=G/c;m(F,t,w,u);m(F,s,E,v)}break;case "b":if(u=z[y++]*h+k,v=z[y++]*h,w=z[y++]*h+k,E=z[y++]*h,x=z[y++]*h+k,D=z[y++]*h,p.bezierCurveTo(w,E,x,D,u,v),s=n[n.length-1])for(t=s.x,s=s.y,G=1;G<=c;G++)F=G/c,q(F,t,w,x,u),q(F,s,E,D,v)}h={offset:l.ha*
h,path:p}}else h=void 0;f+=h.offset;b.push(h.path)}c=[];d=0;for(a=b.length;d<a;d++)Array.prototype.push.apply(c,b[d].toShapes());return c}};THREE.Path=function(a){THREE.CurvePath.call(this);this.actions=[];a&&this.fromPoints(a)};THREE.Path.prototype=Object.create(THREE.CurvePath.prototype);THREE.Path.prototype.constructor=THREE.Path;THREE.Path.prototype.fromPoints=function(a){this.moveTo(a[0].x,a[0].y);for(var b=1,c=a.length;b<c;b++)this.lineTo(a[b].x,a[b].y)};
THREE.Path.prototype.moveTo=function(a,b){this.actions.push({action:"moveTo",args:[a,b]})};THREE.Path.prototype.lineTo=function(a,b){var c=this.actions[this.actions.length-1].args,c=new THREE.LineCurve(new THREE.Vector2(c[c.length-2],c[c.length-1]),new THREE.Vector2(a,b));this.curves.push(c);this.actions.push({action:"lineTo",args:[a,b]})};
THREE.Path.prototype.quadraticCurveTo=function(a,b,c,d){var e=this.actions[this.actions.length-1].args,e=new THREE.QuadraticBezierCurve(new THREE.Vector2(e[e.length-2],e[e.length-1]),new THREE.Vector2(a,b),new THREE.Vector2(c,d));this.curves.push(e);this.actions.push({action:"quadraticCurveTo",args:[a,b,c,d]})};
THREE.Path.prototype.bezierCurveTo=function(a,b,c,d,e,f){var g=this.actions[this.actions.length-1].args,g=new THREE.CubicBezierCurve(new THREE.Vector2(g[g.length-2],g[g.length-1]),new THREE.Vector2(a,b),new THREE.Vector2(c,d),new THREE.Vector2(e,f));this.curves.push(g);this.actions.push({action:"bezierCurveTo",args:[a,b,c,d,e,f]})};
THREE.Path.prototype.splineThru=function(a){var b=Array.prototype.slice.call(arguments),c=this.actions[this.actions.length-1].args,c=[new THREE.Vector2(c[c.length-2],c[c.length-1])];Array.prototype.push.apply(c,a);c=new THREE.SplineCurve(c);this.curves.push(c);this.actions.push({action:"splineThru",args:b})};THREE.Path.prototype.arc=function(a,b,c,d,e,f){var g=this.actions[this.actions.length-1].args;this.absarc(a+g[g.length-2],b+g[g.length-1],c,d,e,f)};
THREE.Path.prototype.absarc=function(a,b,c,d,e,f){this.absellipse(a,b,c,c,d,e,f)};THREE.Path.prototype.ellipse=function(a,b,c,d,e,f,g,h){var k=this.actions[this.actions.length-1].args;this.absellipse(a+k[k.length-2],b+k[k.length-1],c,d,e,f,g,h)};THREE.Path.prototype.absellipse=function(a,b,c,d,e,f,g,h){var k=[a,b,c,d,e,f,g,h||0];a=new THREE.EllipseCurve(a,b,c,d,e,f,g,h);this.curves.push(a);a=a.getPoint(1);k.push(a.x);k.push(a.y);this.actions.push({action:"ellipse",args:k})};
THREE.Path.prototype.getSpacedPoints=function(a){a||(a=40);for(var b=[],c=0;c<a;c++)b.push(this.getPoint(c/a));this.autoClose&&b.push(b[0]);return b};
THREE.Path.prototype.getPoints=function(a){a=a||12;for(var b=THREE.ShapeUtils.b2,c=THREE.ShapeUtils.b3,d=[],e,f,g,h,k,l,p,n,m,q,u=0,v=this.actions.length;u<v;u++){m=this.actions[u];var t=m.args;switch(m.action){case "moveTo":d.push(new THREE.Vector2(t[0],t[1]));break;case "lineTo":d.push(new THREE.Vector2(t[0],t[1]));break;case "quadraticCurveTo":e=t[2];f=t[3];k=t[0];l=t[1];0<d.length?(m=d[d.length-1],p=m.x,n=m.y):(m=this.actions[u-1].args,p=m[m.length-2],n=m[m.length-1]);for(t=1;t<=a;t++)q=t/a,m=
b(q,p,k,e),q=b(q,n,l,f),d.push(new THREE.Vector2(m,q));break;case "bezierCurveTo":e=t[4];f=t[5];k=t[0];l=t[1];g=t[2];h=t[3];0<d.length?(m=d[d.length-1],p=m.x,n=m.y):(m=this.actions[u-1].args,p=m[m.length-2],n=m[m.length-1]);for(t=1;t<=a;t++)q=t/a,m=c(q,p,k,g,e),q=c(q,n,l,h,f),d.push(new THREE.Vector2(m,q));break;case "splineThru":m=this.actions[u-1].args;q=[new THREE.Vector2(m[m.length-2],m[m.length-1])];m=a*t[0].length;q=q.concat(t[0]);q=new THREE.SplineCurve(q);for(t=1;t<=m;t++)d.push(q.getPointAt(t/
m));break;case "arc":e=t[0];f=t[1];l=t[2];g=t[3];m=t[4];k=!!t[5];p=m-g;n=2*a;for(t=1;t<=n;t++)q=t/n,k||(q=1-q),q=g+q*p,m=e+l*Math.cos(q),q=f+l*Math.sin(q),d.push(new THREE.Vector2(m,q));break;case "ellipse":e=t[0];f=t[1];l=t[2];h=t[3];g=t[4];m=t[5];k=!!t[6];var s=t[7];p=m-g;n=2*a;var w,E;0!==s&&(w=Math.cos(s),E=Math.sin(s));for(t=1;t<=n;t++){q=t/n;k||(q=1-q);q=g+q*p;m=e+l*Math.cos(q);q=f+h*Math.sin(q);if(0!==s){var x=m;m=(x-e)*w-(q-f)*E+e;q=(x-e)*E+(q-f)*w+f}d.push(new THREE.Vector2(m,q))}}}a=d[d.length-
1];Math.abs(a.x-d[0].x)<Number.EPSILON&&Math.abs(a.y-d[0].y)<Number.EPSILON&&d.splice(d.length-1,1);this.autoClose&&d.push(d[0]);return d};
THREE.Path.prototype.toShapes=function(a,b){function c(a){for(var b=[],c=0,d=a.length;c<d;c++){var e=a[c],f=new THREE.Shape;f.actions=e.actions;f.curves=e.curves;b.push(f)}return b}function d(a,b){for(var c=b.length,d=!1,e=c-1,f=0;fNumber.EPSILON){if(0>l&&(g=b[f],k=-k,h=b[e],l=-l),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=l*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||
g.x<=a.x&&a.x<=h.x))return!0}return d}var e=THREE.ShapeUtils.isClockWise,f=function(a){for(var b=[],c=new THREE.Path,d=0,e=a.length;d<e;d++){var f=a[d],g=f.args,f=f.action;"moveTo"===f&&0!==c.actions.length&&(b.push(c),c=new THREE.Path);c[f].apply(c,g)}0!==c.actions.length&&b.push(c);return b}(this.actions);if(0===f.length)return[];if(!0===b)return c(f);var g,h,k,l=[];if(1===f.length)return h=f[0],k=new THREE.Shape,k.actions=h.actions,k.curves=h.curves,l.push(k),l;var p=!e(f[0].getPoints()),p=a?!p:
p;k=[];var n=[],m=[],q=0,u;n[q]=void 0;m[q]=[];for(var v=0,t=f.length;v<t;v++)h=f[v],u=h.getPoints(),g=e(u),(g=a?!g:g)?(!p&&n[q]&&q++,n[q]={s:new THREE.Shape,p:u},n[q].s.actions=h.actions,n[q].s.curves=h.curves,p&&q++,m[q]=[]):m[q].push({h:h,p:u[0]});if(!n[0])return c(f);if(1<n.length){v=!1;h=[];e=0;for(f=n.length;e<f;e++)k[e]=[];e=0;for(f=n.length;e<f;e++)for(g=m[e],p=0;p<g.length;p++){q=g[p];u=!0;for(t=0;t<n.length;t++)d(q.p,n[t].p)&&(e!==t&&h.push({froms:e,tos:t,hole:p}),u?(u=!1,k[t].push(q)):
v=!0);u&&k[e].push(q)}0<h.length&&(v||(m=k))}v=0;for(e=n.length;v<e;v++)for(k=n[v].s,l.push(k),h=m[v],f=0,g=h.length;f<g;f++)k.holes.push(h[f].h);return l};THREE.Shape=function(){THREE.Path.apply(this,arguments);this.holes=[]};THREE.Shape.prototype=Object.create(THREE.Path.prototype);THREE.Shape.prototype.constructor=THREE.Shape;THREE.Shape.prototype.extrude=function(a){return new THREE.ExtrudeGeometry(this,a)};THREE.Shape.prototype.makeGeometry=function(a){return new THREE.ShapeGeometry(this,a)};
THREE.Shape.prototype.getPointsHoles=function(a){for(var b=[],c=0,d=this.holes.length;cb.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=THREE.CurveUtils.interpolate;return new THREE.Vector2(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a))};THREE.EllipseCurve=function(a,b,c,d,e,f,g,h){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g;this.aRotation=h||0};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype);
THREE.EllipseCurve.prototype.constructor=THREE.EllipseCurve;
THREE.EllipseCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;0>b&&(b+=2*Math.PI);b>2*Math.PI&&(b-=2*Math.PI);b=!0===this.aClockwise?this.aEndAngle+(1-a)*(2*Math.PI-b):this.aStartAngle+a*b;a=this.aX+this.xRadius*Math.cos(b);var c=this.aY+this.yRadius*Math.sin(b);if(0!==this.aRotation){var b=Math.cos(this.aRotation),d=Math.sin(this.aRotation),e=a;a=(e-this.aX)*b-(c-this.aY)*d+this.aX;c=(e-this.aX)*d+(c-this.aY)*b+this.aY}return new THREE.Vector2(a,c)};
THREE.ArcCurve=function(a,b,c,d,e,f){THREE.EllipseCurve.call(this,a,b,c,c,d,e,f)};THREE.ArcCurve.prototype=Object.create(THREE.EllipseCurve.prototype);THREE.ArcCurve.prototype.constructor=THREE.ArcCurve;THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b});
THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b=THREE.ShapeUtils.b2;return new THREE.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y),b(a,this.v0.z,this.v1.z,this.v2.z))});
THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b=THREE.ShapeUtils.b3;return new THREE.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y),b(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z))});
THREE.SplineCurve3=THREE.Curve.create(function(a){console.warn(“THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3”);this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],f=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=THREE.CurveUtils.interpolate;return new THREE.Vector3(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a),c(d.z,e.z,f.z,b.z,a))});
THREE.CatmullRomCurve3=function(){function a(){}var b=new THREE.Vector3,c=new a,d=new a,e=new a;a.prototype.init=function(a,b,c,d){this.c0=a;this.c1=c;this.c2=-3*a+3*b-2*c-d;this.c3=2*a-2*b+c+d};a.prototype.initNonuniformCatmullRom=function(a,b,c,d,e,p,n){a=((b-a)/e-(c-a)/(e+p)+(c-b)/p)*p;d=((c-b)/p-(d-b)/(p+n)+(d-c)/n)*p;this.init(b,c,a,d)};a.prototype.initCatmullRom=function(a,b,c,d,e){this.init(b,c,e*(c-a),e*(d-b))};a.prototype.calc=function(a){var b=a*a;return this.c0+this.c1*a+this.c2*b+this.c3*
b*a};return THREE.Curve.create(function(a){this.points=a||[];this.closed=!1},function(a){var g=this.points,h,k;k=g.length;2>k&&console.log(“duh, you need at least 2 points”);a*=k-(this.closed?0:1);h=Math.floor(a);a-=h;this.closed?h+=0<h?0:(Math.floor(Math.abs(h)/g.length)+1)*g.length:0===a&&h===k-1&&(h=k-2,a=1);var l,p,n;this.closed||0<h?l=g[(h-1)%k]:(b.subVectors(g[0],g[1]).add(g[0]),l=b);p=g[h%k];n=g[(h+1)%k];this.closed||h+2h&&(h=1);1E-4>k&&(k=h);1E-4>m&&(m=h);c.initNonuniformCatmullRom(l.x,p.x,n.x,g.x,k,h,m);d.initNonuniformCatmullRom(l.y,p.y,n.y,g.y,k,h,m);e.initNonuniformCatmullRom(l.z,p.z,n.z,g.z,k,h,m)}else”catmullrom”===this.type&&(k=void 0!==this.tension?this.tension:.5,c.initCatmullRom(l.x,p.x,n.x,g.x,
k),d.initCatmullRom(l.y,p.y,n.y,g.y,k),e.initCatmullRom(l.z,p.z,n.z,g.z,k));return new THREE.Vector3(c.calc(a),d.calc(a),e.calc(a))})}();THREE.ClosedSplineCurve3=function(a){console.warn(“THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.”);THREE.CatmullRomCurve3.call(this,a);this.type=”catmullrom”;this.closed=!0};THREE.ClosedSplineCurve3.prototype=Object.create(THREE.CatmullRomCurve3.prototype);
THREE.BoxGeometry=function(a,b,c,d,e,f){THREE.Geometry.call(this);this.type=”BoxGeometry”;this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new THREE.BoxBufferGeometry(a,b,c,d,e,f));this.mergeVertices()};THREE.BoxGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.BoxGeometry.prototype.constructor=THREE.BoxGeometry;THREE.CubeGeometry=THREE.BoxGeometry;
THREE.BoxBufferGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,k,l,L,A){var N=f/l,M=g/L,I=f/2,O=g/2,Q=k/2;g=l+1;for(var P=L+1,T=f=0,J=new THREE.Vector3,C=0;C<P;C++)for(var Z=C*M-O,S=0;S<g;S++)J[a]=(S*N-I)*d,J[b]=Z*e,J[c]=Q,n[u]=J.x,n[u+1]=J.y,n[u+2]=J.z,J[a]=0,J[b]=0,J[c]=0<k?1:-1,m[u]=J.x,m[u+1]=J.y,m[u+2]=J.z,q[v]=S/l,q[v+1]=1-C/L,u+=3,v+=2,f+=1;for(C=0;C<L;C++)for(S=0;S<l;S++)a=s+S+g*(C+1),b=s+(S+1)+g*(C+1),c=s+(S+1)+g*C,p[t]=s+S+g*C,p[t+1]=a,p[t+2]=c,p[t+3]=a,p[t+4]=b,p[t+5]=c,t+=6,T+=
6;h.addGroup(w,T,A);w+=T;s+=f}THREE.BufferGeometry.call(this);this.type="BoxBufferGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};var h=this;d=Math.floor(d)||1;e=Math.floor(e)||1;f=Math.floor(f)||1;var k=function(a,b,c){a=0+a*b*2+a*c*2;a+=c*b*2;return 4*a}(d,e,f),l=k/4*6,p=new (65535<l?Uint32Array:Uint16Array)(l),n=new Float32Array(3*k),m=new Float32Array(3*k),q=new Float32Array(2*k),u=0,v=0,t=0,s=0,w=0;g("z","y","x",-1,-1,c,b,a,f,e,0);g("z","y",
"x",1,-1,c,b,-a,f,e,1);g("x","z","y",1,1,a,c,b,d,f,2);g("x","z","y",1,-1,a,c,-b,d,f,3);g("x","y","z",1,-1,a,b,c,d,e,4);g("x","y","z",-1,-1,a,b,-c,d,e,5);this.setIndex(new THREE.BufferAttribute(p,1));this.addAttribute("position",new THREE.BufferAttribute(n,3));this.addAttribute("normal",new THREE.BufferAttribute(m,3));this.addAttribute("uv",new THREE.BufferAttribute(q,2))};THREE.BoxBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);
THREE.BoxBufferGeometry.prototype.constructor=THREE.BoxBufferGeometry;THREE.CircleGeometry=function(a,b,c,d){THREE.Geometry.call(this);this.type="CircleGeometry";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};this.fromBufferGeometry(new THREE.CircleBufferGeometry(a,b,c,d))};THREE.CircleGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CircleGeometry.prototype.constructor=THREE.CircleGeometry;
THREE.CircleBufferGeometry=function(a,b,c,d){THREE.BufferGeometry.call(this);this.type="CircleBufferGeometry";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};a=a||50;b=void 0!==b?Math.max(3,b):8;c=void 0!==c?c:0;d=void 0!==d?d:2*Math.PI;var e=b+2,f=new Float32Array(3*e),g=new Float32Array(3*e),e=new Float32Array(2*e);g[2]=1;e[0]=.5;e[1]=.5;for(var h=0,k=3,l=2;h<=b;h++,k+=3,l+=2){var p=c+h/b*d;f[k]=a*Math.cos(p);f[k+1]=a*Math.sin(p);g[k+2]=1;e[l]=(f[k]/a+1)/2;e[l+1]=(f[k+1]/a+1)/2}c=
[];for(k=1;k<=b;k++)c.push(k,k+1,0);this.setIndex(new THREE.BufferAttribute(new Uint16Array(c),1));this.addAttribute("position",new THREE.BufferAttribute(f,3));this.addAttribute("normal",new THREE.BufferAttribute(g,3));this.addAttribute("uv",new THREE.BufferAttribute(e,2));this.boundingSphere=new THREE.Sphere(new THREE.Vector3,a)};THREE.CircleBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.CircleBufferGeometry.prototype.constructor=THREE.CircleBufferGeometry;
THREE.CylinderBufferGeometry=function(a,b,c,d,e,f,g,h){function k(c){var e,f,k;k=new THREE.Vector2;var l=new THREE.Vector3,p=!0===c?a:b,s=!0===c?1:-1;f=v;for(e=1;e<=d;e++)m.setXYZ(v,0,w*s,0),q.setXYZ(v,0,s,0),!0===c?(k.x=e/d,k.y=0):(k.x=(e-1)/d,k.y=1),u.setXY(v,k.x,k.y),v++;k=v;for(e=0;e<=d;e++){var F=e/d;l.x=p*Math.sin(F*h+g);l.y=w*s;l.z=p*Math.cos(F*h+g);m.setXYZ(v,l.x,l.y,l.z);q.setXYZ(v,0,s,0);u.setXY(v,F,!0===c?1:0);v++}for(e=0;e<d;e++)l=f+e,p=k+e,!0===c?(n.setX(t,p),t++,n.setX(t,p+1)):(n.setX(t,
p+1),t++,n.setX(t,p)),t++,n.setX(t,l),t++}THREE.BufferGeometry.call(this);this.type="CylinderBufferGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};a=void 0!==a?a:20;b=void 0!==b?b:20;c=void 0!==c?c:100;d=Math.floor(d)||8;e=Math.floor(e)||1;f=void 0!==f?f:!1;g=void 0!==g?g:0;h=void 0!==h?h:2*Math.PI;var l=function(){var a=(d+1)*(e+1);!1===f&&(a+=2*(d+1)+2*d);return a}(),p=function(){var a=d*e*6;!1===f&&(a+=6*d);
return a}(),n=new THREE.BufferAttribute(new (65535<p?Uint32Array:Uint16Array)(p),1),m=new THREE.BufferAttribute(new Float32Array(3*l),3),q=new THREE.BufferAttribute(new Float32Array(3*l),3),u=new THREE.BufferAttribute(new Float32Array(2*l),2),v=0,t=0,s=[],w=c/2;(function(){var f,k,l=new THREE.Vector3,p=new THREE.Vector3,y=(b-a)/c;for(k=0;k<=e;k++){var B=[],G=k/e,F=G*(b-a)+a;for(f=0;f<=d;f++){var H=f/d;p.x=F*Math.sin(H*h+g);p.y=-G*c+w;p.z=F*Math.cos(H*h+g);m.setXYZ(v,p.x,p.y,p.z);l.copy(p);if(0===
a&&0===k||0===b&&k===e)l.x=Math.sin(H*h+g),l.z=Math.cos(H*h+g);l.setY(Math.sqrt(l.x*l.x+l.z*l.z)*y).normalize();q.setXYZ(v,l.x,l.y,l.z);u.setXY(v,H,1-G);B.push(v);v++}s.push(B)}for(f=0;f<d;f++)for(k=0;k<e;k++)l=s[k+1][f],p=s[k+1][f+1],y=s[k][f+1],n.setX(t,s[k][f]),t++,n.setX(t,l),t++,n.setX(t,y),t++,n.setX(t,l),t++,n.setX(t,p),t++,n.setX(t,y),t++})();!1===f&&(0<a&&k(!0),0<b&&k(!1));this.setIndex(n);this.addAttribute("position",m);this.addAttribute("normal",q);this.addAttribute("uv",u)};
THREE.CylinderBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.CylinderBufferGeometry.prototype.constructor=THREE.CylinderBufferGeometry;THREE.CylinderGeometry=function(a,b,c,d,e,f,g,h){THREE.Geometry.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new THREE.CylinderBufferGeometry(a,b,c,d,e,f,g,h));this.mergeVertices()};
THREE.CylinderGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.CylinderGeometry.prototype.constructor=THREE.CylinderGeometry;
THREE.EdgesGeometry=function(a,b){function c(a,b){return a-b}THREE.BufferGeometry.call(this);var d=Math.cos(THREE.Math.degToRad(void 0!==b?b:1)),e=[0,0],f={},g=["a","b","c"],h;a instanceof THREE.BufferGeometry?(h=new THREE.Geometry,h.fromBufferGeometry(a)):h=a.clone();h.mergeVertices();h.computeFaceNormals();var k=h.vertices;h=h.faces;for(var l=0,p=h.length;l m;m++){e[0]=n[g[m]];e[1]=n[g[(m+1)%3]];e.sort(c);var q=e.toString();void 0===f[q]?f[q]={vert1:e[0],vert2:e[1],face1:l,
face2:void 0}:f[q].face2=l}e=[];for(q in f)if(g=f[q],void 0===g.face2||h[g.face1].normal.dot(h[g.face2].normal)<=d)l=k[g.vert1],e.push(l.x),e.push(l.y),e.push(l.z),l=k[g.vert2],e.push(l.x),e.push(l.y),e.push(l.z);this.addAttribute("position",new THREE.BufferAttribute(new Float32Array(e),3))};THREE.EdgesGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.EdgesGeometry.prototype.constructor=THREE.EdgesGeometry;
THREE.ExtrudeGeometry=function(a,b){"undefined"!==typeof a&&(THREE.Geometry.call(this),this.type="ExtrudeGeometry",a=Array.isArray(a)?a:[a],this.addShapeList(a,b),this.computeFaceNormals())};THREE.ExtrudeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ExtrudeGeometry.prototype.constructor=THREE.ExtrudeGeometry;THREE.ExtrudeGeometry.prototype.addShapeList=function(a,b){for(var c=a.length,d=0;dNumber.EPSILON){var k=Math.sqrt(h),l=Math.sqrt(f*f+g*g),h=b.x-e/k;b=b.y+d/k;f=((c.x-g/l-h)*g-(c.y+f/l-b)*f)/(d*g-e*f);c=h+d*f-a.x;a=b+e*f-a.y;d=c*c+a*a;if(2>=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,d>Number.EPSILON?
f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(C=a.length;0d&&(d=a.length-1);for(var e=0,f=q+2*p,e=0;e<f;e++){var g=P*e,h=P*(e+1),k=b+c+g,g=b+d+g,l=b+d+h,h=b+c+h,k=k+F,g=g+F,l=l+F,h=h+F;G.faces.push(new THREE.Face3(k,g,h,null,null,1));G.faces.push(new THREE.Face3(g,l,h,null,null,1));k=s.generateSideWallUV(G,
k,g,l,h);G.faceVertexUvs[0].push([k[0],k[1],k[3]]);G.faceVertexUvs[0].push([k[1],k[2],k[3]])}}}function f(a,b,c){G.vertices.push(new THREE.Vector3(a,b,c))}function g(a,b,c){a+=F;b+=F;c+=F;G.faces.push(new THREE.Face3(a,b,c,null,null,0));a=s.generateTopUV(G,a,b,c);G.faceVertexUvs[0].push(a)}var h=void 0!==b.amount?b.amount:100,k=void 0!==b.bevelThickness?b.bevelThickness:6,l=void 0!==b.bevelSize?b.bevelSize:k-2,p=void 0!==b.bevelSegments?b.bevelSegments:3,n=void 0!==b.bevelEnabled?b.bevelEnabled:!0,
m=void 0!==b.curveSegments?b.curveSegments:12,q=void 0!==b.steps?b.steps:1,u=b.extrudePath,v,t=!1,s=void 0!==b.UVGenerator?b.UVGenerator:THREE.ExtrudeGeometry.WorldUVGenerator,w,E,x,D;u&&(v=u.getSpacedPoints(q),t=!0,n=!1,w=void 0!==b.frames?b.frames:new THREE.TubeGeometry.FrenetFrames(u,q,!1),E=new THREE.Vector3,x=new THREE.Vector3,D=new THREE.Vector3);n||(l=k=p=0);var z,y,B,G=this,F=this.vertices.length,u=a.extractPoints(m),m=u.shape,H=u.holes;if(u=!THREE.ShapeUtils.isClockWise(m)){m=m.reverse();
y=0;for(B=H.length;y<B;y++)z=H[y],THREE.ShapeUtils.isClockWise(z)&&(H[y]=z.reverse());u=!1}var L=THREE.ShapeUtils.triangulateShape(m,H),A=m;y=0;for(B=H.length;y<B;y++)z=H[y],m=m.concat(z);var N,M,I,O,Q,P=m.length,T,J=L.length,u=[],C=0;I=A.length;N=I-1;for(M=C+1;C<I;C++,N++,M++)N===I&&(N=0),M===I&&(M=0),u[C]=d(A[C],A[N],A[M]);var Z=[],S,Y=u.concat();y=0;for(B=H.length;y<B;y++){z=H[y];S=[];C=0;I=z.length;N=I-1;for(M=C+1;C<I;C++,N++,M++)N===I&&(N=0),M===I&&(M=0),S[C]=d(z[C],z[N],z[M]);Z.push(S);Y=Y.concat(S)}for(N=
0;N<p;N++){I=N/p;O=k*(1-I);M=l*Math.sin(I*Math.PI/2);C=0;for(I=A.length;C<I;C++)Q=c(A[C],u[C],M),f(Q.x,Q.y,-O);y=0;for(B=H.length;y<B;y++)for(z=H[y],S=Z[y],C=0,I=z.length;C<I;C++)Q=c(z[C],S[C],M),f(Q.x,Q.y,-O)}M=l;for(C=0;C<P;C++)Q=n?c(m[C],Y[C],M):m[C],t?(x.copy(w.normals[0]).multiplyScalar(Q.x),E.copy(w.binormals[0]).multiplyScalar(Q.y),D.copy(v[0]).add(x).add(E),f(D.x,D.y,D.z)):f(Q.x,Q.y,0);for(I=1;I<=q;I++)for(C=0;C<P;C++)Q=n?c(m[C],Y[C],M):m[C],t?(x.copy(w.normals[I]).multiplyScalar(Q.x),E.copy(w.binormals[I]).multiplyScalar(Q.y),
D.copy(v[I]).add(x).add(E),f(D.x,D.y,D.z)):f(Q.x,Q.y,h/q*I);for(N=p-1;0<=N;N–){I=N/p;O=k*(1-I);M=l*Math.sin(I*Math.PI/2);C=0;for(I=A.length;C<I;C++)Q=c(A[C],u[C],M),f(Q.x,Q.y,h+O);y=0;for(B=H.length;y<B;y++)for(z=H[y],S=Z[y],C=0,I=z.length;C<I;C++)Q=c(z[C],S[C],M),t?f(Q.x,Q.y+v[q-1].y,v[q-1].x+O):f(Q.x,Q.y,h+O)}(function(){if(n){var a;a=0*P;for(C=0;C<J;C++)T=L[C],g(T[2]+a,T[1]+a,T[0]+a);a=q+2*p;a*=P;for(C=0;C<J;C++)T=L[C],g(T[0]+a,T[1]+a,T[2]+a)}else{for(C=0;C<J;C++)T=L[C],g(T[2],T[1],T[0]);for(C=
0;C<J;C++)T=L[C],g(T[0]+P*q,T[1]+P*q,T[2]+P*q)}})();(function(){var a=0;e(A,a);a+=A.length;y=0;for(B=H.length;yMath.abs(b.y-c.y)?[new THREE.Vector2(b.x,1-b.z),new THREE.Vector2(c.x,1-c.z),new THREE.Vector2(d.x,1-d.z),new THREE.Vector2(e.x,1-e.z)]:[new THREE.Vector2(b.y,1-b.z),new THREE.Vector2(c.y,1-c.z),new THREE.Vector2(d.y,
1-d.z),new THREE.Vector2(e.y,1-e.z)]}};THREE.ShapeGeometry=function(a,b){THREE.Geometry.call(this);this.type=”ShapeGeometry”;!1===Array.isArray(a)&&(a=[a]);this.addShapeList(a,b);this.computeFaceNormals()};THREE.ShapeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ShapeGeometry.prototype.constructor=THREE.ShapeGeometry;THREE.ShapeGeometry.prototype.addShapeList=function(a,b){for(var c=0,d=a.length;c<d;c++)this.addShape(a[c],b);return this};
THREE.ShapeGeometry.prototype.addShape=function(a,b){void 0===b&&(b={});var c=b.material,d=void 0===b.UVGenerator?THREE.ExtrudeGeometry.WorldUVGenerator:b.UVGenerator,e,f,g,h=this.vertices.length;e=a.extractPoints(void 0!==b.curveSegments?b.curveSegments:12);var k=e.shape,l=e.holes;if(!THREE.ShapeUtils.isClockWise(k))for(k=k.reverse(),e=0,f=l.length;e<f;e++)g=l[e],THREE.ShapeUtils.isClockWise(g)&&(l[e]=g.reverse());var p=THREE.ShapeUtils.triangulateShape(k,l);e=0;for(f=l.length;e<f;e++)g=l[e],k=k.concat(g);
l=k.length;f=p.length;for(e=0;e<l;e++)g=k[e],this.vertices.push(new THREE.Vector3(g.x,g.y,0));for(e=0;e<f;e++)l=p[e],k=l[0]+h,g=l[1]+h,l=l[2]+h,this.faces.push(new THREE.Face3(k,g,l,null,null,c)),this.faceVertexUvs[0].push(d.generateTopUV(this,k,g,l))};
THREE.LatheBufferGeometry=function(a,b,c,d){THREE.BufferGeometry.call(this);this.type="LatheBufferGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};b=Math.floor(b)||12;c=c||0;d=d||2*Math.PI;d=THREE.Math.clamp(d,0,2*Math.PI);for(var e=(b+1)*a.length,f=b*a.length*6,g=new THREE.BufferAttribute(new (65535<f?Uint32Array:Uint16Array)(f),1),h=new THREE.BufferAttribute(new Float32Array(3*e),3),k=new THREE.BufferAttribute(new Float32Array(2*e),2),l=0,p=0,n=1/b,m=new THREE.Vector3,q=new THREE.Vector2,
e=0;e<=b;e++)for(var f=c+e*n*d,u=Math.sin(f),v=Math.cos(f),f=0;f<=a.length-1;f++)m.x=a[f].x*u,m.y=a[f].y,m.z=a[f].x*v,h.setXYZ(l,m.x,m.y,m.z),q.x=e/b,q.y=f/(a.length-1),k.setXY(l,q.x,q.y),l++;for(e=0;e<b;e++)for(f=0;f<a.length-1;f++)c=f+e*a.length,l=c+a.length,n=c+a.length+1,m=c+1,g.setX(p,c),p++,g.setX(p,l),p++,g.setX(p,m),p++,g.setX(p,l),p++,g.setX(p,n),p++,g.setX(p,m),p++;this.setIndex(g);this.addAttribute("position",h);this.addAttribute("uv",k);this.computeVertexNormals();if(d===2*Math.PI)for(d=
this.attributes.normal.array,g=new THREE.Vector3,h=new THREE.Vector3,k=new THREE.Vector3,c=b*a.length*3,f=e=0;e<a.length;e++,f+=3)g.x=d[f+0],g.y=d[f+1],g.z=d[f+2],h.x=d[c+f+0],h.y=d[c+f+1],h.z=d[c+f+2],k.addVectors(g,h).normalize(),d[f+0]=d[c+f+0]=k.x,d[f+1]=d[c+f+1]=k.y,d[f+2]=d[c+f+2]=k.z};THREE.LatheBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.LatheBufferGeometry.prototype.constructor=THREE.LatheBufferGeometry;
THREE.LatheGeometry=function(a,b,c,d){THREE.Geometry.call(this);this.type="LatheGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};this.fromBufferGeometry(new THREE.LatheBufferGeometry(a,b,c,d));this.mergeVertices()};THREE.LatheGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.LatheGeometry.prototype.constructor=THREE.LatheGeometry;
THREE.PlaneGeometry=function(a,b,c,d){THREE.Geometry.call(this);this.type="PlaneGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};this.fromBufferGeometry(new THREE.PlaneBufferGeometry(a,b,c,d))};THREE.PlaneGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.PlaneGeometry.prototype.constructor=THREE.PlaneGeometry;
THREE.PlaneBufferGeometry=function(a,b,c,d){THREE.BufferGeometry.call(this);this.type="PlaneBufferGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};var e=a/2,f=b/2;c=Math.floor(c)||1;d=Math.floor(d)||1;var g=c+1,h=d+1,k=a/c,l=b/d;b=new Float32Array(g*h*3);a=new Float32Array(g*h*3);for(var p=new Float32Array(g*h*2),n=0,m=0,q=0;q<h;q++)for(var u=q*l-f,v=0;v<g;v++)b[n]=v*k-e,b[n+1]=-u,a[n+2]=1,p[m]=v/c,p[m+1]=1-q/d,n+=3,m+=2;n=0;e=new (65535<b.length/3?Uint32Array:Uint16Array)(c*
d*6);for(q=0;q<d;q++)for(v=0;v<c;v++)f=v+g*(q+1),h=v+1+g*(q+1),k=v+1+g*q,e[n]=v+g*q,e[n+1]=f,e[n+2]=k,e[n+3]=f,e[n+4]=h,e[n+5]=k,n+=6;this.setIndex(new THREE.BufferAttribute(e,1));this.addAttribute("position",new THREE.BufferAttribute(b,3));this.addAttribute("normal",new THREE.BufferAttribute(a,3));this.addAttribute("uv",new THREE.BufferAttribute(p,2))};THREE.PlaneBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.PlaneBufferGeometry.prototype.constructor=THREE.PlaneBufferGeometry;
THREE.RingBufferGeometry=function(a,b,c,d,e,f){THREE.BufferGeometry.call(this);this.type="RingBufferGeometry";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};a=a||20;b=b||50;e=void 0!==e?e:0;f=void 0!==f?f:2*Math.PI;c=void 0!==c?Math.max(3,c):8;d=void 0!==d?Math.max(1,d):1;var g=(c+1)*(d+1),h=c*d*6,h=new THREE.BufferAttribute(new (65535<h?Uint32Array:Uint16Array)(h),1),k=new THREE.BufferAttribute(new Float32Array(3*g),3),l=new THREE.BufferAttribute(new Float32Array(3*
g),3),g=new THREE.BufferAttribute(new Float32Array(2*g),2),p=0,n=0,m,q=a,u=(b-a)/d,v=new THREE.Vector3,t=new THREE.Vector2,s;for(a=0;a<=d;a++){for(s=0;s<=c;s++)m=e+s/c*f,v.x=q*Math.cos(m),v.y=q*Math.sin(m),k.setXYZ(p,v.x,v.y,v.z),l.setXYZ(p,0,0,1),t.x=(v.x/b+1)/2,t.y=(v.y/b+1)/2,g.setXY(p,t.x,t.y),p++;q+=u}for(a=0;a<d;a++)for(b=a*(c+1),s=0;s<c;s++)e=m=s+b,f=m+c+1,p=m+c+2,m+=1,h.setX(n,e),n++,h.setX(n,f),n++,h.setX(n,p),n++,h.setX(n,e),n++,h.setX(n,p),n++,h.setX(n,m),n++;this.setIndex(h);this.addAttribute("position",
k);this.addAttribute("normal",l);this.addAttribute("uv",g)};THREE.RingBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.RingBufferGeometry.prototype.constructor=THREE.RingBufferGeometry;THREE.RingGeometry=function(a,b,c,d,e,f){THREE.Geometry.call(this);this.type="RingGeometry";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};this.fromBufferGeometry(new THREE.RingBufferGeometry(a,b,c,d,e,f))};
THREE.RingGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.RingGeometry.prototype.constructor=THREE.RingGeometry;THREE.SphereGeometry=function(a,b,c,d,e,f,g){THREE.Geometry.call(this);this.type="SphereGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,thetaLength:g};this.fromBufferGeometry(new THREE.SphereBufferGeometry(a,b,c,d,e,f,g))};THREE.SphereGeometry.prototype=Object.create(THREE.Geometry.prototype);
THREE.SphereGeometry.prototype.constructor=THREE.SphereGeometry;
THREE.SphereBufferGeometry=function(a,b,c,d,e,f,g){THREE.BufferGeometry.call(this);this.type="SphereBufferGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,thetaLength:g};a=a||50;b=Math.max(3,Math.floor(b)||8);c=Math.max(2,Math.floor(c)||6);d=void 0!==d?d:0;e=void 0!==e?e:2*Math.PI;f=void 0!==f?f:0;g=void 0!==g?g:Math.PI;for(var h=f+g,k=(b+1)*(c+1),l=new THREE.BufferAttribute(new Float32Array(3*k),3),p=new THREE.BufferAttribute(new Float32Array(3*
k),3),k=new THREE.BufferAttribute(new Float32Array(2*k),2),n=0,m=[],q=new THREE.Vector3,u=0;u<=c;u++){for(var v=[],t=u/c,s=0;s<=b;s++){var w=s/b,E=-a*Math.cos(d+w*e)*Math.sin(f+t*g),x=a*Math.cos(f+t*g),D=a*Math.sin(d+w*e)*Math.sin(f+t*g);q.set(E,x,D).normalize();l.setXYZ(n,E,x,D);p.setXYZ(n,q.x,q.y,q.z);k.setXY(n,w,1-t);v.push(n);n++}m.push(v)}d=[];for(u=0;u<c;u++)for(s=0;s<b;s++)e=m[u][s+1],g=m[u][s],n=m[u+1][s],q=m[u+1][s+1],(0!==u||0<f)&&d.push(e,g,q),(u!==c-1||h<Math.PI)&&d.push(g,n,q);this.setIndex(new (65535<
l.count?THREE.Uint32Attribute:THREE.Uint16Attribute)(d,1));this.addAttribute("position",l);this.addAttribute("normal",p);this.addAttribute("uv",k);this.boundingSphere=new THREE.Sphere(new THREE.Vector3,a)};THREE.SphereBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.SphereBufferGeometry.prototype.constructor=THREE.SphereBufferGeometry;
THREE.TextGeometry=function(a,b){b=b||{};var c=b.font;if(!1===c instanceof THREE.Font)return console.error("THREE.TextGeometry: font parameter is not an instance of THREE.Font."),new THREE.Geometry;c=c.generateShapes(a,b.size,b.curveSegments);b.amount=void 0!==b.height?b.height:50;void 0===b.bevelThickness&&(b.bevelThickness=10);void 0===b.bevelSize&&(b.bevelSize=8);void 0===b.bevelEnabled&&(b.bevelEnabled=!1);THREE.ExtrudeGeometry.call(this,c,b);this.type="TextGeometry"};
THREE.TextGeometry.prototype=Object.create(THREE.ExtrudeGeometry.prototype);THREE.TextGeometry.prototype.constructor=THREE.TextGeometry;
THREE.TorusBufferGeometry=function(a,b,c,d,e){THREE.BufferGeometry.call(this);this.type="TorusBufferGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};a=a||100;b=b||40;c=Math.floor(c)||8;d=Math.floor(d)||6;e=e||2*Math.PI;var f=(c+1)*(d+1),g=c*d*6,g=new (65535<g?Uint32Array:Uint16Array)(g),h=new Float32Array(3*f),k=new Float32Array(3*f),f=new Float32Array(2*f),l=0,p=0,n=0,m=new THREE.Vector3,q=new THREE.Vector3,u=new THREE.Vector3,v,t;for(v=0;v<=c;v++)for(t=0;t<=d;t++){var s=
t/d*e,w=v/c*Math.PI*2;q.x=(a+b*Math.cos(w))*Math.cos(s);q.y=(a+b*Math.cos(w))*Math.sin(s);q.z=b*Math.sin(w);h[l]=q.x;h[l+1]=q.y;h[l+2]=q.z;m.x=a*Math.cos(s);m.y=a*Math.sin(s);u.subVectors(q,m).normalize();k[l]=u.x;k[l+1]=u.y;k[l+2]=u.z;f[p]=t/d;f[p+1]=v/c;l+=3;p+=2}for(v=1;v<=c;v++)for(t=1;t<=d;t++)a=(d+1)*(v-1)+t-1,b=(d+1)*(v-1)+t,e=(d+1)*v+t,g[n]=(d+1)*v+t-1,g[n+1]=a,g[n+2]=e,g[n+3]=a,g[n+4]=b,g[n+5]=e,n+=6;this.setIndex(new THREE.BufferAttribute(g,1));this.addAttribute("position",new THREE.BufferAttribute(h,
3));this.addAttribute("normal",new THREE.BufferAttribute(k,3));this.addAttribute("uv",new THREE.BufferAttribute(f,2))};THREE.TorusBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.TorusBufferGeometry.prototype.constructor=THREE.TorusBufferGeometry;
THREE.TorusGeometry=function(a,b,c,d,e){THREE.Geometry.call(this);this.type="TorusGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};this.fromBufferGeometry(new THREE.TorusBufferGeometry(a,b,c,d,e))};THREE.TorusGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TorusGeometry.prototype.constructor=THREE.TorusGeometry;
THREE.TorusKnotBufferGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e){var f=Math.cos(a),g=Math.sin(a);a*=c/b;b=Math.cos(a);e.x=d*(2+b)*.5*f;e.y=d*(2+b)*g*.5;e.z=d*Math.sin(a)*.5}THREE.BufferGeometry.call(this);this.type="TorusKnotBufferGeometry";this.parameters={radius:a,tube:b,tubularSegments:c,radialSegments:d,p:e,q:f};a=a||100;b=b||40;c=Math.floor(c)||64;d=Math.floor(d)||8;e=e||2;f=f||3;var h=(d+1)*(c+1),k=d*c*6,k=new THREE.BufferAttribute(new (65535<k?Uint32Array:Uint16Array)(k),1),l=new THREE.BufferAttribute(new Float32Array(3*
h),3),p=new THREE.BufferAttribute(new Float32Array(3*h),3),h=new THREE.BufferAttribute(new Float32Array(2*h),2),n,m,q=0,u=0,v=new THREE.Vector3,t=new THREE.Vector3,s=new THREE.Vector2,w=new THREE.Vector3,E=new THREE.Vector3,x=new THREE.Vector3,D=new THREE.Vector3,z=new THREE.Vector3;for(n=0;n<=c;++n)for(m=n/c*e*Math.PI*2,g(m,e,f,a,w),g(m+.01,e,f,a,E),D.subVectors(E,w),z.addVectors(E,w),x.crossVectors(D,z),z.crossVectors(x,D),x.normalize(),z.normalize(),m=0;m<=d;++m){var y=m/d*Math.PI*2,B=-b*Math.cos(y),
y=b*Math.sin(y);v.x=w.x+(B*z.x+y*x.x);v.y=w.y+(B*z.y+y*x.y);v.z=w.z+(B*z.z+y*x.z);l.setXYZ(q,v.x,v.y,v.z);t.subVectors(v,w).normalize();p.setXYZ(q,t.x,t.y,t.z);s.x=n/c;s.y=m/d;h.setXY(q,s.x,s.y);q++}for(m=1;m<=c;m++)for(n=1;n<=d;n++)a=(d+1)*m+(n-1),b=(d+1)*m+n,e=(d+1)*(m-1)+n,k.setX(u,(d+1)*(m-1)+(n-1)),u++,k.setX(u,a),u++,k.setX(u,e),u++,k.setX(u,a),u++,k.setX(u,b),u++,k.setX(u,e),u++;this.setIndex(k);this.addAttribute("position",l);this.addAttribute("normal",p);this.addAttribute("uv",h)};
THREE.TorusKnotBufferGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.TorusKnotBufferGeometry.prototype.constructor=THREE.TorusKnotBufferGeometry;
THREE.TorusKnotGeometry=function(a,b,c,d,e,f,g){THREE.Geometry.call(this);this.type="TorusKnotGeometry";this.parameters={radius:a,tube:b,tubularSegments:c,radialSegments:d,p:e,q:f};void 0!==g&&console.warn("THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.");this.fromBufferGeometry(new THREE.TorusKnotBufferGeometry(a,b,c,d,e,f));this.mergeVertices()};THREE.TorusKnotGeometry.prototype=Object.create(THREE.Geometry.prototype);
THREE.TorusKnotGeometry.prototype.constructor=THREE.TorusKnotGeometry;
THREE.TubeGeometry=function(a,b,c,d,e,f){THREE.Geometry.call(this);this.type="TubeGeometry";this.parameters={path:a,segments:b,radius:c,radialSegments:d,closed:e,taper:f};b=b||64;c=c||1;d=d||8;e=e||!1;f=f||THREE.TubeGeometry.NoTaper;var g=[],h,k,l=b+1,p,n,m,q,u,v=new THREE.Vector3,t,s,w;t=new THREE.TubeGeometry.FrenetFrames(a,b,e);s=t.normals;w=t.binormals;this.tangents=t.tangents;this.normals=s;this.binormals=w;for(t=0;t<l;t++)for(g[t]=[],p=t/(l-1),u=a.getPointAt(p),h=s[t],k=w[t],m=c*f(p),p=0;p<
d;p++)n=p/d*2*Math.PI,q=-m*Math.cos(n),n=m*Math.sin(n),v.copy(u),v.x+=q*h.x+n*k.x,v.y+=q*h.y+n*k.y,v.z+=q*h.z+n*k.z,g[t][p]=this.vertices.push(new THREE.Vector3(v.x,v.y,v.z))-1;for(t=0;t<b;t++)for(p=0;p<d;p++)f=e?(t+1)%b:t+1,l=(p+1)%d,a=g[t][p],c=g[f][p],f=g[f][l],l=g[t][l],v=new THREE.Vector2(t/b,p/d),s=new THREE.Vector2((t+1)/b,p/d),w=new THREE.Vector2((t+1)/b,(p+1)/d),h=new THREE.Vector2(t/b,(p+1)/d),this.faces.push(new THREE.Face3(a,c,l)),this.faceVertexUvs[0].push([v,s,h]),this.faces.push(new THREE.Face3(c,
f,l)),this.faceVertexUvs[0].push([s.clone(),w,h.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.TubeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.TubeGeometry.prototype.constructor=THREE.TubeGeometry;THREE.TubeGeometry.NoTaper=function(a){return 1};THREE.TubeGeometry.SinusoidalTaper=function(a){return Math.sin(Math.PI*a)};
THREE.TubeGeometry.FrenetFrames=function(a,b,c){var d=new THREE.Vector3,e=[],f=[],g=[],h=new THREE.Vector3,k=new THREE.Matrix4;b+=1;var l,p,n;this.tangents=e;this.normals=f;this.binormals=g;for(l=0;l<b;l++)p=l/(b-1),e[l]=a.getTangentAt(p),e[l].normalize();f[0]=new THREE.Vector3;g[0]=new THREE.Vector3;a=Number.MAX_VALUE;l=Math.abs(e[0].x);p=Math.abs(e[0].y);n=Math.abs(e[0].z);l<=a&&(a=l,d.set(1,0,0));p<=a&&(a=p,d.set(0,1,0));n<=a&&d.set(0,0,1);h.crossVectors(e[0],d).normalize();f[0].crossVectors(e[0],
h);g[0].crossVectors(e[0],f[0]);for(l=1;lNumber.EPSILON&&(h.normalize(),d=Math.acos(THREE.Math.clamp(e[l-1].dot(e[l]),-1,1)),f[l].applyMatrix4(k.makeRotationAxis(h,d))),g[l].crossVectors(e[l],f[l]);if(c)for(d=Math.acos(THREE.Math.clamp(f[0].dot(f[b-1]),-1,1)),d/=b-1,0<e[0].dot(h.crossVectors(f[0],f[b-1]))&&(d=-d),l=1;l<b;l++)f[l].applyMatrix4(k.makeRotationAxis(e[l],d*l)),g[l].crossVectors(e[l],f[l])};
THREE.PolyhedronGeometry=function(a,b,c,d){function e(a){var b=a.normalize().clone();b.index=k.vertices.push(b)-1;var c=Math.atan2(a.z,-a.x)/2/Math.PI+.5;a=Math.atan2(-a.y,Math.sqrt(a.x*a.x+a.z*a.z))/Math.PI+.5;b.uv=new THREE.Vector2(c,1-a);return b}function f(a,b,c,d){d=new THREE.Face3(a.index,b.index,c.index,[a.clone(),b.clone(),c.clone()],void 0,d);k.faces.push(d);t.copy(a).add(b).add(c).divideScalar(3);d=Math.atan2(t.z,-t.x);k.faceVertexUvs[0].push([h(a.uv,a,d),h(b.uv,b,d),h(c.uv,c,d)])}function g(a,
b){for(var c=Math.pow(2,b),d=e(k.vertices[a.a]),g=e(k.vertices[a.b]),h=e(k.vertices[a.c]),l=[],m=a.materialIndex,n=0;n<=c;n++){l[n]=[];for(var p=e(d.clone().lerp(h,n/c)),q=e(g.clone().lerp(h,n/c)),t=c-n,u=0;u<=t;u++)l[n][u]=0===u&&n===c?p:e(p.clone().lerp(q,u/t))}for(n=0;n<c;n++)for(u=0;uc&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/
2/Math.PI+.5,a.y));return a.clone()}THREE.Geometry.call(this);this.type=”PolyhedronGeometry”;this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,l=0,p=a.length;l<p;l+=3)e(new THREE.Vector3(a[l],a[l+1],a[l+2]));a=this.vertices;for(var n=[],m=l=0,p=b.length;l<p;l+=3,m++){var q=a[b[l]],u=a[b[l+1]],v=a[b[l+2]];n[m]=new THREE.Face3(q.index,u.index,v.index,[q.clone(),u.clone(),v.clone()],void 0,m)}for(var t=new THREE.Vector3,l=0,p=n.length;l<p;l++)g(n[l],d);l=0;for(p=this.faceVertexUvs[0].length;l<
p;l++)b=this.faceVertexUvs[0][l],d=b[0].x,a=b[1].x,n=b[2].x,m=Math.max(d,a,n),q=Math.min(d,a,n),.9q&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>n&&(b[2].x+=1));l=0;for(p=this.vertices.length;l<p;l++)this.vertices[l].multiplyScalar(c);this.mergeVertices();this.computeFaceNormals();this.boundingSphere=new THREE.Sphere(new THREE.Vector3,c)};THREE.PolyhedronGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.PolyhedronGeometry.prototype.constructor=THREE.PolyhedronGeometry;
THREE.DodecahedronGeometry=function(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;THREE.PolyhedronGeometry.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,
12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b}};THREE.DodecahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);THREE.DodecahedronGeometry.prototype.constructor=THREE.DodecahedronGeometry;
THREE.IcosahedronGeometry=function(a,b){var c=(1+Math.sqrt(5))/2;THREE.PolyhedronGeometry.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b}};THREE.IcosahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);
THREE.IcosahedronGeometry.prototype.constructor=THREE.IcosahedronGeometry;THREE.OctahedronGeometry=function(a,b){THREE.PolyhedronGeometry.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b}};THREE.OctahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);THREE.OctahedronGeometry.prototype.constructor=THREE.OctahedronGeometry;
THREE.TetrahedronGeometry=function(a,b){THREE.PolyhedronGeometry.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b}};THREE.TetrahedronGeometry.prototype=Object.create(THREE.PolyhedronGeometry.prototype);THREE.TetrahedronGeometry.prototype.constructor=THREE.TetrahedronGeometry;
THREE.ParametricGeometry=function(a,b,c){THREE.Geometry.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};var d=this.vertices,e=this.faces,f=this.faceVertexUvs[0],g,h,k,l,p=b+1;for(g=0;g<=c;g++)for(l=g/c,h=0;h<=b;h++)k=h/b,k=a(k,l),d.push(k);var n,m,q,u;for(g=0;g<c;g++)for(h=0;h<b;h++)a=g*p+h,d=g*p+h+1,l=(g+1)*p+h+1,k=(g+1)*p+h,n=new THREE.Vector2(h/b,g/c),m=new THREE.Vector2((h+1)/b,g/c),q=new THREE.Vector2((h+1)/b,(g+1)/c),u=new THREE.Vector2(h/b,(g+1)/c),e.push(new THREE.Face3(a,
d,k)),f.push([n,m,u]),e.push(new THREE.Face3(d,l,k)),f.push([m.clone(),q,u.clone()]);this.computeFaceNormals();this.computeVertexNormals()};THREE.ParametricGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ParametricGeometry.prototype.constructor=THREE.ParametricGeometry;
THREE.WireframeGeometry=function(a){function b(a,b){return a-b}THREE.BufferGeometry.call(this);var c=[0,0],d={},e=["a","b","c"];if(a instanceof THREE.Geometry){var f=a.vertices,g=a.faces,h=0,k=new Uint32Array(6*g.length);a=0;for(var l=g.length;an;n++){c[0]=p[e[n]];c[1]=p[e[(n+1)%3]];c.sort(b);var m=c.toString();void 0===d[m]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[m]=!0,h++)}c=new Float32Array(6*h);a=0;for(l=h;an;n++)d=f[k[2*a+n]],h=6*a+3*n,c[h+0]=d.x,c[h+1]=d.y,
c[h+2]=d.z;this.addAttribute(“position”,new THREE.BufferAttribute(c,3))}else if(a instanceof THREE.BufferGeometry){if(null!==a.index){l=a.index.array;f=a.attributes.position;e=a.groups;h=0;0===e.length&&a.addGroup(0,l.length);k=new Uint32Array(2*l.length);g=0;for(p=e.length;g<p;++g){a=e[g];n=a.start;m=a.count;a=n;for(var q=n+m;an;n++)c[0]=l[a+n],c[1]=l[a+(n+1)%3],c.sort(b),m=c.toString(),void 0===d[m]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[m]=!0,h++)}c=new Float32Array(6*h);a=0;for(l=h;an;n++)h=6*a+3*n,d=k[2*a+n],c[h+0]=f.getX(d),c[h+1]=f.getY(d),c[h+2]=f.getZ(d)}else for(f=a.attributes.position.array,h=f.length/3,k=h/3,c=new Float32Array(6*h),a=0,l=k;an;n++)h=18*a+6*n,k=9*a+3*n,c[h+0]=f[k],c[h+1]=f[k+1],c[h+2]=f[k+2],d=9*a+(n+1)%3*3,c[h+3]=f[d],c[h+4]=f[d+1],c[h+5]=f[d+2];this.addAttribute(“position”,new THREE.BufferAttribute(c,3))}};THREE.WireframeGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);
THREE.WireframeGeometry.prototype.constructor=THREE.WireframeGeometry;THREE.AxisHelper=function(a){a=a||1;var b=new Float32Array([0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a]),c=new Float32Array([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1]);a=new THREE.BufferGeometry;a.addAttribute(“position”,new THREE.BufferAttribute(b,3));a.addAttribute(“color”,new THREE.BufferAttribute(c,3));b=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors});THREE.LineSegments.call(this,a,b)};THREE.AxisHelper.prototype=Object.create(THREE.LineSegments.prototype);
THREE.AxisHelper.prototype.constructor=THREE.AxisHelper;
THREE.ArrowHelper=function(){var a=new THREE.Geometry;a.vertices.push(new THREE.Vector3(0,0,0),new THREE.Vector3(0,1,0));var b=new THREE.CylinderGeometry(0,.5,1,5,1);b.translate(0,-.5,0);return function(c,d,e,f,g,h){THREE.Object3D.call(this);void 0===f&&(f=16776960);void 0===e&&(e=1);void 0===g&&(g=.2*e);void 0===h&&(h=.2*g);this.position.copy(d);this.line=new THREE.Line(a,new THREE.LineBasicMaterial({color:f}));this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new THREE.Mesh(b,new THREE.MeshBasicMaterial({color:f}));
this.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(c);this.setLength(e,g,h)}}();THREE.ArrowHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.ArrowHelper.prototype.constructor=THREE.ArrowHelper;THREE.ArrowHelper.prototype.setDirection=function(){var a=new THREE.Vector3,b;return function(c){.99999c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}();
THREE.ArrowHelper.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};THREE.ArrowHelper.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};
THREE.BoxHelper=function(a){var b=new Uint16Array([0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7]),c=new Float32Array(24),d=new THREE.BufferGeometry;d.setIndex(new THREE.BufferAttribute(b,1));d.addAttribute(“position”,new THREE.BufferAttribute(c,3));THREE.LineSegments.call(this,d,new THREE.LineBasicMaterial({color:16776960}));void 0!==a&&this.update(a)};THREE.BoxHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.BoxHelper.prototype.constructor=THREE.BoxHelper;
THREE.BoxHelper.prototype.update=function(){var a=new THREE.Box3;return function(b){a.setFromObject(b);if(!a.isEmpty()){b=a.min;var c=a.max,d=this.geometry.attributes.position,e=d.array;e[0]=c.x;e[1]=c.y;e[2]=c.z;e[3]=b.x;e[4]=c.y;e[5]=c.z;e[6]=b.x;e[7]=b.y;e[8]=c.z;e[9]=c.x;e[10]=b.y;e[11]=c.z;e[12]=c.x;e[13]=c.y;e[14]=b.z;e[15]=b.x;e[16]=c.y;e[17]=b.z;e[18]=b.x;e[19]=b.y;e[20]=b.z;e[21]=c.x;e[22]=b.y;e[23]=b.z;d.needsUpdate=!0;this.geometry.computeBoundingSphere()}}}();
THREE.BoundingBoxHelper=function(a,b){var c=void 0!==b?b:8947848;this.object=a;this.box=new THREE.Box3;THREE.Mesh.call(this,new THREE.BoxGeometry(1,1,1),new THREE.MeshBasicMaterial({color:c,wireframe:!0}))};THREE.BoundingBoxHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.BoundingBoxHelper.prototype.constructor=THREE.BoundingBoxHelper;THREE.BoundingBoxHelper.prototype.update=function(){this.box.setFromObject(this.object);this.box.size(this.scale);this.box.center(this.position)};
THREE.CameraHelper=function(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){d.vertices.push(new THREE.Vector3);d.colors.push(new THREE.Color(b));void 0===f[a]&&(f[a]=[]);f[a].push(d.vertices.length-1)}var d=new THREE.Geometry,e=new THREE.LineBasicMaterial({color:16777215,vertexColors:THREE.FaceColors}),f={};b(“n1″,”n2”,16755200);b(“n2″,”n4”,16755200);b(“n4″,”n3”,16755200);b(“n3″,”n1”,16755200);b(“f1″,”f2”,16755200);b(“f2″,”f4”,16755200);b(“f4″,”f3”,16755200);b(“f3″,”f1”,16755200);b(“n1″,”f1”,16755200);
b(“n2″,”f2”,16755200);b(“n3″,”f3”,16755200);b(“n4″,”f4”,16755200);b(“p”,”n1″,16711680);b(“p”,”n2″,16711680);b(“p”,”n3″,16711680);b(“p”,”n4″,16711680);b(“u1″,”u2”,43775);b(“u2″,”u3”,43775);b(“u3″,”u1”,43775);b(“c”,”t”,16777215);b(“p”,”c”,3355443);b(“cn1″,”cn2”,3355443);b(“cn3″,”cn4”,3355443);b(“cf1″,”cf2”,3355443);b(“cf3″,”cf4”,3355443);THREE.LineSegments.call(this,d,e);this.camera=a;this.camera.updateProjectionMatrix();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=f;this.update()};
THREE.CameraHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.CameraHelper.prototype.constructor=THREE.CameraHelper;
THREE.CameraHelper.prototype.update=function(){function a(a,g,h,k){d.set(g,h,k).unproject(e);a=c[a];if(void 0!==a)for(g=0,h=a.length;g<h;g++)b.vertices[a[g]].copy(d)}var b,c,d=new THREE.Vector3,e=new THREE.Camera;return function(){b=this.geometry;c=this.pointMap;e.projectionMatrix.copy(this.camera.projectionMatrix);a("c",0,0,-1);a("t",0,0,1);a("n1",-1,-1,-1);a("n2",1,-1,-1);a("n3",-1,1,-1);a("n4",1,1,-1);a("f1",-1,-1,1);a("f2",1,-1,1);a("f3",-1,1,1);a("f4",1,1,1);a("u1",.7,1.1,-1);a("u2",-.7,1.1,
-1);a("u3",0,2,-1);a("cf1",-1,0,1);a("cf2",1,0,1);a("cf3",0,-1,1);a("cf4",0,1,1);a("cn1",-1,0,-1);a("cn2",1,0,-1);a("cn3",0,-1,-1);a("cn4",0,1,-1);b.verticesNeedUpdate=!0}}();
THREE.DirectionalLightHelper=function(a,b){THREE.Object3D.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;b=b||1;var c=new THREE.Geometry;c.vertices.push(new THREE.Vector3(-b,b,0),new THREE.Vector3(b,b,0),new THREE.Vector3(b,-b,0),new THREE.Vector3(-b,-b,0),new THREE.Vector3(-b,b,0));var d=new THREE.LineBasicMaterial({fog:!1});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);this.lightPlane=new THREE.Line(c,d);this.add(this.lightPlane);
c=new THREE.Geometry;c.vertices.push(new THREE.Vector3,new THREE.Vector3);d=new THREE.LineBasicMaterial({fog:!1});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);this.targetLine=new THREE.Line(c,d);this.add(this.targetLine);this.update()};THREE.DirectionalLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.DirectionalLightHelper.prototype.constructor=THREE.DirectionalLightHelper;
THREE.DirectionalLightHelper.prototype.dispose=function(){this.lightPlane.geometry.dispose();this.lightPlane.material.dispose();this.targetLine.geometry.dispose();this.targetLine.material.dispose()};
THREE.DirectionalLightHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(){a.setFromMatrixPosition(this.light.matrixWorld);b.setFromMatrixPosition(this.light.target.matrixWorld);c.subVectors(b,a);this.lightPlane.lookAt(c);this.lightPlane.material.color.copy(this.light.color).multiplyScalar(this.light.intensity);this.targetLine.geometry.vertices[1].copy(c);this.targetLine.geometry.verticesNeedUpdate=!0;this.targetLine.material.color.copy(this.lightPlane.material.color)}}();
THREE.EdgesHelper=function(a,b,c){b=void 0!==b?b:16777215;THREE.LineSegments.call(this,new THREE.EdgesGeometry(a.geometry,c),new THREE.LineBasicMaterial({color:b}));this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.EdgesHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.EdgesHelper.prototype.constructor=THREE.EdgesHelper;
THREE.FaceNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof THREE.Geometry?b=c.faces.length:console.warn("THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.");c=new THREE.BufferGeometry;b=new THREE.Float32Attribute(6*b,3);c.addAttribute("position",b);THREE.LineSegments.call(this,c,new THREE.LineBasicMaterial({color:a,linewidth:d}));this.matrixAutoUpdate=
!1;this.update()};THREE.FaceNormalsHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.FaceNormalsHelper.prototype.constructor=THREE.FaceNormalsHelper;
THREE.FaceNormalsHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(){this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);for(var d=this.object.matrixWorld,e=this.geometry.attributes.position,f=this.object.geometry,g=f.vertices,f=f.faces,h=0,k=0,l=f.length;k<l;k++){var p=f[k],n=p.normal;a.copy(g[p.a]).add(g[p.b]).add(g[p.c]).divideScalar(3).applyMatrix4(d);b.copy(n).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);
e.setXYZ(h,a.x,a.y,a.z);h+=1;e.setXYZ(h,b.x,b.y,b.z);h+=1}e.needsUpdate=!0;return this}}();
THREE.GridHelper=function(a,b){var c=new THREE.Geometry,d=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors});this.color1=new THREE.Color(4473924);this.color2=new THREE.Color(8947848);for(var e=-a;ed;d++)c.faces[d].color=this.colors[4>d?0:1];d=new THREE.MeshBasicMaterial({vertexColors:THREE.FaceColors,wireframe:!0});this.lightSphere=new THREE.Mesh(c,d);this.add(this.lightSphere);this.update()};
THREE.HemisphereLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.HemisphereLightHelper.prototype.constructor=THREE.HemisphereLightHelper;THREE.HemisphereLightHelper.prototype.dispose=function(){this.lightSphere.geometry.dispose();this.lightSphere.material.dispose()};
THREE.HemisphereLightHelper.prototype.update=function(){var a=new THREE.Vector3;return function(){this.colors[0].copy(this.light.color).multiplyScalar(this.light.intensity);this.colors[1].copy(this.light.groundColor).multiplyScalar(this.light.intensity);this.lightSphere.lookAt(a.setFromMatrixPosition(this.light.matrixWorld).negate());this.lightSphere.geometry.colorsNeedUpdate=!0}}();
THREE.PointLightHelper=function(a,b){this.light=a;this.light.updateMatrixWorld();var c=new THREE.SphereGeometry(b,4,2),d=new THREE.MeshBasicMaterial({wireframe:!0,fog:!1});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);THREE.Mesh.call(this,c,d);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1};THREE.PointLightHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.PointLightHelper.prototype.constructor=THREE.PointLightHelper;
THREE.PointLightHelper.prototype.dispose=function(){this.geometry.dispose();this.material.dispose()};THREE.PointLightHelper.prototype.update=function(){this.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)};
THREE.SkeletonHelper=function(a){this.bones=this.getBoneList(a);for(var b=new THREE.Geometry,c=0;c<this.bones.length;c++)this.bones[c].parent instanceof THREE.Bone&&(b.vertices.push(new THREE.Vector3),b.vertices.push(new THREE.Vector3),b.colors.push(new THREE.Color(0,0,1)),b.colors.push(new THREE.Color(0,1,0)));b.dynamic=!0;c=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors,depthTest:!1,depthWrite:!1,transparent:!0});THREE.LineSegments.call(this,b,c);this.root=a;this.matrix=a.matrixWorld;
this.matrixAutoUpdate=!1;this.update()};THREE.SkeletonHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.SkeletonHelper.prototype.constructor=THREE.SkeletonHelper;THREE.SkeletonHelper.prototype.getBoneList=function(a){var b=[];a instanceof THREE.Bone&&b.push(a);for(var c=0;c<a.children.length;c++)b.push.apply(b,this.getBoneList(a.children[c]));return b};
THREE.SkeletonHelper.prototype.update=function(){for(var a=this.geometry,b=(new THREE.Matrix4).getInverse(this.root.matrixWorld),c=new THREE.Matrix4,d=0,e=0;e<this.bones.length;e++){var f=this.bones[e];f.parent instanceof THREE.Bone&&(c.multiplyMatrices(b,f.matrixWorld),a.vertices[d].setFromMatrixPosition(c),c.multiplyMatrices(b,f.parent.matrixWorld),a.vertices[d+1].setFromMatrixPosition(c),d+=2)}a.verticesNeedUpdate=!0;a.computeBoundingSphere()};
THREE.SpotLightHelper=function(a){THREE.Object3D.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;a=new THREE.CylinderGeometry(0,1,1,8,1,!0);a.translate(0,-.5,0);a.rotateX(-Math.PI/2);var b=new THREE.MeshBasicMaterial({wireframe:!0,fog:!1});this.cone=new THREE.Mesh(a,b);this.add(this.cone);this.update()};THREE.SpotLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.SpotLightHelper.prototype.constructor=THREE.SpotLightHelper;
THREE.SpotLightHelper.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};THREE.SpotLightHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){var c=this.light.distance?this.light.distance:1E4,d=c*Math.tan(this.light.angle);this.cone.scale.set(d,d,c);a.setFromMatrixPosition(this.light.matrixWorld);b.setFromMatrixPosition(this.light.target.matrixWorld);this.cone.lookAt(b.sub(a));this.cone.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)}}();
THREE.VertexNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16711680;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof THREE.Geometry?b=3*c.faces.length:c instanceof THREE.BufferGeometry&&(b=c.attributes.normal.count);c=new THREE.BufferGeometry;b=new THREE.Float32Attribute(6*b,3);c.addAttribute("position",b);THREE.LineSegments.call(this,c,new THREE.LineBasicMaterial({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()};
THREE.VertexNormalsHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.VertexNormalsHelper.prototype.constructor=THREE.VertexNormalsHelper;
THREE.VertexNormalsHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,f=this.geometry.attributes.position,g=this.object.geometry;if(g instanceof THREE.Geometry)for(var h=g.vertices,k=g.faces,l=g=0,p=k.length;l<p;l++)for(var n=k[l],m=0,q=n.vertexNormals.length;m<q;m++){var u=n.vertexNormals[m];a.copy(h[n[d[m]]]).applyMatrix4(e);
b.copy(u).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);f.setXYZ(g,a.x,a.y,a.z);g+=1;f.setXYZ(g,b.x,b.y,b.z);g+=1}else if(g instanceof THREE.BufferGeometry)for(d=g.attributes.position,h=g.attributes.normal,m=g=0,q=d.count;m<q;m++)a.set(d.getX(m),d.getY(m),d.getZ(m)).applyMatrix4(e),b.set(h.getX(m),h.getY(m),h.getZ(m)),b.applyMatrix3(c).normalize().multiplyScalar(this.size).add(a),f.setXYZ(g,a.x,a.y,a.z),g+=1,f.setXYZ(g,b.x,b.y,b.z),g+=1;f.needsUpdate=!0;return this}}();
THREE.WireframeHelper=function(a,b){var c=void 0!==b?b:16777215;THREE.LineSegments.call(this,new THREE.WireframeGeometry(a.geometry),new THREE.LineBasicMaterial({color:c}));this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1};THREE.WireframeHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.WireframeHelper.prototype.constructor=THREE.WireframeHelper;THREE.ImmediateRenderObject=function(a){THREE.Object3D.call(this);this.material=a;this.render=function(a){}};
THREE.ImmediateRenderObject.prototype=Object.create(THREE.Object3D.prototype);THREE.ImmediateRenderObject.prototype.constructor=THREE.ImmediateRenderObject;THREE.MorphBlendMesh=function(a,b){THREE.Mesh.call(this,a,b);this.animationsMap={};this.animationsList=[];var c=this.geometry.morphTargets.length;this.createAnimation("__default",0,c-1,c/1);this.setAnimationWeight("__default",1)};THREE.MorphBlendMesh.prototype=Object.create(THREE.Mesh.prototype);THREE.MorphBlendMesh.prototype.constructor=THREE.MorphBlendMesh;
THREE.MorphBlendMesh.prototype.createAnimation=function(a,b,c,d){b={start:b,end:c,length:c-b+1,fps:d,duration:(c-b)/d,lastFrame:0,currentFrame:0,active:!1,time:0,direction:1,weight:1,directionBackwards:!1,mirroredLoop:!1};this.animationsMap[a]=b;this.animationsList.push(b)};
THREE.MorphBlendMesh.prototype.autoCreateAnimations=function(a){for(var b=/([a-z]+)_?(\d+)/i,c,d={},e=this.geometry,f=0,g=e.morphTargets.length;f<g;f++){var h=e.morphTargets[f].name.match(b);if(h&&1<h.length){var k=h[1];d[k]||(d[k]={start:Infinity,end:-Infinity});h=d[k];fh.end&&(h.end=f);c||(c=k)}}for(k in d)h=d[k],this.createAnimation(k,h.start,h.end,a);this.firstAnimation=c};
THREE.MorphBlendMesh.prototype.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};THREE.MorphBlendMesh.prototype.setAnimationFPS=function(a,b){var c=this.animationsMap[a];c&&(c.fps=b,c.duration=(c.end-c.start)/c.fps)};
THREE.MorphBlendMesh.prototype.setAnimationDuration=function(a,b){var c=this.animationsMap[a];c&&(c.duration=b,c.fps=(c.end-c.start)/c.duration)};THREE.MorphBlendMesh.prototype.setAnimationWeight=function(a,b){var c=this.animationsMap[a];c&&(c.weight=b)};THREE.MorphBlendMesh.prototype.setAnimationTime=function(a,b){var c=this.animationsMap[a];c&&(c.time=b)};THREE.MorphBlendMesh.prototype.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b};
THREE.MorphBlendMesh.prototype.getAnimationDuration=function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};THREE.MorphBlendMesh.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn(“THREE.MorphBlendMesh: animation[“+a+”] undefined in .playAnimation()”)};THREE.MorphBlendMesh.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1};
THREE.MorphBlendMesh.prototype.update=function(a){for(var b=0,c=this.animationsList.length;bd.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.start+THREE.Math.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight;f!==d.currentFrame&&
(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);d.currentFrame!==d.lastFrame?(this.morphTargetInfluences[d.currentFrame]=e*g,this.morphTargetInfluences[d.lastFrame]=(1-e)*g):this.morphTargetInfluences[d.currentFrame]=g}}};
/**
* @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
*
* A general perpose camera, for setting FOV, Lens Focal Length,
* and switching between perspective and orthographic views easily.
* Use this only if you do not wish to manage
* both a Orthographic and Perspective Camera
*
*/
THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {
THREE.Camera.call( this );
this.fov = fov;
this.left = – width / 2;
this.right = width / 2;
this.top = height / 2;
this.bottom = – height / 2;
// We could also handle the projectionMatrix internally, but just wanted to test nested camera objects
this.cameraO = new THREE.OrthographicCamera( width / – 2, width / 2, height / 2, height / – 2, orthoNear, orthoFar );
this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far );
this.zoom = 1;
this.toPerspective();
};
THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
THREE.CombinedCamera.prototype.constructor = THREE.CombinedCamera;
THREE.CombinedCamera.prototype.toPerspective = function () {
// Switches to the Perspective Camera
this.near = this.cameraP.near;
this.far = this.cameraP.far;
this.cameraP.fov = this.fov / this.zoom ;
this.cameraP.updateProjectionMatrix();
this.projectionMatrix = this.cameraP.projectionMatrix;
this.inPerspectiveMode = true;
this.inOrthographicMode = false;
};
THREE.CombinedCamera.prototype.toOrthographic = function () {
// Switches to the Orthographic camera estimating viewport from Perspective
var fov = this.fov;
var aspect = this.cameraP.aspect;
var near = this.cameraP.near;
var far = this.cameraP.far;
// The size that we set is the mid plane of the viewing frustum
var hyperfocus = ( near + far ) / 2;
var halfHeight = Math.tan( fov * Math.PI / 180 / 2 ) * hyperfocus;
var planeHeight = 2 * halfHeight;
var planeWidth = planeHeight * aspect;
var halfWidth = planeWidth / 2;
halfHeight /= this.zoom;
halfWidth /= this.zoom;
this.cameraO.left = – halfWidth;
this.cameraO.right = halfWidth;
this.cameraO.top = halfHeight;
this.cameraO.bottom = – halfHeight;
// this.cameraO.left = -farHalfWidth;
// this.cameraO.right = farHalfWidth;
// this.cameraO.top = farHalfHeight;
// this.cameraO.bottom = -farHalfHeight;
// this.cameraO.left = this.left / this.zoom;
// this.cameraO.right = this.right / this.zoom;
// this.cameraO.top = this.top / this.zoom;
// this.cameraO.bottom = this.bottom / this.zoom;
this.cameraO.updateProjectionMatrix();
this.near = this.cameraO.near;
this.far = this.cameraO.far;
this.projectionMatrix = this.cameraO.projectionMatrix;
this.inPerspectiveMode = false;
this.inOrthographicMode = true;
};
THREE.CombinedCamera.prototype.setSize = function( width, height ) {
this.cameraP.aspect = width / height;
this.left = – width / 2;
this.right = width / 2;
this.top = height / 2;
this.bottom = – height / 2;
};
THREE.CombinedCamera.prototype.setFov = function( fov ) {
this.fov = fov;
if ( this.inPerspectiveMode ) {
this.toPerspective();
} else {
this.toOrthographic();
}
};
// For maintaining similar API with PerspectiveCamera
THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {
if ( this.inPerspectiveMode ) {
this.toPerspective();
} else {
this.toPerspective();
this.toOrthographic();
}
};
/*
* Uses Focal Length (in mm) to estimate and set FOV
* 35mm (fullframe) camera is used if frame size is not specified;
* Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
*/
THREE.CombinedCamera.prototype.setLens = function ( focalLength, frameHeight ) {
if ( frameHeight === undefined ) frameHeight = 24;
var fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) );
this.setFov( fov );
return fov;
};
THREE.CombinedCamera.prototype.setZoom = function( zoom ) {
this.zoom = zoom;
if ( this.inPerspectiveMode ) {
this.toPerspective();
} else {
this.toOrthographic();
}
};
THREE.CombinedCamera.prototype.toFrontView = function() {
this.rotation.x = 0;
this.rotation.y = 0;
this.rotation.z = 0;
// should we be modifing the matrix instead?
this.rotationAutoUpdate = false;
};
THREE.CombinedCamera.prototype.toBackView = function() {
this.rotation.x = 0;
this.rotation.y = Math.PI;
this.rotation.z = 0;
this.rotationAutoUpdate = false;
};
THREE.CombinedCamera.prototype.toLeftView = function() {
this.rotation.x = 0;
this.rotation.y = – Math.PI / 2;
this.rotation.z = 0;
this.rotationAutoUpdate = false;
};
THREE.CombinedCamera.prototype.toRightView = function() {
this.rotation.x = 0;
this.rotation.y = Math.PI / 2;
this.rotation.z = 0;
this.rotationAutoUpdate = false;
};
THREE.CombinedCamera.prototype.toTopView = function() {
this.rotation.x = – Math.PI / 2;
this.rotation.y = 0;
this.rotation.z = 0;
this.rotationAutoUpdate = false;
};
THREE.CombinedCamera.prototype.toBottomView = function() {
this.rotation.x = Math.PI / 2;
this.rotation.y = 0;
this.rotation.z = 0;
this.rotationAutoUpdate = false;
};
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.SpriteCanvasMaterial = function ( parameters ) {
THREE.Material.call( this );
this.type = ‘SpriteCanvasMaterial’;
this.color = new THREE.Color( 0xffffff );
this.program = function ( context, color ) {};
this.setValues( parameters );
};
THREE.SpriteCanvasMaterial.prototype = Object.create( THREE.Material.prototype );
THREE.SpriteCanvasMaterial.prototype.constructor = THREE.SpriteCanvasMaterial;
THREE.SpriteCanvasMaterial.prototype.clone = function () {
var material = new THREE.SpriteCanvasMaterial();
material.copy( this );
material.color.copy( this.color );
material.program = this.program;
return material;
};
//
THREE.CanvasRenderer = function ( parameters ) {
console.log( ‘THREE.CanvasRenderer’, THREE.REVISION );
parameters = parameters || {};
var _this = this,
_renderData, _elements, _lights,
_projector = new THREE.Projector(),
_canvas = parameters.canvas !== undefined
? parameters.canvas
: document.createElement( ‘canvas’ ),
_canvasWidth = _canvas.width,
_canvasHeight = _canvas.height,
_canvasWidthHalf = Math.floor( _canvasWidth / 2 ),
_canvasHeightHalf = Math.floor( _canvasHeight / 2 ),
_viewportX = 0,
_viewportY = 0,
_viewportWidth = _canvasWidth,
_viewportHeight = _canvasHeight,
_pixelRatio = 1,
_context = _canvas.getContext( ‘2d’, {
alpha: parameters.alpha === true
} ),
_clearColor = new THREE.Color( 0x000000 ),
_clearAlpha = parameters.alpha === true ? 0 : 1,
_contextGlobalAlpha = 1,
_contextGlobalCompositeOperation = 0,
_contextStrokeStyle = null,
_contextFillStyle = null,
_contextLineWidth = null,
_contextLineCap = null,
_contextLineJoin = null,
_contextLineDash = [],
_camera,
_v1, _v2, _v3, _v4,
_v5 = new THREE.RenderableVertex(),
_v6 = new THREE.RenderableVertex(),
_v1x, _v1y, _v2x, _v2y, _v3x, _v3y,
_v4x, _v4y, _v5x, _v5y, _v6x, _v6y,
_color = new THREE.Color(),
_color1 = new THREE.Color(),
_color2 = new THREE.Color(),
_color3 = new THREE.Color(),
_color4 = new THREE.Color(),
_diffuseColor = new THREE.Color(),
_emissiveColor = new THREE.Color(),
_lightColor = new THREE.Color(),
_patterns = {},
_image, _uvs,
_uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y,
_clipBox = new THREE.Box2(),
_clearBox = new THREE.Box2(),
_elemBox = new THREE.Box2(),
_ambientLight = new THREE.Color(),
_directionalLights = new THREE.Color(),
_pointLights = new THREE.Color(),
_vector3 = new THREE.Vector3(), // Needed for PointLight
_centroid = new THREE.Vector3(),
_normal = new THREE.Vector3(),
_normalViewMatrix = new THREE.Matrix3();
/* TODO
_canvas.mozImageSmoothingEnabled = false;
_canvas.webkitImageSmoothingEnabled = false;
_canvas.msImageSmoothingEnabled = false;
_canvas.imageSmoothingEnabled = false;
*/
// dash+gap fallbacks for Firefox and everything else
if ( _context.setLineDash === undefined ) {
_context.setLineDash = function () {};
}
this.domElement = _canvas;
this.autoClear = true;
this.sortObjects = true;
this.sortElements = true;
this.info = {
render: {
vertices: 0,
faces: 0
}
};
// WebGLRenderer compatibility
this.supportsVertexTextures = function () {};
this.setFaceCulling = function () {};
// API
this.getContext = function () {
return _context;
};
this.getContextAttributes = function () {
return _context.getContextAttributes();
};
this.getPixelRatio = function () {
return _pixelRatio;
};
this.setPixelRatio = function ( value ) {
if ( value !== undefined ) _pixelRatio = value;
};
this.setSize = function ( width, height, updateStyle ) {
_canvasWidth = width * _pixelRatio;
_canvasHeight = height * _pixelRatio;
_canvas.width = _canvasWidth;
_canvas.height = _canvasHeight;
_canvasWidthHalf = Math.floor( _canvasWidth / 2 );
_canvasHeightHalf = Math.floor( _canvasHeight / 2 );
if ( updateStyle !== false ) {
_canvas.style.width = width + ‘px’;
_canvas.style.height = height + ‘px’;
}
_clipBox.min.set( – _canvasWidthHalf, – _canvasHeightHalf );
_clipBox.max.set( _canvasWidthHalf, _canvasHeightHalf );
_clearBox.min.set( – _canvasWidthHalf, – _canvasHeightHalf );
_clearBox.max.set( _canvasWidthHalf, _canvasHeightHalf );
_contextGlobalAlpha = 1;
_contextGlobalCompositeOperation = 0;
_contextStrokeStyle = null;
_contextFillStyle = null;
_contextLineWidth = null;
_contextLineCap = null;
_contextLineJoin = null;
this.setViewport( 0, 0, width, height );
};
this.setViewport = function ( x, y, width, height ) {
_viewportX = x * _pixelRatio;
_viewportY = y * _pixelRatio;
_viewportWidth = width * _pixelRatio;
_viewportHeight = height * _pixelRatio;
};
this.setScissor = function () {};
this.setScissorTest = function () {};
this.setClearColor = function ( color, alpha ) {
_clearColor.set( color );
_clearAlpha = alpha !== undefined ? alpha : 1;
_clearBox.min.set( – _canvasWidthHalf, – _canvasHeightHalf );
_clearBox.max.set( _canvasWidthHalf, _canvasHeightHalf );
};
this.setClearColorHex = function ( hex, alpha ) {
console.warn( ‘THREE.CanvasRenderer: .setClearColorHex() is being removed. Use .setClearColor() instead.’ );
this.setClearColor( hex, alpha );
};
this.getClearColor = function () {
return _clearColor;
};
this.getClearAlpha = function () {
return _clearAlpha;
};
this.getMaxAnisotropy = function () {
return 0;
};
this.clear = function () {
if ( _clearBox.isEmpty() === false ) {
_clearBox.intersect( _clipBox );
_clearBox.expandByScalar( 2 );
_clearBox.min.x = _clearBox.min.x + _canvasWidthHalf;
_clearBox.min.y = – _clearBox.min.y + _canvasHeightHalf; // higher y value !
_clearBox.max.x = _clearBox.max.x + _canvasWidthHalf;
_clearBox.max.y = – _clearBox.max.y + _canvasHeightHalf; // lower y value !
if ( _clearAlpha 0 ) {
setBlending( THREE.NormalBlending );
setOpacity( 1 );
setFillStyle( ‘rgba(‘ + Math.floor( _clearColor.r * 255 ) + ‘,’ + Math.floor( _clearColor.g * 255 ) + ‘,’ + Math.floor( _clearColor.b * 255 ) + ‘,’ + _clearAlpha + ‘)’ );
_context.fillRect(
_clearBox.min.x | 0,
_clearBox.max.y | 0,
( _clearBox.max.x – _clearBox.min.x ) | 0,
( _clearBox.min.y – _clearBox.max.y ) | 0
);
}
_clearBox.makeEmpty();
}
};
// compatibility
this.clearColor = function () {};
this.clearDepth = function () {};
this.clearStencil = function () {};
this.render = function ( scene, camera ) {
if ( camera instanceof THREE.Camera === false ) {
console.error( ‘THREE.CanvasRenderer.render: camera is not an instance of THREE.Camera.’ );
return;
}
if ( this.autoClear === true ) this.clear();
_this.info.render.vertices = 0;
_this.info.render.faces = 0;
_context.setTransform( _viewportWidth / _canvasWidth, 0, 0, – _viewportHeight / _canvasHeight, _viewportX, _canvasHeight – _viewportY );
_context.translate( _canvasWidthHalf, _canvasHeightHalf );
_renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
_elements = _renderData.elements;
_lights = _renderData.lights;
_camera = camera;
_normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse );
/* DEBUG
setFillStyle( ‘rgba( 0, 255, 255, 0.5 )’ );
_context.fillRect( _clipBox.min.x, _clipBox.min.y, _clipBox.max.x – _clipBox.min.x, _clipBox.max.y – _clipBox.min.y );
*/
calculateLights();
for ( var e = 0, el = _elements.length; e < el; e ++ ) {
var element = _elements[ e ];
var material = element.material;
if ( material === undefined || material.opacity === 0 ) continue;
_elemBox.makeEmpty();
if ( element instanceof THREE.RenderableSprite ) {
_v1 = element;
_v1.x *= _canvasWidthHalf; _v1.y *= _canvasHeightHalf;
renderSprite( _v1, element, material );
} else if ( element instanceof THREE.RenderableLine ) {
_v1 = element.v1; _v2 = element.v2;
_v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
_v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
_elemBox.setFromPoints( [
_v1.positionScreen,
_v2.positionScreen
] );
if ( _clipBox.intersectsBox( _elemBox ) === true ) {
renderLine( _v1, _v2, element, material );
}
} else if ( element instanceof THREE.RenderableFace ) {
_v1 = element.v1; _v2 = element.v2; _v3 = element.v3;
if ( _v1.positionScreen.z 1 ) continue;
if ( _v2.positionScreen.z 1 ) continue;
if ( _v3.positionScreen.z 1 ) continue;
_v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
_v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
_v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf;
if ( material.overdraw > 0 ) {
expand( _v1.positionScreen, _v2.positionScreen, material.overdraw );
expand( _v2.positionScreen, _v3.positionScreen, material.overdraw );
expand( _v3.positionScreen, _v1.positionScreen, material.overdraw );
}
_elemBox.setFromPoints( [
_v1.positionScreen,
_v2.positionScreen,
_v3.positionScreen
] );
if ( _clipBox.intersectsBox( _elemBox ) === true ) {
renderFace3( _v1, _v2, _v3, 0, 1, 2, element, material );
}
}
/* DEBUG
setLineWidth( 1 );
setStrokeStyle( ‘rgba( 0, 255, 0, 0.5 )’ );
_context.strokeRect( _elemBox.min.x, _elemBox.min.y, _elemBox.max.x – _elemBox.min.x, _elemBox.max.y – _elemBox.min.y );
*/
_clearBox.union( _elemBox );
}
/* DEBUG
setLineWidth( 1 );
setStrokeStyle( ‘rgba( 255, 0, 0, 0.5 )’ );
_context.strokeRect( _clearBox.min.x, _clearBox.min.y, _clearBox.max.x – _clearBox.min.x, _clearBox.max.y – _clearBox.min.y );
*/
_context.setTransform( 1, 0, 0, 1, 0, 0 );
};
//
function calculateLights() {
_ambientLight.setRGB( 0, 0, 0 );
_directionalLights.setRGB( 0, 0, 0 );
_pointLights.setRGB( 0, 0, 0 );
for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
var light = _lights[ l ];
var lightColor = light.color;
if ( light instanceof THREE.AmbientLight ) {
_ambientLight.add( lightColor );
} else if ( light instanceof THREE.DirectionalLight ) {
// for sprites
_directionalLights.add( lightColor );
} else if ( light instanceof THREE.PointLight ) {
// for sprites
_pointLights.add( lightColor );
}
}
}
function calculateLight( position, normal, color ) {
for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
var light = _lights[ l ];
_lightColor.copy( light.color );
if ( light instanceof THREE.DirectionalLight ) {
var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ).normalize();
var amount = normal.dot( lightPosition );
if ( amount <= 0 ) continue;
amount *= light.intensity;
color.add( _lightColor.multiplyScalar( amount ) );
} else if ( light instanceof THREE.PointLight ) {
var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld );
var amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() );
if ( amount <= 0 ) continue;
amount *= light.distance == 0 ? 1 : 1 – Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
if ( amount == 0 ) continue;
amount *= light.intensity;
color.add( _lightColor.multiplyScalar( amount ) );
}
}
}
function renderSprite( v1, element, material ) {
setOpacity( material.opacity );
setBlending( material.blending );
var scaleX = element.scale.x * _canvasWidthHalf;
var scaleY = element.scale.y * _canvasHeightHalf;
var dist = 0.5 * Math.sqrt( scaleX * scaleX + scaleY * scaleY ); // allow for rotated sprite
_elemBox.min.set( v1.x – dist, v1.y – dist );
_elemBox.max.set( v1.x + dist, v1.y + dist );
if ( material instanceof THREE.SpriteMaterial ) {
var texture = material.map;
if ( texture !== null ) {
var pattern = _patterns[ texture.id ];
if ( pattern === undefined || pattern.version !== texture.version ) {
pattern = textureToPattern( texture );
_patterns[ texture.id ] = pattern;
}
if ( pattern.canvas !== undefined ) {
setFillStyle( pattern.canvas );
var bitmap = texture.image;
var ox = bitmap.width * texture.offset.x;
var oy = bitmap.height * texture.offset.y;
var sx = bitmap.width * texture.repeat.x;
var sy = bitmap.height * texture.repeat.y;
var cx = scaleX / sx;
var cy = scaleY / sy;
_context.save();
_context.translate( v1.x, v1.y );
if ( material.rotation !== 0 ) _context.rotate( material.rotation );
_context.translate( – scaleX / 2, – scaleY / 2 );
_context.scale( cx, cy );
_context.translate( – ox, – oy );
_context.fillRect( ox, oy, sx, sy );
_context.restore();
}
} else {
// no texture
setFillStyle( material.color.getStyle() );
_context.save();
_context.translate( v1.x, v1.y );
if ( material.rotation !== 0 ) _context.rotate( material.rotation );
_context.scale( scaleX, – scaleY );
_context.fillRect( – 0.5, – 0.5, 1, 1 );
_context.restore();
}
} else if ( material instanceof THREE.SpriteCanvasMaterial ) {
setStrokeStyle( material.color.getStyle() );
setFillStyle( material.color.getStyle() );
_context.save();
_context.translate( v1.x, v1.y );
if ( material.rotation !== 0 ) _context.rotate( material.rotation );
_context.scale( scaleX, scaleY );
material.program( _context );
_context.restore();
}
/* DEBUG
setStrokeStyle( 'rgb(255,255,0)' );
_context.beginPath();
_context.moveTo( v1.x – 10, v1.y );
_context.lineTo( v1.x + 10, v1.y );
_context.moveTo( v1.x, v1.y – 10 );
_context.lineTo( v1.x, v1.y + 10 );
_context.stroke();
*/
}
function renderLine( v1, v2, element, material ) {
setOpacity( material.opacity );
setBlending( material.blending );
_context.beginPath();
_context.moveTo( v1.positionScreen.x, v1.positionScreen.y );
_context.lineTo( v2.positionScreen.x, v2.positionScreen.y );
if ( material instanceof THREE.LineBasicMaterial ) {
setLineWidth( material.linewidth );
setLineCap( material.linecap );
setLineJoin( material.linejoin );
if ( material.vertexColors !== THREE.VertexColors ) {
setStrokeStyle( material.color.getStyle() );
} else {
var colorStyle1 = element.vertexColors[ 0 ].getStyle();
var colorStyle2 = element.vertexColors[ 1 ].getStyle();
if ( colorStyle1 === colorStyle2 ) {
setStrokeStyle( colorStyle1 );
} else {
try {
var grad = _context.createLinearGradient(
v1.positionScreen.x,
v1.positionScreen.y,
v2.positionScreen.x,
v2.positionScreen.y
);
grad.addColorStop( 0, colorStyle1 );
grad.addColorStop( 1, colorStyle2 );
} catch ( exception ) {
grad = colorStyle1;
}
setStrokeStyle( grad );
}
}
_context.stroke();
_elemBox.expandByScalar( material.linewidth * 2 );
} else if ( material instanceof THREE.LineDashedMaterial ) {
setLineWidth( material.linewidth );
setLineCap( material.linecap );
setLineJoin( material.linejoin );
setStrokeStyle( material.color.getStyle() );
setLineDash( [ material.dashSize, material.gapSize ] );
_context.stroke();
_elemBox.expandByScalar( material.linewidth * 2 );
setLineDash( [] );
}
}
function renderFace3( v1, v2, v3, uv1, uv2, uv3, element, material ) {
_this.info.render.vertices += 3;
_this.info.render.faces ++;
setOpacity( material.opacity );
setBlending( material.blending );
_v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
_v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
_v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
drawTriangle( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y );
if ( ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) && material.map === null ) {
_diffuseColor.copy( material.color );
_emissiveColor.copy( material.emissive );
if ( material.vertexColors === THREE.FaceColors ) {
_diffuseColor.multiply( element.color );
}
_color.copy( _ambientLight );
_centroid.copy( v1.positionWorld ).add( v2.positionWorld ).add( v3.positionWorld ).divideScalar( 3 );
calculateLight( _centroid, element.normalModel, _color );
_color.multiply( _diffuseColor ).add( _emissiveColor );
material.wireframe === true
? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
: fillPath( _color );
} else if ( material instanceof THREE.MeshBasicMaterial ||
material instanceof THREE.MeshLambertMaterial ||
material instanceof THREE.MeshPhongMaterial ) {
if ( material.map !== null ) {
var mapping = material.map.mapping;
if ( mapping === THREE.UVMapping ) {
_uvs = element.uvs;
patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].x, _uvs[ uv1 ].y, _uvs[ uv2 ].x, _uvs[ uv2 ].y, _uvs[ uv3 ].x, _uvs[ uv3 ].y, material.map );
}
} else if ( material.envMap !== null ) {
if ( material.envMap.mapping === THREE.SphericalReflectionMapping ) {
_normal.copy( element.vertexNormalsModel[ uv1 ] ).applyMatrix3( _normalViewMatrix );
_uv1x = 0.5 * _normal.x + 0.5;
_uv1y = 0.5 * _normal.y + 0.5;
_normal.copy( element.vertexNormalsModel[ uv2 ] ).applyMatrix3( _normalViewMatrix );
_uv2x = 0.5 * _normal.x + 0.5;
_uv2y = 0.5 * _normal.y + 0.5;
_normal.copy( element.vertexNormalsModel[ uv3 ] ).applyMatrix3( _normalViewMatrix );
_uv3x = 0.5 * _normal.x + 0.5;
_uv3y = 0.5 * _normal.y + 0.5;
patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, material.envMap );
}
} else {
_color.copy( material.color );
if ( material.vertexColors === THREE.FaceColors ) {
_color.multiply( element.color );
}
material.wireframe === true
? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
: fillPath( _color );
}
} else if ( material instanceof THREE.MeshNormalMaterial ) {
_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix );
_color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
material.wireframe === true
? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
: fillPath( _color );
} else {
_color.setRGB( 1, 1, 1 );
material.wireframe === true
? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin )
: fillPath( _color );
}
}
//
function drawTriangle( x0, y0, x1, y1, x2, y2 ) {
_context.beginPath();
_context.moveTo( x0, y0 );
_context.lineTo( x1, y1 );
_context.lineTo( x2, y2 );
_context.closePath();
}
function strokePath( color, linewidth, linecap, linejoin ) {
setLineWidth( linewidth );
setLineCap( linecap );
setLineJoin( linejoin );
setStrokeStyle( color.getStyle() );
_context.stroke();
_elemBox.expandByScalar( linewidth * 2 );
}
function fillPath( color ) {
setFillStyle( color.getStyle() );
_context.fill();
}
function textureToPattern( texture ) {
if ( texture.version === 0 ||
texture instanceof THREE.CompressedTexture ||
texture instanceof THREE.DataTexture ) {
return {
canvas: undefined,
version: texture.version
};
}
var image = texture.image;
if ( image.complete === false ) {
return {
canvas: undefined,
version: 0
};
}
var canvas = document.createElement( 'canvas' );
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext( '2d' );
context.setTransform( 1, 0, 0, – 1, 0, image.height );
context.drawImage( image, 0, 0 );
var repeatX = texture.wrapS === THREE.RepeatWrapping;
var repeatY = texture.wrapT === THREE.RepeatWrapping;
var repeat = 'no-repeat';
if ( repeatX === true && repeatY === true ) {
repeat = 'repeat';
} else if ( repeatX === true ) {
repeat = 'repeat-x';
} else if ( repeatY === true ) {
repeat = 'repeat-y';
}
var pattern = _context.createPattern( canvas, repeat );
if ( texture.onUpdate ) texture.onUpdate( texture );
return {
canvas: pattern,
version: texture.version
};
}
function patternPath( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, texture ) {
var pattern = _patterns[ texture.id ];
if ( pattern === undefined || pattern.version !== texture.version ) {
pattern = textureToPattern( texture );
_patterns[ texture.id ] = pattern;
}
if ( pattern.canvas !== undefined ) {
setFillStyle( pattern.canvas );
} else {
setFillStyle( 'rgba( 0, 0, 0, 1)' );
_context.fill();
return;
}
// http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
var a, b, c, d, e, f, det, idet,
offsetX = texture.offset.x / texture.repeat.x,
offsetY = texture.offset.y / texture.repeat.y,
width = texture.image.width * texture.repeat.x,
height = texture.image.height * texture.repeat.y;
u0 = ( u0 + offsetX ) * width;
v0 = ( v0 + offsetY ) * height;
u1 = ( u1 + offsetX ) * width;
v1 = ( v1 + offsetY ) * height;
u2 = ( u2 + offsetX ) * width;
v2 = ( v2 + offsetY ) * height;
x1 -= x0; y1 -= y0;
x2 -= x0; y2 -= y0;
u1 -= u0; v1 -= v0;
u2 -= u0; v2 -= v0;
det = u1 * v2 – u2 * v1;
if ( det === 0 ) return;
idet = 1 / det;
a = ( v2 * x1 – v1 * x2 ) * idet;
b = ( v2 * y1 – v1 * y2 ) * idet;
c = ( u1 * x2 – u2 * x1 ) * idet;
d = ( u1 * y2 – u2 * y1 ) * idet;
e = x0 – a * u0 – c * v0;
f = y0 – b * u0 – d * v0;
_context.save();
_context.transform( a, b, c, d, e, f );
_context.fill();
_context.restore();
}
function clipImage( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, image ) {
// http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
var a, b, c, d, e, f, det, idet,
width = image.width – 1,
height = image.height – 1;
u0 *= width; v0 *= height;
u1 *= width; v1 *= height;
u2 *= width; v2 *= height;
x1 -= x0; y1 -= y0;
x2 -= x0; y2 -= y0;
u1 -= u0; v1 -= v0;
u2 -= u0; v2 -= v0;
det = u1 * v2 – u2 * v1;
idet = 1 / det;
a = ( v2 * x1 – v1 * x2 ) * idet;
b = ( v2 * y1 – v1 * y2 ) * idet;
c = ( u1 * x2 – u2 * x1 ) * idet;
d = ( u1 * y2 – u2 * y1 ) * idet;
e = x0 – a * u0 – c * v0;
f = y0 – b * u0 – d * v0;
_context.save();
_context.transform( a, b, c, d, e, f );
_context.clip();
_context.drawImage( image, 0, 0 );
_context.restore();
}
// Hide anti-alias gaps
function expand( v1, v2, pixels ) {
var x = v2.x – v1.x, y = v2.y – v1.y,
det = x * x + y * y, idet;
if ( det === 0 ) return;
idet = pixels / Math.sqrt( det );
x *= idet; y *= idet;
v2.x += x; v2.y += y;
v1.x -= x; v1.y -= y;
}
// Context cached methods.
function setOpacity( value ) {
if ( _contextGlobalAlpha !== value ) {
_context.globalAlpha = value;
_contextGlobalAlpha = value;
}
}
function setBlending( value ) {
if ( _contextGlobalCompositeOperation !== value ) {
if ( value === THREE.NormalBlending ) {
_context.globalCompositeOperation = 'source-over';
} else if ( value === THREE.AdditiveBlending ) {
_context.globalCompositeOperation = 'lighter';
} else if ( value === THREE.SubtractiveBlending ) {
_context.globalCompositeOperation = 'darker';
}
_contextGlobalCompositeOperation = value;
}
}
function setLineWidth( value ) {
if ( _contextLineWidth !== value ) {
_context.lineWidth = value;
_contextLineWidth = value;
}
}
function setLineCap( value ) {
// "butt", "round", "square"
if ( _contextLineCap !== value ) {
_context.lineCap = value;
_contextLineCap = value;
}
}
function setLineJoin( value ) {
// "round", "bevel", "miter"
if ( _contextLineJoin !== value ) {
_context.lineJoin = value;
_contextLineJoin = value;
}
}
function setStrokeStyle( value ) {
if ( _contextStrokeStyle !== value ) {
_context.strokeStyle = value;
_contextStrokeStyle = value;
}
}
function setFillStyle( value ) {
if ( _contextFillStyle !== value ) {
_context.fillStyle = value;
_contextFillStyle = value;
}
}
function setLineDash( value ) {
if ( _contextLineDash.length !== value.length ) {
_context.setLineDash( value );
_contextLineDash = value;
}
}
};
/**
* @author mrdoob / http://mrdoob.com/
* @author supereggbert / http://www.paulbrunt.co.uk/
* @author julianwa / https://github.com/julianwa
*/
THREE.RenderableObject = function () {
this.id = 0;
this.object = null;
this.z = 0;
this.renderOrder = 0;
};
//
THREE.RenderableFace = function () {
this.id = 0;
this.v1 = new THREE.RenderableVertex();
this.v2 = new THREE.RenderableVertex();
this.v3 = new THREE.RenderableVertex();
this.normalModel = new THREE.Vector3();
this.vertexNormalsModel = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
this.vertexNormalsLength = 0;
this.color = new THREE.Color();
this.material = null;
this.uvs = [ new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() ];
this.z = 0;
this.renderOrder = 0;
};
//
THREE.RenderableVertex = function () {
this.position = new THREE.Vector3();
this.positionWorld = new THREE.Vector3();
this.positionScreen = new THREE.Vector4();
this.visible = true;
};
THREE.RenderableVertex.prototype.copy = function ( vertex ) {
this.positionWorld.copy( vertex.positionWorld );
this.positionScreen.copy( vertex.positionScreen );
};
//
THREE.RenderableLine = function () {
this.id = 0;
this.v1 = new THREE.RenderableVertex();
this.v2 = new THREE.RenderableVertex();
this.vertexColors = [ new THREE.Color(), new THREE.Color() ];
this.material = null;
this.z = 0;
this.renderOrder = 0;
};
//
THREE.RenderableSprite = function () {
this.id = 0;
this.object = null;
this.x = 0;
this.y = 0;
this.z = 0;
this.rotation = 0;
this.scale = new THREE.Vector2();
this.material = null;
this.renderOrder = 0;
};
//
THREE.Projector = function () {
var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
_face, _faceCount, _facePool = [], _facePoolLength = 0,
_line, _lineCount, _linePool = [], _linePoolLength = 0,
_sprite, _spriteCount, _spritePool = [], _spritePoolLength = 0,
_renderData = { objects: [], lights: [], elements: [] },
_vector3 = new THREE.Vector3(),
_vector4 = new THREE.Vector4(),
_clipBox = new THREE.Box3( new THREE.Vector3( – 1, – 1, – 1 ), new THREE.Vector3( 1, 1, 1 ) ),
_boundingBox = new THREE.Box3(),
_points3 = new Array( 3 ),
_points4 = new Array( 4 ),
_viewMatrix = new THREE.Matrix4(),
_viewProjectionMatrix = new THREE.Matrix4(),
_modelMatrix,
_modelViewProjectionMatrix = new THREE.Matrix4(),
_normalMatrix = new THREE.Matrix3(),
_frustum = new THREE.Frustum(),
_clippedVertex1PositionScreen = new THREE.Vector4(),
_clippedVertex2PositionScreen = new THREE.Vector4();
//
this.projectVector = function ( vector, camera ) {
console.warn( ‘THREE.Projector: .projectVector() is now vector.project().’ );
vector.project( camera );
};
this.unprojectVector = function ( vector, camera ) {
console.warn( ‘THREE.Projector: .unprojectVector() is now vector.unproject().’ );
vector.unproject( camera );
};
this.pickingRay = function ( vector, camera ) {
console.error( ‘THREE.Projector: .pickingRay() is now raycaster.setFromCamera().’ );
};
//
var RenderList = function () {
var normals = [];
var uvs = [];
var object = null;
var material = null;
var normalMatrix = new THREE.Matrix3();
function setObject( value ) {
object = value;
material = object.material;
normalMatrix.getNormalMatrix( object.matrixWorld );
normals.length = 0;
uvs.length = 0;
}
function projectVertex( vertex ) {
var position = vertex.position;
var positionWorld = vertex.positionWorld;
var positionScreen = vertex.positionScreen;
positionWorld.copy( position ).applyMatrix4( _modelMatrix );
positionScreen.copy( positionWorld ).applyMatrix4( _viewProjectionMatrix );
var invW = 1 / positionScreen.w;
positionScreen.x *= invW;
positionScreen.y *= invW;
positionScreen.z *= invW;
vertex.visible = positionScreen.x >= – 1 && positionScreen.x = – 1 && positionScreen.y = – 1 && positionScreen.z <= 1;
}
function pushVertex( x, y, z ) {
_vertex = getNextVertexInPool();
_vertex.position.set( x, y, z );
projectVertex( _vertex );
}
function pushNormal( x, y, z ) {
normals.push( x, y, z );
}
function pushUv( x, y ) {
uvs.push( x, y );
}
function checkTriangleVisibility( v1, v2, v3 ) {
if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true;
_points3[ 0 ] = v1.positionScreen;
_points3[ 1 ] = v2.positionScreen;
_points3[ 2 ] = v3.positionScreen;
return _clipBox.intersectsBox( _boundingBox.setFromPoints( _points3 ) );
}
function checkBackfaceCulling( v1, v2, v3 ) {
return ( ( v3.positionScreen.x – v1.positionScreen.x ) *
( v2.positionScreen.y – v1.positionScreen.y ) –
( v3.positionScreen.y – v1.positionScreen.y ) *
( v2.positionScreen.x – v1.positionScreen.x ) ) < 0;
}
function pushLine( a, b ) {
var v1 = _vertexPool[ a ];
var v2 = _vertexPool[ b ];
_line = getNextLineInPool();
_line.id = object.id;
_line.v1.copy( v1 );
_line.v2.copy( v2 );
_line.z = ( v1.positionScreen.z + v2.positionScreen.z ) / 2;
_line.renderOrder = object.renderOrder;
_line.material = object.material;
_renderData.elements.push( _line );
}
function pushTriangle( a, b, c ) {
var v1 = _vertexPool[ a ];
var v2 = _vertexPool[ b ];
var v3 = _vertexPool[ c ];
if ( checkTriangleVisibility( v1, v2, v3 ) === false ) return;
if ( material.side === THREE.DoubleSide || checkBackfaceCulling( v1, v2, v3 ) === true ) {
_face = getNextFaceInPool();
_face.id = object.id;
_face.v1.copy( v1 );
_face.v2.copy( v2 );
_face.v3.copy( v3 );
_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
_face.renderOrder = object.renderOrder;
// use first vertex normal as face normal
_face.normalModel.fromArray( normals, a * 3 );
_face.normalModel.applyMatrix3( normalMatrix ).normalize();
for ( var i = 0; i < 3; i ++ ) {
var normal = _face.vertexNormalsModel[ i ];
normal.fromArray( normals, arguments[ i ] * 3 );
normal.applyMatrix3( normalMatrix ).normalize();
var uv = _face.uvs[ i ];
uv.fromArray( uvs, arguments[ i ] * 2 );
}
_face.vertexNormalsLength = 3;
_face.material = object.material;
_renderData.elements.push( _face );
}
}
return {
setObject: setObject,
projectVertex: projectVertex,
checkTriangleVisibility: checkTriangleVisibility,
checkBackfaceCulling: checkBackfaceCulling,
pushVertex: pushVertex,
pushNormal: pushNormal,
pushUv: pushUv,
pushLine: pushLine,
pushTriangle: pushTriangle
}
};
var renderList = new RenderList();
this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
_faceCount = 0;
_lineCount = 0;
_spriteCount = 0;
_renderData.elements.length = 0;
if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
if ( camera.parent === null ) camera.updateMatrixWorld();
_viewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );
_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
_frustum.setFromMatrix( _viewProjectionMatrix );
//
_objectCount = 0;
_renderData.objects.length = 0;
_renderData.lights.length = 0;
scene.traverseVisible( function ( object ) {
if ( object instanceof THREE.Light ) {
_renderData.lights.push( object );
} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Sprite ) {
var material = object.material;
if ( material.visible === false ) return;
if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
_object = getNextObjectInPool();
_object.id = object.id;
_object.object = object;
_vector3.setFromMatrixPosition( object.matrixWorld );
_vector3.applyProjection( _viewProjectionMatrix );
_object.z = _vector3.z;
_object.renderOrder = object.renderOrder;
_renderData.objects.push( _object );
}
}
} );
if ( sortObjects === true ) {
_renderData.objects.sort( painterSort );
}
//
for ( var o = 0, ol = _renderData.objects.length; o < ol; o ++ ) {
var object = _renderData.objects[ o ].object;
var geometry = object.geometry;
renderList.setObject( object );
_modelMatrix = object.matrixWorld;
_vertexCount = 0;
if ( object instanceof THREE.Mesh ) {
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
var groups = geometry.groups;
if ( attributes.position === undefined ) continue;
var positions = attributes.position.array;
for ( var i = 0, l = positions.length; i < l; i += 3 ) {
renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
}
if ( attributes.normal !== undefined ) {
var normals = attributes.normal.array;
for ( var i = 0, l = normals.length; i < l; i += 3 ) {
renderList.pushNormal( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] );
}
}
if ( attributes.uv !== undefined ) {
var uvs = attributes.uv.array;
for ( var i = 0, l = uvs.length; i 0 ) {
for ( var o = 0; o < groups.length; o ++ ) {
var group = groups[ o ];
for ( var i = group.start, l = group.start + group.count; i < l; i += 3 ) {
renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
}
}
} else {
for ( var i = 0, l = indices.length; i < l; i += 3 ) {
renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
}
}
} else {
for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) {
renderList.pushTriangle( i, i + 1, i + 2 );
}
}
} else if ( geometry instanceof THREE.Geometry ) {
var vertices = geometry.vertices;
var faces = geometry.faces;
var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
_normalMatrix.getNormalMatrix( _modelMatrix );
var material = object.material;
var isFaceMaterial = material instanceof THREE.MultiMaterial;
var objectMaterials = isFaceMaterial === true ? object.material : null;
for ( var v = 0, vl = vertices.length; v < vl; v ++ ) {
var vertex = vertices[ v ];
_vector3.copy( vertex );
if ( material.morphTargets === true ) {
var morphTargets = geometry.morphTargets;
var morphInfluences = object.morphTargetInfluences;
for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
var influence = morphInfluences[ t ];
if ( influence === 0 ) continue;
var target = morphTargets[ t ];
var targetVertex = target.vertices[ v ];
_vector3.x += ( targetVertex.x – vertex.x ) * influence;
_vector3.y += ( targetVertex.y – vertex.y ) * influence;
_vector3.z += ( targetVertex.z – vertex.z ) * influence;
}
}
renderList.pushVertex( _vector3.x, _vector3.y, _vector3.z );
}
for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
var face = faces[ f ];
material = isFaceMaterial === true
? objectMaterials.materials[ face.materialIndex ]
: object.material;
if ( material === undefined ) continue;
var side = material.side;
var v1 = _vertexPool[ face.a ];
var v2 = _vertexPool[ face.b ];
var v3 = _vertexPool[ face.c ];
if ( renderList.checkTriangleVisibility( v1, v2, v3 ) === false ) continue;
var visible = renderList.checkBackfaceCulling( v1, v2, v3 );
if ( side !== THREE.DoubleSide ) {
if ( side === THREE.FrontSide && visible === false ) continue;
if ( side === THREE.BackSide && visible === true ) continue;
}
_face = getNextFaceInPool();
_face.id = object.id;
_face.v1.copy( v1 );
_face.v2.copy( v2 );
_face.v3.copy( v3 );
_face.normalModel.copy( face.normal );
if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
_face.normalModel.negate();
}
_face.normalModel.applyMatrix3( _normalMatrix ).normalize();
var faceVertexNormals = face.vertexNormals;
for ( var n = 0, nl = Math.min( faceVertexNormals.length, 3 ); n < nl; n ++ ) {
var normalModel = _face.vertexNormalsModel[ n ];
normalModel.copy( faceVertexNormals[ n ] );
if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
normalModel.negate();
}
normalModel.applyMatrix3( _normalMatrix ).normalize();
}
_face.vertexNormalsLength = faceVertexNormals.length;
var vertexUvs = faceVertexUvs[ f ];
if ( vertexUvs !== undefined ) {
for ( var u = 0; u < 3; u ++ ) {
_face.uvs[ u ].copy( vertexUvs[ u ] );
}
}
_face.color = face.color;
_face.material = material;
_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
_face.renderOrder = object.renderOrder;
_renderData.elements.push( _face );
}
}
} else if ( object instanceof THREE.Line ) {
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
if ( attributes.position !== undefined ) {
var positions = attributes.position.array;
for ( var i = 0, l = positions.length; i < l; i += 3 ) {
renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
}
if ( geometry.index !== null ) {
var indices = geometry.index.array;
for ( var i = 0, l = indices.length; i < l; i += 2 ) {
renderList.pushLine( indices[ i ], indices[ i + 1 ] );
}
} else {
var step = object instanceof THREE.LineSegments ? 2 : 1;
for ( var i = 0, l = ( positions.length / 3 ) – 1; i < l; i += step ) {
renderList.pushLine( i, i + 1 );
}
}
}
} else if ( geometry instanceof THREE.Geometry ) {
_modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix );
var vertices = object.geometry.vertices;
if ( vertices.length === 0 ) continue;
v1 = getNextVertexInPool();
v1.positionScreen.copy( vertices[ 0 ] ).applyMatrix4( _modelViewProjectionMatrix );
var step = object instanceof THREE.LineSegments ? 2 : 1;
for ( var v = 1, vl = vertices.length; v 0 ) continue;
v2 = _vertexPool[ _vertexCount – 2 ];
_clippedVertex1PositionScreen.copy( v1.positionScreen );
_clippedVertex2PositionScreen.copy( v2.positionScreen );
if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
// Perform the perspective divide
_clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
_clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
_line = getNextLineInPool();
_line.id = object.id;
_line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
_line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
_line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
_line.renderOrder = object.renderOrder;
_line.material = object.material;
if ( object.material.vertexColors === THREE.VertexColors ) {
_line.vertexColors[ 0 ].copy( object.geometry.colors[ v ] );
_line.vertexColors[ 1 ].copy( object.geometry.colors[ v – 1 ] );
}
_renderData.elements.push( _line );
}
}
}
} else if ( object instanceof THREE.Sprite ) {
_vector4.set( _modelMatrix.elements[ 12 ], _modelMatrix.elements[ 13 ], _modelMatrix.elements[ 14 ], 1 );
_vector4.applyMatrix4( _viewProjectionMatrix );
var invW = 1 / _vector4.w;
_vector4.z *= invW;
if ( _vector4.z >= – 1 && _vector4.z = 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
// Both vertices lie entirely within all clip planes.
return true;
} else if ( ( bc1near < 0 && bc2near < 0 ) || ( bc1far < 0 && bc2far < 0 ) ) {
// Both vertices lie entirely outside one of the clip planes.
return false;
} else {
// The line segment spans at least one clip plane.
if ( bc1near < 0 ) {
// v1 lies outside the near plane, v2 inside
alpha1 = Math.max( alpha1, bc1near / ( bc1near – bc2near ) );
} else if ( bc2near < 0 ) {
// v2 lies outside the near plane, v1 inside
alpha2 = Math.min( alpha2, bc1near / ( bc1near – bc2near ) );
}
if ( bc1far < 0 ) {
// v1 lies outside the far plane, v2 inside
alpha1 = Math.max( alpha1, bc1far / ( bc1far – bc2far ) );
} else if ( bc2far < 0 ) {
// v2 lies outside the far plane, v2 inside
alpha2 = Math.min( alpha2, bc1far / ( bc1far – bc2far ) );
}
if ( alpha2 < alpha1 ) {
// The line segment spans two boundaries, but is outside both of them.
// (This can't happen when we're only clipping against just near/far but good
// to leave the check here for future usage if other clip planes are added.)
return false;
} else {
// Update the s1 and s2 vertices to match the clipped line segment.
s1.lerp( s2, alpha1 );
s2.lerp( s1, 1 – alpha2 );
return true;
}
}
}
};
//—————————————-
// Oscar de Abril
// Technical University of Madrid
// Email: oscar.deabril@upm.es
// Web site: http://oscardeabril.es
// http://oscardeabril.aq.upm.es
//—————————————-
var container, info, msg, objects, zoom, faces, vlines;
var contWidth, contHeight;
var motMode = 0;
document.getElementById(‘rot3D’).style.color = ‘red’;
var object = ‘prism’;
var camera, scene, renderer;
var projector4D;
var projector3D = new THREE.Projector();
var HobserverDist = 15; // Hyperobserver distance to the reference origin
//var HplaneDist = 2; // Hyperplane distance to the hyperobserver
var HplaneDist = HobserverDist; // Hyperplane distance to the hyperobserver
var dirLight, hemiLight;
var geometry, material, prismMater, hex;
var redMat, yellowMat, greenMat, blueMat, purpleMat, edgeMat, vanLineMat;
// Rotated reference frame
var axisX, oriAxisX, vecAxisX;
var axisY, oriAxisY, vecAxisY;
var axisZ, oriAxisZ, vecAxisZ;
var axisW, oriAxisW, vecAxisW;
// No rotated reference frame
var axisXnr, axisYnr, axisZnr, axisWnr;
var labelAxisX, labelAxisY, labelAxisZ, labelAxisW;
var plnsXY_YZ = false, plnsXY_ZW = false, plnsXY_WX = false;
var axsXZ = false, axsYZ = false, axsXW = false, axsYW = false;
var dir, origin, length;
var grid, axis, group;
var vanLines = false;
var prism1, vertPrism1 = [], prism1Edges, prism1VanLines;
var building1, vertBuilding1 = [], building1Edges = [], building1VanLines = [];
var building2, vertBuilding2 = [], building2Edges = [], building2VanLines = [];
var building3, vertBuilding3 = [], building3Edges = [], building3VanLines = [];
var hypercube, vertHypercube = [], hypercubeEdges, hypercubeVanLines;
var hyperbuilding1, vertHyperbuilding1 = [], hyperbuilding1Edges, hyperbuilding1VanLines;
var hyperbuilding2, vertHyperbuilding2 = [], hyperbuilding2Edges, hyperbuilding2VanLines;
var hyperbuilding3, vertHyperbuilding3 = [], hyperbuilding3Edges, hyperbuilding3VanLines;
var cameraDistFor4Dperspective = 50; //5
var cameraDistFor4Dorthogonal = 50;
var AngTheta = -60*Math.PI/180, AngPhi = -30*Math.PI/180;
var AngThetaOnMouseDown = 0, AngPhiOnMouseDown = 0;
var angXYOnMouseDown = 0, angYZOnMouseDown = 0, angZWOnMouseDown = 0, angWXOnMouseDown = 0;
var pos3DX = 0, pos3DY = 0, pos3DZ = 0;
var pos3DXOnMouseDown = 0, pos3DYOnMouseDown = 0, pos3DZOnMouseDown = 0;
var pos4DXOnMouseDown = 0, pos4DYOnMouseDown = 0, pos4DZOnMouseDown = 0, pos4DWOnMouseDown = 0;
var mouseX = 0, mouseY = 0;
var mouseXOnMouseDown = 0, mouseYOnMouseDown = 0;
//var windowHalfX = window.innerWidth/2;
//var windowHalfY = window.innerHeight/2;
init();
render();
function set4Dorthographic(){
projector4D.repMode = 1;
camera.position.z = cameraDistFor4Dorthogonal; // adjusting the 3D camera distance
document.getElementById(‘4Dpers’).style.color = ‘black’;
document.getElementById(‘4Dorto’).style.color = ‘red’;
updateElements();
render();
}
function set4Dperspective(){
projector4D.repMode = 0;
camera.position.z = cameraDistFor4Dperspective; // adjusting the 3D camera distance
document.getElementById(‘4Dpers’).style.color = ‘red’;
document.getElementById(‘4Dorto’).style.color = ‘black’;
updateElements();
render();
}
function set3Dorthographic(){
camera.toOrthographic();
document.getElementById(‘proj3D’).innerHTML = ‘Ortogonal’;
}
function set3Dperspective(){
camera.toPerspective();
document.getElementById(‘proj3D’).innerHTML = ‘Perspectiva’;
}
function resetMotionIndicators(){
document.getElementById(‘rot3D’).style.color = ‘black’;
document.getElementById(‘XY_YZ’).style.color = ‘black’;
document.getElementById(‘XY_ZW’).style.color = ‘black’;
document.getElementById(‘XY_WX’).style.color = ‘black’;
document.getElementById(‘AngTheta’).style.color = ‘black’;
document.getElementById(‘AngPhi’).style.color = ‘black’;
document.getElementById(‘angXY’).style.color = ‘black’;
document.getElementById(‘angYZ’).style.color = ‘black’;
document.getElementById(‘angZW’).style.color = ‘black’;
document.getElementById(‘angWX’).style.color = ‘black’;
document.getElementById(‘pos3D_YZ’).style.color = ‘black’;
document.getElementById(‘pos4D_YZ’).style.color = ‘black’;
plnsXY_YZ = false; plnsXY_ZW = false; plnsXY_WX = false;
axsXZ = false; axsYZ = false; axsXW = false; axsYW = false;
}
function set3Drotation(){
motMode = 0;
resetMotionIndicators();
document.getElementById(‘rot3D’).style.color = ‘red’;
document.getElementById(‘AngTheta’).style.color = ‘red’;
document.getElementById(‘AngPhi’).style.color = ‘red’;
}
function set4Drotation(planes){
motMode = 1;
resetMotionIndicators();
if(planes == ‘XY_YZ’){
document.getElementById(‘XY_YZ’).style.color = ‘red’;
document.getElementById(‘angXY’).style.color = ‘red’;
document.getElementById(‘angYZ’).style.color = ‘red’;
plnsXY_YZ = true;
}else if(planes == ‘XY_ZW’){
document.getElementById(‘XY_ZW’).style.color = ‘red’;
document.getElementById(‘angXY’).style.color = ‘red’;
document.getElementById(‘angZW’).style.color = ‘red’;
plnsXY_ZW = true;
}else if(planes == ‘XY_WX’){
document.getElementById(‘XY_WX’).style.color = ‘red’;
document.getElementById(‘angXY’).style.color = ‘red’;
document.getElementById(‘angWX’).style.color = ‘red’;
plnsXY_WX = true;
}
}
function set3Dposition(axes){
motMode = 2;
resetMotionIndicators();
document.getElementById(‘pos3D_YZ’).style.color = ‘red’;
if(axes == ‘YZ’){
axsYZ = true;
}
}
function set4Dposition(axes){
motMode = 3;
resetMotionIndicators();
document.getElementById(‘pos4D_YZ’).style.color = ‘red’;
if(axes == ‘YZ’){
axsYZ = true;
}
}
function init4Dangles(){
projector4D.initProjector();
document.getElementById(‘angXY’).innerHTML = (projector4D.angXY*180/3.1416).toFixed(0)+’o ‘;
document.getElementById(‘angYZ’).innerHTML = (projector4D.angYZ*180/3.1416).toFixed(0)+’o ‘;
document.getElementById(‘angZW’).innerHTML = (projector4D.angZW*180/3.1416).toFixed(0)+’o ‘;
document.getElementById(‘angWX’).innerHTML = (projector4D.angWX*180/3.1416).toFixed(0)+’o ‘;
updateElements();
render();
}
function init3Dview(){
AngTheta = -60*Math.PI/180, AngPhi = -30*Math.PI/180;
document.getElementById(‘AngPhi’).innerHTML = (-AngPhi*180/3.1416).toFixed(0)+’o ‘;
document.getElementById(‘AngTheta’).innerHTML = (-AngTheta*180/3.1416).toFixed(0)+’o ‘;
pos3DX = 0;
pos3DY = 0;
pos3DZ = 0;
render();
}
function initPositions(){
projector4D.posX = 0;
projector4D.posY = 0;
projector4D.posZ = 0;
projector4D.posW = 0;
updateElements();
render();
}
function selectObject(obj){
document.getElementById(‘prism’).style.color = ‘black’;
document.getElementById(‘buildings’).style.color = ‘black’;
document.getElementById(‘hypercube’).style.color = ‘black’;
document.getElementById(‘hyperbuilding’).style.color = ‘black’;
if(obj == ‘prism’){
document.getElementById(‘prism’).style.color = ‘red’;
object = ‘prism’;
}else if(obj == ‘buildings’){
document.getElementById(‘buildings’).style.color = ‘red’;
object = ‘buildings’;
}else if(obj == ‘hypercube’){
document.getElementById(‘hypercube’).style.color = ‘red’;
object = ‘hypercube’;
}else if(obj == ‘hyperbuilding’){
document.getElementById(‘hyperbuilding’).style.color = ‘red’;
object = ‘hyperbuilding’;
}
addObjects();
updateElements();
render();
}
function setZoom(zm){
if(projector4D.repMode == 0)
camera.position.z = cameraDistFor4Dperspective/zm;
else if(projector4D.repMode == 1)
camera.position.z = cameraDistFor4Dorthogonal/zm;
// updateElements();
render();
}
function setOpacity(opac){
redMat.opacity = opac;
yellowMat.opacity = opac;
greenMat.opacity = opac;
blueMat.opacity = opac;
purpleMat.opacity = opac;
// updateElements();
render();
}
function setVanLines(bol){
vanLines = bol;
addObjects();
updateElements();
render();
}
function init(){
setContainerSize();
container = document.getElementById(‘container’);
container.style.width = contWidth+’px’;
container.style.height = contHeight+’px’;
info = document.createElement(‘div’);
info.style.position = ‘absolute’;
info.style.bottom = ‘5px’;
info.style.width = ‘100%’;
info.style.textAlign = ‘center’;
info.innerHTML = ‘‘+
‘Proyección 3D del espacio Euclídeo 4D – ‘+
‘Oscar de Abril ‘;
container.appendChild(info);
msg = document.createElement(‘div’);
msg.style.position = ‘absolute’;
msg.style.top = ‘25%’;
msg.style.width = ‘100%’;
msg.style.textAlign = ‘center’;
msg.style.color = ‘#f11′;
msg.style.fontSize = ’15px’;
msg.style.fontWeight = ‘bold’;
msg.style.textShadow = ‘2px 2px 2px #fff’;
msg.innerHTML = ‘Mueve el objeto con el puntero’;
msg.style.pointerEvents = “none”;
container.appendChild(msg);
// Create a scene
scene = new THREE.Scene();
// Add the camera
camera = new THREE.PerspectiveCamera(70,contWidth/contHeight,.1,1e6);
//camera.position.set(0, 100, 250);
camera.position.z = cameraDistFor4Dperspective;
camera.matrixAutoUpdate;
// Add a group
group = new THREE.Group();
scene.add(group);
// Create 4D proyection
projector4D = new Projector4D();
projector4D.ObserverDist = HobserverDist;
projector4D.HyperplaneDist = HplaneDist;
// Add scene elements
addElements();
// Add lights
addLights();
// Create the WebGL Renderer
renderer = new THREE.CanvasRenderer();
renderer.setClearColor(0xa0c0f0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(contWidth,contHeight);
// Append the renderer to the container
container.appendChild(renderer.domElement);
// Add the object menu
objects = document.createElement(‘div’);
objects.style.position = ‘absolute’;
objects.style.top = ’10px’;
objects.style.left = ’10px’;
objects.style.width = ‘50%’;
objects.style.textAlign = ‘left’;
objects.style.zIndex = ’10’;
objects.innerHTML = ‘‘+
‘Prisma 3 Torres ‘+
‘Hipercubo ‘+
‘Hipertorre ‘;
container.appendChild(objects);
// Add the zoom menu
zoom = document.createElement(‘div’);
zoom.style.position = ‘absolute’;
zoom.style.top = ’10px’;
zoom.style.right = ’10px’;
zoom.style.width = ‘50%’;
zoom.style.textAlign = ‘right’;
//zoom.style.zIndex = ‘1’;
zoom.innerHTML = ‘Zoom: x0.5 | ‘+
‘x1 | ‘+
‘x2 ‘;
container.appendChild(zoom);
// Add the faces menu
faces = document.createElement(‘div’);
faces.style.position = ‘absolute’;
faces.style.top = ’30px’;
faces.style.right = ’10px’;
faces.style.width = ‘100%’;
faces.style.textAlign = ‘right’;
//zoom.style.zIndex = ‘1’;
faces.innerHTML = ‘Caras: no | ‘+
‘trans. | ‘+
‘sí ‘;
container.appendChild(faces);
// Add the vanishing lines menu
vlines = document.createElement(‘div’);
vlines.style.position = ‘absolute’;
vlines.style.top = ’50px’;
vlines.style.right = ’10px’;
vlines.style.width = ‘100%’;
vlines.style.textAlign = ‘right’;
//zoom.style.zIndex = ‘1’;
vlines.innerHTML = ‘Líneas de fuga: no | ‘+
‘sí ‘;
container.appendChild(vlines);
// Add a resize event listener
window.addEventListener(‘resize’,onWindowResize,true);
// Add a mouse down event listener
container.addEventListener(‘mousedown’,onDocumentMouseDown,true);
container.addEventListener(‘touchstart’,onDocumentTouchStart,true);
}
function addElements(){
// Add grid
geometry = new THREE.Geometry();
var size = 1e4, step = 50;
for (var i = 0; i <= size; i += step){
if (i < 50) step *= 1; else if (i < 500) step *= 2; else step *= 10;
geometry.vertices.push(new THREE.Vector3(i,-size,0));
geometry.vertices.push(new THREE.Vector3(i,size,0));
geometry.vertices.push(new THREE.Vector3(-i,-size,0));
geometry.vertices.push(new THREE.Vector3(-i,size,0));
geometry.vertices.push(new THREE.Vector3(-size,i,0));
geometry.vertices.push(new THREE.Vector3(size,i,0));
geometry.vertices.push(new THREE.Vector3(-size,-i,0));
geometry.vertices.push(new THREE.Vector3(size,-i,0));
}
material = new THREE.LineBasicMaterial({color: 0x000000, linewidth: 1.5, opacity: 0.15});
grid = new THREE.LineSegments(geometry,material);
group.add(grid);
// Add the reference system
// Axis X
oriAxisX = new THREE.Vector4(0,0,0,0); // origin of the vector
vecAxisX = new THREE.Vector4(20,0,0,0); // as a free vector
hex = 0xff0000;
axisX = new THREE.ArrowHelper(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,0),0,hex);
axisX.line.material.linewidth = 2;
axisX.name = "Axis X";
group.add(axisX);
labelAxisX = document.createElement('div');
labelAxisX.style.position = 'relative';
labelAxisX.style.width = '0px';
labelAxisX.style.height = '0px';
labelAxisX.style.fontWeight = 'bold';
labelAxisX.style.fontSize = '15px';
labelAxisX.style.color = 'red';
labelAxisX.style.pointerEvents = "none";
labelAxisX.innerHTML = 'X\'';
container.appendChild(labelAxisX);
axisXnr = new THREE.ArrowHelper(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,0),0,hex);
axisXnr.line.material.linewidth = 1.5;
axisXnr.name = "No rotated axis X";
group.add(axisXnr);
// Axis Y
oriAxisY = new THREE.Vector4(0,0,0,0); // origin of the vector
vecAxisY = new THREE.Vector4(0,20,0,0); // as a free vector
hex = 0x00aa00;
axisY = new THREE.ArrowHelper(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,0),0,hex);
axisY.line.material.linewidth = 2;
axisY.name = "Axis Y";
group.add(axisY);
labelAxisY = document.createElement('div');
labelAxisY.style.position = 'relative';
labelAxisY.style.width = '0px';
labelAxisY.style.height = '0px';
labelAxisY.style.fontWeight = 'bold';
labelAxisY.style.fontSize = '15px';
labelAxisY.style.color = 'green';
labelAxisY.style.pointerEvents = "none";
labelAxisY.innerHTML = 'Y\'';
container.appendChild(labelAxisY);
axisYnr = new THREE.ArrowHelper(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,0),0,hex);
axisYnr.line.material.linewidth = 1.5;
axisYnr.name = "No rotated axis Y";
group.add(axisYnr);
// Axis Z
oriAxisZ = new THREE.Vector4(0,0,0,0); // origin of the vector
vecAxisZ = new THREE.Vector4(0,0,20,0); // as a free vector
hex = 0x0000ff;
axisZ = new THREE.ArrowHelper(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,0),0,hex);
axisZ.line.material.linewidth = 2;
axisZ.name = "Axis Z";
group.add(axisZ);
labelAxisZ = document.createElement('div');
labelAxisZ.style.position = 'relative';
labelAxisZ.style.width = '0px';
labelAxisZ.style.height = '0px';
labelAxisZ.style.fontWeight = 'bold';
labelAxisZ.style.fontSize = '15px';
labelAxisZ.style.color = 'blue';
labelAxisZ.innerHTML = 'Z\'';
labelAxisZ.style.pointerEvents = "none";
container.appendChild(labelAxisZ);
axisZnr = new THREE.ArrowHelper(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,0),0,hex);
axisZnr.line.material.linewidth = 1.5;
axisZnr.name = "No rotated axis Z";
group.add(axisZnr);
// Axis W
oriAxisW = new THREE.Vector4(0,0,0,0); // origin of the vector
vecAxisW = new THREE.Vector4(0,0,0,20); // as a free vector
hex = 0x000000;
axisW = new THREE.ArrowHelper(new THREE.Vector3(0,0,0),new THREE.Vector3(0,0,0),0,hex);
axisW.line.material.linewidth = 2;
axisW.name = "Axis W";
group.add(axisW);
labelAxisW = document.createElement('div');
labelAxisW.style.position = 'relative';
labelAxisW.style.width = '0px';
labelAxisW.style.height = '0px';
labelAxisW.style.fontWeight = 'bold';
labelAxisW.style.fontSize = '15px';
labelAxisW.style.color = 'black';
labelAxisW.style.pointerEvents = "none";
labelAxisW.innerHTML = 'W\'';
container.appendChild(labelAxisW);
addObjects();
}
function addObjects(){
// Create the materials
redMat = new THREE.MeshPhongMaterial({color: 0xff0000,specular: 0x555555,shininess: 30,opacity: 0.3});
redMat.side = THREE.DoubleSide;
yellowMat = new THREE.MeshPhongMaterial({color: 0xffff00,specular: 0x555555,shininess: 30,opacity: 0.3});
greenMat = new THREE.MeshPhongMaterial({color: 0x00ff00,specular: 0x555555,shininess: 30,opacity: 0.3});
blueMat = new THREE.MeshPhongMaterial({color: 0x0000ff,specular: 0x555555,shininess: 30,opacity: 0.3});
purpleMat = new THREE.MeshPhongMaterial({color: 0x6F6CC5,specular: 0x555555,shininess: 30,opacity: 0.3});
edgeMat = new THREE.LineBasicMaterial({color: 0x000000,opacity: 1,linewidth: 2});
vanLineMat = new THREE.LineBasicMaterial({color: 0xffffff,opacity: 1.,linewidth: 1.5});
// Remove all old objects
group.remove(prism1);
group.remove(prism1Edges);
group.remove(prism1VanLines);
group.remove(building1);
group.remove(building1Edges[1]); group.remove(building1Edges[2]); group.remove(building1Edges[3]);
group.remove(building1VanLines[1]); group.remove(building1VanLines[2]); group.remove(building1VanLines[3]);
group.remove(building2);
group.remove(building2Edges[1]); group.remove(building2Edges[2]); group.remove(building2Edges[3]);
group.remove(building2VanLines[1]); group.remove(building2VanLines[2]); group.remove(building2VanLines[3]);
group.remove(building3);
group.remove(building3Edges[1]); group.remove(building3Edges[2]); group.remove(building3Edges[3]);
group.remove(building3VanLines[1]); group.remove(building3VanLines[2]); group.remove(building3VanLines[3]);
group.remove(hypercube);
group.remove(hypercubeEdges);
group.remove(hypercubeVanLines);
group.remove(hyperbuilding1);
group.remove(hyperbuilding1Edges);
group.remove(hyperbuilding1VanLines);
group.remove(hyperbuilding2);
group.remove(hyperbuilding2Edges);
group.remove(hyperbuilding2VanLines);
group.remove(hyperbuilding3);
group.remove(hyperbuilding3Edges);
group.remove(hyperbuilding3VanLines);
// Add the selected object
if(object == 'prism'){
// Prism1
// Top XY face
// var a = 150, b = 200, c = 300, sftx = 0, sfty = 0, sftz = c/2, sftw = 50;
var a = 7.5, b = 10, c = 15, sftx = 0, sfty = 0, sftz = 0, sftw = 0;
vertPrism1[0] = new THREE.Vector4(a/2+sftx,-b/2+sfty,c/2+sftz,sftw);
vertPrism1[1] = new THREE.Vector4(a/2+sftx,b/2+sfty,c/2+sftz,sftw);
vertPrism1[2] = new THREE.Vector4(-a/2+sftx,b/2+sfty,c/2+sftz,sftw);
vertPrism1[3] = new THREE.Vector4(-a/2+sftx,-b/2+sfty,c/2+sftz,sftw);
// Bottom XY face
vertPrism1[4] = new THREE.Vector4(-a/2+sftx,-b/2+sfty,-c/2+sftz,sftw);
vertPrism1[5] = new THREE.Vector4(-a/2+sftx,b/2+sfty,-c/2+sftz,sftw);
vertPrism1[6] = new THREE.Vector4(a/2+sftx,b/2+sfty,-c/2+sftz,sftw);
vertPrism1[7] = new THREE.Vector4(a/2+sftx,-b/2+sfty,-c/2+sftz,sftw);
prism1 = new THREE.Mesh(geometry,redMat);
//prism1.position.z = 0;
prism1.name = "Prism 1";
group.add(prism1);
prism1Edges = new THREE.Line(geometry,edgeMat);
group.add(prism1Edges);
if(vanLines ==true){
prism1VanLines = new THREE.LineSegments(geometry,vanLineMat);
group.add(prism1VanLines);
}
}else if(object == 'buildings'){
// Building1
// Top prism
var a1 = 1.5, b1 = 3, c1 = 2;
// Middle prism
var a2 = 4.5, b2 = 7, c2 = 4;
// Bottom prism
var a3 = 7.5, b3 = 10, c3 = 15;
// Shifts
var sftx = 0, sfty = 0, sftz = -(c1+c2+c3)/2, sftw = 5;
vertBuilding1 = buildingVertices(a1,b1,c1,a2,b2,c2,a3,b3,c3,sftx,sfty,sftz,sftw);
building1 = new THREE.Mesh(geometry,redMat);
building1.name = "Building 1";
group.add(building1);
building1Edges[1] = new THREE.Line(geometry,edgeMat);
group.add(building1Edges[1]);
building1Edges[2] = new THREE.Line(geometry,edgeMat);
group.add(building1Edges[2]);
building1Edges[3] = new THREE.Line(geometry,edgeMat);
group.add(building1Edges[3]);
if(vanLines ==true){
building1VanLines[1] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building1VanLines[1]);
building1VanLines[2] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building1VanLines[2]);
building1VanLines[3] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building1VanLines[3]);
}
// Building2
sftw = 0;
vertBuilding2 = buildingVertices(a1,b1,c1,a2,b2,c2,a3,b3,c3,sftx,sfty,sftz,sftw);
building2 = new THREE.Mesh(geometry,yellowMat);
building2.name = "Building 2";
group.add(building2);
building2Edges[1] = new THREE.Line(geometry,edgeMat);
group.add(building2Edges[1]);
building2Edges[2] = new THREE.Line(geometry,edgeMat);
group.add(building2Edges[2]);
building2Edges[3] = new THREE.Line(geometry,edgeMat);
group.add(building2Edges[3]);
if(vanLines ==true){
building2VanLines[1] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building2VanLines[1]);
building2VanLines[2] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building2VanLines[2]);
building2VanLines[3] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building2VanLines[3]);
}
// Building3
sftw = -5;
vertBuilding3 = buildingVertices(a1,b1,c1,a2,b2,c2,a3,b3,c3,sftx,sfty,sftz,sftw);
building3 = new THREE.Mesh(geometry,blueMat);
building3.name = "Building 3";
group.add(building3);
building3Edges[1] = new THREE.Line(geometry,edgeMat);
group.add(building3Edges[1]);
building3Edges[2] = new THREE.Line(geometry,edgeMat);
group.add(building3Edges[2]);
building3Edges[3] = new THREE.Line(geometry,edgeMat);
group.add(building3Edges[3]);
if(vanLines ==true){
building3VanLines[1] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building3VanLines[1]);
building3VanLines[2] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building3VanLines[2]);
building3VanLines[3] = new THREE.LineSegments(geometry,vanLineMat);
group.add(building3VanLines[3]);
}
}else if(object == 'hypercube'){
// Hypercube
var a = 10, b = 10, c = 10, d = 10, sftx = 0, sfty = 0, sftz = 0, sftw = 0;
vertHypercube = hyperprismVertices(a,b,c,d,sftx,sfty,sftz,sftw);
hypercube = new THREE.Mesh(geometry,redMat);
hypercube.name = "Hypercube";
group.add(hypercube);
hypercubeEdges = new THREE.Line(geometry,edgeMat);
group.add(hypercubeEdges);
if(vanLines ==true){
hypercubeVanLines = new THREE.LineSegments(geometry,vanLineMat);
group.add(hypercubeVanLines);
}
}else if(object == 'hyperbuilding'){
// Top hyperprism
var a1 = 1.5, b1 = 3, c1 = 2, d1 = 2;
// Middle hyperprism
var a2 = 4.5, b2 = 7, c2 = 4, d2 = 4;
// Bottom hyperprism
var a3 = 7.5, b3 = 10, c3 = 15, d3 = 6;
// Shifts
var sftz = -(c1+c2+c3)/2;
var sftx1 = 0, sfty1 = 0, sftz1 = sftz+c3+c2+c1/2, sftw1 = 0;
var sftx2 = 0, sfty2 = 0, sftz2 = sftz+c3+c2/2, sftw2 = 0;
var sftx3 = 0, sfty3 = 0, sftz3 = sftz+c3/2, sftw3 = 0;
vertHyperbuilding1 = hyperprismVertices(a1,b1,c1,d1,sftx1,sfty1,sftz1,sftw1);
hyperbuilding1 = new THREE.Mesh(geometry,redMat);
hyperbuilding1.name = "Hyperprism 1";
group.add(hyperbuilding1);
hyperbuilding1Edges = new THREE.Line(geometry,edgeMat);
group.add(hyperbuilding1Edges);
if(vanLines ==true){
hyperbuilding1VanLines = new THREE.LineSegments(geometry,vanLineMat);
group.add(hyperbuilding1VanLines);
}
vertHyperbuilding2 = hyperprismVertices(a2,b2,c2,d2,sftx2,sfty2,sftz2,sftw2);
hyperbuilding2 = new THREE.Mesh(geometry,redMat);
hyperbuilding2.name = "Hyperprism 2";
group.add(hyperbuilding2);
hyperbuilding2Edges = new THREE.Line(geometry,edgeMat);
group.add(hyperbuilding2Edges);
if(vanLines ==true){
hyperbuilding2VanLines = new THREE.LineSegments(geometry,vanLineMat);
group.add(hyperbuilding2VanLines);
}
vertHyperbuilding3 = hyperprismVertices(a3,b3,c3,d3,sftx3,sfty3,sftz3,sftw3);
hyperbuilding3 = new THREE.Mesh(geometry,redMat);
hyperbuilding3.name = "Hyperprism 3";
group.add(hyperbuilding3);
hyperbuilding3Edges = new THREE.Line(geometry,edgeMat);
group.add(hyperbuilding3Edges);
if(vanLines ==true){
hyperbuilding3VanLines = new THREE.LineSegments(geometry,vanLineMat);
group.add(hyperbuilding3VanLines);
}
}
updateElements();
}
function updateElements(){
projector4D.updateMatrix();
// Update the reference system
// Axis X
axisX.position.copy(projector4D.project(oriAxisX,true,true)); //origin
projAxisX = projector4D.project(vecAxisX,false,true);
axisX.setDirection(projAxisX.clone().normalize()); //direction
var lngth = projAxisX.length();
var headLngth = (1-Math.exp(-Math.abs(lngth)/2))*1.5
var headWidth = headLngth*.7
axisX.setLength(lngth,headLngth,headWidth); //length
axisXnr.position.copy(projector4D.project(oriAxisX,true,true)); //origin
projAxisXnr = projector4D.project(vecAxisX,false,false);
axisXnr.setDirection(projAxisXnr.clone().normalize()); //direction
lngth = projAxisXnr.length();
headLngth = (1-Math.exp(-Math.abs(lngth)/2))*1.5
headWidth = headLngth*.7
axisXnr.setLength(lngth,headLngth,headWidth); //length
// Axis Y
axisY.position.copy(projector4D.project(oriAxisY,true,true)); //origin
projAxisY = projector4D.project(vecAxisY,false,true);
axisY.setDirection(projAxisY.clone().normalize()); //direction
lngth = projAxisY.length();
headLngth = (1-Math.exp(-Math.abs(lngth)/2))*1.5
headWidth = headLngth*.7
axisY.setLength(lngth,headLngth,headWidth); //length
axisYnr.position.copy(projector4D.project(oriAxisY,true,true)); //origin
projAxisYnr = projector4D.project(vecAxisY,false,false);
axisYnr.setDirection(projAxisYnr.clone().normalize()); //direction
lngth = projAxisYnr.length();
headLngth = (1-Math.exp(-Math.abs(lngth)/2))*1.5
headWidth = headLngth*.7
axisYnr.setLength(lngth,headLngth,headWidth); //length
// Axis Z
axisZ.position.copy(projector4D.project(oriAxisZ,true,true)); //origin
projAxisZ = projector4D.project(vecAxisZ,false,true);
axisZ.setDirection(projAxisZ.clone().normalize()); //direction
lngth = projAxisZ.length();
headLngth = (1-Math.exp(-Math.abs(lngth)/2))*1.5
headWidth = headLngth*.7
axisZ.setLength(lngth,headLngth,headWidth); //length
axisZnr.position.copy(projector4D.project(oriAxisZ,true,true)); //origin
projAxisZnr = projector4D.project(vecAxisZ,false,false);
axisZnr.setDirection(projAxisZnr.clone().normalize()); //direction
lngth = projAxisZnr.length();
headLngth = (1-Math.exp(-Math.abs(lngth)/2))*1.5
headWidth = headLngth*.7
axisZnr.setLength(lngth,headLngth,headWidth); //length
// Axis W
axisW.position.copy(projector4D.project(oriAxisW,true,true)); //origin
projAxisW = projector4D.project(vecAxisW,false,true);
axisW.setDirection(projAxisW.clone().normalize()); //direction
lngth = projAxisW.length();
headLngth = (1-Math.exp(-Math.abs(lngth)/2))*1.5
headWidth = headLngth*.7
axisW.setLength(lngth,headLngth,headWidth); //length
if(object == 'prism'){
// Update the prism1
prism1.geometry = new Prism(
vertPrism1[0],vertPrism1[1],vertPrism1[2],vertPrism1[3],
vertPrism1[4],vertPrism1[5],vertPrism1[6],vertPrism1[7]
);
prism1Edges.geometry = new PrismEdges(
vertPrism1[0],vertPrism1[1],vertPrism1[2],vertPrism1[3],
vertPrism1[4],vertPrism1[5],vertPrism1[6],vertPrism1[7]
);
if(vanLines ==true){
prism1VanLines.geometry = new PrismVanLines(
vertPrism1[0],vertPrism1[1],vertPrism1[2],vertPrism1[3],
vertPrism1[4],vertPrism1[5],vertPrism1[6],vertPrism1[7]
);
}
}else if(object == 'buildings'){
// Update the building1
building1.geometry = new Building(
vertBuilding1[0],vertBuilding1[1],vertBuilding1[2],vertBuilding1[3],
vertBuilding1[4],vertBuilding1[5],vertBuilding1[6],vertBuilding1[7],
vertBuilding1[8],vertBuilding1[9],vertBuilding1[10],vertBuilding1[11],
vertBuilding1[12],vertBuilding1[13],vertBuilding1[14],vertBuilding1[15],
vertBuilding1[16],vertBuilding1[17],vertBuilding1[18],vertBuilding1[19],
vertBuilding1[20],vertBuilding1[21],vertBuilding1[22],vertBuilding1[23]
);
building1Edges[1].geometry = new PrismEdges(
vertBuilding1[0],vertBuilding1[1],vertBuilding1[2],vertBuilding1[3],
vertBuilding1[4],vertBuilding1[5],vertBuilding1[6],vertBuilding1[7]
);
if(vanLines ==true){
building1VanLines[1].geometry = new PrismVanLines(
vertBuilding1[0],vertBuilding1[1],vertBuilding1[2],vertBuilding1[3],
vertBuilding1[4],vertBuilding1[5],vertBuilding1[6],vertBuilding1[7]
);
}
building1Edges[2].geometry = new PrismEdges(
vertBuilding1[8],vertBuilding1[9],vertBuilding1[10],vertBuilding1[11],
vertBuilding1[12],vertBuilding1[13],vertBuilding1[14],vertBuilding1[15]
);
if(vanLines ==true){
building1VanLines[2].geometry = new PrismVanLines(
vertBuilding1[8],vertBuilding1[9],vertBuilding1[10],vertBuilding1[11],
vertBuilding1[12],vertBuilding1[13],vertBuilding1[14],vertBuilding1[15]
);
}
building1Edges[3].geometry = new PrismEdges(
vertBuilding1[16],vertBuilding1[17],vertBuilding1[18],vertBuilding1[19],
vertBuilding1[20],vertBuilding1[21],vertBuilding1[22],vertBuilding1[23]
);
if(vanLines ==true){
building1VanLines[3].geometry = new PrismVanLines(
vertBuilding1[16],vertBuilding1[17],vertBuilding1[18],vertBuilding1[19],
vertBuilding1[20],vertBuilding1[21],vertBuilding1[22],vertBuilding1[23]
);
}
// Update the building2
building2.geometry = new Building(
vertBuilding2[0],vertBuilding2[1],vertBuilding2[2],vertBuilding2[3],
vertBuilding2[4],vertBuilding2[5],vertBuilding2[6],vertBuilding2[7],
vertBuilding2[8],vertBuilding2[9],vertBuilding2[10],vertBuilding2[11],
vertBuilding2[12],vertBuilding2[13],vertBuilding2[14],vertBuilding2[15],
vertBuilding2[16],vertBuilding2[17],vertBuilding2[18],vertBuilding2[19],
vertBuilding2[20],vertBuilding2[21],vertBuilding2[22],vertBuilding2[23]
);
building2Edges[1].geometry = new PrismEdges(
vertBuilding2[0],vertBuilding2[1],vertBuilding2[2],vertBuilding2[3],
vertBuilding2[4],vertBuilding2[5],vertBuilding2[6],vertBuilding2[7]
);
if(vanLines ==true){
building2VanLines[1].geometry = new PrismVanLines(
vertBuilding1[0],vertBuilding1[1],vertBuilding1[2],vertBuilding1[3],
vertBuilding1[4],vertBuilding1[5],vertBuilding1[6],vertBuilding1[7]
);
}
building2Edges[2].geometry = new PrismEdges(
vertBuilding2[8],vertBuilding2[9],vertBuilding2[10],vertBuilding2[11],
vertBuilding2[12],vertBuilding2[13],vertBuilding2[14],vertBuilding2[15]
);
if(vanLines ==true){
building2VanLines[2].geometry = new PrismVanLines(
vertBuilding2[8],vertBuilding2[9],vertBuilding2[10],vertBuilding2[11],
vertBuilding2[12],vertBuilding2[13],vertBuilding2[14],vertBuilding2[15]
);
}
building2Edges[3].geometry = new PrismEdges(
vertBuilding2[16],vertBuilding2[17],vertBuilding2[18],vertBuilding2[19],
vertBuilding2[20],vertBuilding2[21],vertBuilding2[22],vertBuilding2[23]
);
if(vanLines ==true){
building2VanLines[3].geometry = new PrismVanLines(
vertBuilding2[16],vertBuilding2[17],vertBuilding2[18],vertBuilding2[19],
vertBuilding2[20],vertBuilding2[21],vertBuilding2[22],vertBuilding2[23]
);
}
// Update the building3
building3.geometry = new Building(
vertBuilding3[0],vertBuilding3[1],vertBuilding3[2],vertBuilding3[3],
vertBuilding3[4],vertBuilding3[5],vertBuilding3[6],vertBuilding3[7],
vertBuilding3[8],vertBuilding3[9],vertBuilding3[10],vertBuilding3[11],
vertBuilding3[12],vertBuilding3[13],vertBuilding3[14],vertBuilding3[15],
vertBuilding3[16],vertBuilding3[17],vertBuilding3[18],vertBuilding3[19],
vertBuilding3[20],vertBuilding3[21],vertBuilding3[22],vertBuilding3[23]
);
building3Edges[1].geometry = new PrismEdges(
vertBuilding3[0],vertBuilding3[1],vertBuilding3[2],vertBuilding3[3],
vertBuilding3[4],vertBuilding3[5],vertBuilding3[6],vertBuilding3[7]
);
if(vanLines ==true){
building3VanLines[1].geometry = new PrismVanLines(
vertBuilding3[0],vertBuilding3[1],vertBuilding3[2],vertBuilding3[3],
vertBuilding3[4],vertBuilding3[5],vertBuilding3[6],vertBuilding3[7]
);
}
building3Edges[2].geometry = new PrismEdges(
vertBuilding3[8],vertBuilding3[9],vertBuilding3[10],vertBuilding3[11],
vertBuilding3[12],vertBuilding3[13],vertBuilding3[14],vertBuilding3[15]
);
if(vanLines ==true){
building3VanLines[2].geometry = new PrismVanLines(
vertBuilding3[8],vertBuilding3[9],vertBuilding3[10],vertBuilding3[11],
vertBuilding3[12],vertBuilding3[13],vertBuilding3[14],vertBuilding3[15]
);
}
building3Edges[3].geometry = new PrismEdges(
vertBuilding3[16],vertBuilding3[17],vertBuilding3[18],vertBuilding3[19],
vertBuilding3[20],vertBuilding3[21],vertBuilding3[22],vertBuilding3[23]
);
if(vanLines ==true){
building3VanLines[3].geometry = new PrismVanLines(
vertBuilding3[16],vertBuilding3[17],vertBuilding3[18],vertBuilding3[19],
vertBuilding3[20],vertBuilding3[21],vertBuilding3[22],vertBuilding3[23]
);
}
}else if(object == 'hypercube'){
// Update the hypercube
hypercube.geometry = new Hypercube(
vertHypercube[0],vertHypercube[1],vertHypercube[2],vertHypercube[3],
vertHypercube[4],vertHypercube[5],vertHypercube[6],vertHypercube[7],
vertHypercube[8],vertHypercube[9],vertHypercube[10],vertHypercube[11],
vertHypercube[12],vertHypercube[13],vertHypercube[14],vertHypercube[15]
);
hypercubeEdges.geometry = new HypercubeEdges(
vertHypercube[0],vertHypercube[1],vertHypercube[2],vertHypercube[3],
vertHypercube[4],vertHypercube[5],vertHypercube[6],vertHypercube[7],
vertHypercube[8],vertHypercube[9],vertHypercube[10],vertHypercube[11],
vertHypercube[12],vertHypercube[13],vertHypercube[14],vertHypercube[15]
);
if(vanLines ==true){
hypercubeVanLines.geometry = new HypercubeVanLines(
vertHypercube[0],vertHypercube[1],vertHypercube[2],vertHypercube[3],
vertHypercube[4],vertHypercube[5],vertHypercube[6],vertHypercube[7],
vertHypercube[8],vertHypercube[9],vertHypercube[10],vertHypercube[11],
vertHypercube[12],vertHypercube[13],vertHypercube[14],vertHypercube[15]
);
}
}else if(object == 'hyperbuilding'){
// Update the top hyperprism
hyperbuilding1.geometry = new Hypercube(
vertHyperbuilding1[0],vertHyperbuilding1[1],vertHyperbuilding1[2],vertHyperbuilding1[3],
vertHyperbuilding1[4],vertHyperbuilding1[5],vertHyperbuilding1[6],vertHyperbuilding1[7],
vertHyperbuilding1[8],vertHyperbuilding1[9],vertHyperbuilding1[10],vertHyperbuilding1[11],
vertHyperbuilding1[12],vertHyperbuilding1[13],vertHyperbuilding1[14],vertHyperbuilding1[15]
);
hyperbuilding1Edges.geometry = new HypercubeEdges(
vertHyperbuilding1[0],vertHyperbuilding1[1],vertHyperbuilding1[2],vertHyperbuilding1[3],
vertHyperbuilding1[4],vertHyperbuilding1[5],vertHyperbuilding1[6],vertHyperbuilding1[7],
vertHyperbuilding1[8],vertHyperbuilding1[9],vertHyperbuilding1[10],vertHyperbuilding1[11],
vertHyperbuilding1[12],vertHyperbuilding1[13],vertHyperbuilding1[14],vertHyperbuilding1[15]
);
if(vanLines ==true){
hyperbuilding1VanLines.geometry = new HypercubeVanLines(
vertHyperbuilding1[0],vertHyperbuilding1[1],vertHyperbuilding1[2],vertHyperbuilding1[3],
vertHyperbuilding1[4],vertHyperbuilding1[5],vertHyperbuilding1[6],vertHyperbuilding1[7],
vertHyperbuilding1[8],vertHyperbuilding1[9],vertHyperbuilding1[10],vertHyperbuilding1[11],
vertHyperbuilding1[12],vertHyperbuilding1[13],vertHyperbuilding1[14],vertHyperbuilding1[15]
);
}
// Update the middle hyperprism
hyperbuilding2.geometry = new Hypercube(
vertHyperbuilding2[0],vertHyperbuilding2[1],vertHyperbuilding2[2],vertHyperbuilding2[3],
vertHyperbuilding2[4],vertHyperbuilding2[5],vertHyperbuilding2[6],vertHyperbuilding2[7],
vertHyperbuilding2[8],vertHyperbuilding2[9],vertHyperbuilding2[10],vertHyperbuilding2[11],
vertHyperbuilding2[12],vertHyperbuilding2[13],vertHyperbuilding2[14],vertHyperbuilding2[15]
);
hyperbuilding2Edges.geometry = new HypercubeEdges(
vertHyperbuilding2[0],vertHyperbuilding2[1],vertHyperbuilding2[2],vertHyperbuilding2[3],
vertHyperbuilding2[4],vertHyperbuilding2[5],vertHyperbuilding2[6],vertHyperbuilding2[7],
vertHyperbuilding2[8],vertHyperbuilding2[9],vertHyperbuilding2[10],vertHyperbuilding2[11],
vertHyperbuilding2[12],vertHyperbuilding2[13],vertHyperbuilding2[14],vertHyperbuilding2[15]
);
if(vanLines ==true){
hyperbuilding2VanLines.geometry = new HypercubeVanLines(
vertHyperbuilding2[0],vertHyperbuilding2[1],vertHyperbuilding2[2],vertHyperbuilding2[3],
vertHyperbuilding2[4],vertHyperbuilding2[5],vertHyperbuilding2[6],vertHyperbuilding2[7],
vertHyperbuilding2[8],vertHyperbuilding2[9],vertHyperbuilding2[10],vertHyperbuilding2[11],
vertHyperbuilding2[12],vertHyperbuilding2[13],vertHyperbuilding2[14],vertHyperbuilding2[15]
);
}
// Update the bottom hyperprism
hyperbuilding3.geometry = new Hypercube(
vertHyperbuilding3[0],vertHyperbuilding3[1],vertHyperbuilding3[2],vertHyperbuilding3[3],
vertHyperbuilding3[4],vertHyperbuilding3[5],vertHyperbuilding3[6],vertHyperbuilding3[7],
vertHyperbuilding3[8],vertHyperbuilding3[9],vertHyperbuilding3[10],vertHyperbuilding3[11],
vertHyperbuilding3[12],vertHyperbuilding3[13],vertHyperbuilding3[14],vertHyperbuilding3[15]
);
hyperbuilding3Edges.geometry = new HypercubeEdges(
vertHyperbuilding3[0],vertHyperbuilding3[1],vertHyperbuilding3[2],vertHyperbuilding3[3],
vertHyperbuilding3[4],vertHyperbuilding3[5],vertHyperbuilding3[6],vertHyperbuilding3[7],
vertHyperbuilding3[8],vertHyperbuilding3[9],vertHyperbuilding3[10],vertHyperbuilding3[11],
vertHyperbuilding3[12],vertHyperbuilding3[13],vertHyperbuilding3[14],vertHyperbuilding3[15]
);
if(vanLines ==true){
hyperbuilding3VanLines.geometry = new HypercubeVanLines(
vertHyperbuilding3[0],vertHyperbuilding3[1],vertHyperbuilding3[2],vertHyperbuilding3[3],
vertHyperbuilding3[4],vertHyperbuilding3[5],vertHyperbuilding3[6],vertHyperbuilding3[7],
vertHyperbuilding3[8],vertHyperbuilding3[9],vertHyperbuilding3[10],vertHyperbuilding3[11],
vertHyperbuilding3[12],vertHyperbuilding3[13],vertHyperbuilding3[14],vertHyperbuilding3[15]
);
}
}
}
function addLights(){
var ambLight = new THREE.AmbientLight(0x404040);
ambLight.name = "Ambient light";
group.add(ambLight);
var dirLight = new THREE.DirectionalLight(0xffffff,1);
dirLight.position.set(100,70,50).normalize();
dirLight.name = "Directional light";
group.add(dirLight);
}
function setContainerSize(){
// To make the container as big as window
contWidth = window.innerWidth;
//contHeight = window.innerHeight;
contHeight = window.innerHeight-135;
// Or to fix the container size
//contWidth = 300;
//contHeight = 300;
}
function onWindowResize(){
setContainerSize();
camera.aspect = contWidth/contHeight;
renderer.setSize(contWidth,contHeight);
render();
}
function onDocumentMouseDown(event){
//event.preventDefault();
msg.style.display = 'none';
container.addEventListener('mousemove',onDocumentMouseMove,true);
container.addEventListener('mouseup',onDocumentMouseUp,true);
//container.addEventListener('mouseout',onDocumentMouseOut,true);
//mouseXOnMouseDown = event.clientX-contWidth/2;
mouseXOnMouseDown = event.clientX;
//mouseYOnMouseDown = event.clientY-contHeight/2;
mouseYOnMouseDown = event.clientY;
MotionStart();
}
function onDocumentTouchStart(event){
if(event.touches.length === 1){
//event.preventDefault();
msg.style.display = 'none';
container.addEventListener('touchmove',onDocumentTouchMove,true);
container.addEventListener('touchend',onDocumentTouchEnd,true);
//mouseXOnMouseDown = event.touches[0].pageX-contWidth/2;
mouseXOnMouseDown = event.touches[0].pageX;
//mouseYOnMouseDown = event.touches[0].pageY-contHeight/2;
mouseYOnMouseDown = event.touches[0].pageY;
MotionStart();
}
}
function MotionStart(){
AngThetaOnMouseDown = AngTheta;
AngPhiOnMouseDown = AngPhi;
angXYOnMouseDown = projector4D.angXY;
angYZOnMouseDown = projector4D.angYZ;
angZWOnMouseDown = projector4D.angZW;
angWXOnMouseDown = projector4D.angWX;
pos3DXOnMouseDown = pos3DX;
pos3DYOnMouseDown = pos3DY;
pos3DZOnMouseDown = pos3DZ;
pos4DXOnMouseDown = projector4D.posX;
pos4DYOnMouseDown = projector4D.posY;
pos4DZOnMouseDown = projector4D.posZ;
pos4DWOnMouseDown = projector4D.posW;
}
function onDocumentMouseMove(event){
event.preventDefault();
//mouseX = event.clientX-contWidth/2;
mouseX = event.clientX;
//mouseY = event.clientY-contHeight/2;
mouseY = event.clientY;
MotionGoing();
}
function onDocumentTouchMove(event){
if(event.touches.length === 1){
event.preventDefault();
//mouseX = event.touches[0].pageX – contWidth/2;
mouseX = event.touches[0].pageX;
//mouseY = event.touches[0].pageY – contHeight/2;
mouseY = event.touches[0].pageY;
MotionGoing();
}
}
function MotionGoing(){
objects.style.pointerEvents = "none";
zoom.style.pointerEvents = "none";
faces.style.pointerEvents = "none";
vlines.style.pointerEvents = "none";
info.style.pointerEvents = "none";
if(motMode == 0){
AngTheta = AngThetaOnMouseDown+(mouseY-mouseYOnMouseDown)/100;
AngPhi = AngPhiOnMouseDown+(mouseX-mouseXOnMouseDown)/100;
document.getElementById('AngPhi').innerHTML = (-AngPhi*180/3.1416).toFixed(0)+'o ‘;
document.getElementById(‘AngTheta’).innerHTML = (-AngTheta*180/3.1416).toFixed(0)+’o ‘;
}else if(motMode == 1){
if(plnsXY_YZ == true){
projector4D.angXY = angXYOnMouseDown+((mouseY-mouseYOnMouseDown)*0.5)*3.1416/180;
projector4D.angYZ = angYZOnMouseDown+((mouseX-mouseXOnMouseDown)*0.5)*3.1416/180;
document.getElementById(‘angXY’).innerHTML = (projector4D.angXY*180/3.1416).toFixed(0)+’o ‘;
document.getElementById(‘angYZ’).innerHTML = (projector4D.angYZ*180/3.1416).toFixed(0)+’o ‘;
}else if(plnsXY_ZW == true){
projector4D.angXY = angXYOnMouseDown+((mouseY-mouseYOnMouseDown)*0.5)*3.1416/180;
projector4D.angZW = angZWOnMouseDown+((mouseX-mouseXOnMouseDown)*0.5)*3.1416/180;
document.getElementById(‘angXY’).innerHTML = (projector4D.angXY*180/3.1416).toFixed(0)+’o ‘;
document.getElementById(‘angZW’).innerHTML = (projector4D.angZW*180/3.1416).toFixed(0)+’o ‘;
}else if(plnsXY_WX == true){
projector4D.angXY = angXYOnMouseDown+((mouseY-mouseYOnMouseDown)*0.5)*3.1416/180;
projector4D.angWX = angWXOnMouseDown+((mouseX-mouseXOnMouseDown)*0.5)*3.1416/180;
document.getElementById(‘angXY’).innerHTML = (projector4D.angXY*180/3.1416).toFixed(0)+’o ‘;
document.getElementById(‘angWX’).innerHTML = (projector4D.angWX*180/3.1416).toFixed(0)+’o ‘;
}
updateElements();
}else if(motMode == 2){
if(axsYZ == true){
pos3DY = pos3DYOnMouseDown-(mouseX-mouseXOnMouseDown)/30;
pos3DX = pos3DXOnMouseDown+(mouseY-mouseYOnMouseDown)/30;
}
}else if(motMode == 3){
if(axsYZ == true){
projector4D.posY = pos4DYOnMouseDown+(mouseX-mouseXOnMouseDown)/30;
projector4D.posZ = pos4DZOnMouseDown-(mouseY-mouseYOnMouseDown)/30;
}
updateElements();
}
render();
}
function onDocumentMouseUp(event){
container.removeEventListener(‘mousemove’,onDocumentMouseMove,true);
container.removeEventListener(‘mouseup’,onDocumentMouseUp,true);
//container.removeEventListener(‘mouseout’,onDocumentMouseOut,true);
MotionEnd();
}
function onDocumentMouseOut(event){
container.removeEventListener(‘mousemove’,onDocumentMouseMove,true);
container.removeEventListener(‘mouseup’,onDocumentMouseUp,true);
//container.removeEventListener(‘mouseout’,onDocumentMouseOut,true);
MotionEnd();
}
function onDocumentTouchEnd(event){
container.removeEventListener(‘touchmove’,onDocumentTouchMove,true);
container.removeEventListener(‘touchend’,onDocumentTouchEnd,true);
MotionEnd();
}
function MotionEnd(){
objects.style.pointerEvents = “initial”;
zoom.style.pointerEvents = “initial”;
faces.style.pointerEvents = “initial”;
vlines.style.pointerEvents = “initial”;
info.style.pointerEvents = “initial”;
}
function Prism(a,b,c,d,e,f,g,h){
// d——c
// /||\ Z
// a———-b ^
// | || | |
// | e——f | –> Y
// |/ \| /
// h———-g V X
var geom = new THREE.Geometry();
geom.vertices.push(
projector4D.project(a,true,true),
projector4D.project(b,true,true),
projector4D.project(c,true,true),
projector4D.project(d,true,true),
projector4D.project(e,true,true),
projector4D.project(f,true,true),
projector4D.project(g,true,true),
projector4D.project(h,true,true)
);
geom.mergeVertices();
geom.faces.push(
new THREE.Face3(0,1,2),
new THREE.Face3(2,3,0),//top face
new THREE.Face3(0,7,6),
new THREE.Face3(6,1,0),//front face
new THREE.Face3(1,6,5),
new THREE.Face3(5,2,1),//right face
new THREE.Face3(2,5,4),
new THREE.Face3(4,3,2),//back face
new THREE.Face3(0,3,4),
new THREE.Face3(4,7,0),//left face
new THREE.Face3(4,5,6),
new THREE.Face3(6,7,4)//bottom face
);
geom.mergeVertices();
geom.computeVertexNormals();
geom.computeMorphNormals();
geom.computeLineDistances();
geom.computeFaceNormals();
return geom;
}
function PrismEdges(a,b,c,d,e,f,g,h){
// d——c
// /||\ Z
// a———-b ^
// | || | |
// | e——f | –> Y
// |/ \| /
// h———-g V X
var geom = new THREE.Geometry();
geom.vertices.push(
// The edges are defined by a continuous line
projector4D.project(a,true,true),
projector4D.project(b,true,true),
projector4D.project(c,true,true),
projector4D.project(d,true,true),
projector4D.project(a,true,true),
projector4D.project(h,true,true),
projector4D.project(g,true,true),
projector4D.project(f,true,true),
projector4D.project(e,true,true),
projector4D.project(h,true,true),
projector4D.project(g,true,true),
projector4D.project(b,true,true),
projector4D.project(c,true,true),
projector4D.project(f,true,true),
projector4D.project(e,true,true),
projector4D.project(d,true,true)
);
return geom;
}
function PrismVanLines(a,b,c,d,e,f,g,h){
// d——c
// /||\ Z
// a———-b ^
// | || | |
// | e——f | –> Y
// |/ \| /
// h———-g V X
var geom = new THREE.Geometry();
geom.vertices.push(
// Segment ab vanishing line
projector4D.project(a,true,true),projector4D.project(vanPoint(b,a),true,true),
projector4D.project(b,true,true),projector4D.project(vanPoint(a,b),true,true),
// Segment bc vanishing line
projector4D.project(b,true,true),projector4D.project(vanPoint(c,b),true,true),
projector4D.project(c,true,true),projector4D.project(vanPoint(b,c),true,true),
// Segment cd vanishing line
projector4D.project(c,true,true),projector4D.project(vanPoint(d,c),true,true),
projector4D.project(d,true,true),projector4D.project(vanPoint(c,d),true,true),
// Segment da vanishing line
projector4D.project(d,true,true),projector4D.project(vanPoint(a,d),true,true),
projector4D.project(a,true,true),projector4D.project(vanPoint(d,a),true,true),
// Segment de vanishing line
projector4D.project(d,true,true),projector4D.project(vanPoint(e,d),true,true),
projector4D.project(e,true,true),projector4D.project(vanPoint(d,e),true,true),
// Segment ef vanishing line
projector4D.project(e,true,true),projector4D.project(vanPoint(f,e),true,true),
projector4D.project(f,true,true),projector4D.project(vanPoint(e,f),true,true),
// Segment fg vanishing line
projector4D.project(f,true,true),projector4D.project(vanPoint(g,f),true,true),
projector4D.project(g,true,true),projector4D.project(vanPoint(f,g),true,true),
// Segment gh vanishing line
projector4D.project(g,true,true),projector4D.project(vanPoint(h,g),true,true),
projector4D.project(h,true,true),projector4D.project(vanPoint(g,h),true,true),
// Segment he vanishing line
projector4D.project(h,true,true),projector4D.project(vanPoint(e,h),true,true),
projector4D.project(e,true,true),projector4D.project(vanPoint(h,e),true,true),
// Segment ah vanishing line
projector4D.project(a,true,true),projector4D.project(vanPoint(h,a),true,true),
projector4D.project(h,true,true),projector4D.project(vanPoint(a,h),true,true),
// Segment bg vanishing line
projector4D.project(b,true,true),projector4D.project(vanPoint(g,b),true,true),
projector4D.project(g,true,true),projector4D.project(vanPoint(b,g),true,true),
// Segment cf vanishing line
projector4D.project(c,true,true),projector4D.project(vanPoint(f,c),true,true),
projector4D.project(f,true,true),projector4D.project(vanPoint(c,f),true,true),
// Segment de vanishing line
projector4D.project(d,true,true),projector4D.project(vanPoint(e,d),true,true),
projector4D.project(e,true,true),projector4D.project(vanPoint(d,e),true,true)
);
return geom;
}
function vanPoint(a,b){
// Vanishing line of segment [a,b]: vec b + (vec b – vec a) * 1e6 = vec b * (1+1e6) + vec a * (-1e6)
return new THREE.Vector4().addVectors(b.clone().multiplyScalar(1+1e6),a.clone().multiplyScalar(-1e6))
}
function Building(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x){
// d——c
// /||\ Z
// a———-b ^
// l-|-|——|-|-k |
///| | e——f | |\ –> Y
// / | |/ \| | \ /
// / | h———-g | \ V X
// i———————-j
// | | | |
// | | | |
// t-|—|————–|—|-s
///| | m————–n | |\
// / | | / \ | | \
// / | | /\ | | \
// / | |/ \| | \
// / | p———————-o | \
// q————————————–r
// | | | |
// | | | |
// | | | |
// | u————————–v |
// | / \ |
// | /\ |
// | / \ |
// | / \ |
// |/\|
// x————————————–w
//
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
//a,b,c,d,e,f,g,h,i,j, k, l, m, n, o, p, q, r, s, t, u, v, w, x
var geom = new THREE.Geometry();
geom.vertices.push(
projector4D.project(a,true,true),
projector4D.project(b,true,true),
projector4D.project(c,true,true),
projector4D.project(d,true,true),
projector4D.project(e,true,true),
projector4D.project(f,true,true),
projector4D.project(g,true,true),
projector4D.project(h,true,true),
projector4D.project(i,true,true),
projector4D.project(j,true,true),
projector4D.project(k,true,true),
projector4D.project(l,true,true),
projector4D.project(m,true,true),
projector4D.project(n,true,true),
projector4D.project(o,true,true),
projector4D.project(p,true,true),
projector4D.project(q,true,true),
projector4D.project(r,true,true),
projector4D.project(s,true,true),
projector4D.project(t,true,true),
projector4D.project(u,true,true),
projector4D.project(v,true,true),
projector4D.project(w,true,true),
projector4D.project(x,true,true)
);
geom.faces.push(
//top prism
new THREE.Face3(0,1,2),
new THREE.Face3(2,3,0),//top face
new THREE.Face3(0,7,6),
new THREE.Face3(6,1,0),//front face
new THREE.Face3(1,6,5),
new THREE.Face3(5,2,1),//right face
new THREE.Face3(2,5,4),
new THREE.Face3(4,3,2),//back face
new THREE.Face3(0,3,4),
new THREE.Face3(4,7,0),//left face
//middle prism
new THREE.Face3(8,9,6),
new THREE.Face3(6,7,8),//front piece of the top face
new THREE.Face3(9,10,5),
new THREE.Face3(5,6,9),//right piece of the top face
new THREE.Face3(10,11,4),
new THREE.Face3(4,5,10),//back piece of the top face
new THREE.Face3(11,8,7),
new THREE.Face3(7,4,11),//left piece of the top face
new THREE.Face3(8,15,14),
new THREE.Face3(14,9,8),//front face
new THREE.Face3(9,14,13),
new THREE.Face3(13,10,9),//right face
new THREE.Face3(10,13,12),
new THREE.Face3(12,11,10),//back face
new THREE.Face3(11,12,15),
new THREE.Face3(15,8,11),//left face
//bottom prism
new THREE.Face3(16,17,14),
new THREE.Face3(14,15,16),//front piece of the top face
new THREE.Face3(17,18,13),
new THREE.Face3(13,14,17),//right piece of the top face
new THREE.Face3(18,19,12),
new THREE.Face3(12,13,18),//back piece of the top face
new THREE.Face3(19,16,15),
new THREE.Face3(15,12,19),//left piece of the top face
new THREE.Face3(16,23,22),
new THREE.Face3(22,17,16),//front face
new THREE.Face3(17,22,21),
new THREE.Face3(21,18,17),//right face
new THREE.Face3(18,21,20),
new THREE.Face3(20,19,18),//back face
new THREE.Face3(19,20,23),
new THREE.Face3(23,16,19),//left face
new THREE.Face3(20,21,22),
new THREE.Face3(22,23,20)//bottom face
);
geom.computeFaceNormals();
return geom;
}
function buildingVertices(a1,b1,c1,a2,b2,c2,a3,b3,c3,sftx,sfty,sftz,sftw){
var verts = []
// Top prism – Top XY face
var sftz1 = sftz+c3+c2+c1/2;
verts[0] = new THREE.Vector4(a1/2+sftx,-b1/2+sfty,c1/2+sftz1,sftw);
verts[1] = new THREE.Vector4(a1/2+sftx,b1/2+sfty,c1/2+sftz1,sftw);
verts[2] = new THREE.Vector4(-a1/2+sftx,b1/2+sfty,c1/2+sftz1,sftw);
verts[3] = new THREE.Vector4(-a1/2+sftx,-b1/2+sfty,c1/2+sftz1,sftw);
// Top prism – Bottom XY face
verts[4] = new THREE.Vector4(-a1/2+sftx,-b1/2+sfty,-c1/2+sftz1,sftw);
verts[5] = new THREE.Vector4(-a1/2+sftx,b1/2+sfty,-c1/2+sftz1,sftw);
verts[6] = new THREE.Vector4(a1/2+sftx,b1/2+sfty,-c1/2+sftz1,sftw);
verts[7] = new THREE.Vector4(a1/2+sftx,-b1/2+sfty,-c1/2+sftz1,sftw);
// Middle prism – Top XY face
var sftz2 = sftz+c3+c2/2;
verts[8] = new THREE.Vector4(a2/2+sftx,-b2/2+sfty,c2/2+sftz2,sftw);
verts[9] = new THREE.Vector4(a2/2+sftx,b2/2+sfty,c2/2+sftz2,sftw);
verts[10] = new THREE.Vector4(-a2/2+sftx,b2/2+sfty,c2/2+sftz2,sftw);
verts[11] = new THREE.Vector4(-a2/2+sftx,-b2/2+sfty,c2/2+sftz2,sftw);
// Middle prism – Bottom XY face
verts[12] = new THREE.Vector4(-a2/2+sftx,-b2/2+sfty,-c2/2+sftz2,sftw);
verts[13] = new THREE.Vector4(-a2/2+sftx,b2/2+sfty,-c2/2+sftz2,sftw);
verts[14] = new THREE.Vector4(a2/2+sftx,b2/2+sfty,-c2/2+sftz2,sftw);
verts[15] = new THREE.Vector4(a2/2+sftx,-b2/2+sfty,-c2/2+sftz2,sftw);
// Bottom prism – Top XY face
var sftz3 = sftz+c3/2;
verts[16] = new THREE.Vector4(a3/2+sftx,-b3/2+sfty,c3/2+sftz3,sftw);
verts[17] = new THREE.Vector4(a3/2+sftx,b3/2+sfty,c3/2+sftz3,sftw);
verts[18] = new THREE.Vector4(-a3/2+sftx,b3/2+sfty,c3/2+sftz3,sftw);
verts[19] = new THREE.Vector4(-a3/2+sftx,-b3/2+sfty,c3/2+sftz3,sftw);
// Bottom prism – Bottom XY face
verts[20] = new THREE.Vector4(-a3/2+sftx,-b3/2+sfty,-c3/2+sftz3,sftw);
verts[21] = new THREE.Vector4(-a3/2+sftx,b3/2+sfty,-c3/2+sftz3,sftw);
verts[22] = new THREE.Vector4(a3/2+sftx,b3/2+sfty,-c3/2+sftz3,sftw);
verts[23] = new THREE.Vector4(a3/2+sftx,-b3/2+sfty,-c3/2+sftz3,sftw);
return verts;
}
function hyperprismVertices(a,b,c,d,sftx,sfty,sftz,sftw){
var verts = []
// Near prism – Top XY face
verts[0] = new THREE.Vector4(a/2+sftx,-b/2+sfty,c/2+sftz,-d/2+sftw);
verts[1] = new THREE.Vector4(a/2+sftx,b/2+sfty,c/2+sftz,-d/2+sftw);
verts[2] = new THREE.Vector4(-a/2+sftx,b/2+sfty,c/2+sftz,-d/2+sftw);
verts[3] = new THREE.Vector4(-a/2+sftx,-b/2+sfty,c/2+sftz,-d/2+sftw);
// Near prism – Bottom XY face
verts[4] = new THREE.Vector4(-a/2+sftx,-b/2+sfty,-c/2+sftz,-d/2+sftw);
verts[5] = new THREE.Vector4(-a/2+sftx,b/2+sfty,-c/2+sftz,-d/2+sftw);
verts[6] = new THREE.Vector4(a/2+sftx,b/2+sfty,-c/2+sftz,-d/2+sftw);
verts[7] = new THREE.Vector4(a/2+sftx,-b/2+sfty,-c/2+sftz,-d/2+sftw);
// Far prism – Top XY face
verts[8] = new THREE.Vector4(a/2+sftx,-b/2+sfty,c/2+sftz,d/2+sftw);
verts[9] = new THREE.Vector4(a/2+sftx,b/2+sfty,c/2+sftz,d/2+sftw);
verts[10] = new THREE.Vector4(-a/2+sftx,b/2+sfty,c/2+sftz,d/2+sftw);
verts[11] = new THREE.Vector4(-a/2+sftx,-b/2+sfty,c/2+sftz,d/2+sftw);
// Far prism – Bottom XY face
verts[12] = new THREE.Vector4(-a/2+sftx,-b/2+sfty,-c/2+sftz,d/2+sftw);
verts[13] = new THREE.Vector4(-a/2+sftx,b/2+sfty,-c/2+sftz,d/2+sftw);
verts[14] = new THREE.Vector4(a/2+sftx,b/2+sfty,-c/2+sftz,d/2+sftw);
verts[15] = new THREE.Vector4(a/2+sftx,-b/2+sfty,-c/2+sftz,d/2+sftw);
return verts;
}
function Hypercube(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){
// l————–k
///| |\ Z
// / | | \^
// / | | \ |
// i———————-j –> Y
// | | d——c | | /
// | | /||\ | | V X
// | | a———-b | |
// | | | || | | |
// | | | e——f | | |
// | m-|/——–\|-n |
// | / h———-g \ |
// | /\ |
// |/ \|
// p———————-o
//
//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//a,b,c,d,e,f,g,h,i,j, k, l, m, n, o, p
var geom = new THREE.Geometry();
geom.vertices.push(
projector4D.project(a,true,true),
projector4D.project(b,true,true),
projector4D.project(c,true,true),
projector4D.project(d,true,true),
projector4D.project(e,true,true),
projector4D.project(f,true,true),
projector4D.project(g,true,true),
projector4D.project(h,true,true),
projector4D.project(i,true,true),
projector4D.project(j,true,true),
projector4D.project(k,true,true),
projector4D.project(l,true,true),
projector4D.project(m,true,true),
projector4D.project(n,true,true),
projector4D.project(o,true,true),
projector4D.project(p,true,true)
);
geom.faces.push(
//inner prism
new THREE.Face3(0,1,2),
new THREE.Face3(2,3,0),//top face
new THREE.Face3(0,7,6),
new THREE.Face3(6,1,0),//front face
new THREE.Face3(1,6,5),
new THREE.Face3(5,2,1),//right face
new THREE.Face3(2,5,4),
new THREE.Face3(4,3,2),//back face
new THREE.Face3(0,3,4),
new THREE.Face3(4,7,0),//left face
new THREE.Face3(4,5,6),
new THREE.Face3(6,7,4),//bottom face
//outter prism
new THREE.Face3(8,9,10),
new THREE.Face3(10,11,8),//top face
new THREE.Face3(8,15,14),
new THREE.Face3(14,9,8),//front face
new THREE.Face3(9,14,13),
new THREE.Face3(13,10,9),//right face
new THREE.Face3(10,13,12),
new THREE.Face3(12,11,10),//back face
new THREE.Face3(11,12,15),
new THREE.Face3(15,8,11),//left face
//connecting faces
new THREE.Face3(0,8,15),
new THREE.Face3(15,7,0),
new THREE.Face3(1,9,14),
new THREE.Face3(14,6,1),
new THREE.Face3(2,10,13),
new THREE.Face3(13,5,2),
new THREE.Face3(3,11,12),
new THREE.Face3(12,4,3)
/*
//reverse side of the connecting faces
,new THREE.Face3(0,15,8),
new THREE.Face3(15,0,7),
new THREE.Face3(1,14,9),
new THREE.Face3(14,1,6),
new THREE.Face3(2,13,10),
new THREE.Face3(13,2,5),
new THREE.Face3(3,12,11),
new THREE.Face3(12,3,4)
*/
);
geom.computeFaceNormals();
return geom;
}
function HypercubeEdges(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){
var geom = new THREE.Geometry();
geom.vertices.push(
// the edges are defined by continuous line
projector4D.project(a,true,true),
projector4D.project(b,true,true),
projector4D.project(c,true,true),
projector4D.project(d,true,true),
projector4D.project(a,true,true),
projector4D.project(h,true,true),
projector4D.project(g,true,true),
projector4D.project(f,true,true),
projector4D.project(e,true,true),
projector4D.project(h,true,true),
projector4D.project(g,true,true),
projector4D.project(b,true,true),
projector4D.project(c,true,true),
projector4D.project(f,true,true),
projector4D.project(e,true,true),
projector4D.project(d,true,true),
projector4D.project(l,true,true),
projector4D.project(i,true,true),
projector4D.project(j,true,true),
projector4D.project(k,true,true),
projector4D.project(l,true,true),
projector4D.project(m,true,true),
projector4D.project(n,true,true),
projector4D.project(o,true,true),
projector4D.project(p,true,true),
projector4D.project(m,true,true),
projector4D.project(e,true,true),
projector4D.project(h,true,true),
projector4D.project(p,true,true),
projector4D.project(i,true,true),
projector4D.project(a,true,true),
projector4D.project(b,true,true),
projector4D.project(j,true,true),
projector4D.project(o,true,true),
projector4D.project(g,true,true),
projector4D.project(f,true,true),
projector4D.project(n,true,true),
projector4D.project(k,true,true),
projector4D.project(c,true,true)
);
return geom;
}
function HypercubeVanLines(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){
var geom = new THREE.Geometry();
geom.vertices.push(
// Segment ab vanishing line
projector4D.project(a,true,true),projector4D.project(vanPoint(b,a),true,true),
projector4D.project(b,true,true),projector4D.project(vanPoint(a,b),true,true),
// Segment bc vanishing line
projector4D.project(b,true,true),projector4D.project(vanPoint(c,b),true,true),
projector4D.project(c,true,true),projector4D.project(vanPoint(b,c),true,true),
// Segment cd vanishing line
projector4D.project(c,true,true),projector4D.project(vanPoint(d,c),true,true),
projector4D.project(d,true,true),projector4D.project(vanPoint(c,d),true,true),
// Segment da vanishing line
projector4D.project(d,true,true),projector4D.project(vanPoint(a,d),true,true),
projector4D.project(a,true,true),projector4D.project(vanPoint(d,a),true,true),
// Segment de vanishing line
projector4D.project(d,true,true),projector4D.project(vanPoint(e,d),true,true),
projector4D.project(e,true,true),projector4D.project(vanPoint(d,e),true,true),
// Segment ef vanishing line
projector4D.project(e,true,true),projector4D.project(vanPoint(f,e),true,true),
projector4D.project(f,true,true),projector4D.project(vanPoint(e,f),true,true),
// Segment fg vanishing line
projector4D.project(f,true,true),projector4D.project(vanPoint(g,f),true,true),
projector4D.project(g,true,true),projector4D.project(vanPoint(f,g),true,true),
// Segment gh vanishing line
projector4D.project(g,true,true),projector4D.project(vanPoint(h,g),true,true),
projector4D.project(h,true,true),projector4D.project(vanPoint(g,h),true,true),
// Segment he vanishing line
projector4D.project(h,true,true),projector4D.project(vanPoint(e,h),true,true),
projector4D.project(e,true,true),projector4D.project(vanPoint(h,e),true,true),
// Segment ah vanishing line
projector4D.project(a,true,true),projector4D.project(vanPoint(h,a),true,true),
projector4D.project(h,true,true),projector4D.project(vanPoint(a,h),true,true),
// Segment bg vanishing line
projector4D.project(b,true,true),projector4D.project(vanPoint(g,b),true,true),
projector4D.project(g,true,true),projector4D.project(vanPoint(b,g),true,true),
// Segment cf vanishing line
projector4D.project(c,true,true),projector4D.project(vanPoint(f,c),true,true),
projector4D.project(f,true,true),projector4D.project(vanPoint(c,f),true,true),
// Segment de vanishing line
projector4D.project(d,true,true),projector4D.project(vanPoint(e,d),true,true),
projector4D.project(e,true,true),projector4D.project(vanPoint(d,e),true,true),
// Segment ij vanishing line
projector4D.project(i,true,true),projector4D.project(vanPoint(j,i),true,true),
projector4D.project(j,true,true),projector4D.project(vanPoint(i,j),true,true),
// Segment jk vanishing line
projector4D.project(j,true,true),projector4D.project(vanPoint(k,j),true,true),
projector4D.project(k,true,true),projector4D.project(vanPoint(j,k),true,true),
// Segment kl vanishing line
projector4D.project(k,true,true),projector4D.project(vanPoint(l,k),true,true),
projector4D.project(l,true,true),projector4D.project(vanPoint(k,l),true,true),
// Segment li vanishing line
projector4D.project(l,true,true),projector4D.project(vanPoint(i,l),true,true),
projector4D.project(i,true,true),projector4D.project(vanPoint(l,i),true,true),
// Segment mn vanishing line
projector4D.project(m,true,true),projector4D.project(vanPoint(n,m),true,true),
projector4D.project(n,true,true),projector4D.project(vanPoint(m,n),true,true),
// Segment no vanishing line
projector4D.project(n,true,true),projector4D.project(vanPoint(o,n),true,true),
projector4D.project(o,true,true),projector4D.project(vanPoint(n,o),true,true),
// Segment op vanishing line
projector4D.project(o,true,true),projector4D.project(vanPoint(p,o),true,true),
projector4D.project(p,true,true),projector4D.project(vanPoint(o,p),true,true),
// Segment pm vanishing line
projector4D.project(p,true,true),projector4D.project(vanPoint(m,p),true,true),
projector4D.project(m,true,true),projector4D.project(vanPoint(p,m),true,true),
// Segment ip vanishing line
projector4D.project(i,true,true),projector4D.project(vanPoint(p,i),true,true),
projector4D.project(p,true,true),projector4D.project(vanPoint(i,p),true,true),
// Segment jo vanishing line
projector4D.project(j,true,true),projector4D.project(vanPoint(o,j),true,true),
projector4D.project(o,true,true),projector4D.project(vanPoint(j,o),true,true),
// Segment kn vanishing line
projector4D.project(k,true,true),projector4D.project(vanPoint(n,k),true,true),
projector4D.project(n,true,true),projector4D.project(vanPoint(k,n),true,true),
// Segment lm vanishing line
projector4D.project(l,true,true),projector4D.project(vanPoint(m,l),true,true),
projector4D.project(m,true,true),projector4D.project(vanPoint(l,m),true,true),
// Segment ai vanishing line
projector4D.project(a,true,true),projector4D.project(vanPoint(i,a),true,true),
projector4D.project(i,true,true),projector4D.project(vanPoint(a,i),true,true),
// Segment bj vanishing line
projector4D.project(b,true,true),projector4D.project(vanPoint(j,b),true,true),
projector4D.project(j,true,true),projector4D.project(vanPoint(b,j),true,true),
// Segment ck vanishing line
projector4D.project(c,true,true),projector4D.project(vanPoint(k,c),true,true),
projector4D.project(k,true,true),projector4D.project(vanPoint(c,k),true,true),
// Segment dl vanishing line
projector4D.project(d,true,true),projector4D.project(vanPoint(l,d),true,true),
projector4D.project(l,true,true),projector4D.project(vanPoint(d,l),true,true),
// Segment em vanishing line
projector4D.project(e,true,true),projector4D.project(vanPoint(m,e),true,true),
projector4D.project(m,true,true),projector4D.project(vanPoint(e,m),true,true),
// Segment fn vanishing line
projector4D.project(f,true,true),projector4D.project(vanPoint(n,f),true,true),
projector4D.project(n,true,true),projector4D.project(vanPoint(f,n),true,true),
// Segment go vanishing line
projector4D.project(g,true,true),projector4D.project(vanPoint(o,g),true,true),
projector4D.project(o,true,true),projector4D.project(vanPoint(g,o),true,true),
// Segment hp vanishing line
projector4D.project(h,true,true),projector4D.project(vanPoint(p,h),true,true),
projector4D.project(p,true,true),projector4D.project(vanPoint(h,p),true,true)
);
return geom;
}
function Projector4D(){
this.repMode = 0;
document.getElementById(‘4Dpers’).style.color = ‘red’;
this.ObserverDist = 200;
this.HyperplaneDist = 100;
this.angXY = 0;
this.angYZ = 0;
this.angZW = 0;
this.angWX = 0;
this.posX = 0;
this.posY = 0;
this.posZ = 0;
this.posW = 0;
this.rotXY = new THREE.Matrix4();
this.rotYZ = new THREE.Matrix4();
this.rotZW = new THREE.Matrix4();
this.rotWX = new THREE.Matrix4();
this.Mat = new THREE.Matrix4();
this.initProjector = function(){
this.angXY = 0;
this.angYZ = 0;
this.angZW = 0;
this.angWX = 0;
}
this.updateMatrix = function(){
/*
var a = new THREE.Matrix4().set(
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0
)
console.log(a);
var b = new THREE.Matrix4().set(
1, 1, 1, 1,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0
)
console.log(b);
var c = new THREE.Matrix4().multiplyMatrices(a,b);
console.log(c);
// / 1 1 1 1 \
// c = | 1 1 1 1 |
// | 1 1 1 1 |
// \ 1 1 1 1 /
var d = new THREE.Matrix4().multiplyMatrices(b,a);
console.log(d);
// / 4 0 0 0 \
// d = | 0 0 0 0 |
// | 0 0 0 0 |
// \ 0 0 0 0 /
*/
// Indices of the matrix elements
// / 0 4 8 12 \
// | 1 5 9 13 |
// | 2 6 10 14 |
// \ 3 7 11 15 /
this.rotXY.elements[0] = 1; this.rotXY.elements[4] = 0; this.rotXY.elements[8] = 0; this.rotXY.elements[12] = 0;
this.rotXY.elements[1] = 0; this.rotXY.elements[5] = 1; this.rotXY.elements[9] = 0; this.rotXY.elements[13] = 0;
this.rotXY.elements[2] = 0; this.rotXY.elements[6] = 0; this.rotXY.elements[10] = Math.cos(this.angXY); this.rotXY.elements[14] = -Math.sin(this.angXY);
this.rotXY.elements[3] = 0; this.rotXY.elements[7] = 0; this.rotXY.elements[11] = Math.sin(this.angXY); this.rotXY.elements[15] = Math.cos(this.angXY);
//Matrix of this.rotation about YZ plane
this.rotYZ.elements[0] = Math.cos(this.angYZ); this.rotYZ.elements[4] = 0; this.rotYZ.elements[8] = 0; this.rotYZ.elements[12] = -Math.sin(this.angYZ);
this.rotYZ.elements[1] = 0; this.rotYZ.elements[5] = 1; this.rotYZ.elements[9] = 0; this.rotYZ.elements[13] = 0;
this.rotYZ.elements[2] = 0; this.rotYZ.elements[6] = 0; this.rotYZ.elements[10] = 1; this.rotYZ.elements[14] = 0;
this.rotYZ.elements[3] = Math.sin(this.angYZ); this.rotYZ.elements[7] = 0; this.rotYZ.elements[11] = 0; this.rotYZ.elements[15] = Math.cos(this.angYZ);
//Matrix of this.rotation about ZW plane
this.rotZW.elements[0] = Math.cos(this.angZW); this.rotZW.elements[4] = -Math.sin(this.angZW); this.rotZW.elements[8] = 0; this.rotZW.elements[12] = 0;
this.rotZW.elements[1] = Math.sin(this.angZW); this.rotZW.elements[5] = Math.cos(this.angZW); this.rotZW.elements[9] = 0; this.rotZW.elements[13] = 0;
this.rotZW.elements[2] = 0; this.rotZW.elements[6] = 0; this.rotZW.elements[10] = 1; this.rotZW.elements[14] = 0;
this.rotZW.elements[3] = 0; this.rotZW.elements[7] = 0; this.rotZW.elements[11] = 0; this.rotZW.elements[15] = 1;
//Matrix of this.rotation about WX plane
this.rotWX.elements[0] = 1; this.rotWX.elements[4] = 0; this.rotWX.elements[8] = 0; this.rotWX.elements[12] = 0;
this.rotWX.elements[1] = 0; this.rotWX.elements[5] = Math.cos(this.angWX); this.rotWX.elements[9] = -Math.sin(this.angWX); this.rotWX.elements[13] = 0;
this.rotWX.elements[2] = 0; this.rotWX.elements[6] = Math.sin(this.angWX); this.rotWX.elements[10] = Math.cos(this.angWX); this.rotWX.elements[14] = 0;
this.rotWX.elements[3] = 0; this.rotWX.elements[7] = 0; this.rotWX.elements[11] = 0; this.rotWX.elements[15] = 1;
this.Mat = new THREE.Matrix4().multiplyMatrices(this.rotYZ,this.rotXY);
this.Mat = new THREE.Matrix4().multiplyMatrices(this.rotZW,this.Mat.clone());
this.Mat = new THREE.Matrix4().multiplyMatrices(this.rotWX,this.Mat.clone());
/*
document.getElementById(‘msg’).innerHTML =
this.rotXY.elements[0].toFixed(2)+’ ‘+this.rotXY.elements[4].toFixed(2)+’ ‘+this.rotXY.elements[8].toFixed(2)+’ ‘+this.rotXY.elements[12].toFixed(2)+’ ‘+
this.rotXY.elements[1].toFixed(2)+’ ‘+this.rotXY.elements[5].toFixed(2)+’ ‘+this.rotXY.elements[9].toFixed(2)+’ ‘+this.rotXY.elements[13].toFixed(2)+’ ‘+
this.rotXY.elements[2].toFixed(2)+’ ‘+this.rotXY.elements[6].toFixed(2)+’ ‘+this.rotXY.elements[10].toFixed(2)+’ ‘+this.rotXY.elements[14].toFixed(2)+’ ‘+
this.rotXY.elements[3].toFixed(2)+’ ‘+this.rotXY.elements[7].toFixed(2)+’ ‘+this.rotXY.elements[11].toFixed(2)+’ ‘+this.rotXY.elements[15].toFixed(2)+’ ‘
document.getElementById(‘msg’).innerHTML =
this.rotYZ.elements[0].toFixed(2)+’ ‘+this.rotYZ.elements[4].toFixed(2)+’ ‘+this.rotYZ.elements[8].toFixed(2)+’ ‘+this.rotYZ.elements[12].toFixed(2)+’ ‘+
this.rotYZ.elements[1].toFixed(2)+’ ‘+this.rotYZ.elements[5].toFixed(2)+’ ‘+this.rotYZ.elements[9].toFixed(2)+’ ‘+this.rotYZ.elements[13].toFixed(2)+’ ‘+
this.rotYZ.elements[2].toFixed(2)+’ ‘+this.rotYZ.elements[6].toFixed(2)+’ ‘+this.rotYZ.elements[10].toFixed(2)+’ ‘+this.rotYZ.elements[14].toFixed(2)+’ ‘+
this.rotYZ.elements[3].toFixed(2)+’ ‘+this.rotYZ.elements[7].toFixed(2)+’ ‘+this.rotYZ.elements[11].toFixed(2)+’ ‘+this.rotYZ.elements[15].toFixed(2)+’ ‘
document.getElementById(‘msg’).innerHTML =
this.Mat.elements[0].toFixed(2)+’ ‘+this.Mat.elements[4].toFixed(2)+’ ‘+this.Mat.elements[8].toFixed(2)+’ ‘+this.Mat.elements[12].toFixed(2)+’ ‘+
this.Mat.elements[1].toFixed(2)+’ ‘+this.Mat.elements[5].toFixed(2)+’ ‘+this.Mat.elements[9].toFixed(2)+’ ‘+this.Mat.elements[13].toFixed(2)+’ ‘+
this.Mat.elements[2].toFixed(2)+’ ‘+this.Mat.elements[6].toFixed(2)+’ ‘+this.Mat.elements[10].toFixed(2)+’ ‘+this.Mat.elements[14].toFixed(2)+’ ‘+
this.Mat.elements[3].toFixed(2)+’ ‘+this.Mat.elements[7].toFixed(2)+’ ‘+this.Mat.elements[11].toFixed(2)+’ ‘+this.Mat.elements[15].toFixed(2)+’ ‘
*/
}
this.updateMatrix();
this.project = function(p,sft,rot){ // p = 4D Vector, sft = boolean (shift the vector origin), rot = boolean (rotate the vector direction)
var pp = [];
var qq = [];
pp[0]=p.x;
pp[1]=p.y;
pp[2]=p.z;
pp[3]=p.w;
// Shift the four vector
if(sft == true){
pp[0] += this.posX;
pp[1] += this.posY;
pp[2] += this.posZ;
pp[3] += this.posW;
}
// Rotate the four vector
if(rot == true){
qq[0]=pp[0]*this.Mat.elements[0]+pp[1]*this.Mat.elements[4]+pp[2]*this.Mat.elements[8]+pp[3]*this.Mat.elements[12];
qq[1]=pp[0]*this.Mat.elements[1]+pp[1]*this.Mat.elements[5]+pp[2]*this.Mat.elements[9]+pp[3]*this.Mat.elements[13];
qq[2]=pp[0]*this.Mat.elements[2]+pp[1]*this.Mat.elements[6]+pp[2]*this.Mat.elements[10]+pp[3]*this.Mat.elements[14];
qq[3]=pp[0]*this.Mat.elements[3]+pp[1]*this.Mat.elements[7]+pp[2]*this.Mat.elements[11]+pp[3]*this.Mat.elements[15];
}else{
qq[0]=pp[0];
qq[1]=pp[1];
qq[2]=pp[2];
qq[3]=pp[3];
}
//Shift of the coordinate origin a distance “ObserverDist”, to place the origin where the observer is:
qq[3]=qq[3]+this.ObserverDist;
//where “ObserverDist” is the hyperobserver radial distance.
if(this.repMode == 0){
//The hyperplane equation is: vec{a}·vec{x} = d => a1*x1+a2*x2+a3*x3+a4*x4 = d
//The equation of the ray from the observer to a point P is: vec{x} = vec{o}+(vec{p}-vec{o})*t
// x1 = o1+(p1-o1)*t
// x2 = o2+(p2-o2)*t
// x3 = o3+(p3-o3)*t
// x4 = o4+(p4-o4)*t
//Considering that the observer is on the origin: vec{o}=(0,0,0,0)
// x1 = p1*t
// x2 = p2*t
// x3 = p3*t
// x4 = p4*t
//The observer is looking at on the direction of axis W vec{a}=(0,0,0,1),
//i.e., the vector normal to the hyperplane is equal to the unitary vector on axis W,
//and then, the hyperplane equation is: x4=hplaneDist (hyperplane distance)
//To compute the ray-hyperplane intersection, we take: t = hplaneDist/p4
//and so:
// x1 = hplaneDist*p1/p4
// x2 = hplaneDist*p2/p4
// x3 = hplaneDist*p3/p4
pp[0]=this.HyperplaneDist*qq[0]/qq[3];
pp[1]=this.HyperplaneDist*qq[1]/qq[3];
pp[2]=this.HyperplaneDist*qq[2]/qq[3];
}
if(this.repMode == 1){
pp[0]=qq[0];
pp[1]=qq[1];
pp[2]=qq[2];
}
var np = new THREE.Vector3(pp[0],pp[1],pp[2]);
//alert(q.x);
return np;
}
}
function objectDetection(){
var obj;
for(var i = 0;i < group.children.length;i += 1){
obj = group.children[i];
alert('Inside group: #'+(i+1)+' '+obj.type+': '+obj.name);
if(obj.type == "Object3D"){
alert(obj.name+' has '+obj.children.length+' children');
for(var j = 0;j < obj.children.length;j += 1){
alert('The child #'+(j+1)+' of '+obj.name+' is a '+obj.children[j].type);
}
}
if(obj.type == "Mesh"){
alert(obj.name+' has a Geometry with '+obj.geometry.vertices.length+' vertices');
}
}
}
function Point3DToScreen2D(point3D,camera){
var p = point3D.clone();
var vector = p.project(camera);
vector.x = Math.floor((vector.x+1)/2*contWidth);
vector.y = Math.floor(-(vector.y-1)/2*contHeight);
return vector;
}
function render(){
var origin = new THREE.Vector3(pos3DY,pos3DX,0);
group.rotation.z = -Math.PI/2+AngPhi;
group.rotation.x = AngTheta; //Math.PI/2+AngTheta;
//camera.up = new THREE.Vector3(0,0,1);
//camera.lookAt(scene.position);
camera.lookAt(origin);
//camera.target = origin.clone();
camera.updateProjectionMatrix();
camera.updateMatrixWorld();
renderer.render(scene,camera);
//document.getElementById('msg').innerHTML = '('+camera.getWorldDirection().x.toFixed(2)+','+camera.getWorldDirection().y.toFixed(2)+','+camera.getWorldDirection().z.toFixed(2)+')';
var origin4D = new THREE.Vector4(projector4D.posX,projector4D.posY,projector4D.posZ,projector4D.posW);
var posAxisX = projector4D.project(vecAxisX.clone().add(origin4D),false,true).applyAxisAngle(new THREE.Vector3(0,0,1),-Math.PI/2+AngPhi).applyAxisAngle(new THREE.Vector3(1,0,0),AngTheta);
var AxisX2D = Point3DToScreen2D(posAxisX,camera);
labelAxisX.style.top = AxisX2D.y + 'px';
labelAxisX.style.left = AxisX2D.x + 'px';
var posAxisY = projector4D.project(vecAxisY.clone().add(origin4D),false,true).applyAxisAngle(new THREE.Vector3(0,0,1),-Math.PI/2+AngPhi).applyAxisAngle(new THREE.Vector3(1,0,0),AngTheta);
var AxisY2D = Point3DToScreen2D(posAxisY,camera);
labelAxisY.style.top = AxisY2D.y + 'px';
labelAxisY.style.left = AxisY2D.x + 'px';
var posAxisZ = projector4D.project(vecAxisZ.clone().add(origin4D),false,true).applyAxisAngle(new THREE.Vector3(0,0,1),-Math.PI/2+AngPhi).applyAxisAngle(new THREE.Vector3(1,0,0),AngTheta);
var AxisZ2D = Point3DToScreen2D(posAxisZ,camera);
labelAxisZ.style.top = AxisZ2D.y + 'px';
labelAxisZ.style.left = (AxisZ2D.x+5) + 'px';
var posAxisW = projector4D.project(vecAxisW.clone().add(origin4D),false,true).applyAxisAngle(new THREE.Vector3(0,0,1),-Math.PI/2+AngPhi).applyAxisAngle(new THREE.Vector3(1,0,0),AngTheta);
var AxisW2D = Point3DToScreen2D(posAxisW,camera);
labelAxisW.style.top = AxisW2D.y + 'px';
labelAxisW.style.left = (AxisW2D.x+5) + 'px';
//document.getElementById('msg').innerHTML = labelAxisX.style.left+' '+labelAxisX.style.top;
}