diff --git a/build/three.js b/build/three.js index 8872b17e536b2bb592ebf6e3d0e22ade05e19b4b..d6840a499139a3f4a058435ae82dbcd85f5a8f78 100644 --- a/build/three.js +++ b/build/three.js @@ -16622,10 +16622,17 @@ THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS this.image = { data: data, width: width, height: height }; + this.magFilter = magFilter !== undefined ? magFilter : THREE.NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : THREE.NearestFilter; + + this.flipY = false; + this.generateMipmaps = false; + }; THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype ); THREE.DataTexture.prototype.constructor = THREE.DataTexture; + // File:src/textures/VideoTexture.js /** @@ -16959,7 +16966,9 @@ THREE.Line.prototype.raycast = ( function () { if ( distSq > precisionSq ) continue; - var distance = ray.origin.distanceTo( interRay ); + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + + var distance = raycaster.ray.origin.distanceTo( interRay ); if ( distance < raycaster.near || distance > raycaster.far ) continue; @@ -16994,7 +17003,9 @@ THREE.Line.prototype.raycast = ( function () { if ( distSq > precisionSq ) continue; - var distance = ray.origin.distanceTo( interRay ); + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + + var distance = raycaster.ray.origin.distanceTo( interRay ); if ( distance < raycaster.near || distance > raycaster.far ) continue; @@ -17025,8 +17036,10 @@ THREE.Line.prototype.raycast = ( function () { var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); if ( distSq > precisionSq ) continue; + + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation - var distance = ray.origin.distanceTo( interRay ); + var distance = raycaster.ray.origin.distanceTo( interRay ); if ( distance < raycaster.near || distance > raycaster.far ) continue; @@ -17521,10 +17534,6 @@ THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) { this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType ); - this.boneTexture.minFilter = THREE.NearestFilter; - this.boneTexture.magFilter = THREE.NearestFilter; - this.boneTexture.generateMipmaps = false; - this.boneTexture.flipY = false; } else { @@ -19741,15 +19750,12 @@ THREE.WebGLRenderer = function ( parameters ) { pixelRatio = 1, - _precision = parameters.precision !== undefined ? parameters.precision : 'highp', - _alpha = parameters.alpha !== undefined ? parameters.alpha : false, _depth = parameters.depth !== undefined ? parameters.depth : true, _stencil = parameters.stencil !== undefined ? parameters.stencil : true, _antialias = parameters.antialias !== undefined ? parameters.antialias : false, _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, - _logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false, _clearColor = new THREE.Color( 0x000000 ), _clearAlpha = 0; @@ -19757,13 +19763,18 @@ THREE.WebGLRenderer = function ( parameters ) { var lights = []; var opaqueObjects = []; + var opaqueObjectsLastIndex = -1; var transparentObjects = []; + var transparentObjectsLastIndex = -1; var opaqueImmediateObjects = []; + var opaqueImmediateObjectsLastIndex = -1; var transparentImmediateObjects = []; + var transparentImmediateObjectsLastIndex = -1; var morphInfluences = new Float32Array( 8 ); + var sprites = []; var lensFlares = []; @@ -19928,11 +19939,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - if ( _logarithmicDepthBuffer ) { - - extensions.get( 'EXT_frag_depth' ); - - } + var capabilities = new THREE.WebGLCapabilities( _gl, extensions, parameters ); var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL ); var properties = new THREE.WebGLProperties(); @@ -19982,6 +19989,7 @@ THREE.WebGLRenderer = function ( parameters ) { setDefaultGLState(); this.context = _gl; + this.capabilities = capabilities; this.extensions = extensions; this.state = state; @@ -19991,24 +19999,6 @@ THREE.WebGLRenderer = function ( parameters ) { this.shadowMap = shadowMap; - // GPU capabilities - - var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ); - var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); - var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ); - var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE ); - - var _supportsVertexTextures = _maxVertexTextures > 0; - var _supportsBoneTextures = _supportsVertexTextures && extensions.get( 'OES_texture_float' ); - - var _maxPrecision = state.getMaxPrecision( _precision ); - - if ( _maxPrecision !== _precision ) { - - console.warn( 'THREE.WebGLRenderer:', _precision, 'not supported, using', _maxPrecision, 'instead.' ); - _precision = _maxPrecision; - - } // Plugins @@ -20063,7 +20053,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.getPrecision = function () { - return _precision; + return capabilities.precision; }; @@ -20345,7 +20335,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( newReferenceCount === 0 ) { - // the last meterial that has been using the program let + // the last material that has been using the program let // go of it, so remove it from the (unordered) _programs // set and deallocate the GL resource @@ -20868,17 +20858,23 @@ THREE.WebGLRenderer = function ( parameters ) { lights.length = 0; - opaqueObjects.length = 0; - transparentObjects.length = 0; + opaqueObjectsLastIndex = -1; + transparentObjectsLastIndex = -1; - opaqueImmediateObjects.length = 0; - transparentImmediateObjects.length = 0; + opaqueImmediateObjectsLastIndex = -1; + transparentImmediateObjectsLastIndex = -1; sprites.length = 0; lensFlares.length = 0; projectObject( scene ); + opaqueObjects.length = opaqueObjectsLastIndex + 1; + transparentObjects.length = transparentObjectsLastIndex + 1; + + opaqueImmediateObjects.length = opaqueImmediateObjectsLastIndex + 1; + transparentImmediateObjects.length = transparentImmediateObjectsLastIndex + 1; + if ( _this.sortObjects === true ) { opaqueObjects.sort( painterSortStable ); @@ -20958,40 +20954,84 @@ THREE.WebGLRenderer = function ( parameters ) { function pushImmediateRenderItem( object ) { + var array, index; + + // allocate the next position in the appropriate array + if ( object.material.transparent ) { - transparentImmediateObjects.push( object ); + array = transparentImmediateObjects; + index = ++ transparentImmediateObjectsLastIndex; } else { - opaqueImmediateObjects.push( object ); + array = opaqueImmediateObjects; + index = ++ opaqueImmediateObjectsLastIndex; } + // recycle existing position or grow the array + + if ( index < array.length ) { + + array[ index ] = object; + + } else { + + // assert( index === array.length ); + array.push( object ); + + } + + } function pushRenderItem( object, geometry, material, z, group ) { - var renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - z: _vector3.z, - group: group - }; + var array, index; + + // allocate the next position in the appropriate array if ( material.transparent ) { - transparentObjects.push( renderItem ); + array = transparentObjects; + index = ++ transparentObjectsLastIndex; } else { - opaqueObjects.push( renderItem ); + array = opaqueObjects; + index = ++ opaqueObjectsLastIndex; } - material.program = properties.get( material ).program; // TODO: Do this at compile time + // recycle existing render item or grow the array + + var renderItem = array[ index ]; + + if ( renderItem !== undefined ) { + + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.z = _vector3.z; + renderItem.group = group; + + } else { + + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + z: _vector3.z, + group: group + }; + + // assert( index === array.length ); + array.push( renderItem ); + + } } @@ -21152,11 +21192,11 @@ THREE.WebGLRenderer = function ( parameters ) { var maxLightCount = allocateLights( lights ); var maxShadows = allocateShadows( lights ); var maxBones = allocateBones( object ); - var precision = _precision; + var precision = capabilities.precision; if ( material.precision !== null ) { - precision = state.getMaxPrecision( material.precision ); + precision = capabilities.getMaxPrecision( material.precision ); if ( precision !== material.precision ) { @@ -21169,7 +21209,7 @@ THREE.WebGLRenderer = function ( parameters ) { var parameters = { precision: precision, - supportsVertexTextures: _supportsVertexTextures, + supportsVertexTextures: capabilities.vertexTextures, map: !! material.map, envMap: !! material.envMap, @@ -21193,11 +21233,11 @@ THREE.WebGLRenderer = function ( parameters ) { flatShading: material.shading === THREE.FlatShading, sizeAttenuation: material.sizeAttenuation, - logarithmicDepthBuffer: _logarithmicDepthBuffer, + logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer, skinning: material.skinning, maxBones: maxBones, - useVertexTexture: _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture, + useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture, morphTargets: material.morphTargets, morphNormals: material.morphNormals, @@ -21336,6 +21376,7 @@ THREE.WebGLRenderer = function ( parameters ) { } materialProperties.program = program; + material.program = program; var attributes = program.getAttributes(); @@ -21463,7 +21504,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements ); - if ( _logarithmicDepthBuffer ) { + if ( capabilities.logarithmicDepthBuffer ) { _gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); @@ -21522,7 +21563,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - if ( _supportsBoneTextures && object.skeleton && object.skeleton.useVertexTexture ) { + if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) { if ( p_uniforms.boneTexture !== undefined ) { @@ -21928,9 +21969,9 @@ THREE.WebGLRenderer = function ( parameters ) { var textureUnit = _usedTextureUnits; - if ( textureUnit >= _maxTextures ) { + if ( textureUnit >= capabilities.maxTextures ) { - console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); + console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); } @@ -22547,7 +22588,10 @@ THREE.WebGLRenderer = function ( parameters ) { extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) { + if ( extension ) { + + if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; + if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return; if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { @@ -22583,7 +22627,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment ); - texture.image = clampToMaxSize( texture.image, _maxTextureSize ); + texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize ); var image = texture.image, isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ), @@ -22768,7 +22812,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) { - cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize ); + cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize ); } else { @@ -23231,7 +23275,7 @@ THREE.WebGLRenderer = function ( parameters ) { function allocateBones ( object ) { - if ( _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture ) { + if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) { return 1024; @@ -23356,7 +23400,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.supportsVertexTextures = function () { - return _supportsVertexTextures; + return capabilities.vertexTextures; }; @@ -23747,6 +23791,76 @@ THREE.WebGLExtensions = function ( gl ) { }; +// File:src/renderers/webgl/WebGLCapabilities.js + +THREE.WebGLCapabilities = function ( gl, extensions, parameters ) { + + function getMaxPrecision( precision ) { + + if ( precision === 'highp' ) { + + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { + + return 'highp'; + + } + + precision = 'mediump'; + + } + + if ( precision === 'mediump' ) { + + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { + + return 'mediump'; + + } + + } + + return 'lowp'; + + } + + this.getMaxPrecision = getMaxPrecision; + + this.precision = parameters.precision !== undefined ? parameters.precision : 'highp', + this.logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false; + + this.maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); + this.maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); + this.maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE ); + this.maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE ); + + this.maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + this.maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS ); + this.maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS ); + this.maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS ); + + this.vertexTextures = this.maxVertexTextures > 0; + this.floatFragmentTextures = !! extensions.get( 'OES_texture_float' ); + this.floatVertexTextures = this.vertexTextures && this.floatFragmentTextures; + + var _maxPrecision = getMaxPrecision( this.precision ); + + if ( _maxPrecision !== this.precision ) { + + console.warn( 'THREE.WebGLRenderer:', this.precision, 'not supported, using', _maxPrecision, 'instead.' ); + this.precision = _maxPrecision; + + } + + if ( this.logarithmicDepthBuffer ) { + + this.logarithmicDepthBuffer = !! extensions.get( 'EXT_frag_depth' ); + + } + +}; + // File:src/renderers/webgl/WebGLGeometries.js /** @@ -24874,9 +24988,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { var groups = geometry.groups; var materials = material.materials; - for ( var j = 0, jl = groups.length; j < jl; j ++ ) { + for ( var k = 0, kl = groups.length; k < kl; k ++ ) { - var group = groups[ j ]; + var group = groups[ k ]; var groupMaterial = materials[ group.materialIndex ]; if ( groupMaterial.visible === true ) { @@ -25131,36 +25245,6 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { }; - this.getMaxPrecision = function ( precision ) { - - if ( precision === 'highp' ) { - - if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && - gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { - - return 'highp'; - - } - - precision = 'mediump'; - - } - - if ( precision === 'mediump' ) { - - if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && - gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { - - return 'mediump'; - - } - - } - - return 'lowp'; - - }; - this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { if ( blending !== currentBlending ) { diff --git a/build/three.min.js b/build/three.min.js index 9d271eec67e7de4b9bc4405595170b9a166c42f0..d8e0240f35b14227e70dd70d0b7e0569fd50200d 100644 --- a/build/three.min.js +++ b/build/three.min.js @@ -106,8 +106,8 @@ e=Math.sin(e);if("XYZ"===a.order){a=g*h;var k=g*e,l=c*h,n=c*e;b[0]=f*h;b[4]=-f*e n*d+a,b[9]=k*d-l,b[2]=-d,b[6]=c*f,b[10]=g*f):"YZX"===a.order?(a=g*f,k=g*d,l=c*f,n=c*d,b[0]=f*h,b[4]=n-a*e,b[8]=l*e+k,b[1]=e,b[5]=g*h,b[9]=-c*h,b[2]=-d*h,b[6]=k*e+l,b[10]=a-n*e):"XZY"===a.order&&(a=g*f,k=g*d,l=c*f,n=c*d,b[0]=f*h,b[4]=-e,b[8]=d*h,b[1]=a*e+n,b[5]=g*h,b[9]=k*e-l,b[2]=l*e-k,b[6]=c*h,b[10]=n*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},setRotationFromQuaternion:function(a){console.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion()."); return this.makeRotationFromQuaternion(a)},makeRotationFromQuaternion:function(a){var b=this.elements,c=a.x,d=a.y,e=a.z,g=a.w,f=c+c,h=d+d,k=e+e;a=c*f;var l=c*h,c=c*k,n=d*h,d=d*k,e=e*k,f=g*f,h=g*h,g=g*k;b[0]=1-(n+e);b[4]=l-g;b[8]=c+h;b[1]=l+g;b[5]=1-(a+e);b[9]=d-f;b[2]=c-h;b[6]=d+f;b[10]=1-(a+n);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},lookAt:function(){var a,b,c;return function(d,e,g){void 0===a&&(a=new THREE.Vector3);void 0===b&&(b=new THREE.Vector3);void 0===c&&(c=new THREE.Vector3); var f=this.elements;c.subVectors(d,e).normalize();0===c.length()&&(c.z=1);a.crossVectors(g,c).normalize();0===a.length()&&(c.x+=1E-4,a.crossVectors(g,c).normalize());b.crossVectors(c,a);f[0]=a.x;f[4]=b.x;f[8]=c.x;f[1]=a.y;f[5]=b.y;f[9]=c.y;f[2]=a.z;f[6]=b.z;f[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},multiplyMatrices:function(a, -b){var c=a.elements,d=b.elements,e=this.elements,g=c[0],f=c[4],h=c[8],k=c[12],l=c[1],n=c[5],p=c[9],m=c[13],q=c[2],s=c[6],r=c[10],u=c[14],x=c[3],v=c[7],y=c[11],c=c[15],w=d[0],E=d[4],B=d[8],z=d[12],A=d[1],O=d[5],L=d[9],C=d[13],P=d[2],J=d[6],F=d[10],D=d[14],G=d[3],N=d[7],R=d[11],d=d[15];e[0]=g*w+f*A+h*P+k*G;e[4]=g*E+f*O+h*J+k*N;e[8]=g*B+f*L+h*F+k*R;e[12]=g*z+f*C+h*D+k*d;e[1]=l*w+n*A+p*P+m*G;e[5]=l*E+n*O+p*J+m*N;e[9]=l*B+n*L+p*F+m*R;e[13]=l*z+n*C+p*D+m*d;e[2]=q*w+s*A+r*P+u*G;e[6]=q*E+s*O+r*J+u*N;e[10]= -q*B+s*L+r*F+u*R;e[14]=q*z+s*C+r*D+u*d;e[3]=x*w+v*A+y*P+c*G;e[7]=x*E+v*O+y*J+c*N;e[11]=x*B+v*L+y*F+c*R;e[15]=x*z+v*C+y*D+c*d;return this},multiplyToArray:function(a,b,c){var d=this.elements;this.multiplyMatrices(a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12];c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*= +b){var c=a.elements,d=b.elements,e=this.elements,g=c[0],f=c[4],h=c[8],k=c[12],l=c[1],n=c[5],p=c[9],m=c[13],q=c[2],s=c[6],r=c[10],u=c[14],x=c[3],v=c[7],y=c[11],c=c[15],w=d[0],G=d[4],B=d[8],z=d[12],A=d[1],O=d[5],K=d[9],D=d[13],P=d[2],J=d[6],H=d[10],C=d[14],F=d[3],N=d[7],R=d[11],d=d[15];e[0]=g*w+f*A+h*P+k*F;e[4]=g*G+f*O+h*J+k*N;e[8]=g*B+f*K+h*H+k*R;e[12]=g*z+f*D+h*C+k*d;e[1]=l*w+n*A+p*P+m*F;e[5]=l*G+n*O+p*J+m*N;e[9]=l*B+n*K+p*H+m*R;e[13]=l*z+n*D+p*C+m*d;e[2]=q*w+s*A+r*P+u*F;e[6]=q*G+s*O+r*J+u*N;e[10]= +q*B+s*K+r*H+u*R;e[14]=q*z+s*D+r*C+u*d;e[3]=x*w+v*A+y*P+c*F;e[7]=x*G+v*O+y*J+c*N;e[11]=x*B+v*K+y*H+c*R;e[15]=x*z+v*D+y*C+c*d;return this},multiplyToArray:function(a,b,c){var d=this.elements;this.multiplyMatrices(a,b);c[0]=d[0];c[1]=d[1];c[2]=d[2];c[3]=d[3];c[4]=d[4];c[5]=d[5];c[6]=d[6];c[7]=d[7];c[8]=d[8];c[9]=d[9];c[10]=d[10];c[11]=d[11];c[12]=d[12];c[13]=d[13];c[14]=d[14];c[15]=d[15];return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*= a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},multiplyVector3:function(a){console.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.");return a.applyProjection(this)},multiplyVector4:function(a){console.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},multiplyVector3Array:function(a){console.warn("THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead."); return this.applyToVector3Array(a)},applyToVector3Array:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Vector3);void 0===c&&(c=0);void 0===d&&(d=b.length);for(var e=0;ed?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cd?-1:1,e.vertexTangents[c]=new THREE.Vector4(w.x,w.y,w.z,d);this.hasTangents=!0},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;cga?-1:1;h[4*a]=Q.x;h[4*a+1]=Q.y;h[4*a+2]=Q.z;h[4*a+3]=Z}if(void 0===this.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.index.array, -d=this.attributes.position.array,e=this.attributes.normal.array,g=this.attributes.uv.array,f=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*f),4));for(var h=this.attributes.tangent.array,k=[],l=[],n=0;nza?-1:1;h[4*a]=Q.x;h[4*a+1]=Q.y;h[4*a+2]=Q.z;h[4*a+3]=X}if(void 0===this.index||void 0===this.attributes.position||void 0===this.attributes.normal||void 0===this.attributes.uv)console.warn("THREE.BufferGeometry: Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()");else{var c=this.index.array, +d=this.attributes.position.array,e=this.attributes.normal.array,g=this.attributes.uv.array,f=d.length/3;void 0===this.attributes.tangent&&this.addAttribute("tangent",new THREE.BufferAttribute(new Float32Array(4*f),4));for(var h=this.attributes.tangent.array,k=[],l=[],n=0;nf;f++)m=v[k++],x=u[2*m],m=u[2*m+1],x=new THREE.Vector2(x, +d.type){console.error("THREE.JSONLoader: "+a+" should be loaded with THREE.SceneLoader instead.");return}}c=e.parse(c,g);b(c.geometry,c.materials)})},setCrossOrigin:function(a){this.crossOrigin=a},setTexturePath:function(a){this.texturePath=a},parse:function(a,b){var c=new THREE.Geometry,d=void 0!==a.scale?1/a.scale:1;(function(b){var d,f,h,k,l,n,p,m,q,s,r,u,x,v=a.faces;n=a.vertices;var y=a.normals,w=a.colors,G=0;if(void 0!==a.uvs){for(d=0;df;f++)m=v[k++],x=u[2*m],m=u[2*m+1],x=new THREE.Vector2(x, m),2!==f&&c.faceVertexUvs[d][h].push(x),0!==f&&c.faceVertexUvs[d][h+1].push(x);p&&(p=3*v[k++],q.normal.set(y[p++],y[p++],y[p]),r.normal.copy(q.normal));if(s)for(d=0;4>d;d++)p=3*v[k++],s=new THREE.Vector3(y[p++],y[p++],y[p]),2!==d&&q.vertexNormals.push(s),0!==d&&r.vertexNormals.push(s);n&&(n=v[k++],n=w[n],q.color.setHex(n),r.color.setHex(n));if(b)for(d=0;4>d;d++)n=v[k++],n=w[n],2!==d&&q.vertexColors.push(new THREE.Color(n)),0!==d&&r.vertexColors.push(new THREE.Color(n));c.faces.push(q);c.faces.push(r)}else{q= -new THREE.Face3;q.a=v[k++];q.b=v[k++];q.c=v[k++];h&&(h=v[k++],q.materialIndex=h);h=c.faces.length;if(d)for(d=0;df;f++)m=v[k++],x=u[2*m],m=u[2*m+1],x=new THREE.Vector2(x,m),c.faceVertexUvs[d][h].push(x);p&&(p=3*v[k++],q.normal.set(y[p++],y[p++],y[p]));if(s)for(d=0;3>d;d++)p=3*v[k++],s=new THREE.Vector3(y[p++],y[p++],y[p]),q.vertexNormals.push(s);n&&(n=v[k++],q.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=v[k++],q.vertexColors.push(new THREE.Color(w[n])); +new THREE.Face3;q.a=v[k++];q.b=v[k++];q.c=v[k++];h&&(h=v[k++],q.materialIndex=h);h=c.faces.length;if(d)for(d=0;df;f++)m=v[k++],x=u[2*m],m=u[2*m+1],x=new THREE.Vector2(x,m),c.faceVertexUvs[d][h].push(x);p&&(p=3*v[k++],q.normal.set(y[p++],y[p++],y[p]));if(s)for(d=0;3>d;d++)p=3*v[k++],s=new THREE.Vector3(y[p++],y[p++],y[p]),q.vertexNormals.push(s);n&&(n=v[k++],q.color.setHex(w[n]));if(b)for(d=0;3>d;d++)n=v[k++],q.vertexColors.push(new THREE.Color(w[n])); c.faces.push(q)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,f=a.skinWeights.length;dc.far||d.push({distance:l,distanceToRay:Math.sqrt(g),point:k.clone(),index:f,face:null,object:e})}};if(g instanceof THREE.BufferGeometry){var l=g.index,n=g.attributes.position.array;if(null!==l){var l=l.array,p=g.groups;0===p.length&&(p=[{start:0,count:l.length}]);for(var m=0,q=p.length;mg||(v=b.origin.distanceTo(n),vd.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,offsetIndex:r,face:null,faceIndex:null,object:this}))}}else for(q= -q.position.array,f=0;fg||(v=b.origin.distanceTo(n),vd.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,face:null,faceIndex:null,object:this}))}else if(f instanceof THREE.Geometry)for(h=f.vertices,k=h.length,f=0;fg||(v=b.origin.distanceTo(n),vd.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld), -index:f,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)}; +THREE.BufferGeometry){var m=f.index,q=f.attributes;if(null!==m){var m=m.array,q=q.position.array,s=f.groups;0===s.length&&(s=[{start:0,count:m.length}]);for(var r=0;rg||(n.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(n),vd.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,offsetIndex:r,face:null, +faceIndex:null,object:this}))}}else for(q=q.position.array,f=0;fg||(n.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(n),vd.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,face:null,faceIndex:null,object:this}))}else if(f instanceof THREE.Geometry)for(h=f.vertices,k=h.length,f=0;fg||(n.applyMatrix4(this.matrixWorld), +v=d.ray.origin.distanceTo(n),vd.far||e.push({distance:v,point:l.clone().applyMatrix4(this.matrixWorld),index:f,face:null,faceIndex:null,object:this}))}}}();THREE.Line.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)}; THREE.Line.prototype.toJSON=function(a){var b=THREE.Object3D.prototype.toJSON.call(this,a);void 0===a.geometries[this.geometry.uuid]&&(a.geometries[this.geometry.uuid]=this.geometry.toJSON());void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON());b.object.geometry=this.geometry.uuid;b.object.material=this.material.uuid;return b};THREE.LineStrip=0;THREE.LinePieces=1;THREE.LineSegments=function(a,b){THREE.Line.call(this,a,b);this.type="LineSegments"}; THREE.LineSegments.prototype=Object.create(THREE.Line.prototype);THREE.LineSegments.prototype.constructor=THREE.LineSegments;THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype);THREE.Mesh.prototype.constructor=THREE.Mesh; THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0l.far||n.push({distance:z,point:B,face:new THREE.Face3(q,s,r,THREE.Triangle.normal(d,e,g)),faceIndex:Math.floor(w/3),object:this})}}}}else for(x=q.position.array,w=0,E=x.length;wl.far||(q=w/3,s=q+1,r=q+2,n.push({distance:z,point:B,face:new THREE.Face3(q,s,r,THREE.Triangle.normal(d,e,g)),index:q,object:this})));else if(p instanceof THREE.Geometry)for(u=m instanceof THREE.MeshFaceMaterial,x=!0===u?m.materials:null,v=p.vertices,y=p.faces,w=0,E=y.length;wl.far||n.push({distance:z,point:B,face:A,faceIndex:w,object:this}))}}}}}(); +p.boundingBox||!1!==b.isIntersectionBox(p.boundingBox)))){var q,s,r;if(p instanceof THREE.BufferGeometry)if(s=p.index,q=p.attributes,null!==s){var u=s.array,x=q.position.array,p=p.groups;0===p.length&&(p=[{start:0,count:u.length}]);for(var v=0,y=p.length;vl.far||n.push({distance:z,point:B,face:new THREE.Face3(q,s,r,THREE.Triangle.normal(d,e,g)),faceIndex:Math.floor(w/3),object:this})}}}}else for(x=q.position.array,w=0,G=x.length;wl.far||(q=w/3,s=q+1,r=q+2,n.push({distance:z,point:B,face:new THREE.Face3(q,s,r,THREE.Triangle.normal(d,e,g)),index:q,object:this})));else if(p instanceof THREE.Geometry)for(u=m instanceof THREE.MeshFaceMaterial,x=!0===u?m.materials:null,v=p.vertices,y=p.faces,w=0,G=y.length;wl.far||n.push({distance:z,point:B,face:A,faceIndex:w,object:this}))}}}}}(); THREE.Mesh.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};THREE.Mesh.prototype.toJSON=function(a){var b=THREE.Object3D.prototype.toJSON.call(this,a);void 0===a.geometries[this.geometry.uuid]&&(a.geometries[this.geometry.uuid]=this.geometry.toJSON(a));void 0===a.materials[this.material.uuid]&&(a.materials[this.material.uuid]=this.material.toJSON(a));b.object.geometry=this.geometry.uuid;b.object.material=this.material.uuid;return b}; THREE.Bone=function(a){THREE.Object3D.call(this);this.type="Bone";this.skin=a};THREE.Bone.prototype=Object.create(THREE.Object3D.prototype);THREE.Bone.prototype.constructor=THREE.Bone;THREE.Bone.prototype.copy=function(a){THREE.Object3D.prototype.copy.call(this,a);this.skin=a.skin;return this}; -THREE.Skeleton=function(a,b,c){this.useVertexTexture=void 0!==c?c:!0;this.identityMatrix=new THREE.Matrix4;a=a||[];this.bones=a.slice(0);this.useVertexTexture?(a=Math.sqrt(4*this.bones.length),a=THREE.Math.nextPowerOfTwo(Math.ceil(a)),this.boneTextureHeight=this.boneTextureWidth=a=Math.max(a,4),this.boneMatrices=new Float32Array(this.boneTextureWidth*this.boneTextureHeight*4),this.boneTexture=new THREE.DataTexture(this.boneMatrices,this.boneTextureWidth,this.boneTextureHeight,THREE.RGBAFormat,THREE.FloatType), -this.boneTexture.minFilter=THREE.NearestFilter,this.boneTexture.magFilter=THREE.NearestFilter,this.boneTexture.generateMipmaps=!1,this.boneTexture.flipY=!1):this.boneMatrices=new Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else for(console.warn("THREE.Skeleton bonInverses is the wrong length."),this.boneInverses=[],b=0,a=this.bones.length;bc;c++)t.deleteFramebuffer(b.__webglFramebuffer[c]),t.deleteRenderbuffer(b.__webglRenderbuffer[c]);else t.deleteFramebuffer(b.__webglFramebuffer),t.deleteRenderbuffer(b.__webglRenderbuffer);$.delete(a)}Ba.textures--}function h(a){a=a.target;a.removeEventListener("dispose",h);k(a);$.delete(a)}function k(a){var b= -$.get(a).program.program;if(void 0!==b){a.program=void 0;a=0;for(var c=ua.length;a!==c;++a){var d=ua[a];if(d.program===b){0===--d.usedTimes&&(c-=1,ua[a]=ua[c],ua.pop(),t.deleteProgram(b),Ba.programs=c);break}}}}function l(a,b){return b[0]-a[0]}function n(a,b){return a.object.renderOrder!==b.object.renderOrder?a.object.renderOrder-b.object.renderOrder:a.material.id!==b.material.id?a.material.id-b.material.id:a.z!==b.z?a.z-b.z:a.id-b.id}function p(a,b){return a.object.renderOrder!==b.object.renderOrder? -a.object.renderOrder-b.object.renderOrder:a.z!==b.z?b.z-a.z:a.id-b.id}function m(a,b,c,d,e){a={id:a.id,object:a,geometry:b,material:c,z:da.z,group:e};c.transparent?la.push(a):va.push(a);c.program=$.get(c).program}function q(a){if(!1!==a.visible){if(a instanceof THREE.Light)ga.push(a);else if(a instanceof THREE.Sprite)ra.push(a);else if(a instanceof THREE.LensFlare)Ya.push(a);else if(a instanceof THREE.ImmediateRenderObject)a.material.transparent?Ca.push(a):sa.push(a);else if(a instanceof THREE.Mesh|| -a instanceof THREE.Line||a instanceof THREE.PointCloud)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===Za.intersectsObject(a)){var b=a.material;if(!0===b.visible){!0===ma.sortObjects&&(da.setFromMatrixPosition(a.matrixWorld),da.applyProjection(Ja));var c=xa.update(a);if(b instanceof THREE.MeshFaceMaterial)for(var d=c.groups,e=b.materials,b=0,f=d.length;bia;ia++)Na[ia]=!ma.autoScaleCubemaps||Zb||Kb?Kb?ea.image[ia].image:ea.image[ia]:B(ea.image[ia],dc);var $b=Na[0],ac=THREE.Math.isPowerOfTwo($b.width)&&THREE.Math.isPowerOfTwo($b.height),Fa=L(ea.format),Lb=L(ea.type);E(t.TEXTURE_CUBE_MAP,ea,ac);for(ia=0;6>ia;ia++)if(Zb)for(var Oa,bc=Na[ia].mipmaps,fb=0,ec=bc.length;fb=gb&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+gb);jb+=1;return a}function w(a,b,c,d){a[b+0]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function E(a,b,c){c?(t.texParameteri(a,t.TEXTURE_WRAP_S,L(b.wrapS)),t.texParameteri(a,t.TEXTURE_WRAP_T,L(b.wrapT)),t.texParameteri(a,t.TEXTURE_MAG_FILTER,L(b.magFilter)),t.texParameteri(a,t.TEXTURE_MIN_FILTER,L(b.minFilter))):(t.texParameteri(a,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(a,t.TEXTURE_WRAP_T, -t.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+" )"),t.texParameteri(a,t.TEXTURE_MAG_FILTER,O(b.magFilter)),t.texParameteri(a,t.TEXTURE_MIN_FILTER,O(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+ -b.sourceFile+" )"));(c=X.get("EXT_texture_filter_anisotropic"))&&b.type!==THREE.FloatType&&b.type!==THREE.HalfFloatType&&(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a, -0,0,a.width,a.height,0,0,d.width,d.height);console.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function z(a,b,c){t.bindFramebuffer(t.FRAMEBUFFER,a);t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,c,$.get(b).__webglTexture,0)}function A(a,b){t.bindRenderbuffer(t.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_COMPONENT16,b.width,b.height),t.framebufferRenderbuffer(t.FRAMEBUFFER, -t.DEPTH_ATTACHMENT,t.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_STENCIL,b.width,b.height),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,a)):t.renderbufferStorage(t.RENDERBUFFER,t.RGBA4,b.width,b.height)}function O(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?t.NEAREST:t.LINEAR}function L(a){var b;if(a===THREE.RepeatWrapping)return t.REPEAT;if(a===THREE.ClampToEdgeWrapping)return t.CLAMP_TO_EDGE; -if(a===THREE.MirroredRepeatWrapping)return t.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return t.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return t.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return t.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return t.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return t.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return t.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return t.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return t.UNSIGNED_SHORT_4_4_4_4; -if(a===THREE.UnsignedShort5551Type)return t.UNSIGNED_SHORT_5_5_5_1;if(a===THREE.UnsignedShort565Type)return t.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return t.BYTE;if(a===THREE.ShortType)return t.SHORT;if(a===THREE.UnsignedShortType)return t.UNSIGNED_SHORT;if(a===THREE.IntType)return t.INT;if(a===THREE.UnsignedIntType)return t.UNSIGNED_INT;if(a===THREE.FloatType)return t.FLOAT;b=X.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return t.ALPHA; -if(a===THREE.RGBFormat)return t.RGB;if(a===THREE.RGBAFormat)return t.RGBA;if(a===THREE.LuminanceFormat)return t.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return t.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return t.FUNC_ADD;if(a===THREE.SubtractEquation)return t.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return t.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return t.ZERO;if(a===THREE.OneFactor)return t.ONE;if(a===THREE.SrcColorFactor)return t.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return t.ONE_MINUS_SRC_COLOR; -if(a===THREE.SrcAlphaFactor)return t.SRC_ALPHA;if(a===THREE.OneMinusSrcAlphaFactor)return t.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return t.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return t.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return t.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return t.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return t.SRC_ALPHA_SATURATE;b=X.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=X.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=X.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 C=void 0!==a.canvas?a.canvas:document.createElement("canvas"),P=void 0!==a.context?a.context:null,J=C.width,F=C.height,D=1,G=void 0!==a.precision?a.precision:"highp",N=void 0!==a.alpha?a.alpha:!1,R=void 0!==a.depth?a.depth:!0, -T=void 0!==a.stencil?a.stencil:!0,Q=void 0!==a.antialias?a.antialias:!1,S=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,H=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,ta=void 0!==a.logarithmicDepthBuffer?a.logarithmicDepthBuffer:!1,Z=new THREE.Color(0),fa=0,ga=[],va=[],la=[],sa=[],Ca=[],hb=new Float32Array(8),ra=[],Ya=[];this.domElement=C;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.gammaOutput= -this.gammaInput=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;var ma=this,ua=[],pb=null,Pa=null,Xa=-1,Ia="",Wa=null,jb=0,Ga=0,Ha=0,Aa=C.width,wa=C.height,nb=0,ob=0,Za=new THREE.Frustum,Ja=new THREE.Matrix4,da=new THREE.Vector3,ha=new THREE.Vector3,ib=!0,Sb={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[], -decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},Ba={programs:0,geometries:0,textures:0},ka={calls:0,vertices:0,faces:0,points:0};this.info={render:ka,memory:Ba,programs:ua};var t;try{a={alpha:N,depth:R,stencil:T,antialias:Q,premultipliedAlpha:S,preserveDrawingBuffer:H};t=P||C.getContext("webgl",a)||C.getContext("experimental-webgl",a);if(null===t){if(null!==C.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context."; -}C.addEventListener("webglcontextlost",e,!1)}catch(Mb){console.error("THREE.WebGLRenderer: "+Mb)}var X=new THREE.WebGLExtensions(t);X.get("OES_texture_float");X.get("OES_texture_float_linear");X.get("OES_texture_half_float");X.get("OES_texture_half_float_linear");X.get("OES_standard_derivatives");X.get("ANGLE_instanced_arrays");X.get("OES_element_index_uint")&&(THREE.BufferGeometry.MaxIndex=4294967296);ta&&X.get("EXT_frag_depth");var K=new THREE.WebGLState(t,X,L),$=new THREE.WebGLProperties,xa=new THREE.WebGLObjects(t, -$,this.info),Nb=new THREE.WebGLBufferRenderer(t,X,ka),Ob=new THREE.WebGLIndexedBufferRenderer(t,X,ka);c();this.context=t;this.extensions=X;this.state=K;var na=new THREE.WebGLShadowMap(this,ga,xa);this.shadowMap=na;var gb=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),P=t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),Pb=t.getParameter(t.MAX_TEXTURE_SIZE),dc=t.getParameter(t.MAX_CUBE_MAP_TEXTURE_SIZE),rb=0h;h++)c.__webglFramebuffer[h]=t.createFramebuffer(),c.__webglRenderbuffer[h]=t.createRenderbuffer(),K.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,e,a.width,a.height,0,e,g,null),z(c.__webglFramebuffer[h],a,t.TEXTURE_CUBE_MAP_POSITIVE_X+h),A(c.__webglRenderbuffer[h],a);a.generateMipmaps&&d&&t.generateMipmap(t.TEXTURE_CUBE_MAP)}else c.__webglFramebuffer=t.createFramebuffer(),c.__webglRenderbuffer=a.shareDepthFrom? -a.shareDepthFrom.__webglRenderbuffer:t.createRenderbuffer(),K.bindTexture(t.TEXTURE_2D,c.__webglTexture),E(t.TEXTURE_2D,a,d),K.texImage2D(t.TEXTURE_2D,0,e,a.width,a.height,0,e,g,null),z(c.__webglFramebuffer,a,t.TEXTURE_2D),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,c.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,c.__webglRenderbuffer): -A(c.__webglRenderbuffer,a),a.generateMipmaps&&d&&t.generateMipmap(t.TEXTURE_2D);b?K.bindTexture(t.TEXTURE_CUBE_MAP,null):K.bindTexture(t.TEXTURE_2D,null);t.bindRenderbuffer(t.RENDERBUFFER,null);t.bindFramebuffer(t.FRAMEBUFFER,null)}a?(c=$.get(a),b=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,c=a.width,a=a.height,e=d=0):(b=null,c=Aa,a=wa,d=Ga,e=Ha);b!==Pa&&(t.bindFramebuffer(t.FRAMEBUFFER,b),t.viewport(d,e,c,a),Pa=b);nb=c;ob=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof -THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if($.get(a).__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.");else{var g=!1;$.get(a).__webglFramebuffer!==Pa&&(t.bindFramebuffer(t.FRAMEBUFFER,$.get(a).__webglFramebuffer),g=!0);t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE? -t.readPixels(b,c,d,e,t.RGBA,t.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&t.bindFramebuffer(t.FRAMEBUFFER,Pa)}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");return X.get("OES_texture_float")};this.supportsHalfFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' )."); -return X.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return X.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");return X.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC= -function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return X.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return X.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return rb};this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' )."); -return X.get("ANGLE_instanced_arrays")};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")};this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")};Object.defineProperties(this,{shadowMapEnabled:{get:function(){return na.enabled}, -set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");na.enabled=a}},shadowMapType:{get:function(){return na.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");na.type=a}},shadowMapCullFace:{get:function(){return na.cullFace},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");na.cullFace=a}},shadowMapDebug:{get:function(){return na.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug."); -na.debug=a}}})}; -THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1,1); -this.format=void 0!==c.format?c.format:THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; +THREE.WebGLRenderer=function(a){function b(a,b,c,d){!0===Q&&(a*=d,b*=d,c*=d);t.clearColor(a,b,c,d)}function c(){L.init();t.viewport(Ia,Aa,Ba,Ca);b(E.r,E.g,E.b,ha)}function d(){$a=rb=null;va="";ab=-1;jb=!0;L.reset()}function e(a){a.preventDefault();d();c();$.clear()}function g(a){a=a.target;a.removeEventListener("dispose",g);a:{var b=$.get(a);if(a.image&&b.__image__webglTextureCube)t.deleteTexture(b.__image__webglTextureCube);else{if(void 0===b.__webglInit)break a;t.deleteTexture(b.__webglTexture)}$.delete(a)}Da.textures--} +function f(a){a=a.target;a.removeEventListener("dispose",f);var b=$.get(a);if(a&&void 0!==b.__webglTexture){t.deleteTexture(b.__webglTexture);if(a instanceof THREE.WebGLRenderTargetCube)for(var c=0;6>c;c++)t.deleteFramebuffer(b.__webglFramebuffer[c]),t.deleteRenderbuffer(b.__webglRenderbuffer[c]);else t.deleteFramebuffer(b.__webglFramebuffer),t.deleteRenderbuffer(b.__webglRenderbuffer);$.delete(a)}Da.textures--}function h(a){a=a.target;a.removeEventListener("dispose",h);k(a);$.delete(a)}function k(a){var b= +$.get(a).program.program;if(void 0!==b){a.program=void 0;a=0;for(var c=ra.length;a!==c;++a){var d=ra[a];if(d.program===b){0===--d.usedTimes&&(c-=1,ra[a]=ra[c],ra.pop(),t.deleteProgram(b),Da.programs=c);break}}}}function l(a,b){return b[0]-a[0]}function n(a,b){return a.object.renderOrder!==b.object.renderOrder?a.object.renderOrder-b.object.renderOrder:a.material.id!==b.material.id?a.material.id-b.material.id:a.z!==b.z?a.z-b.z:a.id-b.id}function p(a,b){return a.object.renderOrder!==b.object.renderOrder? +a.object.renderOrder-b.object.renderOrder:a.z!==b.z?b.z-a.z:a.id-b.id}function m(a,b,c,d,e){var f;c.transparent?(d=ya,f=++Ha):(d=ia,f=++za);f=d[f];void 0!==f?(f.id=a.id,f.object=a,f.geometry=b,f.material=c,f.z=ba.z,f.group=e):(f={id:a.id,object:a,geometry:b,material:c,z:ba.z,group:e},d.push(f))}function q(a){if(!1!==a.visible){if(a instanceof THREE.Light)X.push(a);else if(a instanceof THREE.Sprite)Ra.push(a);else if(a instanceof THREE.LensFlare)Sa.push(a);else if(a instanceof THREE.ImmediateRenderObject){var b, +c;a.material.transparent?(b=Ja,c=++Ka):(b=qa,c=++bb);cga;ga++)Oa[ga]=!la.autoScaleCubemaps||Wb||Ib?Ib?ea.image[ga].image:ea.image[ga]:B(ea.image[ga],ka.maxCubemapSize);var Xb=Oa[0],Yb=THREE.Math.isPowerOfTwo(Xb.width)&& +THREE.Math.isPowerOfTwo(Xb.height),Ga=K(ea.format),Jb=K(ea.type);G(t.TEXTURE_CUBE_MAP,ea,Yb);for(ga=0;6>ga;ga++)if(Wb)for(var Pa,Zb=Oa[ga].mipmaps,ib=0,ac=Zb.length;ib=ka.maxTextures&&console.warn("WebGLRenderer: trying to use "+a+" texture units while this GPU supports only "+ka.maxTextures);lb+=1;return a}function w(a,b,c,d){a[b+0]=c.r*d;a[b+1]=c.g*d;a[b+2]=c.b*d}function G(a,b,c){c?(t.texParameteri(a,t.TEXTURE_WRAP_S, +K(b.wrapS)),t.texParameteri(a,t.TEXTURE_WRAP_T,K(b.wrapT)),t.texParameteri(a,t.TEXTURE_MAG_FILTER,K(b.magFilter)),t.texParameteri(a,t.TEXTURE_MIN_FILTER,K(b.minFilter))):(t.texParameteri(a,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(a,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),b.wrapS===THREE.ClampToEdgeWrapping&&b.wrapT===THREE.ClampToEdgeWrapping||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( "+b.sourceFile+ +" )"),t.texParameteri(a,t.TEXTURE_MAG_FILTER,O(b.magFilter)),t.texParameteri(a,t.TEXTURE_MIN_FILTER,O(b.minFilter)),b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( "+b.sourceFile+" )"));!(c=W.get("EXT_texture_filter_anisotropic"))||b.type===THREE.FloatType&&null===W.get("OES_texture_float_linear")||b.type===THREE.HalfFloatType&&null=== +W.get("OES_texture_half_float_linear")||!(1b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);console.warn("THREE.WebGLRenderer: image is too big ("+ +a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function z(a,b,c){t.bindFramebuffer(t.FRAMEBUFFER,a);t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,c,$.get(b).__webglTexture,0)}function A(a,b){t.bindRenderbuffer(t.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_COMPONENT16,b.width,b.height),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(t.renderbufferStorage(t.RENDERBUFFER, +t.DEPTH_STENCIL,b.width,b.height),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,a)):t.renderbufferStorage(t.RENDERBUFFER,t.RGBA4,b.width,b.height)}function O(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?t.NEAREST:t.LINEAR}function K(a){var b;if(a===THREE.RepeatWrapping)return t.REPEAT;if(a===THREE.ClampToEdgeWrapping)return t.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return t.MIRRORED_REPEAT; +if(a===THREE.NearestFilter)return t.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return t.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return t.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return t.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return t.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return t.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return t.UNSIGNED_BYTE;if(a===THREE.UnsignedShort4444Type)return t.UNSIGNED_SHORT_4_4_4_4;if(a===THREE.UnsignedShort5551Type)return t.UNSIGNED_SHORT_5_5_5_1; +if(a===THREE.UnsignedShort565Type)return t.UNSIGNED_SHORT_5_6_5;if(a===THREE.ByteType)return t.BYTE;if(a===THREE.ShortType)return t.SHORT;if(a===THREE.UnsignedShortType)return t.UNSIGNED_SHORT;if(a===THREE.IntType)return t.INT;if(a===THREE.UnsignedIntType)return t.UNSIGNED_INT;if(a===THREE.FloatType)return t.FLOAT;b=W.get("OES_texture_half_float");if(null!==b&&a===THREE.HalfFloatType)return b.HALF_FLOAT_OES;if(a===THREE.AlphaFormat)return t.ALPHA;if(a===THREE.RGBFormat)return t.RGB;if(a===THREE.RGBAFormat)return t.RGBA; +if(a===THREE.LuminanceFormat)return t.LUMINANCE;if(a===THREE.LuminanceAlphaFormat)return t.LUMINANCE_ALPHA;if(a===THREE.AddEquation)return t.FUNC_ADD;if(a===THREE.SubtractEquation)return t.FUNC_SUBTRACT;if(a===THREE.ReverseSubtractEquation)return t.FUNC_REVERSE_SUBTRACT;if(a===THREE.ZeroFactor)return t.ZERO;if(a===THREE.OneFactor)return t.ONE;if(a===THREE.SrcColorFactor)return t.SRC_COLOR;if(a===THREE.OneMinusSrcColorFactor)return t.ONE_MINUS_SRC_COLOR;if(a===THREE.SrcAlphaFactor)return t.SRC_ALPHA; +if(a===THREE.OneMinusSrcAlphaFactor)return t.ONE_MINUS_SRC_ALPHA;if(a===THREE.DstAlphaFactor)return t.DST_ALPHA;if(a===THREE.OneMinusDstAlphaFactor)return t.ONE_MINUS_DST_ALPHA;if(a===THREE.DstColorFactor)return t.DST_COLOR;if(a===THREE.OneMinusDstColorFactor)return t.ONE_MINUS_DST_COLOR;if(a===THREE.SrcAlphaSaturateFactor)return t.SRC_ALPHA_SATURATE;b=W.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=W.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= +W.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 D=void 0!==a.canvas?a.canvas:document.createElement("canvas"),P=void 0!==a.context?a.context:null,J=D.width,H=D.height,C=1,F=void 0!==a.alpha?a.alpha:!1,N=void 0!==a.depth?a.depth:!0,R=void 0!==a.stencil?a.stencil:!0,U=void 0!==a.antialias?a.antialias:!1,Q=void 0!==a.premultipliedAlpha?a.premultipliedAlpha: +!0,S=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,E=new THREE.Color(0),ha=0,X=[],ia=[],za=-1,ya=[],Ha=-1,qa=[],bb=-1,Ja=[],Ka=-1,ta=new Float32Array(8),Ra=[],Sa=[];this.domElement=D;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.gammaFactor=2;this.gammaOutput=this.gammaInput=!1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;var la=this,ra=[],rb=null,Qa=null,ab=-1,va="",$a=null,lb=0,Ia= +0,Aa=0,Ba=D.width,Ca=D.height,pb=0,qb=0,kb=new THREE.Frustum,Ta=new THREE.Matrix4,ba=new THREE.Vector3,fa=new THREE.Vector3,jb=!0,Pb={ambient:[0,0,0],directional:{length:0,colors:[],positions:[]},point:{length:0,colors:[],positions:[],distances:[],decays:[]},spot:{length:0,colors:[],positions:[],distances:[],directions:[],anglesCos:[],exponents:[],decays:[]},hemi:{length:0,skyColors:[],groundColors:[],positions:[]}},Da={programs:0,geometries:0,textures:0},ua={calls:0,vertices:0,faces:0,points:0}; +this.info={render:ua,memory:Da,programs:ra};var t;try{F={alpha:F,depth:N,stencil:R,antialias:U,premultipliedAlpha:Q,preserveDrawingBuffer:S};t=P||D.getContext("webgl",F)||D.getContext("experimental-webgl",F);if(null===t){if(null!==D.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}D.addEventListener("webglcontextlost",e,!1)}catch(Kb){console.error("THREE.WebGLRenderer: "+Kb)}var W=new THREE.WebGLExtensions(t);W.get("OES_texture_float"); +W.get("OES_texture_float_linear");W.get("OES_texture_half_float");W.get("OES_texture_half_float_linear");W.get("OES_standard_derivatives");W.get("ANGLE_instanced_arrays");W.get("OES_element_index_uint")&&(THREE.BufferGeometry.MaxIndex=4294967296);var ka=new THREE.WebGLCapabilities(t,W,a),L=new THREE.WebGLState(t,W,K),$=new THREE.WebGLProperties,sa=new THREE.WebGLObjects(t,$,this.info),Lb=new THREE.WebGLBufferRenderer(t,W,ua),Mb=new THREE.WebGLIndexedBufferRenderer(t,W,ua);c();this.context=t;this.capabilities= +ka;this.extensions=W;this.state=L;var ma=new THREE.WebGLShadowMap(this,X,sa);this.shadowMap=ma;var Nb=new THREE.SpritePlugin(this,Ra),Ob=new THREE.LensFlarePlugin(this,Sa);this.getContext=function(){return t};this.getContextAttributes=function(){return t.getContextAttributes()};this.forceContextLoss=function(){W.get("WEBGL_lose_context").loseContext()};this.getMaxAnisotropy=function(){var a;return function(){if(void 0!==a)return a;var b=W.get("EXT_texture_filter_anisotropic");return a=null!==b?t.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT): +0}}();this.getPrecision=function(){return ka.precision};this.getPixelRatio=function(){return C};this.setPixelRatio=function(a){void 0!==a&&(C=a)};this.getSize=function(){return{width:J,height:H}};this.setSize=function(a,b,c){J=a;H=b;D.width=a*C;D.height=b*C;!1!==c&&(D.style.width=a+"px",D.style.height=b+"px");this.setViewport(0,0,a,b)};this.setViewport=function(a,b,c,d){Ia=a*C;Aa=b*C;Ba=c*C;Ca=d*C;t.viewport(Ia,Aa,Ba,Ca)};this.setScissor=function(a,b,c,d){t.scissor(a*C,b*C,c*C,d*C)};this.enableScissorTest= +function(a){L.setScissorTest(a)};this.getClearColor=function(){return E};this.setClearColor=function(a,c){E.set(a);ha=void 0!==c?c:1;b(E.r,E.g,E.b,ha)};this.getClearAlpha=function(){return ha};this.setClearAlpha=function(a){ha=a;b(E.r,E.g,E.b,ha)};this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=t.COLOR_BUFFER_BIT;if(void 0===b||b)d|=t.DEPTH_BUFFER_BIT;if(void 0===c||c)d|=t.STENCIL_BUFFER_BIT;t.clear(d)};this.clearColor=function(){t.clear(t.COLOR_BUFFER_BIT)};this.clearDepth=function(){t.clear(t.DEPTH_BUFFER_BIT)}; +this.clearStencil=function(){t.clear(t.STENCIL_BUFFER_BIT)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){D.removeEventListener("webglcontextlost",e,!1)};this.renderBufferImmediate=function(a,b,c){L.initAttributes();var d=$.get(a);a.hasPositions&&!d.position&&(d.position=t.createBuffer());a.hasNormals&&!d.normal&&(d.normal=t.createBuffer());a.hasUvs&&!d.uv&&(d.uv=t.createBuffer());a.hasColors&&!d.color&&(d.color=t.createBuffer()); +b=b.getAttributes();a.hasPositions&&(t.bindBuffer(t.ARRAY_BUFFER,d.position),t.bufferData(t.ARRAY_BUFFER,a.positionArray,t.DYNAMIC_DRAW),L.enableAttribute(b.position),t.vertexAttribPointer(b.position,3,t.FLOAT,!1,0,0));if(a.hasNormals){t.bindBuffer(t.ARRAY_BUFFER,d.normal);if("MeshPhongMaterial"!==c.type&&c.shading===THREE.FlatShading)for(var e=0,f=3*a.count;eh;h++)c.__webglFramebuffer[h]=t.createFramebuffer(),c.__webglRenderbuffer[h]=t.createRenderbuffer(),L.texImage2D(t.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,e,a.width,a.height,0,e,g,null),z(c.__webglFramebuffer[h],a,t.TEXTURE_CUBE_MAP_POSITIVE_X+ +h),A(c.__webglRenderbuffer[h],a);a.generateMipmaps&&d&&t.generateMipmap(t.TEXTURE_CUBE_MAP)}else c.__webglFramebuffer=t.createFramebuffer(),c.__webglRenderbuffer=a.shareDepthFrom?a.shareDepthFrom.__webglRenderbuffer:t.createRenderbuffer(),L.bindTexture(t.TEXTURE_2D,c.__webglTexture),G(t.TEXTURE_2D,a,d),L.texImage2D(t.TEXTURE_2D,0,e,a.width,a.height,0,e,g,null),z(c.__webglFramebuffer,a,t.TEXTURE_2D),a.shareDepthFrom?a.depthBuffer&&!a.stencilBuffer?t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT, +t.RENDERBUFFER,c.__webglRenderbuffer):a.depthBuffer&&a.stencilBuffer&&t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,c.__webglRenderbuffer):A(c.__webglRenderbuffer,a),a.generateMipmaps&&d&&t.generateMipmap(t.TEXTURE_2D);b?L.bindTexture(t.TEXTURE_CUBE_MAP,null):L.bindTexture(t.TEXTURE_2D,null);t.bindRenderbuffer(t.RENDERBUFFER,null);t.bindFramebuffer(t.FRAMEBUFFER,null)}a?(c=$.get(a),b=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,c=a.width,a=a.height, +e=d=0):(b=null,c=Ba,a=Ca,d=Ia,e=Aa);b!==Qa&&(t.bindFramebuffer(t.FRAMEBUFFER,b),t.viewport(d,e,c,a),Qa=b);pb=c;qb=a};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!(a instanceof THREE.WebGLRenderTarget))console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else if($.get(a).__webglFramebuffer)if(a.format!==THREE.RGBAFormat)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format."); +else{var g=!1;$.get(a).__webglFramebuffer!==Qa&&(t.bindFramebuffer(t.FRAMEBUFFER,$.get(a).__webglFramebuffer),g=!0);t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE?t.readPixels(b,c,d,e,t.RGBA,t.UNSIGNED_BYTE,f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.");g&&t.bindFramebuffer(t.FRAMEBUFFER,Qa)}};this.supportsFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' )."); +return W.get("OES_texture_float")};this.supportsHalfFloatTextures=function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return W.get("OES_texture_half_float")};this.supportsStandardDerivatives=function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");return W.get("OES_standard_derivatives")};this.supportsCompressedTextureS3TC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' )."); +return W.get("WEBGL_compressed_texture_s3tc")};this.supportsCompressedTexturePVRTC=function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return W.get("WEBGL_compressed_texture_pvrtc")};this.supportsBlendMinMax=function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return W.get("EXT_blend_minmax")};this.supportsVertexTextures=function(){return ka.vertexTextures}; +this.supportsInstancedArrays=function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");return W.get("ANGLE_instanced_arrays")};this.initMaterial=function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")};this.addPrePlugin=function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")};this.addPostPlugin=function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")}; +this.updateShadowMap=function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")};Object.defineProperties(this,{shadowMapEnabled:{get:function(){return ma.enabled},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");ma.enabled=a}},shadowMapType:{get:function(){return ma.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");ma.type=a}},shadowMapCullFace:{get:function(){return ma.cullFace}, +set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");ma.cullFace=a}},shadowMapDebug:{get:function(){return ma.debug},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapDebug is now .shadowMap.debug.");ma.debug=a}}})}; +THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;c=c||{};this.wrapS=void 0!==c.wrapS?c.wrapS:THREE.ClampToEdgeWrapping;this.wrapT=void 0!==c.wrapT?c.wrapT:THREE.ClampToEdgeWrapping;this.magFilter=void 0!==c.magFilter?c.magFilter:THREE.LinearFilter;this.minFilter=void 0!==c.minFilter?c.minFilter:THREE.LinearMipMapLinearFilter;this.anisotropy=void 0!==c.anisotropy?c.anisotropy:1;this.offset=new THREE.Vector2(0,0);this.repeat=new THREE.Vector2(1, +1);this.format=void 0!==c.format?c.format:THREE.RGBAFormat;this.type=void 0!==c.type?c.type:THREE.UnsignedByteType;this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.generateMipmaps=!0;this.shareDepthFrom=void 0!==c.shareDepthFrom?c.shareDepthFrom:null}; 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()},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.wrapS=a.wrapS;this.wrapT=a.wrapT;this.magFilter=a.magFilter;this.minFilter=a.minFilter;this.anisotropy=a.anisotropy;this.offset.copy(a.offset);this.repeat.copy(a.repeat);this.format=a.format;this.type=a.type;this.depthBuffer= a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.generateMipmaps=a.generateMipmaps;this.shareDepthFrom=a.shareDepthFrom;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.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype); THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube; @@ -583,6 +583,9 @@ THREE.WebGLIndexedBufferRenderer=function(a,b,c){var d,e,g;this.setMode=function c.drawElementsInstancedANGLE(d,a.index.array.length,e,0,a.maxInstancedCount)}}; 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;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 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")); -w.compileShader(G);w.compileShader(N);w.attachShader(D,G);w.attachShader(D,N);w.linkProgram(D);A=D;x=w.getAttribLocation(A,"position");v=w.getAttribLocation(A,"uv");c=w.getUniformLocation(A,"uvOffset");d=w.getUniformLocation(A,"uvScale");e=w.getUniformLocation(A,"rotation");g=w.getUniformLocation(A,"scale");f=w.getUniformLocation(A,"color");h=w.getUniformLocation(A,"map");k=w.getUniformLocation(A,"opacity");l=w.getUniformLocation(A,"modelViewMatrix");n=w.getUniformLocation(A,"projectionMatrix");p= -w.getUniformLocation(A,"fogType");m=w.getUniformLocation(A,"fogDensity");q=w.getUniformLocation(A,"fogNear");s=w.getUniformLocation(A,"fogFar");r=w.getUniformLocation(A,"fogColor");u=w.getUniformLocation(A,"alphaTest");D=document.createElement("canvas");D.width=8;D.height=8;G=D.getContext("2d");G.fillStyle="white";G.fillRect(0,0,8,8);O=new THREE.Texture(D);O.needsUpdate=!0}w.useProgram(A);E.initAttributes();E.enableAttribute(x);E.enableAttribute(v);E.disableUnusedAttributes();E.disable(w.CULL_FACE); -E.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER,B);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,z);w.uniformMatrix4fv(n,!1,F.projectionMatrix.elements);E.activeTexture(w.TEXTURE0);w.uniform1i(h,0);G=D=0;(N=J.fog)?(w.uniform3f(r,N.color.r,N.color.g,N.color.b),N instanceof THREE.Fog?(w.uniform1f(q,N.near),w.uniform1f(s,N.far),w.uniform1i(p,1),G=D=1):N instanceof THREE.FogExp2&&(w.uniform1f(m,N.density),w.uniform1i(p,2),G=D=2)): -(w.uniform1i(p,0),G=D=0);for(var N=0,R=b.length;Ne)return null;var g=[],f=[],h=[],k,l,n;if(0=p--){console.warn("THREE.FontUtils: Warning, unable to triangulate polygon! in Triangulate.process()");break}k=l;e<=k&&(k=0);l=k+1;e<=l&&(l=0);n=l+1;e<=n&&(n=0);var m;a:{var q=m=void 0,s=void 0,r=void 0, -u=void 0,x=void 0,v=void 0,y=void 0,w=void 0,q=a[f[k]].x,s=a[f[k]].y,r=a[f[l]].x,u=a[f[l]].y,x=a[f[n]].x,v=a[f[n]].y;if(1E-10>(r-q)*(v-s)-(u-s)*(x-q))m=!1;else{var E=void 0,B=void 0,z=void 0,A=void 0,O=void 0,L=void 0,C=void 0,P=void 0,J=void 0,F=void 0,J=P=C=w=y=void 0,E=x-r,B=v-u,z=q-x,A=s-v,O=r-q,L=u-s;for(m=0;m(r-q)*(v-s)-(u-s)*(x-q))m=!1;else{var G=void 0,B=void 0,z=void 0,A=void 0,O=void 0,K=void 0,D=void 0,P=void 0,J=void 0,H=void 0,J=P=D=w=y=void 0,G=x-r,B=v-u,z=q-x,A=s-v,O=r-q,K=u-s;for(m=0;mA||A>z)return[];k=l*n-k*p;if(0>k||k>z)return[]}else{if(0d?[]: k===d?f?[]:[g]:a<=d?[g,h]:[g,l]}function e(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return 1E-10f&&(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;cF){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(p=L;pf&&(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;cH){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(p=K;ph;h++)l=k[h].x+":"+k[h].y,l=n[l],void 0!==l&&(k[h]=l);return p.concat()},isClockWise:function(a){return 0>THREE.FontUtils.Triangulate.area(a)},b2p0:function(a,b){var c=1-a;return c*c*b},b2p1:function(a,b){return 2*(1-a)*a*b},b2p2:function(a,b){return a*a*b},b2:function(a,b,c,d){return this.b2p0(a,b)+this.b2p1(a,c)+this.b2p2(a,d)},b3p0:function(a,b){var c=1-a;return c*c*c*b},b3p1:function(a,b){var c=1-a;return 3*c*c*a*b},b3p2:function(a,b){return 3*(1- a)*a*a*b},b3p3:function(a,b){return a*a*a*b},b3:function(a,b,c,d,e){return this.b3p0(a,b)+this.b3p1(a,c)+this.b3p2(a,d)+this.b3p3(a,e)}};THREE.LineCurve=function(a,b){this.v1=a;this.v2=b};THREE.LineCurve.prototype=Object.create(THREE.Curve.prototype);THREE.LineCurve.prototype.constructor=THREE.LineCurve;THREE.LineCurve.prototype.getPoint=function(a){var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};THREE.LineCurve.prototype.getPointAt=function(a){return this.getPoint(a)}; THREE.LineCurve.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};THREE.QuadraticBezierCurve=function(a,b,c){this.v0=a;this.v1=b;this.v2=c};THREE.QuadraticBezierCurve.prototype=Object.create(THREE.Curve.prototype);THREE.QuadraticBezierCurve.prototype.constructor=THREE.QuadraticBezierCurve; @@ -739,8 +741,8 @@ g.interpolate(f,f.time);this.data.hierarchy[a].node.updateMatrix();c.matrixWorld THREE.MorphAnimation=function(a){this.mesh=a;this.frames=a.morphTargetInfluences.length;this.currentTime=0;this.duration=1E3;this.loop=!0;this.currentFrame=this.lastFrame=0;this.isPlaying=!1}; THREE.MorphAnimation.prototype={constructor:THREE.MorphAnimation,play:function(){this.isPlaying=!0},pause:function(){this.isPlaying=!1},update:function(a){if(!1!==this.isPlaying){this.currentTime+=a;!0===this.loop&&this.currentTime>this.duration&&(this.currentTime%=this.duration);this.currentTime=Math.min(this.currentTime,this.duration);var b=this.duration/this.frames;a=Math.floor(this.currentTime/b);var c=this.mesh.morphTargetInfluences;a!==this.currentFrame&&(c[this.lastFrame]=0,c[this.currentFrame]= 1,c[a]=0,this.lastFrame=this.currentFrame,this.currentFrame=a);b=this.currentTime%b/b;c[a]=b;c[this.lastFrame]=1-b}}}; -THREE.BoxGeometry=function(a,b,c,d,e,g){function f(a,b,c,d,e,f,g,r){var u,x=h.widthSegments,v=h.heightSegments,y=e/2,w=f/2,E=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)u="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)u="y",v=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)u="x",x=h.depthSegments;var B=x+1,z=v+1,A=e/x,O=f/v,L=new THREE.Vector3;L[u]=0m;m++){d[0]=p[f[m]];d[1]=p[f[(m+1)%3]];d.sort(g);var q=d.toString();void 0===e[q]?e[q]={vert1:d[0],vert2:d[1],face1:l, face2:void 0}:e[q].face2=l}d=[];for(q in e)if(g=e[q],void 0===g.face2||h[g.face1].normal.dot(h[g.face2].normal)<=c)f=k[g.vert1],d.push(f.x),d.push(f.y),d.push(f.z),f=k[g.vert2],d.push(f.x),d.push(f.y),d.push(f.z);this.addAttribute("position",new THREE.BufferAttribute(new Float32Array(d),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;d=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,1E-10d?-1E-10>f&&(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(H=a.length;0<=--H;){c=H;d=H-1;0>d&&(d=a.length-1);for(var e=0,f=q+2*n,e=0;ed?-1E-10>f&&(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(E=a.length;0<=--E;){c=E;d=E-1;0>d&&(d=a.length-1);for(var e=0,f=q+2*n,e=0;eMath.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[name]( [page:Vector3 origin], [page:Vector3 direction], [page:Float near], [page:Float far] ) {
[page:Vector3 origin] — The origin vector where the ray casts from.
- [page:Vector3 direction] — The direction vector that gives direction to the ray.
+ [page:Vector3 direction] — The direction vector that gives direction to the ray. Should be normalized.
[page:Float near] — All results returned are further away than near. Near can't be negative. Default value is 0.
[page:Float far] — All results returned are closer then far. Far can't be lower then near . Default value is Infinity.
@@ -109,7 +109,7 @@

[method:null set]( [page:Vector3 origin], [page:Vector3 direction] )

[page:Vector3 origin] — The origin vector where the ray casts from.
- [page:Vector3 direction] — The direction vector that gives direction to the ray. + [page:Vector3 direction] — The normalized direction vector that gives direction to the ray.
Updates the ray with a new origin and direction. diff --git a/docs/api/math/Matrix3.html b/docs/api/math/Matrix3.html index db495029c9bdfc9bb064bc1a6eba5f4f10a7b8de..53036b864a0d2bd31ee834e9a4e0395632fd59e3 100644 --- a/docs/api/math/Matrix3.html +++ b/docs/api/math/Matrix3.html @@ -16,26 +16,9 @@

Constructor

-

[name]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33])

+

[name]()

- n11 -- [page:Float]
- n12 -- [page:Float]
- n13 -- [page:Float]
- n21 -- [page:Float]
- n22 -- [page:Float]
- n23 -- [page:Float]
- n31 -- [page:Float]
- n32 -- [page:Float]
- n33 -- [page:Float] -
-
- Initialize the 3x3 matrix with a row-major sequence of values.

- - n11, n12, n13,
- n21, n22, n23,
- n31, n32, n33

- - If no values are sent the matrix will be initialized as an identity matrix. + Creates and initializes the 3x3 matrix to the identity matrix.
@@ -44,7 +27,7 @@

[property:Float32Array elements]

- Float32Array with column-major matrix values. + A column-major list of matrix values.
@@ -60,13 +43,13 @@ array -- [page:Array]
- Transposes this matrix into the supplied array, and returns itself. + Transposes this matrix into the supplied array, and returns itself unchanged.

[method:Float determinant]()

- Returns the matrix's determinant. + Computes and returns the determinant of this matrix.

[method:Matrix3 set]([page:Float n11], [page:Float n12], [page:Float n13], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n31], [page:Float n32], [page:Float n33]) [page:Matrix3 this]

@@ -82,15 +65,15 @@ n33 -- [page:Float]
- Set the 3x3 matrix values to the given row-major sequence of values. + Sets the 3x3 matrix values to the given row-major sequence of values.
-

[method:Matrix3 multiplyScalar]([page:Float scalar]) [page:Matrix3 this]

+

[method:Matrix3 multiplyScalar]([page:Float s]) [page:Matrix3 this]

scalar -- [page:Float]
- Multiply every component of the matrix by a scalar value. + Multiplies every component of the matrix by the scalar value *s*.

[method:Array applyToVector3Array]([page:Array array])

@@ -98,42 +81,42 @@ array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
- Multiply (apply) this matrix to every vector3 in the array. + Multiplies (applies) this matrix to every vector3 in the array.
-

[method:Matrix3 getNormalMatrix]([page:Matrix4 matrix4]) [page:Matrix3 this]

+

[method:Matrix3 getNormalMatrix]([page:Matrix4 m]) [page:Matrix3 this]

- matrix4 -- [page:Matrix4] + m -- [page:Matrix4]
- Set this matrix as the normal matrix of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix. + Sets this matrix as the normal matrix (upper left 3x3)of the passed [page:Matrix4 matrix4]. The normal matrix is the inverse transpose of the matrix *m*.
-

[method:Matrix3 getInverse]([page:Matrix4 matrix4], [page:Boolean throwOnInvertible]) [page:Matrix3 this]

+

[method:Matrix3 getInverse]([page:Matrix4 m], [page:Boolean throwOnInvertible]) [page:Matrix3 this]

- matrix4 -- [page:Matrix4]
+ m -- [page:Matrix4]
throwOnInvertible -- [Page:Boolean] If true, throw an error if the matrix is invertible.
Set this matrix to the inverse of the passed matrix.
-

[method:Matrix3 copy]([page:Matrix3 matrix]) [page:Matrix3 this]

+

[method:Matrix3 copy]([page:Matrix3 m]) [page:Matrix3 this]

- matrix -- [page:Matrix3] + m -- [page:Matrix4]
- Copy the values of the passed matrix. + Copies the values of matrix *m* into this matrix.

[method:Matrix3 clone]()

- Create a copy of the matrix. + Creates a copy of this matrix.

[method:Matrix3 identity]() [page:Matrix3 this]

- Set as an identity matrix.

+ Resets this matrix to identity.

1, 0, 0
0, 1, 0
diff --git a/docs/api/math/Matrix4.html b/docs/api/math/Matrix4.html index 353f194fbd04e7c32fdd110ebdd1129c6bfc262e..d92b919a645c17ec87da95c036c34209e30142b6 100644 --- a/docs/api/math/Matrix4.html +++ b/docs/api/math/Matrix4.html @@ -39,10 +39,10 @@

Constructor

-

[name]( [page:Float n11], [page:Float n12], [page:Float n13], [page:Float n14], [page:Float n21], [page:Float n22], [page:Float n23], [page:Float n24], [page:Float n31], [page:Float n32], [page:Float n33], [page:Float n34], [page:Float n41], [page:Float n42], [page:Float n43], [page:Float n44] )

+

[name]()

- Initialises the matrix with the supplied row-major values n11..n44, or just creates an identity matrix if no values are passed. + Creates and initializes the matrix to the identity matrix.

Properties

@@ -64,7 +64,7 @@

[method:Matrix4 copy]( [page:Matrix4 m] ) [page:Matrix4 this]

- Copies a matrix *m* into this matrix. + Copies the values of matrix *m* into this matrix.

[method:Matrix4 copyPosition]( [page:Matrix4 m] ) [page:Matrix4 this]

@@ -72,12 +72,12 @@ Copies the translation component of the supplied matrix *m* into this matrix translation component.
-

[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]

+

[method:Matrix4 makeBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]

Creates the basis matrix consisting of the three provided axis vectors. Returns the current matrix.
-

[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 yAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]

+

[method:Matrix4 extractBasis]( [page:Vector3 xAxis], [page:Vector3 zAxis], [page:Vector3 zAxis] ) [page:Matrix4 this]

Extracts basis of into the three axis vectors provided. Returns the current matrix.
@@ -110,12 +110,12 @@

[method:Matrix4 multiplyScalar]( [page:Float s] ) [page:Matrix4 this]

- Multiplies this matrix by *s*. + Multiplies every component of the matrix by a scalar value *s*.

[method:Float determinant]()

- Computes determinant of this matrix.
+ Computes and returns the determinant of this matrix.
Based on [link:http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm]
@@ -142,7 +142,7 @@

[method:Matrix4 makeRotationFromEuler]( [page:Euler euler] ) [page:Matrix4 this]

- euler — Rotation vector followed by order of rotations. Eg. "XYZ". + euler — Rotation vector followed by order of rotations, e.g., "XYZ".
Sets the rotation submatrix of this matrix to the rotation specified by Euler angles, the rest of the matrix is identity.
@@ -230,7 +230,7 @@

[method:Matrix4 clone]()

- Clones this matrix. + Creates a copy of this matrix.

[method:Array applyToVector3Array]([page:Array a])

@@ -238,12 +238,12 @@ array -- An array in the form [vector1x, vector1y, vector1z, vector2x, vector2y, vector2z, ...]
- Multiply (apply) this matrix to every vector3 in the array. + Multiplies (applies) this matrix to every vector3 in the array.

[method:Float getMaxScaleOnAxis]()

- Gets the max scale value of the 3 axes. + Gets the maximum scale value of the 3 axes.

Source

diff --git a/editor/index.html b/editor/index.html index 8cddd389f8263c3e746badc4245567b5a7603dfc..72cf505f52f0129e918762bf1a98e8e521df9053 100644 --- a/editor/index.html +++ b/editor/index.html @@ -112,6 +112,8 @@ + + diff --git a/editor/js/Loader.js b/editor/js/Loader.js index 6e65187619ab221ee2f505c05ccdb99e07b96235..fb19f7217b0948d1f04ceea37c01cf3b18a45d28 100644 --- a/editor/js/Loader.js +++ b/editor/js/Loader.js @@ -7,6 +7,8 @@ var Loader = function ( editor ) { var scope = this; var signals = editor.signals; + this.texturePath = ''; + this.loadFile = function ( file ) { var filename = file.name; @@ -386,6 +388,8 @@ var Loader = function ( editor ) { } else if ( data.metadata.type.toLowerCase() === 'geometry' ) { var loader = new THREE.JSONLoader(); + loader.setTexturePath( scope.texturePath ); + var result = loader.parse( data ); var geometry = result.geometry; @@ -432,6 +436,8 @@ var Loader = function ( editor ) { } else if ( data.metadata.type.toLowerCase() === 'object' ) { var loader = new THREE.ObjectLoader(); + loader.setTexturePath( scope.texturePath ); + var result = loader.parse( data ); if ( result instanceof THREE.Scene ) { diff --git a/editor/js/Menubar.Add.js b/editor/js/Menubar.Add.js index c8d232234b1cd139f3a19156dcce72e673425eb8..e5751fa9320aa3ddeca60ba64e9a441de0242feb 100644 --- a/editor/js/Menubar.Add.js +++ b/editor/js/Menubar.Add.js @@ -236,6 +236,34 @@ Menubar.Add = function ( editor ) { } ); options.add( option ); + // Teapot + + var option = new UI.Panel(); + option.setClass( 'option' ); + option.setTextContent( 'Teapot' ); + option.onClick( function () { + + var size = 50; + var segments = 10; + var bottom = true; + var lid = true; + var body = true; + var fitLid = false; + var blinnScale = true; + + var material = new THREE.MeshPhongMaterial(); + material.side = 2; + + var geometry = new THREE.TeapotBufferGeometry( size, segments, bottom, lid, body, fitLid, blinnScale ); + var mesh = new THREE.Mesh( geometry, material ); + mesh.name = 'Teapot ' + ( ++ meshCount ); + + editor.addObject( mesh ); + editor.select( mesh ); + + } ); + options.add( option ); + // Sprite var option = new UI.Panel(); diff --git a/editor/js/Sidebar.Geometry.TeapotBufferGeometry.js b/editor/js/Sidebar.Geometry.TeapotBufferGeometry.js new file mode 100644 index 0000000000000000000000000000000000000000..bcbd97bfdb68856b909113f80331d0fcb9775979 --- /dev/null +++ b/editor/js/Sidebar.Geometry.TeapotBufferGeometry.js @@ -0,0 +1,103 @@ +/** + * @author tschw + */ + +Sidebar.Geometry.TeapotBufferGeometry = function ( signals, object ) { + + var container = new UI.Panel(); + + var parameters = object.geometry.parameters; + + // size + + var sizeRow = new UI.Panel(); + var size = new UI.Number( parameters.size ).onChange( update ); + + sizeRow.add( new UI.Text( 'Size' ).setWidth( '90px' ) ); + sizeRow.add( size ); + + container.add( sizeRow ); + + // segments + + var segmentsRow = new UI.Panel(); + var segments = new UI.Integer( parameters.segments ).setRange( 1, Infinity ).onChange( update ); + + segmentsRow.add( new UI.Text( 'Segments' ).setWidth( '90px' ) ); + segmentsRow.add( segments ); + + container.add( segmentsRow ); + + // bottom + + var bottomRow = new UI.Panel(); + var bottom = new UI.Checkbox( parameters.bottom ).onChange( update ); + + bottomRow.add( new UI.Text( 'Bottom' ).setWidth( '90px' ) ); + bottomRow.add( bottom ); + + container.add( bottomRow ); + + // lid + + var lidRow = new UI.Panel(); + var lid = new UI.Checkbox( parameters.lid ).onChange( update ); + + lidRow.add( new UI.Text( 'Lid' ).setWidth( '90px' ) ); + lidRow.add( lid ); + + container.add( lidRow ); + + // body + + var bodyRow = new UI.Panel(); + var body = new UI.Checkbox( parameters.body ).onChange( update ); + + bodyRow.add( new UI.Text( 'Body' ).setWidth( '90px' ) ); + bodyRow.add( body ); + + container.add( bodyRow ); + + // fitted lid + + var fitLidRow = new UI.Panel(); + var fitLid = new UI.Checkbox( parameters.fitLid ).onChange( update ); + + fitLidRow.add( new UI.Text( 'Fitted Lid' ).setWidth( '90px' ) ); + fitLidRow.add( fitLid ); + + container.add( fitLidRow ); + + // blinn-sized + + var blinnRow = new UI.Panel(); + var blinn = new UI.Checkbox( parameters.blinn ).onChange( update ); + + blinnRow.add( new UI.Text( 'Blinn-scaled' ).setWidth( '90px' ) ); + blinnRow.add( blinn ); + + container.add( blinnRow ); + + function update() { + + object.geometry.dispose(); + + object.geometry = new THREE.TeapotBufferGeometry( + size.getValue(), + segments.getValue(), + bottom.getValue(), + lid.getValue(), + body.getValue(), + fitLid.getValue(), + blinn.getValue() + ); + + object.geometry.computeBoundingSphere(); + + signals.geometryChanged.dispatch( object ); + + } + + return container; + +} diff --git a/editor/js/Sidebar.Material.js b/editor/js/Sidebar.Material.js index d31cb04069a93aa3c29b7642ca607ba6c805e45b..a526e1221a90e971019326e16b4201cbdeadced1 100644 --- a/editor/js/Sidebar.Material.js +++ b/editor/js/Sidebar.Material.js @@ -551,7 +551,7 @@ Sidebar.Material = function ( editor ) { if ( objectHasUvs ) { - material.lightMap = specularMapEnabled ? materialLightMap.getValue() : null; + material.lightMap = lightMapEnabled ? materialLightMap.getValue() : null; material.needsUpdate = true; } else { @@ -683,7 +683,7 @@ Sidebar.Material = function ( editor ) { }; - function refreshUi(resetTextureSelectors) { + function refreshUi( resetTextureSelectors ) { var material = currentObject.material; diff --git a/editor/js/Viewport.Info.js b/editor/js/Viewport.Info.js index 67ebd1e2350e468707743e08bd44cccd6686d1fc..ff0ed3942bccbee4dea26d93c3019144d2477766 100644 --- a/editor/js/Viewport.Info.js +++ b/editor/js/Viewport.Info.js @@ -53,15 +53,15 @@ Viewport.Info = function ( editor ) { } else if ( geometry instanceof THREE.BufferGeometry ) { - vertices += geometry.attributes.position.array.length / 3; + if ( geometry.index !== null ) { - if ( geometry.attributes.index !== undefined ) { - - triangles += geometry.attributes.index.array.length / 3; + vertices += geometry.index.count * 3; + triangles += geometry.index.count; } else { - triangles += geometry.attributes.position.array.length / 9; + vertices += geometry.attributes.position.count; + triangles += geometry.attributes.position.count / 3; } diff --git a/examples/index.html b/examples/index.html index 798fb109b4981d380ca1b8f3e5ccb2d9d6318c20..7450db5d1b7fbdf10fcfaaa846c7587807041e56 100644 --- a/examples/index.html +++ b/examples/index.html @@ -381,6 +381,7 @@ "webgl_buffergeometry_lines_indexed", "webgl_buffergeometry_particles", "webgl_buffergeometry_rawshader", + "webgl_buffergeometry_teapot", "webgl_buffergeometry_uint", "webgl_custom_attributes", "webgl_custom_attributes_lines", diff --git a/examples/js/controls/TransformControls.js b/examples/js/controls/TransformControls.js index 6ea5f43a93f65e4bc5245607e96b4af188134032..990d49b315a3e815d7e0423ed69d749571ca2345 100644 --- a/examples/js/controls/TransformControls.js +++ b/examples/js/controls/TransformControls.js @@ -806,7 +806,7 @@ function onPointerHover( event ) { - if ( scope.object === undefined || _dragging === true ) return; + if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return; var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event; @@ -834,7 +834,7 @@ function onPointerDown( event ) { - if ( scope.object === undefined || _dragging === true ) return; + if ( scope.object === undefined || _dragging === true || ( event.button !== undefined && event.button !== 0 ) ) return; var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event; @@ -884,7 +884,7 @@ function onPointerMove( event ) { - if ( scope.object === undefined || scope.axis === null || _dragging === false ) return; + if ( scope.object === undefined || scope.axis === null || _dragging === false || ( event.button !== undefined && event.button !== 0 ) ) return; var pointer = event.changedTouches ? event.changedTouches[ 0 ] : event; @@ -1055,6 +1055,8 @@ function onPointerUp( event ) { + if ( event.button !== undefined && event.button !== 0 ) return; + if ( _dragging && ( scope.axis !== null ) ) { mouseUpEvent.mode = _mode; diff --git a/examples/js/geometries/TeapotBufferGeometry.js b/examples/js/geometries/TeapotBufferGeometry.js new file mode 100644 index 0000000000000000000000000000000000000000..4f6b3a6d129695f1b0d8b8ac5517ed3a2228adee --- /dev/null +++ b/examples/js/geometries/TeapotBufferGeometry.js @@ -0,0 +1,751 @@ +/** + * @author Eric Haines / http://erichaines.com/ + * + * Tessellates the famous Utah teapot database by Martin Newell into triangles. + * + * THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn ) + * + * defaults: size = 50, segments = 10, bottom = true, lid = true, body = true, + * fitLid = false, blinn = true + * + * size is a relative scale: I've scaled the teapot to fit vertically between -1 and 1. + * Think of it as a "radius". + * segments - number of line segments to subdivide each patch edge; + * 1 is possible but gives degenerates, so two is the real minimum. + * bottom - boolean, if true (default) then the bottom patches are added. Some consider + * adding the bottom heresy, so set this to "false" to adhere to the One True Way. + * lid - to remove the lid and look inside, set to true. + * body - to remove the body and leave the lid, set this and "bottom" to false. + * fitLid - the lid is a tad small in the original. This stretches it a bit so you can't + * see the teapot's insides through the gap. + * blinn - Jim Blinn scaled the original data vertically by dividing by about 1.3 to look + * nicer. If you want to see the original teapot, similar to the real-world model, set + * this to false. True by default. + * See http://en.wikipedia.org/wiki/File:Original_Utah_Teapot.jpg for the original + * real-world teapot (from http://en.wikipedia.org/wiki/Utah_teapot). + * + * Note that the bottom (the last four patches) is not flat - blame Frank Crow, not me. + * + * The teapot should normally be rendered as a double sided object, since for some + * patches both sides can be seen, e.g., the gap around the lid and inside the spout. + * + * Segments 'n' determines the number of triangles output. + * Total triangles = 32*2*n*n - 8*n [degenerates at the top and bottom cusps are deleted] + * + * size_factor # triangles + * 1 56 + * 2 240 + * 3 552 + * 4 992 + * + * 10 6320 + * 20 25440 + * 30 57360 + * + * Code converted from my ancient SPD software, http://tog.acm.org/resources/SPD/ + * Created for the Udacity course "Interactive Rendering", http://bit.ly/ericity + * Lesson: https://www.udacity.com/course/viewer#!/c-cs291/l-68866048/m-106482448 + * YouTube video on teapot history: https://www.youtube.com/watch?v=DxMfblPzFNc + * + * See https://en.wikipedia.org/wiki/Utah_teapot for the history of the teapot + * + */ +/*global THREE */ + +THREE.TeapotBufferGeometry = function ( size, segments, bottom, lid, body, fitLid, blinn ) { + + "use strict"; + + // 32 * 4 * 4 Bezier spline patches + var teapotPatches = [ +/*rim*/ +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, +3,16,17,18,7,19,20,21,11,22,23,24,15,25,26,27, +18,28,29,30,21,31,32,33,24,34,35,36,27,37,38,39, +30,40,41,0,33,42,43,4,36,44,45,8,39,46,47,12, +/*body*/ +12,13,14,15,48,49,50,51,52,53,54,55,56,57,58,59, +15,25,26,27,51,60,61,62,55,63,64,65,59,66,67,68, +27,37,38,39,62,69,70,71,65,72,73,74,68,75,76,77, +39,46,47,12,71,78,79,48,74,80,81,52,77,82,83,56, +56,57,58,59,84,85,86,87,88,89,90,91,92,93,94,95, +59,66,67,68,87,96,97,98,91,99,100,101,95,102,103,104, +68,75,76,77,98,105,106,107,101,108,109,110,104,111,112,113, +77,82,83,56,107,114,115,84,110,116,117,88,113,118,119,92, +/*handle*/ +120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135, +123,136,137,120,127,138,139,124,131,140,141,128,135,142,143,132, +132,133,134,135,144,145,146,147,148,149,150,151,68,152,153,154, +135,142,143,132,147,155,156,144,151,157,158,148,154,159,160,68, +/*spout*/ +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +164,177,178,161,168,179,180,165,172,181,182,169,176,183,184,173, +173,174,175,176,185,186,187,188,189,190,191,192,193,194,195,196, +176,183,184,173,188,197,198,185,192,199,200,189,196,201,202,193, +/*lid*/ +203,203,203,203,204,205,206,207,208,208,208,208,209,210,211,212, +203,203,203,203,207,213,214,215,208,208,208,208,212,216,217,218, +203,203,203,203,215,219,220,221,208,208,208,208,218,222,223,224, +203,203,203,203,221,225,226,204,208,208,208,208,224,227,228,209, +209,210,211,212,229,230,231,232,233,234,235,236,237,238,239,240, +212,216,217,218,232,241,242,243,236,244,245,246,240,247,248,249, +218,222,223,224,243,250,251,252,246,253,254,255,249,256,257,258, +224,227,228,209,252,259,260,229,255,261,262,233,258,263,264,237, +/*bottom*/ +265,265,265,265,266,267,268,269,270,271,272,273,92,119,118,113, +265,265,265,265,269,274,275,276,273,277,278,279,113,112,111,104, +265,265,265,265,276,280,281,282,279,283,284,285,104,103,102,95, +265,265,265,265,282,286,287,266,285,288,289,270,95,94,93,92 + ] ; + + var teapotVertices = [ +1.4,0,2.4, +1.4,-0.784,2.4, +0.784,-1.4,2.4, +0,-1.4,2.4, +1.3375,0,2.53125, +1.3375,-0.749,2.53125, +0.749,-1.3375,2.53125, +0,-1.3375,2.53125, +1.4375,0,2.53125, +1.4375,-0.805,2.53125, +0.805,-1.4375,2.53125, +0,-1.4375,2.53125, +1.5,0,2.4, +1.5,-0.84,2.4, +0.84,-1.5,2.4, +0,-1.5,2.4, +-0.784,-1.4,2.4, +-1.4,-0.784,2.4, +-1.4,0,2.4, +-0.749,-1.3375,2.53125, +-1.3375,-0.749,2.53125, +-1.3375,0,2.53125, +-0.805,-1.4375,2.53125, +-1.4375,-0.805,2.53125, +-1.4375,0,2.53125, +-0.84,-1.5,2.4, +-1.5,-0.84,2.4, +-1.5,0,2.4, +-1.4,0.784,2.4, +-0.784,1.4,2.4, +0,1.4,2.4, +-1.3375,0.749,2.53125, +-0.749,1.3375,2.53125, +0,1.3375,2.53125, +-1.4375,0.805,2.53125, +-0.805,1.4375,2.53125, +0,1.4375,2.53125, +-1.5,0.84,2.4, +-0.84,1.5,2.4, +0,1.5,2.4, +0.784,1.4,2.4, +1.4,0.784,2.4, +0.749,1.3375,2.53125, +1.3375,0.749,2.53125, +0.805,1.4375,2.53125, +1.4375,0.805,2.53125, +0.84,1.5,2.4, +1.5,0.84,2.4, +1.75,0,1.875, +1.75,-0.98,1.875, +0.98,-1.75,1.875, +0,-1.75,1.875, +2,0,1.35, +2,-1.12,1.35, +1.12,-2,1.35, +0,-2,1.35, +2,0,0.9, +2,-1.12,0.9, +1.12,-2,0.9, +0,-2,0.9, +-0.98,-1.75,1.875, +-1.75,-0.98,1.875, +-1.75,0,1.875, +-1.12,-2,1.35, +-2,-1.12,1.35, +-2,0,1.35, +-1.12,-2,0.9, +-2,-1.12,0.9, +-2,0,0.9, +-1.75,0.98,1.875, +-0.98,1.75,1.875, +0,1.75,1.875, +-2,1.12,1.35, +-1.12,2,1.35, +0,2,1.35, +-2,1.12,0.9, +-1.12,2,0.9, +0,2,0.9, +0.98,1.75,1.875, +1.75,0.98,1.875, +1.12,2,1.35, +2,1.12,1.35, +1.12,2,0.9, +2,1.12,0.9, +2,0,0.45, +2,-1.12,0.45, +1.12,-2,0.45, +0,-2,0.45, +1.5,0,0.225, +1.5,-0.84,0.225, +0.84,-1.5,0.225, +0,-1.5,0.225, +1.5,0,0.15, +1.5,-0.84,0.15, +0.84,-1.5,0.15, +0,-1.5,0.15, +-1.12,-2,0.45, +-2,-1.12,0.45, +-2,0,0.45, +-0.84,-1.5,0.225, +-1.5,-0.84,0.225, +-1.5,0,0.225, +-0.84,-1.5,0.15, +-1.5,-0.84,0.15, +-1.5,0,0.15, +-2,1.12,0.45, +-1.12,2,0.45, +0,2,0.45, +-1.5,0.84,0.225, +-0.84,1.5,0.225, +0,1.5,0.225, +-1.5,0.84,0.15, +-0.84,1.5,0.15, +0,1.5,0.15, +1.12,2,0.45, +2,1.12,0.45, +0.84,1.5,0.225, +1.5,0.84,0.225, +0.84,1.5,0.15, +1.5,0.84,0.15, +-1.6,0,2.025, +-1.6,-0.3,2.025, +-1.5,-0.3,2.25, +-1.5,0,2.25, +-2.3,0,2.025, +-2.3,-0.3,2.025, +-2.5,-0.3,2.25, +-2.5,0,2.25, +-2.7,0,2.025, +-2.7,-0.3,2.025, +-3,-0.3,2.25, +-3,0,2.25, +-2.7,0,1.8, +-2.7,-0.3,1.8, +-3,-0.3,1.8, +-3,0,1.8, +-1.5,0.3,2.25, +-1.6,0.3,2.025, +-2.5,0.3,2.25, +-2.3,0.3,2.025, +-3,0.3,2.25, +-2.7,0.3,2.025, +-3,0.3,1.8, +-2.7,0.3,1.8, +-2.7,0,1.575, +-2.7,-0.3,1.575, +-3,-0.3,1.35, +-3,0,1.35, +-2.5,0,1.125, +-2.5,-0.3,1.125, +-2.65,-0.3,0.9375, +-2.65,0,0.9375, +-2,-0.3,0.9, +-1.9,-0.3,0.6, +-1.9,0,0.6, +-3,0.3,1.35, +-2.7,0.3,1.575, +-2.65,0.3,0.9375, +-2.5,0.3,1.125, +-1.9,0.3,0.6, +-2,0.3,0.9, +1.7,0,1.425, +1.7,-0.66,1.425, +1.7,-0.66,0.6, +1.7,0,0.6, +2.6,0,1.425, +2.6,-0.66,1.425, +3.1,-0.66,0.825, +3.1,0,0.825, +2.3,0,2.1, +2.3,-0.25,2.1, +2.4,-0.25,2.025, +2.4,0,2.025, +2.7,0,2.4, +2.7,-0.25,2.4, +3.3,-0.25,2.4, +3.3,0,2.4, +1.7,0.66,0.6, +1.7,0.66,1.425, +3.1,0.66,0.825, +2.6,0.66,1.425, +2.4,0.25,2.025, +2.3,0.25,2.1, +3.3,0.25,2.4, +2.7,0.25,2.4, +2.8,0,2.475, +2.8,-0.25,2.475, +3.525,-0.25,2.49375, +3.525,0,2.49375, +2.9,0,2.475, +2.9,-0.15,2.475, +3.45,-0.15,2.5125, +3.45,0,2.5125, +2.8,0,2.4, +2.8,-0.15,2.4, +3.2,-0.15,2.4, +3.2,0,2.4, +3.525,0.25,2.49375, +2.8,0.25,2.475, +3.45,0.15,2.5125, +2.9,0.15,2.475, +3.2,0.15,2.4, +2.8,0.15,2.4, +0,0,3.15, +0.8,0,3.15, +0.8,-0.45,3.15, +0.45,-0.8,3.15, +0,-0.8,3.15, +0,0,2.85, +0.2,0,2.7, +0.2,-0.112,2.7, +0.112,-0.2,2.7, +0,-0.2,2.7, +-0.45,-0.8,3.15, +-0.8,-0.45,3.15, +-0.8,0,3.15, +-0.112,-0.2,2.7, +-0.2,-0.112,2.7, +-0.2,0,2.7, +-0.8,0.45,3.15, +-0.45,0.8,3.15, +0,0.8,3.15, +-0.2,0.112,2.7, +-0.112,0.2,2.7, +0,0.2,2.7, +0.45,0.8,3.15, +0.8,0.45,3.15, +0.112,0.2,2.7, +0.2,0.112,2.7, +0.4,0,2.55, +0.4,-0.224,2.55, +0.224,-0.4,2.55, +0,-0.4,2.55, +1.3,0,2.55, +1.3,-0.728,2.55, +0.728,-1.3,2.55, +0,-1.3,2.55, +1.3,0,2.4, +1.3,-0.728,2.4, +0.728,-1.3,2.4, +0,-1.3,2.4, +-0.224,-0.4,2.55, +-0.4,-0.224,2.55, +-0.4,0,2.55, +-0.728,-1.3,2.55, +-1.3,-0.728,2.55, +-1.3,0,2.55, +-0.728,-1.3,2.4, +-1.3,-0.728,2.4, +-1.3,0,2.4, +-0.4,0.224,2.55, +-0.224,0.4,2.55, +0,0.4,2.55, +-1.3,0.728,2.55, +-0.728,1.3,2.55, +0,1.3,2.55, +-1.3,0.728,2.4, +-0.728,1.3,2.4, +0,1.3,2.4, +0.224,0.4,2.55, +0.4,0.224,2.55, +0.728,1.3,2.55, +1.3,0.728,2.55, +0.728,1.3,2.4, +1.3,0.728,2.4, +0,0,0, +1.425,0,0, +1.425,0.798,0, +0.798,1.425,0, +0,1.425,0, +1.5,0,0.075, +1.5,0.84,0.075, +0.84,1.5,0.075, +0,1.5,0.075, +-0.798,1.425,0, +-1.425,0.798,0, +-1.425,0,0, +-0.84,1.5,0.075, +-1.5,0.84,0.075, +-1.5,0,0.075, +-1.425,-0.798,0, +-0.798,-1.425,0, +0,-1.425,0, +-1.5,-0.84,0.075, +-0.84,-1.5,0.075, +0,-1.5,0.075, +0.798,-1.425,0, +1.425,-0.798,0, +0.84,-1.5,0.075, +1.5,-0.84,0.075 + ] ; + + THREE.BufferGeometry.call( this ); + + this.type = 'TeapotBufferGeometry'; + + this.parameters = { + size: size, + segments: segments, + bottom: bottom, + lid: lid, + body: body, + fitLid: fitLid, + blinn: blinn + }; + + size = size || 50; + + // number of segments per patch + segments = segments !== undefined ? Math.max( 2, Math.floor( segments ) || 10 ) : 10; + + // which parts should be visible + bottom = bottom === undefined ? true : bottom; + lid = lid === undefined ? true : lid; + body = body === undefined ? true : body; + + // Should the lid be snug? It's not traditional, so off by default + fitLid = fitLid === undefined ? false : fitLid; + + // Jim Blinn scaled the teapot down in size by about 1.3 for + // some rendering tests. He liked the new proportions that he kept + // the data in this form. The model was distributed with these new + // proportions and became the norm. Trivia: comparing images of the + // real teapot and the computer model, the ratio for the bowl of the + // real teapot is more like 1.25, but since 1.3 is the traditional + // value given, we use it here. + var blinnScale = 1.3; + blinn = blinn === undefined ? true : blinn; + + // scale the size to be the real scaling factor + var maxHeight = 3.15 * ( blinn ? 1 : blinnScale ); + + var maxHeight2 = maxHeight / 2; + var trueSize = size / maxHeight2; + + // Number of elements depends on what is needed. Subtract degenerate + // triangles at tip of bottom and lid out in advance. + var numTriangles = bottom ? ( 8 * segments - 4 ) * segments : 0; + numTriangles += lid ? ( 16 * segments - 4 ) * segments : 0; + numTriangles += body ? 40 * segments * segments : 0; + + var indices = new Uint32Array( numTriangles * 3 ); + + var numVertices = bottom ? 4 : 0; + numVertices += lid ? 8 : 0; + numVertices += body ? 20 : 0; + numVertices *= ( segments + 1 ) * ( segments + 1 ); + + var vertices = new Float32Array( numVertices * 3 ); + var normals = new Float32Array( numVertices * 3 ); + var uvs = new Float32Array( numVertices * 2 ); + + // Bezier form + var ms = new THREE.Matrix4(); + ms.set( -1.0, 3.0, -3.0, 1.0, + 3.0, -6.0, 3.0, 0.0, + -3.0, 3.0, 0.0, 0.0, + 1.0, 0.0, 0.0, 0.0 ) ; + + var g = []; + var i, r, c; + + var sp = []; + var tp = []; + var dsp = []; + var dtp = []; + + // M * G * M matrix, sort of see + // http://www.cs.helsinki.fi/group/goa/mallinnus/curves/surfaces.html + var mgm = []; + + var vert = []; + var sdir = []; + var tdir = []; + + var norm = new THREE.Vector3(); + + var tcoord; + + var sstep, tstep; + var vertPerRow, eps; + + var s, t, sval, tval, p, dsval, dtval; + + var normOut = new THREE.Vector3(); + var v1, v2, v3, v4; + + var gmx = new THREE.Matrix4(); + var tmtx = new THREE.Matrix4(); + + var vsp = new THREE.Vector4(); + var vtp = new THREE.Vector4(); + var vdsp = new THREE.Vector4(); + var vdtp = new THREE.Vector4(); + + var vsdir = new THREE.Vector3(); + var vtdir = new THREE.Vector3(); + + var mst = ms.clone(); + mst.transpose(); + + // internal function: test if triangle has any matching vertices; + // if so, don't save triangle, since it won't display anything. + var notDegenerate = function ( vtx1, vtx2, vtx3 ) { + + // if any vertex matches, return false + return ! ( ( ( vertices[ vtx1 * 3 ] === vertices[ vtx2 * 3 ] ) && + ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx2 * 3 + 1 ] ) && + ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx2 * 3 + 2 ] ) ) || + ( ( vertices[ vtx1 * 3 ] === vertices[ vtx3 * 3 ] ) && + ( vertices[ vtx1 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) && + ( vertices[ vtx1 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) || + ( ( vertices[ vtx2 * 3 ] === vertices[ vtx3 * 3 ] ) && + ( vertices[ vtx2 * 3 + 1 ] === vertices[ vtx3 * 3 + 1 ] ) && + ( vertices[ vtx2 * 3 + 2 ] === vertices[ vtx3 * 3 + 2 ] ) ) ); + + }; + + + for ( i = 0; i < 3; i ++ ) + { + + mgm[ i ] = new THREE.Matrix4(); + + } + + var minPatches = body ? 0 : 20; + var maxPatches = bottom ? 32 : 28; + + vertPerRow = segments + 1; + + eps = 0.0000001; + + var surfCount = 0; + + var vertCount = 0; + var normCount = 0; + var uvCount = 0; + + var indexCount = 0; + + for ( var surf = minPatches ; surf < maxPatches ; surf ++ ) { + + // lid is in the middle of the data, patches 20-27, + // so ignore it for this part of the loop if the lid is not desired + if ( lid || ( surf < 20 || surf >= 28 ) ) { + + // get M * G * M matrix for x,y,z + for ( i = 0 ; i < 3 ; i ++ ) { + + // get control patches + for ( r = 0 ; r < 4 ; r ++ ) { + + for ( c = 0 ; c < 4 ; c ++ ) { + + // transposed + g[ c * 4 + r ] = teapotVertices[ teapotPatches[ surf * 16 + r * 4 + c ] * 3 + i ] ; + + // is the lid to be made larger, and is this a point on the lid + // that is X or Y? + if ( fitLid && ( surf >= 20 && surf < 28 ) && ( i !== 2 ) ) { + + // increase XY size by 7.7%, found empirically. I don't + // increase Z so that the teapot will continue to fit in the + // space -1 to 1 for Y (Y is up for the final model). + g[ c * 4 + r ] *= 1.077; + + } + + // Blinn "fixed" the teapot by dividing Z by blinnScale, and that's the + // data we now use. The original teapot is taller. Fix it: + if ( ! blinn && ( i === 2 ) ) { + + g[ c * 4 + r ] *= blinnScale; + + } + + } + + } + + gmx.set( g[ 0 ], g[ 1 ], g[ 2 ], g[ 3 ], g[ 4 ], g[ 5 ], g[ 6 ], g[ 7 ], g[ 8 ], g[ 9 ], g[ 10 ], g[ 11 ], g[ 12 ], g[ 13 ], g[ 14 ], g[ 15 ] ); + + tmtx.multiplyMatrices( gmx, ms ); + mgm[ i ].multiplyMatrices( mst, tmtx ); + + } + + // step along, get points, and output + for ( sstep = 0 ; sstep <= segments ; sstep ++ ) { + + s = sstep / segments; + + for ( tstep = 0 ; tstep <= segments ; tstep ++ ) { + + t = tstep / segments; + + // point from basis + // get power vectors and their derivatives + for ( p = 4, sval = tval = 1.0 ; p -- ; ) { + + sp[ p ] = sval ; + tp[ p ] = tval ; + sval *= s ; + tval *= t ; + + if ( p === 3 ) { + + dsp[ p ] = dtp[ p ] = 0.0 ; + dsval = dtval = 1.0 ; + + } else { + + dsp[ p ] = dsval * ( 3 - p ) ; + dtp[ p ] = dtval * ( 3 - p ) ; + dsval *= s ; + dtval *= t ; + + } + + } + + vsp.fromArray( sp ); + vtp.fromArray( tp ); + vdsp.fromArray( dsp ); + vdtp.fromArray( dtp ); + + // do for x,y,z + for ( i = 0 ; i < 3 ; i ++ ) { + + // multiply power vectors times matrix to get value + tcoord = vsp.clone(); + tcoord.applyMatrix4( mgm[ i ] ); + vert[ i ] = tcoord.dot( vtp ); + + // get s and t tangent vectors + tcoord = vdsp.clone(); + tcoord.applyMatrix4( mgm[ i ] ); + sdir[ i ] = tcoord.dot( vtp ) ; + + tcoord = vsp.clone(); + tcoord.applyMatrix4( mgm[ i ] ); + tdir[ i ] = tcoord.dot( vdtp ) ; + + } + + // find normal + vsdir.fromArray( sdir ); + vtdir.fromArray( tdir ); + norm.crossVectors( vtdir, vsdir ); + norm.normalize(); + + // if X and Z length is 0, at the cusp, so point the normal up or down, depending on patch number + if ( vert[ 0 ] === 0 && vert[ 1 ] === 0 ) + { + + // if above the middle of the teapot, normal points up, else down + normOut.set( 0, vert[ 2 ] > maxHeight2 ? 1 : - 1, 0 ); + + } + else + { + + // standard output: rotate on X axis + normOut.set( norm.x, norm.z, - norm.y ); + + } + + // store it all + vertices[ vertCount ++ ] = trueSize * vert[ 0 ]; + vertices[ vertCount ++ ] = trueSize * ( vert[ 2 ] - maxHeight2 ); + vertices[ vertCount ++ ] = - trueSize * vert[ 1 ]; + + normals[ normCount ++ ] = normOut.x; + normals[ normCount ++ ] = normOut.y; + normals[ normCount ++ ] = normOut.z; + + uvs[ uvCount ++ ] = 1 - t; + uvs[ uvCount ++ ] = 1 - s; + + } + + } + + // save the faces + for ( sstep = 0 ; sstep < segments ; sstep ++ ) { + + for ( tstep = 0 ; tstep < segments ; tstep ++ ) { + + v1 = surfCount * vertPerRow * vertPerRow + sstep * vertPerRow + tstep; + v2 = v1 + 1; + v3 = v2 + vertPerRow; + v4 = v1 + vertPerRow; + + // Normals and UVs cannot be shared. Without clone(), you can see the consequences + // of sharing if you call geometry.applyMatrix( matrix ). + if ( notDegenerate ( v1, v2, v3 ) ) { + + indices[ indexCount ++ ] = v1; + indices[ indexCount ++ ] = v2; + indices[ indexCount ++ ] = v3; + + } + if ( notDegenerate ( v1, v3, v4 ) ) { + + indices[ indexCount ++ ] = v1; + indices[ indexCount ++ ] = v3; + indices[ indexCount ++ ] = v4; + + } + + } + + } + + // increment only if a surface was used + surfCount ++; + + } + + } + + this.addIndex( new THREE.BufferAttribute( indices, 1 ) ); + this.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); + + this.computeBoundingSphere(); + +}; + + +THREE.TeapotBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.TeapotBufferGeometry.prototype.constructor = THREE.TeapotBufferGeometry; + +THREE.TeapotBufferGeometry.prototype.clone = function () { + + var bufferGeometry = new THREE.TeapotBufferGeometry( + this.parameters.size, + this.parameters.segments, + this.parameters.bottom, + this.parameters.lid, + this.parameters.body, + this.parameters.fitLid, + this.parameters.blinn + ); + + return bufferGeometry; + +}; diff --git a/examples/webgl_buffergeometry_teapot.html b/examples/webgl_buffergeometry_teapot.html new file mode 100644 index 0000000000000000000000000000000000000000..b74b9db55b70314fb0581a441e81a9f70b954491 --- /dev/null +++ b/examples/webgl_buffergeometry_teapot.html @@ -0,0 +1,393 @@ + + + + three.js webgl - teapot buffer geometry + + + + + +
+ three.js - the Utah Teapot from the Udacity Interactive 3D Graphics course +
+ + + + + + + + + + + + + + + diff --git a/src/objects/Line.js b/src/objects/Line.js index 5704a23e2842e0d36bc97852a403e7155c172923..8e859a79646c9019be278b95450ef8e0bd5045fa 100644 --- a/src/objects/Line.js +++ b/src/objects/Line.js @@ -97,7 +97,9 @@ THREE.Line.prototype.raycast = ( function () { if ( distSq > precisionSq ) continue; - var distance = ray.origin.distanceTo( interRay ); + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + + var distance = raycaster.ray.origin.distanceTo( interRay ); if ( distance < raycaster.near || distance > raycaster.far ) continue; @@ -132,7 +134,9 @@ THREE.Line.prototype.raycast = ( function () { if ( distSq > precisionSq ) continue; - var distance = ray.origin.distanceTo( interRay ); + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + + var distance = raycaster.ray.origin.distanceTo( interRay ); if ( distance < raycaster.near || distance > raycaster.far ) continue; @@ -163,8 +167,10 @@ THREE.Line.prototype.raycast = ( function () { var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); if ( distSq > precisionSq ) continue; + + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation - var distance = ray.origin.distanceTo( interRay ); + var distance = raycaster.ray.origin.distanceTo( interRay ); if ( distance < raycaster.near || distance > raycaster.far ) continue; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 4866e870185038d73632fd749a3e80a9ae441162..600bac91e239a7a0389be916ab1cb3966b30e221 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -19,15 +19,12 @@ THREE.WebGLRenderer = function ( parameters ) { pixelRatio = 1, - _precision = parameters.precision !== undefined ? parameters.precision : 'highp', - _alpha = parameters.alpha !== undefined ? parameters.alpha : false, _depth = parameters.depth !== undefined ? parameters.depth : true, _stencil = parameters.stencil !== undefined ? parameters.stencil : true, _antialias = parameters.antialias !== undefined ? parameters.antialias : false, _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true, _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, - _logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false, _clearColor = new THREE.Color( 0x000000 ), _clearAlpha = 0; @@ -35,13 +32,18 @@ THREE.WebGLRenderer = function ( parameters ) { var lights = []; var opaqueObjects = []; + var opaqueObjectsLastIndex = -1; var transparentObjects = []; + var transparentObjectsLastIndex = -1; var opaqueImmediateObjects = []; + var opaqueImmediateObjectsLastIndex = -1; var transparentImmediateObjects = []; + var transparentImmediateObjectsLastIndex = -1; var morphInfluences = new Float32Array( 8 ); + var sprites = []; var lensFlares = []; @@ -206,11 +208,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - if ( _logarithmicDepthBuffer ) { - - extensions.get( 'EXT_frag_depth' ); - - } + var capabilities = new THREE.WebGLCapabilities( _gl, extensions, parameters ); var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL ); var properties = new THREE.WebGLProperties(); @@ -260,6 +258,7 @@ THREE.WebGLRenderer = function ( parameters ) { setDefaultGLState(); this.context = _gl; + this.capabilities = capabilities; this.extensions = extensions; this.state = state; @@ -269,24 +268,6 @@ THREE.WebGLRenderer = function ( parameters ) { this.shadowMap = shadowMap; - // GPU capabilities - - var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS ); - var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); - var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE ); - var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE ); - - var _supportsVertexTextures = _maxVertexTextures > 0; - var _supportsBoneTextures = _supportsVertexTextures && extensions.get( 'OES_texture_float' ); - - var _maxPrecision = state.getMaxPrecision( _precision ); - - if ( _maxPrecision !== _precision ) { - - console.warn( 'THREE.WebGLRenderer:', _precision, 'not supported, using', _maxPrecision, 'instead.' ); - _precision = _maxPrecision; - - } // Plugins @@ -341,7 +322,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.getPrecision = function () { - return _precision; + return capabilities.precision; }; @@ -623,7 +604,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( newReferenceCount === 0 ) { - // the last meterial that has been using the program let + // the last material that has been using the program let // go of it, so remove it from the (unordered) _programs // set and deallocate the GL resource @@ -1146,17 +1127,23 @@ THREE.WebGLRenderer = function ( parameters ) { lights.length = 0; - opaqueObjects.length = 0; - transparentObjects.length = 0; + opaqueObjectsLastIndex = -1; + transparentObjectsLastIndex = -1; - opaqueImmediateObjects.length = 0; - transparentImmediateObjects.length = 0; + opaqueImmediateObjectsLastIndex = -1; + transparentImmediateObjectsLastIndex = -1; sprites.length = 0; lensFlares.length = 0; projectObject( scene ); + opaqueObjects.length = opaqueObjectsLastIndex + 1; + transparentObjects.length = transparentObjectsLastIndex + 1; + + opaqueImmediateObjects.length = opaqueImmediateObjectsLastIndex + 1; + transparentImmediateObjects.length = transparentImmediateObjectsLastIndex + 1; + if ( _this.sortObjects === true ) { opaqueObjects.sort( painterSortStable ); @@ -1236,36 +1223,82 @@ THREE.WebGLRenderer = function ( parameters ) { function pushImmediateRenderItem( object ) { + var array, index; + + // allocate the next position in the appropriate array + if ( object.material.transparent ) { - transparentImmediateObjects.push( object ); + array = transparentImmediateObjects; + index = ++ transparentImmediateObjectsLastIndex; } else { - opaqueImmediateObjects.push( object ); + array = opaqueImmediateObjects; + index = ++ opaqueImmediateObjectsLastIndex; } + // recycle existing position or grow the array + + if ( index < array.length ) { + + array[ index ] = object; + + } else { + + // assert( index === array.length ); + array.push( object ); + + } + + } function pushRenderItem( object, geometry, material, z, group ) { - var renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - z: _vector3.z, - group: group - }; + var array, index; + + // allocate the next position in the appropriate array if ( material.transparent ) { - transparentObjects.push( renderItem ); + array = transparentObjects; + index = ++ transparentObjectsLastIndex; } else { - opaqueObjects.push( renderItem ); + array = opaqueObjects; + index = ++ opaqueObjectsLastIndex; + + } + + // recycle existing render item or grow the array + + var renderItem = array[ index ]; + + if ( renderItem !== undefined ) { + + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.z = _vector3.z; + renderItem.group = group; + + } else { + + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + z: _vector3.z, + group: group + }; + + // assert( index === array.length ); + array.push( renderItem ); } @@ -1428,11 +1461,11 @@ THREE.WebGLRenderer = function ( parameters ) { var maxLightCount = allocateLights( lights ); var maxShadows = allocateShadows( lights ); var maxBones = allocateBones( object ); - var precision = _precision; + var precision = capabilities.precision; if ( material.precision !== null ) { - precision = state.getMaxPrecision( material.precision ); + precision = capabilities.getMaxPrecision( material.precision ); if ( precision !== material.precision ) { @@ -1445,7 +1478,7 @@ THREE.WebGLRenderer = function ( parameters ) { var parameters = { precision: precision, - supportsVertexTextures: _supportsVertexTextures, + supportsVertexTextures: capabilities.vertexTextures, map: !! material.map, envMap: !! material.envMap, @@ -1469,11 +1502,11 @@ THREE.WebGLRenderer = function ( parameters ) { flatShading: material.shading === THREE.FlatShading, sizeAttenuation: material.sizeAttenuation, - logarithmicDepthBuffer: _logarithmicDepthBuffer, + logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer, skinning: material.skinning, maxBones: maxBones, - useVertexTexture: _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture, + useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture, morphTargets: material.morphTargets, morphNormals: material.morphNormals, @@ -1740,7 +1773,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements ); - if ( _logarithmicDepthBuffer ) { + if ( capabilities.logarithmicDepthBuffer ) { _gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); @@ -1799,7 +1832,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - if ( _supportsBoneTextures && object.skeleton && object.skeleton.useVertexTexture ) { + if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) { if ( p_uniforms.boneTexture !== undefined ) { @@ -2205,9 +2238,9 @@ THREE.WebGLRenderer = function ( parameters ) { var textureUnit = _usedTextureUnits; - if ( textureUnit >= _maxTextures ) { + if ( textureUnit >= capabilities.maxTextures ) { - console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + _maxTextures ); + console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); } @@ -2824,7 +2857,10 @@ THREE.WebGLRenderer = function ( parameters ) { extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - if ( extension && texture.type !== THREE.FloatType && texture.type !== THREE.HalfFloatType ) { + if ( extension ) { + + if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return; + if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return; if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) { @@ -2860,7 +2896,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ); _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment ); - texture.image = clampToMaxSize( texture.image, _maxTextureSize ); + texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize ); var image = texture.image, isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ), @@ -3045,7 +3081,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) { - cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize ); + cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize ); } else { @@ -3508,7 +3544,7 @@ THREE.WebGLRenderer = function ( parameters ) { function allocateBones ( object ) { - if ( _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture ) { + if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) { return 1024; @@ -3633,7 +3669,7 @@ THREE.WebGLRenderer = function ( parameters ) { this.supportsVertexTextures = function () { - return _supportsVertexTextures; + return capabilities.vertexTextures; }; diff --git a/src/renderers/webgl/WebGLCapabilities.js b/src/renderers/webgl/WebGLCapabilities.js new file mode 100644 index 0000000000000000000000000000000000000000..318e7d8c463c859916a08034f7354df2c4a4cd09 --- /dev/null +++ b/src/renderers/webgl/WebGLCapabilities.js @@ -0,0 +1,67 @@ +THREE.WebGLCapabilities = function ( gl, extensions, parameters ) { + + function getMaxPrecision( precision ) { + + if ( precision === 'highp' ) { + + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { + + return 'highp'; + + } + + precision = 'mediump'; + + } + + if ( precision === 'mediump' ) { + + if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { + + return 'mediump'; + + } + + } + + return 'lowp'; + + } + + this.getMaxPrecision = getMaxPrecision; + + this.precision = parameters.precision !== undefined ? parameters.precision : 'highp', + this.logarithmicDepthBuffer = parameters.logarithmicDepthBuffer !== undefined ? parameters.logarithmicDepthBuffer : false; + + this.maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); + this.maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ); + this.maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE ); + this.maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE ); + + this.maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + this.maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS ); + this.maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS ); + this.maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS ); + + this.vertexTextures = this.maxVertexTextures > 0; + this.floatFragmentTextures = !! extensions.get( 'OES_texture_float' ); + this.floatVertexTextures = this.vertexTextures && this.floatFragmentTextures; + + var _maxPrecision = getMaxPrecision( this.precision ); + + if ( _maxPrecision !== this.precision ) { + + console.warn( 'THREE.WebGLRenderer:', this.precision, 'not supported, using', _maxPrecision, 'instead.' ); + this.precision = _maxPrecision; + + } + + if ( this.logarithmicDepthBuffer ) { + + this.logarithmicDepthBuffer = !! extensions.get( 'EXT_frag_depth' ); + + } + +}; diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js index c66d840ffebf1feaa20fcd1f4e814755c8adca49..5a407d3ba5a7474f3eca9a3143c72a38786b0675 100644 --- a/src/renderers/webgl/WebGLShadowMap.js +++ b/src/renderers/webgl/WebGLShadowMap.js @@ -209,9 +209,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { var groups = geometry.groups; var materials = material.materials; - for ( var j = 0, jl = groups.length; j < jl; j ++ ) { + for ( var k = 0, kl = groups.length; k < kl; k ++ ) { - var group = groups[ j ]; + var group = groups[ k ]; var groupMaterial = materials[ group.materialIndex ]; if ( groupMaterial.visible === true ) { diff --git a/src/renderers/webgl/WebGLState.js b/src/renderers/webgl/WebGLState.js index b43282ccc79e15781f891948e4e0b8bb3b3a7708..94faaf1b22f1b4a6d1a16764d589a25e6e64c81c 100644 --- a/src/renderers/webgl/WebGLState.js +++ b/src/renderers/webgl/WebGLState.js @@ -142,36 +142,6 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { }; - this.getMaxPrecision = function ( precision ) { - - if ( precision === 'highp' ) { - - if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 && - gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) { - - return 'highp'; - - } - - precision = 'mediump'; - - } - - if ( precision === 'mediump' ) { - - if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 && - gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) { - - return 'mediump'; - - } - - } - - return 'lowp'; - - }; - this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { if ( blending !== currentBlending ) { diff --git a/src/textures/DataTexture.js b/src/textures/DataTexture.js index 83806f2cb7f9e8a389a4c218d65cac739e3c6154..e3b9baee6955eeb58aa9beed1d7a747cc155b9d5 100644 --- a/src/textures/DataTexture.js +++ b/src/textures/DataTexture.js @@ -3,22 +3,13 @@ */ THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) { - - if ( magFilter === undefined ) { - - magFilter = THREE.NearestFilter; - - } - - if ( minFilter === undefined ) { - - minFilter = THREE.NearestFilter; - - } THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); this.image = { data: data, width: width, height: height }; + + this.magFilter = magFilter !== undefined ? magFilter : THREE.NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : THREE.NearestFilter; this.flipY = false; this.generateMipmaps = false; @@ -26,4 +17,4 @@ THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS }; THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype ); -THREE.DataTexture.prototype.constructor = THREE.DataTexture; \ No newline at end of file +THREE.DataTexture.prototype.constructor = THREE.DataTexture; diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index 4894ac482a8e7598eaa1364342141206a4cb9896..f528c4761136031424491d0436dae19da383445d 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -170,6 +170,7 @@ "src/renderers/webgl/WebGLBufferRenderer.js", "src/renderers/webgl/WebGLIndexedBufferRenderer.js", "src/renderers/webgl/WebGLExtensions.js", + "src/renderers/webgl/WebGLCapabilities.js", "src/renderers/webgl/WebGLGeometries.js", "src/renderers/webgl/WebGLObjects.js", "src/renderers/webgl/WebGLProgram.js",