From 6ac7601da6817ed5ccebb2b21cef4fc0de84b306 Mon Sep 17 00:00:00 2001 From: Robin Hawkes Date: Thu, 16 Jun 2016 09:46:46 +0100 Subject: [PATCH] Updated three.js version --- examples/vendor/three.js | 15271 ++++++++++++++++++--------------- examples/vendor/three.min.js | 1379 +-- 2 files changed, 8936 insertions(+), 7714 deletions(-) diff --git a/examples/vendor/three.js b/examples/vendor/three.js index 9274cfe..d641a28 100644 --- a/examples/vendor/three.js +++ b/examples/vendor/three.js @@ -4,7 +4,7 @@ * @author mrdoob / http://mrdoob.com/ */ -var THREE = { REVISION: '74' }; +var THREE = { REVISION: '77' }; // @@ -18,7 +18,7 @@ if ( typeof define === 'function' && define.amd ) { } -// +// Polyfills if ( Number.EPSILON === undefined ) { @@ -40,7 +40,7 @@ if ( Math.sign === undefined ) { } -if ( Function.prototype.name === undefined && Object.defineProperty !== undefined ) { +if ( Function.prototype.name === undefined ) { // Missing in IE9-11. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name @@ -59,43 +59,36 @@ if ( Function.prototype.name === undefined && Object.defineProperty !== undefine if ( Object.assign === undefined ) { + // Missing in IE. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - Object.defineProperty( Object, 'assign', { + ( function () { - writable: true, - configurable: true, - - value: function ( target ) { + Object.assign = function ( target ) { 'use strict'; if ( target === undefined || target === null ) { - throw new TypeError( "Cannot convert first argument to object" ); + throw new TypeError( 'Cannot convert undefined or null to object' ); } - var to = Object( target ); + var output = Object( target ); - for ( var i = 1, n = arguments.length; i !== n; ++ i ) { + for ( var index = 1; index < arguments.length; index ++ ) { - var nextSource = arguments[ i ]; + var source = arguments[ index ]; - if ( nextSource === undefined || nextSource === null ) continue; + if ( source !== undefined && source !== null ) { - nextSource = Object( nextSource ); + for ( var nextKey in source ) { - var keysArray = Object.keys( nextSource ); + if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) { - for ( var nextIndex = 0, len = keysArray.length; nextIndex !== len; ++ nextIndex ) { + output[ nextKey ] = source[ nextKey ]; - var nextKey = keysArray[ nextIndex ]; - var desc = Object.getOwnPropertyDescriptor( nextSource, nextKey ); - - if ( desc !== undefined && desc.enumerable ) { - - to[ nextKey ] = nextSource[ nextKey ]; + } } @@ -103,210 +96,245 @@ if ( Object.assign === undefined ) { } - return to; + return output; - } + }; - } ); + } )(); } -// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button +// -THREE.MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; +Object.assign( THREE, { -// GL STATE CONSTANTS + // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button -THREE.CullFaceNone = 0; -THREE.CullFaceBack = 1; -THREE.CullFaceFront = 2; -THREE.CullFaceFrontBack = 3; + MOUSE: { LEFT: 0, MIDDLE: 1, RIGHT: 2 }, -THREE.FrontFaceDirectionCW = 0; -THREE.FrontFaceDirectionCCW = 1; + // GL STATE CONSTANTS -// SHADOWING TYPES + CullFaceNone: 0, + CullFaceBack: 1, + CullFaceFront: 2, + CullFaceFrontBack: 3, -THREE.BasicShadowMap = 0; -THREE.PCFShadowMap = 1; -THREE.PCFSoftShadowMap = 2; + FrontFaceDirectionCW: 0, + FrontFaceDirectionCCW: 1, -// MATERIAL CONSTANTS + // SHADOWING TYPES -// side + BasicShadowMap: 0, + PCFShadowMap: 1, + PCFSoftShadowMap: 2, -THREE.FrontSide = 0; -THREE.BackSide = 1; -THREE.DoubleSide = 2; + // MATERIAL CONSTANTS -// shading + // side -THREE.FlatShading = 1; -THREE.SmoothShading = 2; + FrontSide: 0, + BackSide: 1, + DoubleSide: 2, -// colors + // shading -THREE.NoColors = 0; -THREE.FaceColors = 1; -THREE.VertexColors = 2; + FlatShading: 1, + SmoothShading: 2, -// blending modes + // colors -THREE.NoBlending = 0; -THREE.NormalBlending = 1; -THREE.AdditiveBlending = 2; -THREE.SubtractiveBlending = 3; -THREE.MultiplyBlending = 4; -THREE.CustomBlending = 5; + NoColors: 0, + FaceColors: 1, + VertexColors: 2, -// custom blending equations -// (numbers start from 100 not to clash with other -// mappings to OpenGL constants defined in Texture.js) + // blending modes -THREE.AddEquation = 100; -THREE.SubtractEquation = 101; -THREE.ReverseSubtractEquation = 102; -THREE.MinEquation = 103; -THREE.MaxEquation = 104; + NoBlending: 0, + NormalBlending: 1, + AdditiveBlending: 2, + SubtractiveBlending: 3, + MultiplyBlending: 4, + CustomBlending: 5, -// custom blending destination factors + // custom blending equations + // (numbers start from 100 not to clash with other + // mappings to OpenGL constants defined in Texture.js) -THREE.ZeroFactor = 200; -THREE.OneFactor = 201; -THREE.SrcColorFactor = 202; -THREE.OneMinusSrcColorFactor = 203; -THREE.SrcAlphaFactor = 204; -THREE.OneMinusSrcAlphaFactor = 205; -THREE.DstAlphaFactor = 206; -THREE.OneMinusDstAlphaFactor = 207; + AddEquation: 100, + SubtractEquation: 101, + ReverseSubtractEquation: 102, + MinEquation: 103, + MaxEquation: 104, -// custom blending source factors + // custom blending destination factors -//THREE.ZeroFactor = 200; -//THREE.OneFactor = 201; -//THREE.SrcAlphaFactor = 204; -//THREE.OneMinusSrcAlphaFactor = 205; -//THREE.DstAlphaFactor = 206; -//THREE.OneMinusDstAlphaFactor = 207; -THREE.DstColorFactor = 208; -THREE.OneMinusDstColorFactor = 209; -THREE.SrcAlphaSaturateFactor = 210; + ZeroFactor: 200, + OneFactor: 201, + SrcColorFactor: 202, + OneMinusSrcColorFactor: 203, + SrcAlphaFactor: 204, + OneMinusSrcAlphaFactor: 205, + DstAlphaFactor: 206, + OneMinusDstAlphaFactor: 207, -// depth modes + // custom blending source factors -THREE.NeverDepth = 0; -THREE.AlwaysDepth = 1; -THREE.LessDepth = 2; -THREE.LessEqualDepth = 3; -THREE.EqualDepth = 4; -THREE.GreaterEqualDepth = 5; -THREE.GreaterDepth = 6; -THREE.NotEqualDepth = 7; + //ZeroFactor: 200, + //OneFactor: 201, + //SrcAlphaFactor: 204, + //OneMinusSrcAlphaFactor: 205, + //DstAlphaFactor: 206, + //OneMinusDstAlphaFactor: 207, + DstColorFactor: 208, + OneMinusDstColorFactor: 209, + SrcAlphaSaturateFactor: 210, + + // depth modes + + NeverDepth: 0, + AlwaysDepth: 1, + LessDepth: 2, + LessEqualDepth: 3, + EqualDepth: 4, + GreaterEqualDepth: 5, + GreaterDepth: 6, + NotEqualDepth: 7, -// TEXTURE CONSTANTS + // TEXTURE CONSTANTS -THREE.MultiplyOperation = 0; -THREE.MixOperation = 1; -THREE.AddOperation = 2; + MultiplyOperation: 0, + MixOperation: 1, + AddOperation: 2, -// Mapping modes + // Tone Mapping modes -THREE.UVMapping = 300; + NoToneMapping: 0, // do not do any tone mapping, not even exposure (required for special purpose passes.) + LinearToneMapping: 1, // only apply exposure. + ReinhardToneMapping: 2, + Uncharted2ToneMapping: 3, // John Hable + CineonToneMapping: 4, // optimized filmic operator by Jim Hejl and Richard Burgess-Dawson -THREE.CubeReflectionMapping = 301; -THREE.CubeRefractionMapping = 302; + // Mapping modes -THREE.EquirectangularReflectionMapping = 303; -THREE.EquirectangularRefractionMapping = 304; + UVMapping: 300, -THREE.SphericalReflectionMapping = 305; + CubeReflectionMapping: 301, + CubeRefractionMapping: 302, -// Wrapping modes + EquirectangularReflectionMapping: 303, + EquirectangularRefractionMapping: 304, -THREE.RepeatWrapping = 1000; -THREE.ClampToEdgeWrapping = 1001; -THREE.MirroredRepeatWrapping = 1002; + SphericalReflectionMapping: 305, + CubeUVReflectionMapping: 306, + CubeUVRefractionMapping: 307, -// Filters + // Wrapping modes -THREE.NearestFilter = 1003; -THREE.NearestMipMapNearestFilter = 1004; -THREE.NearestMipMapLinearFilter = 1005; -THREE.LinearFilter = 1006; -THREE.LinearMipMapNearestFilter = 1007; -THREE.LinearMipMapLinearFilter = 1008; + RepeatWrapping: 1000, + ClampToEdgeWrapping: 1001, + MirroredRepeatWrapping: 1002, -// Data types + // Filters -THREE.UnsignedByteType = 1009; -THREE.ByteType = 1010; -THREE.ShortType = 1011; -THREE.UnsignedShortType = 1012; -THREE.IntType = 1013; -THREE.UnsignedIntType = 1014; -THREE.FloatType = 1015; -THREE.HalfFloatType = 1025; + NearestFilter: 1003, + NearestMipMapNearestFilter: 1004, + NearestMipMapLinearFilter: 1005, + LinearFilter: 1006, + LinearMipMapNearestFilter: 1007, + LinearMipMapLinearFilter: 1008, -// Pixel types + // Data types -//THREE.UnsignedByteType = 1009; -THREE.UnsignedShort4444Type = 1016; -THREE.UnsignedShort5551Type = 1017; -THREE.UnsignedShort565Type = 1018; + UnsignedByteType: 1009, + ByteType: 1010, + ShortType: 1011, + UnsignedShortType: 1012, + IntType: 1013, + UnsignedIntType: 1014, + FloatType: 1015, + HalfFloatType: 1025, -// Pixel formats + // Pixel types -THREE.AlphaFormat = 1019; -THREE.RGBFormat = 1020; -THREE.RGBAFormat = 1021; -THREE.LuminanceFormat = 1022; -THREE.LuminanceAlphaFormat = 1023; -// THREE.RGBEFormat handled as THREE.RGBAFormat in shaders -THREE.RGBEFormat = THREE.RGBAFormat; //1024; + //UnsignedByteType: 1009, + UnsignedShort4444Type: 1016, + UnsignedShort5551Type: 1017, + UnsignedShort565Type: 1018, -// DDS / ST3C Compressed texture formats + // Pixel formats -THREE.RGB_S3TC_DXT1_Format = 2001; -THREE.RGBA_S3TC_DXT1_Format = 2002; -THREE.RGBA_S3TC_DXT3_Format = 2003; -THREE.RGBA_S3TC_DXT5_Format = 2004; + AlphaFormat: 1019, + RGBFormat: 1020, + RGBAFormat: 1021, + LuminanceFormat: 1022, + LuminanceAlphaFormat: 1023, + // THREE.RGBEFormat handled as THREE.RGBAFormat in shaders + RGBEFormat: THREE.RGBAFormat, //1024; + DepthFormat: 1026, + // DDS / ST3C Compressed texture formats -// PVRTC compressed texture formats + RGB_S3TC_DXT1_Format: 2001, + RGBA_S3TC_DXT1_Format: 2002, + RGBA_S3TC_DXT3_Format: 2003, + RGBA_S3TC_DXT5_Format: 2004, -THREE.RGB_PVRTC_4BPPV1_Format = 2100; -THREE.RGB_PVRTC_2BPPV1_Format = 2101; -THREE.RGBA_PVRTC_4BPPV1_Format = 2102; -THREE.RGBA_PVRTC_2BPPV1_Format = 2103; + // PVRTC compressed texture formats -// ETC compressed texture formats + RGB_PVRTC_4BPPV1_Format: 2100, + RGB_PVRTC_2BPPV1_Format: 2101, + RGBA_PVRTC_4BPPV1_Format: 2102, + RGBA_PVRTC_2BPPV1_Format: 2103, -THREE.RGB_ETC1_Format = 2151; + // ETC compressed texture formats -// Loop styles for AnimationAction + RGB_ETC1_Format: 2151, -THREE.LoopOnce = 2200; -THREE.LoopRepeat = 2201; -THREE.LoopPingPong = 2202; + // Loop styles for AnimationAction -// Interpolation + LoopOnce: 2200, + LoopRepeat: 2201, + LoopPingPong: 2202, -THREE.InterpolateDiscrete = 2300; -THREE.InterpolateLinear = 2301; -THREE.InterpolateSmooth = 2302; + // Interpolation -// Interpolant ending modes + InterpolateDiscrete: 2300, + InterpolateLinear: 2301, + InterpolateSmooth: 2302, -THREE.ZeroCurvatureEnding = 2400; -THREE.ZeroSlopeEnding = 2401; -THREE.WrapAroundEnding = 2402; + // Interpolant ending modes -// Triangle Draw modes + ZeroCurvatureEnding: 2400, + ZeroSlopeEnding: 2401, + WrapAroundEnding: 2402, -THREE.TrianglesDrawMode = 0; -THREE.TriangleStripDrawMode = 1; -THREE.TriangleFanDrawMode = 2; + // Triangle Draw modes + + TrianglesDrawMode: 0, + TriangleStripDrawMode: 1, + TriangleFanDrawMode: 2, + + // Texture Encodings + + LinearEncoding: 3000, // No encoding at all. + sRGBEncoding: 3001, + GammaEncoding: 3007, // uses GAMMA_FACTOR, for backwards compatibility with WebGLRenderer.gammaInput/gammaOutput + + // The following Texture Encodings are for RGB-only (no alpha) HDR light emission sources. + // These encodings should not specified as output encodings except in rare situations. + RGBEEncoding: 3002, // AKA Radiance. + LogLuvEncoding: 3003, + RGBM7Encoding: 3004, + RGBM16Encoding: 3005, + RGBDEncoding: 3006, // MaxRange is 256. + + // Depth packing strategies + + BasicDepthPacking: 3200, // for writing to float textures for high precision or for visualizing results in RGB buffers + RGBADepthPacking: 3201 // for packing into RGBA buffers. + +} ); // File:src/math/Color.js @@ -314,15 +342,16 @@ THREE.TriangleFanDrawMode = 2; * @author mrdoob / http://mrdoob.com/ */ -THREE.Color = function ( color ) { +THREE.Color = function ( r, g, b ) { - if ( arguments.length === 3 ) { + if ( g === undefined && b === undefined ) { - return this.fromArray( arguments ); + // r is THREE.Color, hex or string + return this.set( r ); } - return this.set( color ); + return this.setRGB( r, g, b ); }; @@ -1106,9 +1135,7 @@ THREE.Quaternion.prototype = { this._z = v1.z; this._w = r; - this.normalize(); - - return this; + return this.normalize(); }; @@ -1116,9 +1143,7 @@ THREE.Quaternion.prototype = { inverse: function () { - this.conjugate().normalize(); - - return this; + return this.conjugate().normalize(); }, @@ -1193,6 +1218,12 @@ THREE.Quaternion.prototype = { }, + premultiply: function ( q ) { + + return this.multiplyQuaternions( q, this ); + + }, + multiplyQuaternions: function ( a, b ) { // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm @@ -1689,9 +1720,7 @@ THREE.Vector2.prototype = { var length = this.length(); - this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length ); - - return this; + return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length ); }, @@ -1812,9 +1841,7 @@ THREE.Vector2.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - - return this; + return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); }, @@ -2130,9 +2157,7 @@ THREE.Vector3.prototype = { if ( quaternion === undefined ) quaternion = new THREE.Quaternion(); - this.applyQuaternion( quaternion.setFromEuler( euler ) ); - - return this; + return this.applyQuaternion( quaternion.setFromEuler( euler ) ); }; @@ -2146,9 +2171,7 @@ THREE.Vector3.prototype = { if ( quaternion === undefined ) quaternion = new THREE.Quaternion(); - this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); - - return this; + return this.applyQuaternion( quaternion.setFromAxisAngle( axis, angle ) ); }; @@ -2156,10 +2179,7 @@ THREE.Vector3.prototype = { applyMatrix3: function ( m ) { - var x = this.x; - var y = this.y; - var z = this.z; - + var x = this.x, y = this.y, z = this.z; var e = m.elements; this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; @@ -2175,7 +2195,6 @@ THREE.Vector3.prototype = { // input: THREE.Matrix4 affine matrix var x = this.x, y = this.y, z = this.z; - var e = m.elements; this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ]; @@ -2191,7 +2210,6 @@ THREE.Vector3.prototype = { // input: THREE.Matrix4 projection matrix var x = this.x, y = this.y, z = this.z; - var e = m.elements; var d = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); // perspective divide @@ -2205,14 +2223,8 @@ THREE.Vector3.prototype = { applyQuaternion: function ( q ) { - var x = this.x; - var y = this.y; - var z = this.z; - - var qx = q.x; - var qy = q.y; - var qz = q.z; - var qw = q.w; + var x = this.x, y = this.y, z = this.z; + var qx = q.x, qy = q.y, qz = q.z, qw = q.w; // calculate quat * vector @@ -2267,16 +2279,13 @@ THREE.Vector3.prototype = { // vector interpreted as a direction var x = this.x, y = this.y, z = this.z; - var e = m.elements; this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; - this.normalize(); - - return this; + return this.normalize(); }, @@ -2354,9 +2363,7 @@ THREE.Vector3.prototype = { var length = this.length(); - this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length ); - - return this; + return this.multiplyScalar( Math.max( min, Math.min( max, length ) ) / length ); }, @@ -2458,9 +2465,7 @@ THREE.Vector3.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - - return this; + return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); }, @@ -2526,7 +2531,7 @@ THREE.Vector3.prototype = { return this.sub( v1 ); - } + }; }(), @@ -2543,7 +2548,7 @@ THREE.Vector3.prototype = { return this.sub( v1.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); - } + }; }(), @@ -2565,29 +2570,35 @@ THREE.Vector3.prototype = { distanceToSquared: function ( v ) { - var dx = this.x - v.x; - var dy = this.y - v.y; - var dz = this.z - v.z; + var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; return dx * dx + dy * dy + dz * dz; }, - setFromMatrixPosition: function ( m ) { + setFromSpherical: function( s ) { - this.x = m.elements[ 12 ]; - this.y = m.elements[ 13 ]; - this.z = m.elements[ 14 ]; + var sinPhiRadius = Math.sin( s.phi ) * s.radius; + + this.x = sinPhiRadius * Math.sin( s.theta ); + this.y = Math.cos( s.phi ) * s.radius; + this.z = sinPhiRadius * Math.cos( s.theta ); return this; }, + setFromMatrixPosition: function ( m ) { + + return this.setFromMatrixColumn( m, 3 ); + + }, + setFromMatrixScale: function ( m ) { - var sx = this.set( m.elements[ 0 ], m.elements[ 1 ], m.elements[ 2 ] ).length(); - var sy = this.set( m.elements[ 4 ], m.elements[ 5 ], m.elements[ 6 ] ).length(); - var sz = this.set( m.elements[ 8 ], m.elements[ 9 ], m.elements[ 10 ] ).length(); + var sx = this.setFromMatrixColumn( m, 0 ).length(); + var sy = this.setFromMatrixColumn( m, 1 ).length(); + var sz = this.setFromMatrixColumn( m, 2 ).length(); this.x = sx; this.y = sy; @@ -2597,17 +2608,18 @@ THREE.Vector3.prototype = { }, - setFromMatrixColumn: function ( index, matrix ) { + setFromMatrixColumn: function ( m, index ) { - var offset = index * 4; + if ( typeof m === 'number' ) { - var me = matrix.elements; + console.warn( 'THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).' ); + var temp = m + m = index; + index = temp; - this.x = me[ offset ]; - this.y = me[ offset + 1 ]; - this.z = me[ offset + 2 ]; + } - return this; + return this.fromArray( m.elements, index * 4 ); }, @@ -2895,11 +2907,7 @@ THREE.Vector4.prototype = { applyMatrix4: function ( m ) { - var x = this.x; - var y = this.y; - var z = this.z; - var w = this.w; - + var x = this.x, y = this.y, z = this.z, w = this.w; var e = m.elements; this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; @@ -2961,18 +2969,18 @@ THREE.Vector4.prototype = { m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - if ( ( Math.abs( m12 - m21 ) < epsilon ) - && ( Math.abs( m13 - m31 ) < epsilon ) - && ( Math.abs( m23 - m32 ) < epsilon ) ) { + if ( ( Math.abs( m12 - m21 ) < epsilon ) && + ( Math.abs( m13 - m31 ) < epsilon ) && + ( Math.abs( m23 - m32 ) < epsilon ) ) { // singularity found // first check for identity matrix which must have +1 for all terms // in leading diagonal and zero in other terms - if ( ( Math.abs( m12 + m21 ) < epsilon2 ) - && ( Math.abs( m13 + m31 ) < epsilon2 ) - && ( Math.abs( m23 + m32 ) < epsilon2 ) - && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { + if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && + ( Math.abs( m13 + m31 ) < epsilon2 ) && + ( Math.abs( m23 + m32 ) < epsilon2 ) && + ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { // this singularity is identity matrix so angle = 0 @@ -3057,9 +3065,9 @@ THREE.Vector4.prototype = { // as we have reached here there are no singularities so we can handle normally - var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) - + ( m13 - m31 ) * ( m13 - m31 ) - + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize + var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + + ( m13 - m31 ) * ( m13 - m31 ) + + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize if ( Math.abs( s ) < 0.001 ) s = 1; @@ -3236,9 +3244,7 @@ THREE.Vector4.prototype = { lerpVectors: function ( v1, v2, alpha ) { - this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); - - return this; + return this.subVectors( v2, v1 ).multiplyScalar( alpha ).add( v1 ); }, @@ -3512,7 +3518,7 @@ THREE.Euler.prototype = { } else { - console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ) + console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ); } @@ -3531,10 +3537,10 @@ THREE.Euler.prototype = { return function ( q, order, update ) { if ( matrix === undefined ) matrix = new THREE.Matrix4(); - matrix.makeRotationFromQuaternion( q ); - this.setFromRotationMatrix( matrix, order, update ); - return this; + matrix.makeRotationFromQuaternion( q ); + + return this.setFromRotationMatrix( matrix, order, update ); }; @@ -3555,7 +3561,8 @@ THREE.Euler.prototype = { return function ( newOrder ) { q.setFromEuler( this ); - this.setFromQuaternion( q, newOrder ); + + return this.setFromQuaternion( q, newOrder ); }; @@ -4017,8 +4024,6 @@ THREE.Box3.prototype = { setFromArray: function ( array ) { - this.makeEmpty(); - var minX = + Infinity; var minY = + Infinity; var minZ = + Infinity; @@ -4027,19 +4032,19 @@ THREE.Box3.prototype = { var maxY = - Infinity; var maxZ = - Infinity; - for ( var i = 0, il = array.length; i < il; i += 3 ) { + for ( var i = 0, l = array.length; i < l; i += 3 ) { var x = array[ i ]; var y = array[ i + 1 ]; var z = array[ i + 2 ]; - minX = Math.min( minX, x ); - minY = Math.min( minY, y ); - minZ = Math.min( minZ, z ); + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; - maxX = Math.max( maxX, x ); - maxY = Math.max( maxY, y ); - maxZ = Math.max( maxZ, z ); + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; } @@ -4084,34 +4089,50 @@ THREE.Box3.prototype = { // Computes the world-axis-aligned bounding box of an object (including its children), // accounting for both the object's, and children's, world transforms - var box; + var v1 = new THREE.Vector3(); return function ( object ) { - if ( box === undefined ) box = new THREE.Box3(); - var scope = this; - this.makeEmpty(); - object.updateMatrixWorld( true ); + this.makeEmpty(); + object.traverse( function ( node ) { var geometry = node.geometry; if ( geometry !== undefined ) { - if ( geometry.boundingBox === null ) { + if ( geometry instanceof THREE.Geometry ) { - geometry.computeBoundingBox(); + var vertices = geometry.vertices; + + for ( var i = 0, il = vertices.length; i < il; i ++ ) { + + v1.copy( vertices[ i ] ); + v1.applyMatrix4( node.matrixWorld ); + + scope.expandByPoint( v1 ); + + } + + } else if ( geometry instanceof THREE.BufferGeometry && geometry.attributes[ 'position' ] !== undefined ) { + + var positions = geometry.attributes[ 'position' ].array; + + for ( var i = 0, il = positions.length; i < il; i += 3 ) { + + v1.fromArray( positions, i ); + v1.applyMatrix4( node.matrixWorld ); + + scope.expandByPoint( v1 ); + + } } - box.copy( geometry.boundingBox ); - box.applyMatrix4( node.matrixWorld ); - scope.union( box ); - } } ); @@ -4361,6 +4382,9 @@ THREE.Box3.prototype = { this.min.max( box.min ); this.max.min( box.max ); + // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. + if( this.isEmpty() ) this.makeEmpty(); + return this; }, @@ -4389,6 +4413,9 @@ THREE.Box3.prototype = { return function ( matrix ) { + // transform of empty box is an empty box. + if( this.isEmpty() ) return this; + // NOTE: I am using a binary pattern to specify all 2^3 combinations below points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 @@ -4399,7 +4426,6 @@ THREE.Box3.prototype = { points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 - this.makeEmpty(); this.setFromPoints( points ); return this; @@ -4431,6 +4457,7 @@ THREE.Box3.prototype = { * @author alteredq / http://alteredqualia.com/ * @author WestLangley / http://github.com/WestLangley * @author bhouston / http://clara.io + * @author tschw */ THREE.Matrix3 = function () { @@ -4459,9 +4486,9 @@ THREE.Matrix3.prototype = { var te = this.elements; - te[ 0 ] = n11; te[ 3 ] = n12; te[ 6 ] = n13; - te[ 1 ] = n21; te[ 4 ] = n22; te[ 7 ] = n23; - te[ 2 ] = n31; te[ 5 ] = n32; te[ 8 ] = n33; + te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; + te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; + te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; return this; @@ -4503,6 +4530,22 @@ THREE.Matrix3.prototype = { }, + setFromMatrix4: function( m ) { + + var me = m.elements; + + this.set( + + me[ 0 ], me[ 4 ], me[ 8 ], + me[ 1 ], me[ 5 ], me[ 9 ], + me[ 2 ], me[ 6 ], me[ 10 ] + + ); + + return this; + + }, + applyToVector3Array: function () { var v1; @@ -4581,25 +4624,24 @@ THREE.Matrix3.prototype = { getInverse: function ( matrix, throwOnDegenerate ) { - // input: THREE.Matrix4 - // ( based on http://code.google.com/p/webgl-mjs/ ) + if ( matrix instanceof THREE.Matrix4 ) { - var me = matrix.elements; - var te = this.elements; + console.error( "THREE.Matrix3.getInverse no longer takes a Matrix4 argument." ); - te[ 0 ] = me[ 10 ] * me[ 5 ] - me[ 6 ] * me[ 9 ]; - te[ 1 ] = - me[ 10 ] * me[ 1 ] + me[ 2 ] * me[ 9 ]; - te[ 2 ] = me[ 6 ] * me[ 1 ] - me[ 2 ] * me[ 5 ]; - te[ 3 ] = - me[ 10 ] * me[ 4 ] + me[ 6 ] * me[ 8 ]; - te[ 4 ] = me[ 10 ] * me[ 0 ] - me[ 2 ] * me[ 8 ]; - te[ 5 ] = - me[ 6 ] * me[ 0 ] + me[ 2 ] * me[ 4 ]; - te[ 6 ] = me[ 9 ] * me[ 4 ] - me[ 5 ] * me[ 8 ]; - te[ 7 ] = - me[ 9 ] * me[ 0 ] + me[ 1 ] * me[ 8 ]; - te[ 8 ] = me[ 5 ] * me[ 0 ] - me[ 1 ] * me[ 4 ]; + } - var det = me[ 0 ] * te[ 0 ] + me[ 1 ] * te[ 3 ] + me[ 2 ] * te[ 6 ]; + var me = matrix.elements, + te = this.elements, - // no inverse + n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], + n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ], + n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ], + + t11 = n33 * n22 - n32 * n23, + t12 = n32 * n13 - n33 * n12, + t13 = n23 * n12 - n22 * n13, + + det = n11 * t11 + n21 * t12 + n31 * t13; if ( det === 0 ) { @@ -4615,13 +4657,22 @@ THREE.Matrix3.prototype = { } - this.identity(); - - return this; - + return this.identity(); } + + var detInv = 1 / det; - this.multiplyScalar( 1.0 / det ); + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; + te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; + + te[ 3 ] = t12 * detInv; + te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; + te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; + + te[ 6 ] = t13 * detInv; + te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; + te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; return this; @@ -4641,31 +4692,16 @@ THREE.Matrix3.prototype = { flattenToArrayOffset: function ( array, offset ) { - var te = this.elements; + console.warn( "THREE.Matrix3: .flattenToArrayOffset is deprecated " + + "- just use .toArray instead." ); - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - - array[ offset + 3 ] = te[ 3 ]; - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; - array[ offset + 8 ] = te[ 8 ]; - - return array; + return this.toArray( array, offset ); }, - getNormalMatrix: function ( m ) { + getNormalMatrix: function ( matrix4 ) { - // input: THREE.Matrix4 - - this.getInverse( m ).transpose(); - - return this; + return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose(); }, @@ -4695,15 +4731,26 @@ THREE.Matrix3.prototype = { }, - toArray: function () { + toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; var te = this.elements; - return [ - te[ 0 ], te[ 1 ], te[ 2 ], - te[ 3 ], te[ 4 ], te[ 5 ], - te[ 6 ], te[ 7 ], te[ 8 ] - ]; + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + + array[ offset + 3 ] = te[ 3 ]; + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + array[ offset + 8 ] = te[ 8 ]; + + return array; } @@ -4804,11 +4851,9 @@ THREE.Matrix4.prototype = { extractBasis: function ( xAxis, yAxis, zAxis ) { - var te = this.elements; - - xAxis.set( te[ 0 ], te[ 1 ], te[ 2 ] ); - yAxis.set( te[ 4 ], te[ 5 ], te[ 6 ] ); - zAxis.set( te[ 8 ], te[ 9 ], te[ 10 ] ); + xAxis.setFromMatrixColumn( this, 0 ); + yAxis.setFromMatrixColumn( this, 1 ); + zAxis.setFromMatrixColumn( this, 2 ); return this; @@ -4838,9 +4883,9 @@ THREE.Matrix4.prototype = { var te = this.elements; var me = m.elements; - var scaleX = 1 / v1.set( me[ 0 ], me[ 1 ], me[ 2 ] ).length(); - var scaleY = 1 / v1.set( me[ 4 ], me[ 5 ], me[ 6 ] ).length(); - var scaleZ = 1 / v1.set( me[ 8 ], me[ 9 ], me[ 10 ] ).length(); + var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length(); + var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length(); + var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length(); te[ 0 ] = me[ 0 ] * scaleX; te[ 1 ] = me[ 1 ] * scaleX; @@ -5031,9 +5076,13 @@ THREE.Matrix4.prototype = { return function ( eye, target, up ) { - if ( x === undefined ) x = new THREE.Vector3(); - if ( y === undefined ) y = new THREE.Vector3(); - if ( z === undefined ) z = new THREE.Vector3(); + if ( x === undefined ) { + + x = new THREE.Vector3(); + y = new THREE.Vector3(); + z = new THREE.Vector3(); + + } var te = this.elements; @@ -5049,7 +5098,7 @@ THREE.Matrix4.prototype = { if ( x.lengthSq() === 0 ) { - z.x += 0.0001; + z.z += 0.0001; x.crossVectors( up, z ).normalize(); } @@ -5080,6 +5129,12 @@ THREE.Matrix4.prototype = { }, + premultiply: function ( m ) { + + return this.multiplyMatrices( m, this ); + + }, + multiplyMatrices: function ( a, b ) { var ae = a.elements; @@ -5269,29 +5324,10 @@ THREE.Matrix4.prototype = { flattenToArrayOffset: function ( array, offset ) { - var te = this.elements; + console.warn( "THREE.Matrix3: .flattenToArrayOffset is deprecated " + + "- just use .toArray instead." ); - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - array[ offset + 3 ] = te[ 3 ]; - - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; - - array[ offset + 8 ] = te[ 8 ]; - array[ offset + 9 ] = te[ 9 ]; - array[ offset + 10 ] = te[ 10 ]; - array[ offset + 11 ] = te[ 11 ]; - - array[ offset + 12 ] = te[ 12 ]; - array[ offset + 13 ] = te[ 13 ]; - array[ offset + 14 ] = te[ 14 ]; - array[ offset + 15 ] = te[ 15 ]; - - return array; + return this.toArray( array, offset ); }, @@ -5304,8 +5340,7 @@ THREE.Matrix4.prototype = { if ( v1 === undefined ) v1 = new THREE.Vector3(); console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' ); - var te = this.elements; - return v1.set( te[ 12 ], te[ 13 ], te[ 14 ] ); + return v1.setFromMatrixColumn( this, 3 ); }; @@ -5323,41 +5358,29 @@ THREE.Matrix4.prototype = { }, - getInverse: function ( m, throwOnInvertible ) { + getInverse: function ( m, throwOnDegenerate ) { // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - var te = this.elements; - var me = m.elements; + var te = this.elements, + me = m.elements, - var n11 = me[ 0 ], n12 = me[ 4 ], n13 = me[ 8 ], n14 = me[ 12 ]; - var n21 = me[ 1 ], n22 = me[ 5 ], n23 = me[ 9 ], n24 = me[ 13 ]; - var n31 = me[ 2 ], n32 = me[ 6 ], n33 = me[ 10 ], n34 = me[ 14 ]; - var n41 = me[ 3 ], n42 = me[ 7 ], n43 = me[ 11 ], n44 = me[ 15 ]; + n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ], + n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ], + n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ], + n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ], - te[ 0 ] = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44; - te[ 4 ] = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44; - te[ 8 ] = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44; - te[ 12 ] = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; - te[ 1 ] = n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44; - te[ 5 ] = n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44; - te[ 9 ] = n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44; - te[ 13 ] = n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34; - te[ 2 ] = n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44; - te[ 6 ] = n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44; - te[ 10 ] = n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44; - te[ 14 ] = n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34; - te[ 3 ] = n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43; - te[ 7 ] = n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43; - te[ 11 ] = n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43; - te[ 15 ] = n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33; + t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, + t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, + t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, + t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; - var det = n11 * te[ 0 ] + n21 * te[ 4 ] + n31 * te[ 8 ] + n41 * te[ 12 ]; + var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; if ( det === 0 ) { var msg = "THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0"; - if ( throwOnInvertible || false ) { + if ( throwOnDegenerate || false ) { throw new Error( msg ); @@ -5367,13 +5390,31 @@ THREE.Matrix4.prototype = { } - this.identity(); - - return this; + return this.identity(); } + + var detInv = 1 / det; - this.multiplyScalar( 1 / det ); + te[ 0 ] = t11 * detInv; + te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; + te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; + te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; + + te[ 4 ] = t12 * detInv; + te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; + te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; + te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; + + te[ 8 ] = t13 * detInv; + te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; + te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; + te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; + + te[ 12 ] = t14 * detInv; + te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; + te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; + te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; return this; @@ -5525,8 +5566,12 @@ THREE.Matrix4.prototype = { return function ( position, quaternion, scale ) { - if ( vector === undefined ) vector = new THREE.Vector3(); - if ( matrix === undefined ) matrix = new THREE.Matrix4(); + if ( vector === undefined ) { + + vector = new THREE.Vector3(); + matrix = new THREE.Matrix4(); + + } var te = this.elements; @@ -5600,7 +5645,7 @@ THREE.Matrix4.prototype = { makePerspective: function ( fov, aspect, near, far ) { - var ymax = near * Math.tan( THREE.Math.degToRad( fov * 0.5 ) ); + var ymax = near * Math.tan( THREE.Math.DEG2RAD * fov * 0.5 ); var ymin = - ymax; var xmin = ymin * aspect; var xmax = ymax * aspect; @@ -5612,17 +5657,17 @@ THREE.Matrix4.prototype = { makeOrthographic: function ( left, right, top, bottom, near, far ) { var te = this.elements; - var w = right - left; - var h = top - bottom; - var p = far - near; + var w = 1.0 / ( right - left ); + var h = 1.0 / ( top - bottom ); + var p = 1.0 / ( far - near ); - var x = ( right + left ) / w; - var y = ( top + bottom ) / h; - var z = ( far + near ) / p; + var x = ( right + left ) * w; + var y = ( top + bottom ) * h; + var z = ( far + near ) * p; - te[ 0 ] = 2 / w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; - te[ 1 ] = 0; te[ 5 ] = 2 / h; te[ 9 ] = 0; te[ 13 ] = - y; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 / p; te[ 14 ] = - z; + te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; + te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; return this; @@ -5652,16 +5697,34 @@ THREE.Matrix4.prototype = { }, - toArray: function () { + toArray: function ( array, offset ) { + + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; var te = this.elements; - return [ - te[ 0 ], te[ 1 ], te[ 2 ], te[ 3 ], - te[ 4 ], te[ 5 ], te[ 6 ], te[ 7 ], - te[ 8 ], te[ 9 ], te[ 10 ], te[ 11 ], - te[ 12 ], te[ 13 ], te[ 14 ], te[ 15 ] - ]; + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + array[ offset + 3 ] = te[ 3 ]; + + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + + array[ offset + 8 ] = te[ 8 ]; + array[ offset + 9 ] = te[ 9 ]; + array[ offset + 10 ] = te[ 10 ]; + array[ offset + 11 ] = te[ 11 ]; + + array[ offset + 12 ] = te[ 12 ]; + array[ offset + 13 ] = te[ 13 ]; + array[ offset + 14 ] = te[ 14 ]; + array[ offset + 15 ] = te[ 15 ]; + + return array; } @@ -5720,6 +5783,8 @@ THREE.Ray.prototype = { this.direction.copy( v ).sub( this.origin ).normalize(); + return this; + }, recast: function () { @@ -5790,7 +5855,7 @@ THREE.Ray.prototype = { return function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - // from http://www.geometrictools.com/LibMathematics/Distance/Wm5DistRay3Segment3.cpp + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h // It returns the min distance between the ray and the segment // defined by v0 and v1 // It can also set two optional targets : @@ -5941,7 +6006,7 @@ THREE.Ray.prototype = { // else t0 is in front of the ray, so return the first collision point scaled by t0 return this.at( t0, optionalTarget ); - } + }; }(), @@ -6111,7 +6176,7 @@ THREE.Ray.prototype = { return function ( a, b, c, backfaceCulling, optionalTarget ) { - // from http://www.geometrictools.com/LibMathematics/Intersection/Wm5IntrRay3Triangle3.cpp + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h edge1.subVectors( b, a ); edge2.subVectors( c, a ); @@ -6470,10 +6535,27 @@ THREE.Frustum.prototype = { var geometry = object.geometry; - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + if ( geometry.boundingSphere === null ) + geometry.computeBoundingSphere(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( object.matrixWorld ); + sphere.copy( geometry.boundingSphere ) + .applyMatrix4( object.matrixWorld ); + + return this.intersectsSphere( sphere ); + + }; + + }(), + + intersectsSprite: function () { + + var sphere = new THREE.Sphere(); + + return function ( sprite ) { + + sphere.center.set( 0, 0, 0 ); + sphere.radius = 0.7071067811865476; + sphere.applyMatrix4( sprite.matrixWorld ); return this.intersectsSphere( sphere ); @@ -6762,20 +6844,19 @@ THREE.Plane.prototype = { applyMatrix4: function () { var v1 = new THREE.Vector3(); - var v2 = new THREE.Vector3(); var m1 = new THREE.Matrix3(); return function ( matrix, optionalNormalMatrix ) { - // compute new normal based on theory here: + var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix ); + + // transform normal based on theory here: // http://www.songho.ca/opengl/gl_normaltransform.html var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); - var newNormal = v1.copy( this.normal ).applyMatrix3( normalMatrix ); + var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); - var newCoplanarPoint = this.coplanarPoint( v2 ); - newCoplanarPoint.applyMatrix4( matrix ); - - this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint ); + // recalculate constant (like in setFromNormalAndCoplanarPoint) + this.constant = - referencePoint.dot( normal ); return this; @@ -6799,6 +6880,90 @@ THREE.Plane.prototype = { }; +// File:src/math/Spherical.js + +/** + * @author bhouston / http://clara.io + * @author WestLangley / http://github.com/WestLangley + * + * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system + * + * The poles (phi) are at the positive and negative y axis. + * The equator starts at positive z. + */ + +THREE.Spherical = function ( radius, phi, theta ) { + + this.radius = ( radius !== undefined ) ? radius : 1.0; + this.phi = ( phi !== undefined ) ? phi : 0; // up / down towards top and bottom pole + this.theta = ( theta !== undefined ) ? theta : 0; // around the equator of the sphere + + return this; + +}; + +THREE.Spherical.prototype = { + + constructor: THREE.Spherical, + + set: function ( radius, phi, theta ) { + + this.radius = radius; + this.phi = phi; + this.theta = theta; + + return this; + + }, + + clone: function () { + + return new this.constructor().copy( this ); + + }, + + copy: function ( other ) { + + this.radius.copy( other.radius ); + this.phi.copy( other.phi ); + this.theta.copy( other.theta ); + + return this; + + }, + + // restrict phi to be betwee EPS and PI-EPS + makeSafe: function() { + + var EPS = 0.000001; + this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) ); + + return this; + + }, + + setFromVector3: function( vec3 ) { + + this.radius = vec3.length(); + + if ( this.radius === 0 ) { + + this.theta = 0; + this.phi = 0; + + } else { + + this.theta = Math.atan2( vec3.x, vec3.z ); // equator angle around y-up axis + this.phi = Math.acos( THREE.Math.clamp( vec3.y / this.radius, - 1, 1 ) ); // polar angle + + } + + return this; + + }, + +}; + // File:src/math/Math.js /** @@ -6808,6 +6973,9 @@ THREE.Plane.prototype = { THREE.Math = { + DEG2RAD: Math.PI / 180, + RAD2DEG: 180 / Math.PI, + generateUUID: function () { // http://www.broofa.com/Tools/Math.uuid.htm @@ -6923,29 +7091,17 @@ THREE.Math = { }, - degToRad: function () { + degToRad: function ( degrees ) { - var degreeToRadiansFactor = Math.PI / 180; + return degrees * THREE.Math.DEG2RAD; - return function ( degrees ) { + }, - return degrees * degreeToRadiansFactor; + radToDeg: function ( radians ) { - }; + return radians * THREE.Math.RAD2DEG; - }(), - - radToDeg: function () { - - var radianToDegreesFactor = 180 / Math.PI; - - return function ( radians ) { - - return radians * radianToDegreesFactor; - - }; - - }(), + }, isPowerOfTwo: function ( value ) { @@ -7341,6 +7497,69 @@ THREE.Triangle.prototype = { }, + closestPointToPoint: function () { + + var plane, edgeList, projectedPoint, closestPoint; + + return function closestPointToPoint( point, optionalTarget ) { + + if ( plane === undefined ) { + + plane = new THREE.Plane(); + edgeList = [ new THREE.Line3(), new THREE.Line3(), new THREE.Line3() ]; + projectedPoint = new THREE.Vector3(); + closestPoint = new THREE.Vector3(); + + } + + var result = optionalTarget || new THREE.Vector3(); + var minDistance = Infinity; + + // project the point onto the plane of the triangle + + plane.setFromCoplanarPoints( this.a, this.b, this.c ); + plane.projectPoint( point, projectedPoint ); + + // check if the projection lies within the triangle + + if( this.containsPoint( projectedPoint ) === true ) { + + // if so, this is the closest point + + result.copy( projectedPoint ); + + } else { + + // if not, the point falls outside the triangle. the result is the closest point to the triangle's edges or vertices + + edgeList[ 0 ].set( this.a, this.b ); + edgeList[ 1 ].set( this.b, this.c ); + edgeList[ 2 ].set( this.c, this.a ); + + for( var i = 0; i < edgeList.length; i ++ ) { + + edgeList[ i ].closestPointToPoint( projectedPoint, true, closestPoint ); + + var distance = projectedPoint.distanceToSquared( closestPoint ); + + if( distance < minDistance ) { + + minDistance = distance; + + result.copy( closestPoint ); + + } + + } + + } + + return result; + + }; + + }(), + equals: function ( triangle ) { return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); @@ -7908,7 +8127,7 @@ THREE.Clock.prototype = { start: function () { - this.startTime = performance.now(); + this.startTime = ( performance || Date ).now(); this.oldTime = this.startTime; this.running = true; @@ -7941,9 +8160,9 @@ THREE.Clock.prototype = { if ( this.running ) { - var newTime = performance.now(); + var newTime = ( performance || Date ).now(); - diff = 0.001 * ( newTime - this.oldTime ); + diff = ( newTime - this.oldTime ) / 1000; this.oldTime = newTime; this.elapsedTime += diff; @@ -7964,18 +8183,7 @@ THREE.Clock.prototype = { THREE.EventDispatcher = function () {}; -THREE.EventDispatcher.prototype = { - - constructor: THREE.EventDispatcher, - - apply: function ( object ) { - - object.addEventListener = THREE.EventDispatcher.prototype.addEventListener; - object.hasEventListener = THREE.EventDispatcher.prototype.hasEventListener; - object.removeEventListener = THREE.EventDispatcher.prototype.removeEventListener; - object.dispatchEvent = THREE.EventDispatcher.prototype.dispatchEvent; - - }, +Object.assign( THREE.EventDispatcher.prototype, { addEventListener: function ( type, listener ) { @@ -8045,16 +8253,16 @@ THREE.EventDispatcher.prototype = { event.target = this; - var array = []; + var array = [], i = 0; var length = listenerArray.length; - for ( var i = 0; i < length; i ++ ) { + for ( i = 0; i < length; i ++ ) { array[ i ] = listenerArray[ i ]; } - for ( var i = 0; i < length; i ++ ) { + for ( i = 0; i < length; i ++ ) { array[ i ].call( this, event ); @@ -8064,7 +8272,7 @@ THREE.EventDispatcher.prototype = { } -}; +} ); // File:src/core/Layers.js @@ -8321,8 +8529,6 @@ THREE.Object3D = function () { } } ); - this.rotationAutoUpdate = true; - this.matrix = new THREE.Matrix4(); this.matrixWorld = new THREE.Matrix4(); @@ -8345,9 +8551,7 @@ THREE.Object3D = function () { THREE.Object3D.DefaultUp = new THREE.Vector3( 0, 1, 0 ); THREE.Object3D.DefaultMatrixAutoUpdate = true; -THREE.Object3D.prototype = { - - constructor: THREE.Object3D, +Object.assign( THREE.Object3D.prototype, THREE.EventDispatcher.prototype, { applyMatrix: function ( matrix ) { @@ -8802,7 +9006,8 @@ THREE.Object3D.prototype = { toJSON: function ( meta ) { - var isRootObject = ( meta === undefined ); + // meta is '' when called from JSON.stringify + var isRootObject = ( meta === undefined || meta === '' ); var output = {}; @@ -8937,8 +9142,6 @@ THREE.Object3D.prototype = { this.quaternion.copy( source.quaternion ); this.scale.copy( source.scale ); - this.rotationAutoUpdate = source.rotationAutoUpdate; - this.matrix.copy( source.matrix ); this.matrixWorld.copy( source.matrixWorld ); @@ -8970,9 +9173,7 @@ THREE.Object3D.prototype = { } -}; - -THREE.EventDispatcher.prototype.apply( THREE.Object3D.prototype ); +} ); THREE.Object3DIdCount = 0; @@ -9044,7 +9245,7 @@ THREE.Face3.prototype = { * @author mrdoob / http://mrdoob.com/ */ -THREE.BufferAttribute = function ( array, itemSize ) { +THREE.BufferAttribute = function ( array, itemSize, normalized ) { this.uuid = THREE.Math.generateUUID(); @@ -9055,6 +9256,7 @@ THREE.BufferAttribute = function ( array, itemSize ) { this.updateRange = { offset: 0, count: - 1 }; this.version = 0; + this.normalized = normalized === true; }; @@ -9733,9 +9935,7 @@ THREE.Geometry = function () { }; -THREE.Geometry.prototype = { - - constructor: THREE.Geometry, +Object.assign( THREE.Geometry.prototype, THREE.EventDispatcher.prototype, { applyMatrix: function ( matrix ) { @@ -9776,6 +9976,8 @@ THREE.Geometry.prototype = { this.verticesNeedUpdate = true; this.normalsNeedUpdate = true; + return this; + }, rotateX: function () { @@ -9945,12 +10147,12 @@ THREE.Geometry.prototype = { } - function addFace( a, b, c ) { + function addFace( a, b, c, materialIndex ) { var vertexNormals = normals !== undefined ? [ tempNormals[ a ].clone(), tempNormals[ b ].clone(), tempNormals[ c ].clone() ] : []; var vertexColors = colors !== undefined ? [ scope.colors[ a ].clone(), scope.colors[ b ].clone(), scope.colors[ c ].clone() ] : []; - var face = new THREE.Face3( a, b, c, vertexNormals, vertexColors ); + var face = new THREE.Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); scope.faces.push( face ); @@ -9983,7 +10185,7 @@ THREE.Geometry.prototype = { for ( var j = start, jl = start + count; j < jl; j += 3 ) { - addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ] ); + addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); } @@ -10889,9 +11091,7 @@ THREE.Geometry.prototype = { } -}; - -THREE.EventDispatcher.prototype.apply( THREE.Geometry.prototype ); +} ); THREE.GeometryIdCount = 0; @@ -10939,9 +11139,7 @@ THREE.DirectGeometry = function () { }; -THREE.DirectGeometry.prototype = { - - constructor: THREE.DirectGeometry, +Object.assign( THREE.DirectGeometry.prototype, THREE.EventDispatcher.prototype, { computeBoundingBox: THREE.Geometry.prototype.computeBoundingBox, computeBoundingSphere: THREE.Geometry.prototype.computeBoundingSphere, @@ -11184,9 +11382,7 @@ THREE.DirectGeometry.prototype = { } -}; - -THREE.EventDispatcher.prototype.apply( THREE.DirectGeometry.prototype ); +} ); // File:src/core/BufferGeometry.js @@ -11218,9 +11414,7 @@ THREE.BufferGeometry = function () { }; -THREE.BufferGeometry.prototype = { - - constructor: THREE.BufferGeometry, +Object.assign( THREE.BufferGeometry.prototype, THREE.EventDispatcher.prototype, { getIndex: function () { @@ -11334,6 +11528,8 @@ THREE.BufferGeometry.prototype = { } + return this; + }, rotateX: function () { @@ -11742,47 +11938,38 @@ THREE.BufferGeometry.prototype = { computeBoundingBox: function () { - var vector = new THREE.Vector3(); + if ( this.boundingBox === null ) { - return function () { + this.boundingBox = new THREE.Box3(); - if ( this.boundingBox === null ) { + } - this.boundingBox = new THREE.Box3(); + var positions = this.attributes.position.array; - } + if ( positions !== undefined ) { - var positions = this.attributes.position.array; + this.boundingBox.setFromArray( positions ); - if ( positions ) { + } else { - this.boundingBox.setFromArray( positions ); + this.boundingBox.makeEmpty(); - } + } - if ( positions === undefined || positions.length === 0 ) { + if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - this.boundingBox.min.set( 0, 0, 0 ); - this.boundingBox.max.set( 0, 0, 0 ); + console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); - } + } - if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - - console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); - - } - - }; - - }(), + }, computeBoundingSphere: function () { var box = new THREE.Box3(); var vector = new THREE.Vector3(); - return function () { + return function computeBoundingSphere() { if ( this.boundingSphere === null ) { @@ -12117,7 +12304,8 @@ THREE.BufferGeometry.prototype = { data.data.attributes[ key ] = { itemSize: attribute.itemSize, type: attribute.array.constructor.name, - array: array + array: array, + normalized: attribute.normalized }; } @@ -12199,7 +12387,7 @@ THREE.BufferGeometry.prototype = { for ( var i = 0, l = groups.length; i < l; i ++ ) { var group = groups[ i ]; - this.addGroup( group.start, group.count ); + this.addGroup( group.start, group.count, group.materialIndex ); } @@ -12213,9 +12401,7 @@ THREE.BufferGeometry.prototype = { } -}; - -THREE.EventDispatcher.prototype.apply( THREE.BufferGeometry.prototype ); +} ); THREE.BufferGeometry.MaxIndex = 65535; @@ -12281,17 +12467,21 @@ THREE.InstancedBufferGeometry.prototype.copy = function ( source ) { }; -THREE.EventDispatcher.prototype.apply( THREE.InstancedBufferGeometry.prototype ); - // File:src/core/Uniform.js /** * @author mrdoob / http://mrdoob.com/ */ -THREE.Uniform = function ( type, value ) { +THREE.Uniform = function ( value ) { + + if ( typeof value === 'string' ) { + + console.warn( 'THREE.Uniform: Type parameter is no longer needed.' ); + value = arguments[ 1 ]; + + } - this.type = type; this.value = value; this.dynamic = false; @@ -12313,635 +12503,28 @@ THREE.Uniform.prototype = { }; -// File:src/animation/AnimationClip.js +// File:src/animation/AnimationAction.js /** * - * Reusable set of Tracks that represent an animation. - * - * @author Ben Houston / http://clara.io/ - * @author David Sarno / http://lighthaus.us/ - */ - -THREE.AnimationClip = function ( name, duration, tracks ) { - - this.name = name || THREE.Math.generateUUID(); - this.tracks = tracks; - this.duration = ( duration !== undefined ) ? duration : -1; - - // this means it should figure out its duration by scanning the tracks - if ( this.duration < 0 ) { - - this.resetDuration(); - - } - - // maybe only do these on demand, as doing them here could potentially slow down loading - // but leaving these here during development as this ensures a lot of testing of these functions - this.trim(); - this.optimize(); - -}; - -THREE.AnimationClip.prototype = { - - constructor: THREE.AnimationClip, - - resetDuration: function() { - - var tracks = this.tracks, - duration = 0; - - for ( var i = 0, n = tracks.length; i !== n; ++ i ) { - - var track = this.tracks[ i ]; - - duration = Math.max( - duration, track.times[ track.times.length - 1 ] ); - - } - - this.duration = duration; - - }, - - trim: function() { - - for ( var i = 0; i < this.tracks.length; i ++ ) { - - this.tracks[ i ].trim( 0, this.duration ); - - } - - return this; - - }, - - optimize: function() { - - for ( var i = 0; i < this.tracks.length; i ++ ) { - - this.tracks[ i ].optimize(); - - } - - return this; - - } - -}; - -// Static methods: - -Object.assign( THREE.AnimationClip, { - - parse: function( json ) { - - var tracks = [], - jsonTracks = json.tracks, - frameTime = 1.0 / ( json.fps || 1.0 ); - - for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) { - - tracks.push( THREE.KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) ); - - } - - return new THREE.AnimationClip( json.name, json.duration, tracks ); - - }, - - - toJSON: function( clip ) { - - var tracks = [], - clipTracks = clip.tracks; - - var json = { - - 'name': clip.name, - 'duration': clip.duration, - 'tracks': tracks - - }; - - for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) { - - tracks.push( THREE.KeyframeTrack.toJSON( clipTracks[ i ] ) ); - - } - - return json; - - }, - - - CreateFromMorphTargetSequence: function( name, morphTargetSequence, fps ) { - - var numMorphTargets = morphTargetSequence.length; - var tracks = []; - - for ( var i = 0; i < numMorphTargets; i ++ ) { - - var times = []; - var values = []; - - times.push( - ( i + numMorphTargets - 1 ) % numMorphTargets, - i, - ( i + 1 ) % numMorphTargets ); - - values.push( 0, 1, 0 ); - - var order = THREE.AnimationUtils.getKeyframeOrder( times ); - times = THREE.AnimationUtils.sortedArray( times, 1, order ); - values = THREE.AnimationUtils.sortedArray( values, 1, order ); - - // if there is a key at the first frame, duplicate it as the - // last frame as well for perfect loop. - if ( times[ 0 ] === 0 ) { - - times.push( numMorphTargets ); - values.push( values[ 0 ] ); - - } - - tracks.push( - new THREE.NumberKeyframeTrack( - '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']', - times, values - ).scale( 1.0 / fps ) ); - } - - return new THREE.AnimationClip( name, -1, tracks ); - - }, - - findByName: function( clipArray, name ) { - - for ( var i = 0; i < clipArray.length; i ++ ) { - - if ( clipArray[ i ].name === name ) { - - return clipArray[ i ]; - - } - } - - return null; - - }, - - CreateClipsFromMorphTargetSequences: function( morphTargets, fps ) { - - var animationToMorphTargets = {}; - - // tested with https://regex101.com/ on trick sequences - // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 - var pattern = /^([\w-]*?)([\d]+)$/; - - // sort morph target names into animation groups based - // patterns like Walk_001, Walk_002, Run_001, Run_002 - for ( var i = 0, il = morphTargets.length; i < il; i ++ ) { - - var morphTarget = morphTargets[ i ]; - var parts = morphTarget.name.match( pattern ); - - if ( parts && parts.length > 1 ) { - - var name = parts[ 1 ]; - - var animationMorphTargets = animationToMorphTargets[ name ]; - if ( ! animationMorphTargets ) { - - animationToMorphTargets[ name ] = animationMorphTargets = []; - - } - - animationMorphTargets.push( morphTarget ); - - } - - } - - var clips = []; - - for ( var name in animationToMorphTargets ) { - - clips.push( THREE.AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps ) ); - - } - - return clips; - - }, - - // parse the animation.hierarchy format - parseAnimation: function( animation, bones, nodeName ) { - - if ( ! animation ) { - - console.error( " no animation in JSONLoader data" ); - return null; - - } - - var addNonemptyTrack = function( - trackType, trackName, animationKeys, propertyName, destTracks ) { - - // only return track if there are actually keys. - if ( animationKeys.length !== 0 ) { - - var times = []; - var values = []; - - THREE.AnimationUtils.flattenJSON( - animationKeys, times, values, propertyName ); - - // empty keys are filtered out, so check again - if ( times.length !== 0 ) { - - destTracks.push( new trackType( trackName, times, values ) ); - - } - - } - - }; - - var tracks = []; - - var clipName = animation.name || 'default'; - // automatic length determination in AnimationClip. - var duration = animation.length || -1; - var fps = animation.fps || 30; - - var hierarchyTracks = animation.hierarchy || []; - - for ( var h = 0; h < hierarchyTracks.length; h ++ ) { - - var animationKeys = hierarchyTracks[ h ].keys; - - // skip empty tracks - if ( ! animationKeys || animationKeys.length == 0 ) continue; - - // process morph targets in a way exactly compatible - // with AnimationHandler.init( animation ) - if ( animationKeys[0].morphTargets ) { - - // figure out all morph targets used in this track - var morphTargetNames = {}; - for ( var k = 0; k < animationKeys.length; k ++ ) { - - if ( animationKeys[k].morphTargets ) { - - for ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) { - - morphTargetNames[ animationKeys[k].morphTargets[m] ] = -1; - } - - } - - } - - // create a track for each morph target with all zero - // morphTargetInfluences except for the keys in which - // the morphTarget is named. - for ( var morphTargetName in morphTargetNames ) { - - var times = []; - var values = []; - - for ( var m = 0; - m !== animationKeys[k].morphTargets.length; ++ m ) { - - var animationKey = animationKeys[k]; - - times.push( animationKey.time ); - values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 ) - - } - - tracks.push( new THREE.NumberKeyframeTrack( - '.morphTargetInfluence[' + morphTargetName + ']', times, values ) ); - - } - - duration = morphTargetNames.length * ( fps || 1.0 ); - - } else { - // ...assume skeletal animation - - var boneName = '.bones[' + bones[ h ].name + ']'; - - addNonemptyTrack( - THREE.VectorKeyframeTrack, boneName + '.position', - animationKeys, 'pos', tracks ); - - addNonemptyTrack( - THREE.QuaternionKeyframeTrack, boneName + '.quaternion', - animationKeys, 'rot', tracks ); - - addNonemptyTrack( - THREE.VectorKeyframeTrack, boneName + '.scale', - animationKeys, 'scl', tracks ); - - } - - } - - if ( tracks.length === 0 ) { - - return null; - - } - - var clip = new THREE.AnimationClip( clipName, duration, tracks ); - - return clip; - - } - -} ); - - -// File:src/animation/AnimationMixer.js - -/** - * - * Player for AnimationClips. - * + * Action provided by AnimationMixer for scheduling clip playback on specific + * objects. * * @author Ben Houston / http://clara.io/ * @author David Sarno / http://lighthaus.us/ * @author tschw + * */ -THREE.AnimationMixer = function( root ) { +THREE.AnimationAction = function() { - this._root = root; - this._initMemoryManager(); - this._accuIndex = 0; - - this.time = 0; - - this.timeScale = 1.0; + throw new Error( "THREE.AnimationAction: " + + "Use mixer.clipAction for construction." ); }; -THREE.AnimationMixer.prototype = { - - constructor: THREE.AnimationMixer, - - // return an action for a clip optionally using a custom root target - // object (this method allocates a lot of dynamic memory in case a - // previously unknown clip/root combination is specified) - clipAction: function( clip, optionalRoot ) { - - var root = optionalRoot || this._root, - rootUuid = root.uuid, - clipName = ( typeof clip === 'string' ) ? clip : clip.name, - clipObject = ( clip !== clipName ) ? clip : null, - - actionsForClip = this._actionsByClip[ clipName ], - prototypeAction; - - if ( actionsForClip !== undefined ) { - - var existingAction = - actionsForClip.actionByRoot[ rootUuid ]; - - if ( existingAction !== undefined ) { - - return existingAction; - - } - - // we know the clip, so we don't have to parse all - // the bindings again but can just copy - prototypeAction = actionsForClip.knownActions[ 0 ]; - - // also, take the clip from the prototype action - clipObject = prototypeAction._clip; - - if ( clip !== clipName && clip !== clipObject ) { - - throw new Error( - "Different clips with the same name detected!" ); - - } - - } - - // clip must be known when specified via string - if ( clipObject === null ) return null; - - // allocate all resources required to run it - var newAction = new THREE. - AnimationMixer._Action( this, clipObject, optionalRoot ); - - this._bindAction( newAction, prototypeAction ); - - // and make the action known to the memory manager - this._addInactiveAction( newAction, clipName, rootUuid ); - - return newAction; - - }, - - // get an existing action - existingAction: function( clip, optionalRoot ) { - - var root = optionalRoot || this._root, - rootUuid = root.uuid, - clipName = ( typeof clip === 'string' ) ? clip : clip.name, - actionsForClip = this._actionsByClip[ clipName ]; - - if ( actionsForClip !== undefined ) { - - return actionsForClip.actionByRoot[ rootUuid ] || null; - - } - - return null; - - }, - - // deactivates all previously scheduled actions - stopAllAction: function() { - - var actions = this._actions, - nActions = this._nActiveActions, - bindings = this._bindings, - nBindings = this._nActiveBindings; - - this._nActiveActions = 0; - this._nActiveBindings = 0; - - for ( var i = 0; i !== nActions; ++ i ) { - - actions[ i ].reset(); - - } - - for ( var i = 0; i !== nBindings; ++ i ) { - - bindings[ i ].useCount = 0; - - } - - return this; - - }, - - // advance the time and update apply the animation - update: function( deltaTime ) { - - deltaTime *= this.timeScale; - - var actions = this._actions, - nActions = this._nActiveActions, - - time = this.time += deltaTime, - timeDirection = Math.sign( deltaTime ), - - accuIndex = this._accuIndex ^= 1; - - // run active actions - - for ( var i = 0; i !== nActions; ++ i ) { - - var action = actions[ i ]; - - if ( action.enabled ) { - - action._update( time, deltaTime, timeDirection, accuIndex ); - - } - - } - - // update scene graph - - var bindings = this._bindings, - nBindings = this._nActiveBindings; - - for ( var i = 0; i !== nBindings; ++ i ) { - - bindings[ i ].apply( accuIndex ); - - } - - return this; - - }, - - // return this mixer's root target object - getRoot: function() { - - return this._root; - - }, - - // free all resources specific to a particular clip - uncacheClip: function( clip ) { - - var actions = this._actions, - clipName = clip.name, - actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[ clipName ]; - - if ( actionsForClip !== undefined ) { - - // note: just calling _removeInactiveAction would mess up the - // iteration state and also require updating the state we can - // just throw away - - var actionsToRemove = actionsForClip.knownActions; - - for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) { - - var action = actionsToRemove[ i ]; - - this._deactivateAction( action ); - - var cacheIndex = action._cacheIndex, - lastInactiveAction = actions[ actions.length - 1 ]; - - action._cacheIndex = null; - action._byClipCacheIndex = null; - - lastInactiveAction._cacheIndex = cacheIndex; - actions[ cacheIndex ] = lastInactiveAction; - actions.pop(); - - this._removeInactiveBindingsForAction( action ); - - } - - delete actionsByClip[ clipName ]; - - } - - }, - - // free all resources specific to a particular root target object - uncacheRoot: function( root ) { - - var rootUuid = root.uuid, - actionsByClip = this._actionsByClip; - - for ( var clipName in actionsByClip ) { - - var actionByRoot = actionsByClip[ clipName ].actionByRoot, - action = actionByRoot[ rootUuid ]; - - if ( action !== undefined ) { - - this._deactivateAction( action ); - this._removeInactiveAction( action ); - - } - - } - - var bindingsByRoot = this._bindingsByRootAndName, - bindingByName = bindingsByRoot[ rootUuid ]; - - if ( bindingByName !== undefined ) { - - for ( var trackName in bindingByName ) { - - var binding = bindingByName[ trackName ]; - binding.restoreOriginalState(); - this._removeInactiveBinding( binding ); - - } - - } - - }, - - // remove a targeted clip from the cache - uncacheAction: function( clip, optionalRoot ) { - - var action = this.existingAction( clip, optionalRoot ); - - if ( action !== null ) { - - this._deactivateAction( action ); - this._removeInactiveAction( action ); - - } - - } - -}; - -THREE.EventDispatcher.prototype.apply( THREE.AnimationMixer.prototype ); - -THREE.AnimationMixer._Action = - function( mixer, clip, localRoot ) { +THREE.AnimationAction._new = + function AnimationAction( mixer, clip, localRoot ) { this._mixer = mixer; this._clip = clip; @@ -12960,7 +12543,7 @@ THREE.AnimationMixer._Action = var interpolant = tracks[ i ].createInterpolant( null ); interpolants[ i ] = interpolant; - interpolant.settings = interpolantSettings + interpolant.settings = interpolantSettings; } @@ -13006,9 +12589,9 @@ THREE.AnimationMixer._Action = }; -THREE.AnimationMixer._Action.prototype = { +THREE.AnimationAction._new.prototype = { - constructor: THREE.AnimationMixer._Action, + constructor: THREE.AnimationAction._new, // State & Scheduling @@ -13046,7 +12629,7 @@ THREE.AnimationMixer._Action.prototype = { var start = this._startTime; return this.enabled && ! this.paused && this.timeScale !== 0 && - this._startTime === null && this._mixer._isActiveAction( this ) + this._startTime === null && this._mixer._isActiveAction( this ); }, @@ -13194,7 +12777,7 @@ THREE.AnimationMixer._Action.prototype = { halt: function( duration ) { - return this.warp( this._currentTimeScale, 0, duration ); + return this.warp( this._effectiveTimeScale, 0, duration ); }, @@ -13371,7 +12954,7 @@ THREE.AnimationMixer._Action.prototype = { if ( timeScale === 0 ) { // motion has halted, pause - this.pause = true; + this.paused = true; } else { @@ -13400,22 +12983,19 @@ THREE.AnimationMixer._Action.prototype = { var duration = this._clip.duration, loop = this.loop, - loopCount = this._loopCount, + loopCount = this._loopCount; - pingPong = false; + if ( loop === THREE.LoopOnce ) { - switch ( loop ) { + if ( loopCount === -1 ) { + // just started - case THREE.LoopOnce: + this.loopCount = 0; + this._setEndings( true, true, false ); - if ( loopCount === -1 ) { + } - // just started - - this.loopCount = 0; - this._setEndings( true, true, false ); - - } + handle_stop: { if ( time >= duration ) { @@ -13425,11 +13005,9 @@ THREE.AnimationMixer._Action.prototype = { time = 0; - } else break; + } else break handle_stop; - // reached the end - - if ( this.clampWhenFinished ) this.pause = true; + if ( this.clampWhenFinished ) this.paused = true; else this.enabled = false; this._mixer.dispatchEvent( { @@ -13437,68 +13015,63 @@ THREE.AnimationMixer._Action.prototype = { direction: deltaTime < 0 ? -1 : 1 } ); - break; + } - case THREE.LoopPingPong: + } else { // repetitive Repeat or PingPong - pingPong = true; + var pingPong = ( loop === THREE.LoopPingPong ); - case THREE.LoopRepeat: + if ( loopCount === -1 ) { + // just started - if ( loopCount === -1 ) { + if ( deltaTime >= 0 ) { - // just started + loopCount = 0; - if ( deltaTime > 0 ) { + this._setEndings( + true, this.repetitions === 0, pingPong ); - loopCount = 0; + } else { - this._setEndings( - true, this.repetitions === 0, pingPong ); + // when looping in reverse direction, the initial + // transition through zero counts as a repetition, + // so leave loopCount at -1 - } else { - - // when looping in reverse direction, the initial - // transition through zero counts as a repetition, - // so leave loopCount at -1 - - this._setEndings( - this.repetitions === 0, true, pingPong ); - - } + this._setEndings( + this.repetitions === 0, true, pingPong ); } - if ( time >= duration || time < 0 ) { + } - // wrap around + if ( time >= duration || time < 0 ) { + // wrap around - var loopDelta = Math.floor( time / duration ); // signed - time -= duration * loopDelta; + var loopDelta = Math.floor( time / duration ); // signed + time -= duration * loopDelta; - loopCount += Math.abs( loopDelta ); + loopCount += Math.abs( loopDelta ); - var pending = this.repetitions - loopCount; + var pending = this.repetitions - loopCount; - if ( pending < 0 ) { + if ( pending < 0 ) { + // have to stop (switch state, clamp time, fire event) - // stop (switch state, clamp time, fire event) + if ( this.clampWhenFinished ) this.paused = true; + else this.enabled = false; - if ( this.clampWhenFinished ) this.paused = true; - else this.enabled = false; + time = deltaTime > 0 ? duration : 0; - time = deltaTime > 0 ? duration : 0; + this._mixer.dispatchEvent( { + type: 'finished', action: this, + direction: deltaTime > 0 ? 1 : -1 + } ); - this._mixer.dispatchEvent( { - type: 'finished', action: this, - direction: deltaTime > 0 ? 1 : -1 - } ); + } else { + // keep running - break; - - } else if ( pending === 0 ) { - - // transition to last round + if ( pending === 0 ) { + // entering the last round var atStart = deltaTime < 0; this._setEndings( atStart, ! atStart, pingPong ); @@ -13517,22 +13090,19 @@ THREE.AnimationMixer._Action.prototype = { } - if ( loop === THREE.LoopPingPong && ( loopCount & 1 ) === 1 ) { + } - // invert time for the "pong round" + if ( pingPong && ( loopCount & 1 ) === 1 ) { + // invert time for the "pong round" - this.time = time; + this.time = time; + return duration - time; - return duration - time; - - } - - break; + } } this.time = time; - return time; }, @@ -13600,6 +13170,644 @@ THREE.AnimationMixer._Action.prototype = { }; + +// File:src/animation/AnimationClip.js + +/** + * + * Reusable set of Tracks that represent an animation. + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + */ + +THREE.AnimationClip = function ( name, duration, tracks ) { + + this.name = name; + this.tracks = tracks; + this.duration = ( duration !== undefined ) ? duration : -1; + + this.uuid = THREE.Math.generateUUID(); + + // this means it should figure out its duration by scanning the tracks + if ( this.duration < 0 ) { + + this.resetDuration(); + + } + + // maybe only do these on demand, as doing them here could potentially slow down loading + // but leaving these here during development as this ensures a lot of testing of these functions + this.trim(); + this.optimize(); + +}; + +THREE.AnimationClip.prototype = { + + constructor: THREE.AnimationClip, + + resetDuration: function() { + + var tracks = this.tracks, + duration = 0; + + for ( var i = 0, n = tracks.length; i !== n; ++ i ) { + + var track = this.tracks[ i ]; + + duration = Math.max( + duration, track.times[ track.times.length - 1 ] ); + + } + + this.duration = duration; + + }, + + trim: function() { + + for ( var i = 0; i < this.tracks.length; i ++ ) { + + this.tracks[ i ].trim( 0, this.duration ); + + } + + return this; + + }, + + optimize: function() { + + for ( var i = 0; i < this.tracks.length; i ++ ) { + + this.tracks[ i ].optimize(); + + } + + return this; + + } + +}; + +// Static methods: + +Object.assign( THREE.AnimationClip, { + + parse: function( json ) { + + var tracks = [], + jsonTracks = json.tracks, + frameTime = 1.0 / ( json.fps || 1.0 ); + + for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) { + + tracks.push( THREE.KeyframeTrack.parse( jsonTracks[ i ] ).scale( frameTime ) ); + + } + + return new THREE.AnimationClip( json.name, json.duration, tracks ); + + }, + + + toJSON: function( clip ) { + + var tracks = [], + clipTracks = clip.tracks; + + var json = { + + 'name': clip.name, + 'duration': clip.duration, + 'tracks': tracks + + }; + + for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) { + + tracks.push( THREE.KeyframeTrack.toJSON( clipTracks[ i ] ) ); + + } + + return json; + + }, + + + CreateFromMorphTargetSequence: function( name, morphTargetSequence, fps, noLoop ) { + + var numMorphTargets = morphTargetSequence.length; + var tracks = []; + + for ( var i = 0; i < numMorphTargets; i ++ ) { + + var times = []; + var values = []; + + times.push( + ( i + numMorphTargets - 1 ) % numMorphTargets, + i, + ( i + 1 ) % numMorphTargets ); + + values.push( 0, 1, 0 ); + + var order = THREE.AnimationUtils.getKeyframeOrder( times ); + times = THREE.AnimationUtils.sortedArray( times, 1, order ); + values = THREE.AnimationUtils.sortedArray( values, 1, order ); + + // if there is a key at the first frame, duplicate it as the + // last frame as well for perfect loop. + if ( ! noLoop && times[ 0 ] === 0 ) { + + times.push( numMorphTargets ); + values.push( values[ 0 ] ); + + } + + tracks.push( + new THREE.NumberKeyframeTrack( + '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']', + times, values + ).scale( 1.0 / fps ) ); + } + + return new THREE.AnimationClip( name, -1, tracks ); + + }, + + findByName: function( objectOrClipArray, name ) { + + var clipArray = objectOrClipArray; + + if ( ! Array.isArray( objectOrClipArray ) ) { + + var o = objectOrClipArray; + clipArray = o.geometry && o.geometry.animations || o.animations; + + } + + for ( var i = 0; i < clipArray.length; i ++ ) { + + if ( clipArray[ i ].name === name ) { + + return clipArray[ i ]; + + } + } + + return null; + + }, + + CreateClipsFromMorphTargetSequences: function( morphTargets, fps, noLoop ) { + + var animationToMorphTargets = {}; + + // tested with https://regex101.com/ on trick sequences + // such flamingo_flyA_003, flamingo_run1_003, crdeath0059 + var pattern = /^([\w-]*?)([\d]+)$/; + + // sort morph target names into animation groups based + // patterns like Walk_001, Walk_002, Run_001, Run_002 + for ( var i = 0, il = morphTargets.length; i < il; i ++ ) { + + var morphTarget = morphTargets[ i ]; + var parts = morphTarget.name.match( pattern ); + + if ( parts && parts.length > 1 ) { + + var name = parts[ 1 ]; + + var animationMorphTargets = animationToMorphTargets[ name ]; + if ( ! animationMorphTargets ) { + + animationToMorphTargets[ name ] = animationMorphTargets = []; + + } + + animationMorphTargets.push( morphTarget ); + + } + + } + + var clips = []; + + for ( var name in animationToMorphTargets ) { + + clips.push( THREE.AnimationClip.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) ); + + } + + return clips; + + }, + + // parse the animation.hierarchy format + parseAnimation: function( animation, bones, nodeName ) { + + if ( ! animation ) { + + console.error( " no animation in JSONLoader data" ); + return null; + + } + + var addNonemptyTrack = function( + trackType, trackName, animationKeys, propertyName, destTracks ) { + + // only return track if there are actually keys. + if ( animationKeys.length !== 0 ) { + + var times = []; + var values = []; + + THREE.AnimationUtils.flattenJSON( + animationKeys, times, values, propertyName ); + + // empty keys are filtered out, so check again + if ( times.length !== 0 ) { + + destTracks.push( new trackType( trackName, times, values ) ); + + } + + } + + }; + + var tracks = []; + + var clipName = animation.name || 'default'; + // automatic length determination in AnimationClip. + var duration = animation.length || -1; + var fps = animation.fps || 30; + + var hierarchyTracks = animation.hierarchy || []; + + for ( var h = 0; h < hierarchyTracks.length; h ++ ) { + + var animationKeys = hierarchyTracks[ h ].keys; + + // skip empty tracks + if ( ! animationKeys || animationKeys.length === 0 ) continue; + + // process morph targets in a way exactly compatible + // with AnimationHandler.init( animation ) + if ( animationKeys[0].morphTargets ) { + + // figure out all morph targets used in this track + var morphTargetNames = {}; + for ( var k = 0; k < animationKeys.length; k ++ ) { + + if ( animationKeys[k].morphTargets ) { + + for ( var m = 0; m < animationKeys[k].morphTargets.length; m ++ ) { + + morphTargetNames[ animationKeys[k].morphTargets[m] ] = -1; + } + + } + + } + + // create a track for each morph target with all zero + // morphTargetInfluences except for the keys in which + // the morphTarget is named. + for ( var morphTargetName in morphTargetNames ) { + + var times = []; + var values = []; + + for ( var m = 0; + m !== animationKeys[k].morphTargets.length; ++ m ) { + + var animationKey = animationKeys[k]; + + times.push( animationKey.time ); + values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 ); + + } + + tracks.push( new THREE.NumberKeyframeTrack( + '.morphTargetInfluence[' + morphTargetName + ']', times, values ) ); + + } + + duration = morphTargetNames.length * ( fps || 1.0 ); + + } else { + // ...assume skeletal animation + + var boneName = '.bones[' + bones[ h ].name + ']'; + + addNonemptyTrack( + THREE.VectorKeyframeTrack, boneName + '.position', + animationKeys, 'pos', tracks ); + + addNonemptyTrack( + THREE.QuaternionKeyframeTrack, boneName + '.quaternion', + animationKeys, 'rot', tracks ); + + addNonemptyTrack( + THREE.VectorKeyframeTrack, boneName + '.scale', + animationKeys, 'scl', tracks ); + + } + + } + + if ( tracks.length === 0 ) { + + return null; + + } + + var clip = new THREE.AnimationClip( clipName, duration, tracks ); + + return clip; + + } + +} ); + +// File:src/animation/AnimationMixer.js + +/** + * + * Player for AnimationClips. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ + +THREE.AnimationMixer = function( root ) { + + this._root = root; + this._initMemoryManager(); + this._accuIndex = 0; + + this.time = 0; + + this.timeScale = 1.0; + +}; + +Object.assign( THREE.AnimationMixer.prototype, THREE.EventDispatcher.prototype, { + + // return an action for a clip optionally using a custom root target + // object (this method allocates a lot of dynamic memory in case a + // previously unknown clip/root combination is specified) + clipAction: function( clip, optionalRoot ) { + + var root = optionalRoot || this._root, + rootUuid = root.uuid, + + clipObject = typeof clip === 'string' ? + THREE.AnimationClip.findByName( root, clip ) : clip, + + clipUuid = clipObject !== null ? clipObject.uuid : clip, + + actionsForClip = this._actionsByClip[ clipUuid ], + prototypeAction = null; + + if ( actionsForClip !== undefined ) { + + var existingAction = + actionsForClip.actionByRoot[ rootUuid ]; + + if ( existingAction !== undefined ) { + + return existingAction; + + } + + // we know the clip, so we don't have to parse all + // the bindings again but can just copy + prototypeAction = actionsForClip.knownActions[ 0 ]; + + // also, take the clip from the prototype action + if ( clipObject === null ) + clipObject = prototypeAction._clip; + + } + + // clip must be known when specified via string + if ( clipObject === null ) return null; + + // allocate all resources required to run it + var newAction = new THREE. + AnimationMixer._Action( this, clipObject, optionalRoot ); + + this._bindAction( newAction, prototypeAction ); + + // and make the action known to the memory manager + this._addInactiveAction( newAction, clipUuid, rootUuid ); + + return newAction; + + }, + + // get an existing action + existingAction: function( clip, optionalRoot ) { + + var root = optionalRoot || this._root, + rootUuid = root.uuid, + + clipObject = typeof clip === 'string' ? + THREE.AnimationClip.findByName( root, clip ) : clip, + + clipUuid = clipObject ? clipObject.uuid : clip, + + actionsForClip = this._actionsByClip[ clipUuid ]; + + if ( actionsForClip !== undefined ) { + + return actionsForClip.actionByRoot[ rootUuid ] || null; + + } + + return null; + + }, + + // deactivates all previously scheduled actions + stopAllAction: function() { + + var actions = this._actions, + nActions = this._nActiveActions, + bindings = this._bindings, + nBindings = this._nActiveBindings; + + this._nActiveActions = 0; + this._nActiveBindings = 0; + + for ( var i = 0; i !== nActions; ++ i ) { + + actions[ i ].reset(); + + } + + for ( var i = 0; i !== nBindings; ++ i ) { + + bindings[ i ].useCount = 0; + + } + + return this; + + }, + + // advance the time and update apply the animation + update: function( deltaTime ) { + + deltaTime *= this.timeScale; + + var actions = this._actions, + nActions = this._nActiveActions, + + time = this.time += deltaTime, + timeDirection = Math.sign( deltaTime ), + + accuIndex = this._accuIndex ^= 1; + + // run active actions + + for ( var i = 0; i !== nActions; ++ i ) { + + var action = actions[ i ]; + + if ( action.enabled ) { + + action._update( time, deltaTime, timeDirection, accuIndex ); + + } + + } + + // update scene graph + + var bindings = this._bindings, + nBindings = this._nActiveBindings; + + for ( var i = 0; i !== nBindings; ++ i ) { + + bindings[ i ].apply( accuIndex ); + + } + + return this; + + }, + + // return this mixer's root target object + getRoot: function() { + + return this._root; + + }, + + // free all resources specific to a particular clip + uncacheClip: function( clip ) { + + var actions = this._actions, + clipUuid = clip.uuid, + actionsByClip = this._actionsByClip, + actionsForClip = actionsByClip[ clipUuid ]; + + if ( actionsForClip !== undefined ) { + + // note: just calling _removeInactiveAction would mess up the + // iteration state and also require updating the state we can + // just throw away + + var actionsToRemove = actionsForClip.knownActions; + + for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) { + + var action = actionsToRemove[ i ]; + + this._deactivateAction( action ); + + var cacheIndex = action._cacheIndex, + lastInactiveAction = actions[ actions.length - 1 ]; + + action._cacheIndex = null; + action._byClipCacheIndex = null; + + lastInactiveAction._cacheIndex = cacheIndex; + actions[ cacheIndex ] = lastInactiveAction; + actions.pop(); + + this._removeInactiveBindingsForAction( action ); + + } + + delete actionsByClip[ clipUuid ]; + + } + + }, + + // free all resources specific to a particular root target object + uncacheRoot: function( root ) { + + var rootUuid = root.uuid, + actionsByClip = this._actionsByClip; + + for ( var clipUuid in actionsByClip ) { + + var actionByRoot = actionsByClip[ clipUuid ].actionByRoot, + action = actionByRoot[ rootUuid ]; + + if ( action !== undefined ) { + + this._deactivateAction( action ); + this._removeInactiveAction( action ); + + } + + } + + var bindingsByRoot = this._bindingsByRootAndName, + bindingByName = bindingsByRoot[ rootUuid ]; + + if ( bindingByName !== undefined ) { + + for ( var trackName in bindingByName ) { + + var binding = bindingByName[ trackName ]; + binding.restoreOriginalState(); + this._removeInactiveBinding( binding ); + + } + + } + + }, + + // remove a targeted clip from the cache + uncacheAction: function( clip, optionalRoot ) { + + var action = this.existingAction( clip, optionalRoot ); + + if ( action !== null ) { + + this._deactivateAction( action ); + this._removeInactiveAction( action ); + + } + + } + +} ); + +THREE.AnimationMixer._Action = THREE.AnimationAction._new; + // Implementation details: Object.assign( THREE.AnimationMixer.prototype, { @@ -13681,13 +13889,13 @@ Object.assign( THREE.AnimationMixer.prototype, { // appears to be still using it -> rebind var rootUuid = ( action._localRoot || this._root ).uuid, - clipName = action._clip.name, - actionsForClip = this._actionsByClip[ clipName ]; + clipUuid = action._clip.uuid, + actionsForClip = this._actionsByClip[ clipUuid ]; this._bindAction( action, actionsForClip && actionsForClip.knownActions[ 0 ] ); - this._addInactiveAction( action, clipName, rootUuid ); + this._addInactiveAction( action, clipUuid, rootUuid ); } @@ -13793,11 +14001,11 @@ Object.assign( THREE.AnimationMixer.prototype, { }, - _addInactiveAction: function( action, clipName, rootUuid ) { + _addInactiveAction: function( action, clipUuid, rootUuid ) { var actions = this._actions, actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[ clipName ]; + actionsForClip = actionsByClip[ clipUuid ]; if ( actionsForClip === undefined ) { @@ -13810,7 +14018,7 @@ Object.assign( THREE.AnimationMixer.prototype, { action._byClipCacheIndex = 0; - actionsByClip[ clipName ] = actionsForClip; + actionsByClip[ clipUuid ] = actionsForClip; } else { @@ -13841,9 +14049,9 @@ Object.assign( THREE.AnimationMixer.prototype, { action._cacheIndex = null; - var clipName = action._clip.name, + var clipUuid = action._clip.uuid, actionsByClip = this._actionsByClip, - actionsForClip = actionsByClip[ clipName ], + actionsForClip = actionsByClip[ clipUuid ], knownActionsForClip = actionsForClip.knownActions, lastKnownAction = @@ -13865,7 +14073,7 @@ Object.assign( THREE.AnimationMixer.prototype, { if ( knownActionsForClip.length === 0 ) { - delete actionsByClip[ clipName ]; + delete actionsByClip[ clipUuid ]; } @@ -14066,7 +14274,6 @@ Object.assign( THREE.AnimationMixer.prototype, { } ); - // File:src/animation/AnimationObjectGroup.js /** @@ -14668,7 +14875,7 @@ THREE.KeyframeTrack.prototype = { setInterpolation: function( interpolation ) { - var factoryMethod = undefined; + var factoryMethod; switch ( interpolation ) { @@ -14992,8 +15199,6 @@ Object.assign( THREE.KeyframeTrack, { if ( json.times === undefined ) { - console.warn( "legacy JSON format detected, converting" ); - var times = [], values = []; THREE.AnimationUtils.flattenJSON( json.keys, times, values, 'value' ); @@ -15092,7 +15297,7 @@ Object.assign( THREE.KeyframeTrack, { return THREE.StringKeyframeTrack; - }; + } throw new Error( "Unsupported typeName: " + typeName ); @@ -15647,7 +15852,7 @@ THREE.PropertyBinding.parseTrackName = function( trackName ) { // .bone[Armature.DEF_cog].position // created and tested via https://regex101.com/#javascript - var re = /^(([\w]+\/)*)([\w-\d]+)?(\.([\w]+)(\[([\w\d\[\]\_. ]+)\])?)?(\.([\w.]+)(\[([\w\d\[\]\_. ]+)\])?)$/; + var re = /^(([\w]+\/)*)([\w-\d]+)?(\.([\w]+)(\[([\w\d\[\]\_.:\- ]+)\])?)?(\.([\w.]+)(\[([\w\d\[\]\_. ]+)\])?)$/; var matches = re.exec(trackName); if( ! matches ) { @@ -15749,7 +15954,7 @@ THREE.PropertyBinding.findNode = function( root, nodeName ) { return null; -} +}; // File:src/animation/PropertyMixer.js @@ -15983,7 +16188,7 @@ THREE.BooleanKeyframeTrack.prototype = ValueTypeName: 'bool', ValueBufferType: Array, - DefaultInterpolation: THREE.IntepolateDiscrete, + DefaultInterpolation: THREE.InterpolateDiscrete, InterpolantFactoryMethodLinear: undefined, InterpolantFactoryMethodSmooth: undefined @@ -15994,6 +16199,41 @@ THREE.BooleanKeyframeTrack.prototype = } ); +// File:src/animation/tracks/ColorKeyframeTrack.js + +/** + * + * A Track of keyframe values that represent color. + * + * + * @author Ben Houston / http://clara.io/ + * @author David Sarno / http://lighthaus.us/ + * @author tschw + */ + +THREE.ColorKeyframeTrack = function ( name, times, values, interpolation ) { + + THREE.KeyframeTrack.call( this, name, times, values, interpolation ); + +}; + +THREE.ColorKeyframeTrack.prototype = + Object.assign( Object.create( THREE.KeyframeTrack.prototype ), { + + constructor: THREE.ColorKeyframeTrack, + + ValueTypeName: 'color' + + // ValueBufferType is inherited + + // DefaultInterpolation is inherited + + + // Note: Very basic implementation and nothing special yet. + // However, this is the place for color space parameterization. + +} ); + // File:src/animation/tracks/NumberKeyframeTrack.js /** @@ -16089,7 +16329,7 @@ THREE.StringKeyframeTrack.prototype = ValueTypeName: 'string', ValueBufferType: Array, - DefaultInterpolation: THREE.IntepolateDiscrete, + DefaultInterpolation: THREE.InterpolateDiscrete, InterpolantFactoryMethodLinear: undefined, @@ -16132,6 +16372,7 @@ THREE.VectorKeyframeTrack.prototype = /** * @author mrdoob / http://mrdoob.com/ + * @author Reece Aaron Lecrivain / http://reecenotes.com/ */ THREE.Audio = function ( listener ) { @@ -16155,240 +16396,267 @@ THREE.Audio = function ( listener ) { this.hasPlaybackControl = true; this.sourceType = 'empty'; - this.filter = null; + this.filters = []; }; -THREE.Audio.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Audio.prototype.constructor = THREE.Audio; +THREE.Audio.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.Audio.prototype.getOutput = function () { + constructor: THREE.Audio, - return this.gain; + getOutput: function () { -}; + return this.gain; -THREE.Audio.prototype.load = function ( file ) { + }, - var buffer = new THREE.AudioBuffer( this.context ); - buffer.load( file ); + setNodeSource: function ( audioNode ) { - this.setBuffer( buffer ); - - return this; - -}; - -THREE.Audio.prototype.setNodeSource = function ( audioNode ) { - - this.hasPlaybackControl = false; - this.sourceType = 'audioNode'; - this.source = audioNode; - this.connect(); - - return this; - -}; - -THREE.Audio.prototype.setBuffer = function ( audioBuffer ) { - - var scope = this; - - audioBuffer.onReady( function( buffer ) { - - scope.source.buffer = buffer; - scope.sourceType = 'buffer'; - if ( scope.autoplay ) scope.play(); - - } ); - - return this; - -}; - -THREE.Audio.prototype.play = function () { - - if ( this.isPlaying === true ) { - - console.warn( 'THREE.Audio: Audio is already playing.' ); - return; - - } - - if ( this.hasPlaybackControl === false ) { - - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; - - } - - var source = this.context.createBufferSource(); - - source.buffer = this.source.buffer; - source.loop = this.source.loop; - source.onended = this.source.onended; - source.start( 0, this.startTime ); - source.playbackRate.value = this.playbackRate; - - this.isPlaying = true; - - this.source = source; - - this.connect(); - -}; - -THREE.Audio.prototype.pause = function () { - - if ( this.hasPlaybackControl === false ) { - - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; - - } - - this.source.stop(); - this.startTime = this.context.currentTime; - -}; - -THREE.Audio.prototype.stop = function () { - - if ( this.hasPlaybackControl === false ) { - - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; - - } - - this.source.stop(); - this.startTime = 0; - -}; - -THREE.Audio.prototype.connect = function () { - - if ( this.filter !== null ) { - - this.source.connect( this.filter ); - this.filter.connect( this.getOutput() ); - - } else { - - this.source.connect( this.getOutput() ); - - } - -}; - -THREE.Audio.prototype.disconnect = function () { - - if ( this.filter !== null ) { - - this.source.disconnect( this.filter ); - this.filter.disconnect( this.getOutput() ); - - } else { - - this.source.disconnect( this.getOutput() ); - - } - -}; - -THREE.Audio.prototype.getFilter = function () { - - return this.filter; - -}; - -THREE.Audio.prototype.setFilter = function ( value ) { - - if ( value === undefined ) value = null; - - if ( this.isPlaying === true ) { - - this.disconnect(); - this.filter = value; + this.hasPlaybackControl = false; + this.sourceType = 'audioNode'; + this.source = audioNode; this.connect(); - } else { + return this; - this.filter = value; + }, + + setBuffer: function ( audioBuffer ) { + + this.source.buffer = audioBuffer; + this.sourceType = 'buffer'; + + if ( this.autoplay ) this.play(); + + return this; + + }, + + play: function () { + + if ( this.isPlaying === true ) { + + console.warn( 'THREE.Audio: Audio is already playing.' ); + return; + + } + + if ( this.hasPlaybackControl === false ) { + + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; + + } + + var source = this.context.createBufferSource(); + + source.buffer = this.source.buffer; + source.loop = this.source.loop; + source.onended = this.source.onended; + source.start( 0, this.startTime ); + source.playbackRate.value = this.playbackRate; + + this.isPlaying = true; + + this.source = source; + + return this.connect(); + + }, + + pause: function () { + + if ( this.hasPlaybackControl === false ) { + + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; + + } + + this.source.stop(); + this.startTime = this.context.currentTime; + + return this; + + }, + + stop: function () { + + if ( this.hasPlaybackControl === false ) { + + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; + + } + + this.source.stop(); + this.startTime = 0; + + return this; + + }, + + connect: function () { + + if ( this.filters.length > 0 ) { + + this.source.connect( this.filters[ 0 ] ); + + for ( var i = 1, l = this.filters.length; i < l; i ++ ) { + + this.filters[ i - 1 ].connect( this.filters[ i ] ); + + } + + this.filters[ this.filters.length - 1 ].connect( this.getOutput() ); + + } else { + + this.source.connect( this.getOutput() ); + + } + + return this; + + }, + + disconnect: function () { + + if ( this.filters.length > 0 ) { + + this.source.disconnect( this.filters[ 0 ] ); + + for ( var i = 1, l = this.filters.length; i < l; i ++ ) { + + this.filters[ i - 1 ].disconnect( this.filters[ i ] ); + + } + + this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() ); + + } else { + + this.source.disconnect( this.getOutput() ); + + } + + return this; + + }, + + getFilters: function () { + + return this.filters; + + }, + + setFilters: function ( value ) { + + if ( ! value ) value = []; + + if ( this.isPlaying === true ) { + + this.disconnect(); + this.filters = value; + this.connect(); + + } else { + + this.filters = value; + + } + + return this; + + }, + + getFilter: function () { + + return this.getFilters()[ 0 ]; + + }, + + setFilter: function ( filter ) { + + return this.setFilters( filter ? [ filter ] : [] ); + + }, + + setPlaybackRate: function ( value ) { + + if ( this.hasPlaybackControl === false ) { + + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; + + } + + this.playbackRate = value; + + if ( this.isPlaying === true ) { + + this.source.playbackRate.value = this.playbackRate; + + } + + return this; + + }, + + getPlaybackRate: function () { + + return this.playbackRate; + + }, + + onEnded: function () { + + this.isPlaying = false; + + }, + + getLoop: function () { + + if ( this.hasPlaybackControl === false ) { + + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return false; + + } + + return this.source.loop; + + }, + + setLoop: function ( value ) { + + if ( this.hasPlaybackControl === false ) { + + console.warn( 'THREE.Audio: this Audio has no playback control.' ); + return; + + } + + this.source.loop = value; + + }, + + getVolume: function () { + + return this.gain.gain.value; + + }, + + + setVolume: function ( value ) { + + this.gain.gain.value = value; + + return this; } -}; - -THREE.Audio.prototype.setPlaybackRate = function ( value ) { - - if ( this.hasPlaybackControl === false ) { - - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; - - } - - this.playbackRate = value; - - if ( this.isPlaying === true ) { - - this.source.playbackRate.value = this.playbackRate; - - } - -}; - -THREE.Audio.prototype.getPlaybackRate = function () { - - return this.playbackRate; - -}; - -THREE.Audio.prototype.onEnded = function() { - - this.isPlaying = false; - -}; - -THREE.Audio.prototype.setLoop = function ( value ) { - - if ( this.hasPlaybackControl === false ) { - - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return; - - } - - this.source.loop = value; - -}; - -THREE.Audio.prototype.getLoop = function () { - - if ( this.hasPlaybackControl === false ) { - - console.warn( 'THREE.Audio: this Audio has no playback control.' ); - return false; - - } - - return this.source.loop; - -}; - - -THREE.Audio.prototype.setVolume = function ( value ) { - - this.gain.gain.value = value; - -}; - -THREE.Audio.prototype.getVolume = function () { - - return this.gain.gain.value; - -}; +} ); // File:src/audio/AudioAnalyser.js @@ -16407,77 +16675,59 @@ THREE.AudioAnalyser = function ( audio, fftSize ) { }; -THREE.AudioAnalyser.prototype = { +Object.assign( THREE.AudioAnalyser.prototype, { - constructor: THREE.AudioAnalyser, - - getData: function () { + getFrequencyData: function () { this.analyser.getByteFrequencyData( this.data ); + return this.data; + }, + + getAverageFrequency: function () { + + var value = 0, data = this.getFrequencyData(); + + for ( var i = 0; i < data.length; i ++ ) { + + value += data[ i ]; + + } + + return value / data.length; + } -}; +} ); -// File:src/audio/AudioBuffer.js +// File:src/audio/AudioContext.js /** * @author mrdoob / http://mrdoob.com/ */ -THREE.AudioBuffer = function ( context ) { +Object.defineProperty( THREE, 'AudioContext', { - this.context = context; - this.ready = false; - this.readyCallbacks = []; + get: ( function () { -}; + var context; -THREE.AudioBuffer.prototype.load = function ( file ) { + return function () { - var scope = this; + if ( context === undefined ) { - var request = new XMLHttpRequest(); - request.open( 'GET', file, true ); - request.responseType = 'arraybuffer'; - request.onload = function ( e ) { - - scope.context.decodeAudioData( this.response, function ( buffer ) { - - scope.buffer = buffer; - scope.ready = true; - - for ( var i = 0; i < scope.readyCallbacks.length; i ++ ) { - - scope.readyCallbacks[ i ]( scope.buffer ); + context = new ( window.AudioContext || window.webkitAudioContext )(); } - scope.readyCallbacks = []; + return context; - } ); + }; - }; - request.send(); + } )() - return this; - -}; - -THREE.AudioBuffer.prototype.onReady = function ( callback ) { - - if ( this.ready ) { - - callback( this.buffer ); - - } else { - - this.readyCallbacks.push( callback ); - - } - -}; +} ); // File:src/audio/PositionalAudio.js @@ -16494,78 +16744,82 @@ THREE.PositionalAudio = function ( listener ) { }; -THREE.PositionalAudio.prototype = Object.create( THREE.Audio.prototype ); -THREE.PositionalAudio.prototype.constructor = THREE.PositionalAudio; +THREE.PositionalAudio.prototype = Object.assign( Object.create( THREE.Audio.prototype ), { -THREE.PositionalAudio.prototype.getOutput = function () { + constructor: THREE.PositionalAudio, - return this.panner; + getOutput: function () { -}; + return this.panner; -THREE.PositionalAudio.prototype.setRefDistance = function ( value ) { + }, - this.panner.refDistance = value; + getRefDistance: function () { -}; + return this.panner.refDistance; -THREE.PositionalAudio.prototype.getRefDistance = function () { + }, - return this.panner.refDistance; + setRefDistance: function ( value ) { -}; + this.panner.refDistance = value; -THREE.PositionalAudio.prototype.setRolloffFactor = function ( value ) { + }, - this.panner.rolloffFactor = value; + getRolloffFactor: function () { -}; + return this.panner.rolloffFactor; -THREE.PositionalAudio.prototype.getRolloffFactor = function () { + }, - return this.panner.rolloffFactor; + setRolloffFactor: function ( value ) { -}; + this.panner.rolloffFactor = value; -THREE.PositionalAudio.prototype.setDistanceModel = function ( value ) { + }, - this.panner.distanceModel = value; + getDistanceModel: function () { -}; + return this.panner.distanceModel; -THREE.PositionalAudio.prototype.getDistanceModel = function () { + }, - return this.panner.distanceModel; + setDistanceModel: function ( value ) { -}; + this.panner.distanceModel = value; -THREE.PositionalAudio.prototype.setMaxDistance = function ( value ) { + }, - this.panner.maxDistance = value; + getMaxDistance: function () { -}; + return this.panner.maxDistance; -THREE.PositionalAudio.prototype.getMaxDistance = function () { + }, - return this.panner.maxDistance; + setMaxDistance: function ( value ) { -}; + this.panner.maxDistance = value; -THREE.PositionalAudio.prototype.updateMatrixWorld = ( function () { + }, - var position = new THREE.Vector3(); + updateMatrixWorld: ( function () { - return function updateMatrixWorld( force ) { + var position = new THREE.Vector3(); - THREE.Object3D.prototype.updateMatrixWorld.call( this, force ); + return function updateMatrixWorld( force ) { - position.setFromMatrixPosition( this.matrixWorld ); + THREE.Object3D.prototype.updateMatrixWorld.call( this, force ); - this.panner.setPosition( position.x, position.y, position.z ); + position.setFromMatrixPosition( this.matrixWorld ); - }; + this.panner.setPosition( position.x, position.y, position.z ); -} )(); + }; + + } )() + + +} ); // File:src/audio/AudioListener.js @@ -16579,7 +16833,7 @@ THREE.AudioListener = function () { this.type = 'AudioListener'; - this.context = new ( window.AudioContext || window.webkitAudioContext )(); + this.context = THREE.AudioContext; this.gain = this.context.createGain(); this.gain.connect( this.context.destination ); @@ -16588,91 +16842,93 @@ THREE.AudioListener = function () { }; -THREE.AudioListener.prototype = Object.create( THREE.Object3D.prototype ); -THREE.AudioListener.prototype.constructor = THREE.AudioListener; +THREE.AudioListener.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.AudioListener.prototype.getInput = function () { + constructor: THREE.AudioListener, - return this.gain; + getInput: function () { -}; + return this.gain; -THREE.AudioListener.prototype.removeFilter = function ( ) { + }, - if ( this.filter !== null ) { + removeFilter: function ( ) { - this.gain.disconnect( this.filter ); - this.filter.disconnect( this.context.destination ); - this.gain.connect( this.context.destination ); - this.filter = null; + if ( this.filter !== null ) { - } + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); + this.gain.connect( this.context.destination ); + this.filter = null; -}; + } -THREE.AudioListener.prototype.setFilter = function ( value ) { + }, - if ( this.filter !== null ) { + getFilter: function () { - this.gain.disconnect( this.filter ); - this.filter.disconnect( this.context.destination ); + return this.filter; - } else { + }, - this.gain.disconnect( this.context.destination ); + setFilter: function ( value ) { - } + if ( this.filter !== null ) { - this.filter = value; - this.gain.connect( this.filter ); - this.filter.connect( this.context.destination ); + this.gain.disconnect( this.filter ); + this.filter.disconnect( this.context.destination ); -}; + } else { -THREE.AudioListener.prototype.getFilter = function () { + this.gain.disconnect( this.context.destination ); - return this.filter; + } -}; + this.filter = value; + this.gain.connect( this.filter ); + this.filter.connect( this.context.destination ); -THREE.AudioListener.prototype.setMasterVolume = function ( value ) { + }, - this.gain.gain.value = value; + getMasterVolume: function () { -}; + return this.gain.gain.value; -THREE.AudioListener.prototype.getMasterVolume = function () { + }, - return this.gain.gain.value; + setMasterVolume: function ( value ) { -}; + this.gain.gain.value = value; + }, -THREE.AudioListener.prototype.updateMatrixWorld = ( function () { + updateMatrixWorld: ( function () { - var position = new THREE.Vector3(); - var quaternion = new THREE.Quaternion(); - var scale = new THREE.Vector3(); + var position = new THREE.Vector3(); + var quaternion = new THREE.Quaternion(); + var scale = new THREE.Vector3(); - var orientation = new THREE.Vector3(); + var orientation = new THREE.Vector3(); - return function updateMatrixWorld( force ) { + return function updateMatrixWorld( force ) { - THREE.Object3D.prototype.updateMatrixWorld.call( this, force ); + THREE.Object3D.prototype.updateMatrixWorld.call( this, force ); - var listener = this.context.listener; - var up = this.up; + var listener = this.context.listener; + var up = this.up; - this.matrixWorld.decompose( position, quaternion, scale ); + this.matrixWorld.decompose( position, quaternion, scale ); - orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion ); + orientation.set( 0, 0, - 1 ).applyQuaternion( quaternion ); - listener.setPosition( position.x, position.y, position.z ); - listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z ); + listener.setPosition( position.x, position.y, position.z ); + listener.setOrientation( orientation.x, orientation.y, orientation.z, up.x, up.y, up.z ); - }; + }; -} )(); + } )() + +} ); // File:src/cameras/Camera.js @@ -16860,52 +17116,55 @@ THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) { }; -THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype ); -THREE.OrthographicCamera.prototype.constructor = THREE.OrthographicCamera; +THREE.OrthographicCamera.prototype = Object.assign( Object.create( THREE.Camera.prototype ), { -THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () { + constructor: THREE.OrthographicCamera, - var dx = ( this.right - this.left ) / ( 2 * this.zoom ); - var dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); - var cx = ( this.right + this.left ) / 2; - var cy = ( this.top + this.bottom ) / 2; + copy: function ( source ) { - this.projectionMatrix.makeOrthographic( cx - dx, cx + dx, cy + dy, cy - dy, this.near, this.far ); + THREE.Camera.prototype.copy.call( this, source ); -}; + this.left = source.left; + this.right = source.right; + this.top = source.top; + this.bottom = source.bottom; + this.near = source.near; + this.far = source.far; -THREE.OrthographicCamera.prototype.copy = function ( source ) { + this.zoom = source.zoom; - THREE.Camera.prototype.copy.call( this, source ); + return this; - this.left = source.left; - this.right = source.right; - this.top = source.top; - this.bottom = source.bottom; - this.near = source.near; - this.far = source.far; + }, - this.zoom = source.zoom; + updateProjectionMatrix: function () { - return this; + var dx = ( this.right - this.left ) / ( 2 * this.zoom ); + var dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); + var cx = ( this.right + this.left ) / 2; + var cy = ( this.top + this.bottom ) / 2; -}; + this.projectionMatrix.makeOrthographic( cx - dx, cx + dx, cy + dy, cy - dy, this.near, this.far ); -THREE.OrthographicCamera.prototype.toJSON = function ( meta ) { + }, - var data = THREE.Object3D.prototype.toJSON.call( this, meta ); + toJSON: function ( meta ) { - data.object.zoom = this.zoom; - data.object.left = this.left; - data.object.right = this.right; - data.object.top = this.top; - data.object.bottom = this.bottom; - data.object.near = this.near; - data.object.far = this.far; + var data = THREE.Object3D.prototype.toJSON.call( this, meta ); - return data; + data.object.zoom = this.zoom; + data.object.left = this.left; + data.object.right = this.right; + data.object.top = this.top; + data.object.bottom = this.bottom; + data.object.near = this.near; + data.object.far = this.far; -}; + return data; + + } + +} ); // File:src/cameras/PerspectiveCamera.js @@ -16913,158 +17172,219 @@ THREE.OrthographicCamera.prototype.toJSON = function ( meta ) { * @author mrdoob / http://mrdoob.com/ * @author greggman / http://games.greggman.com/ * @author zz85 / http://www.lab4games.net/zz85/blog + * @author tschw */ -THREE.PerspectiveCamera = function ( fov, aspect, near, far ) { +THREE.PerspectiveCamera = function( fov, aspect, near, far ) { THREE.Camera.call( this ); this.type = 'PerspectiveCamera'; - this.focalLength = 10; + this.fov = fov !== undefined ? fov : 50; this.zoom = 1; - this.fov = fov !== undefined ? fov : 50; - this.aspect = aspect !== undefined ? aspect : 1; this.near = near !== undefined ? near : 0.1; this.far = far !== undefined ? far : 2000; + this.focus = 10; + + this.aspect = aspect !== undefined ? aspect : 1; + this.view = null; + + this.filmGauge = 35; // width of the film (default in millimeters) + this.filmOffset = 0; // horizontal film offset (same unit as gauge) this.updateProjectionMatrix(); }; -THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype ); -THREE.PerspectiveCamera.prototype.constructor = THREE.PerspectiveCamera; +THREE.PerspectiveCamera.prototype = Object.assign( Object.create( THREE.Camera.prototype ), { + constructor: THREE.PerspectiveCamera, -/** - * Uses Focal Length (in mm) to estimate and set FOV - * 35mm (full-frame) camera is used if frame size is not specified; - * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html - */ + copy: function ( source ) { -THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) { + THREE.Camera.prototype.copy.call( this, source ); - if ( frameHeight === undefined ) frameHeight = 24; + this.fov = source.fov; + this.zoom = source.zoom; - this.fov = 2 * THREE.Math.radToDeg( Math.atan( frameHeight / ( focalLength * 2 ) ) ); - this.updateProjectionMatrix(); + this.near = source.near; + this.far = source.far; + this.focus = source.focus; -}; + this.aspect = source.aspect; + this.view = source.view === null ? null : Object.assign( {}, source.view ); + this.filmGauge = source.filmGauge; + this.filmOffset = source.filmOffset; -/** - * Sets an offset in a larger frustum. This is useful for multi-window or - * multi-monitor/multi-machine setups. - * - * For example, if you have 3x2 monitors and each monitor is 1920x1080 and - * the monitors are in grid like this - * - * +---+---+---+ - * | A | B | C | - * +---+---+---+ - * | D | E | F | - * +---+---+---+ - * - * then for each monitor you would call it like this - * - * var w = 1920; - * var h = 1080; - * var fullWidth = w * 3; - * var fullHeight = h * 2; - * - * --A-- - * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * --B-- - * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * --C-- - * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * --D-- - * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * --E-- - * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * --F-- - * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * - * Note there is no reason monitors have to be the same size or in a grid. - */ + return this; -THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) { + }, - this.fullWidth = fullWidth; - this.fullHeight = fullHeight; - this.x = x; - this.y = y; - this.width = width; - this.height = height; + /** + * Sets the FOV by focal length in respect to the current .filmGauge. + * + * The default film gauge is 35, so that the focal length can be specified for + * a 35mm (full frame) camera. + * + * Values for focal length and film gauge must have the same unit. + */ + setFocalLength: function ( focalLength ) { - this.updateProjectionMatrix(); + // see http://www.bobatkins.com/photography/technical/field_of_view.html + var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; -}; + this.fov = THREE.Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.updateProjectionMatrix(); + }, -THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () { + /** + * Calculates the focal length from the current .fov and .filmGauge. + */ + getFocalLength: function () { - var fov = THREE.Math.radToDeg( 2 * Math.atan( Math.tan( THREE.Math.degToRad( this.fov ) * 0.5 ) / this.zoom ) ); + var vExtentSlope = Math.tan( THREE.Math.DEG2RAD * 0.5 * this.fov ); - if ( this.fullWidth ) { + return 0.5 * this.getFilmHeight() / vExtentSlope; - var aspect = this.fullWidth / this.fullHeight; - var top = Math.tan( THREE.Math.degToRad( fov * 0.5 ) ) * this.near; - var bottom = - top; - var left = aspect * bottom; - var right = aspect * top; - var width = Math.abs( right - left ); - var height = Math.abs( top - bottom ); + }, + + getEffectiveFOV: function () { + + return THREE.Math.RAD2DEG * 2 * Math.atan( + Math.tan( THREE.Math.DEG2RAD * 0.5 * this.fov ) / this.zoom ); + + }, + + getFilmWidth: function () { + + // film not completely covered in portrait format (aspect < 1) + return this.filmGauge * Math.min( this.aspect, 1 ); + + }, + + getFilmHeight: function () { + + // film not completely covered in landscape format (aspect > 1) + return this.filmGauge / Math.max( this.aspect, 1 ); + + }, + + /** + * Sets an offset in a larger frustum. This is useful for multi-window or + * multi-monitor/multi-machine setups. + * + * For example, if you have 3x2 monitors and each monitor is 1920x1080 and + * the monitors are in grid like this + * + * +---+---+---+ + * | A | B | C | + * +---+---+---+ + * | D | E | F | + * +---+---+---+ + * + * then for each monitor you would call it like this + * + * var w = 1920; + * var h = 1080; + * var fullWidth = w * 3; + * var fullHeight = h * 2; + * + * --A-- + * camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * --B-- + * camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * --C-- + * camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * --D-- + * camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * --E-- + * camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * --F-- + * camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * + * Note there is no reason monitors have to be the same size or in a grid. + */ + setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) { + + this.aspect = fullWidth / fullHeight; + + this.view = { + fullWidth: fullWidth, + fullHeight: fullHeight, + offsetX: x, + offsetY: y, + width: width, + height: height + }; + + this.updateProjectionMatrix(); + + }, + + clearViewOffset: function() { + + this.view = null; + this.updateProjectionMatrix(); + + }, + + updateProjectionMatrix: function () { + + var near = this.near, + top = near * Math.tan( + THREE.Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, + height = 2 * top, + width = this.aspect * height, + left = - 0.5 * width, + view = this.view; + + if ( view !== null ) { + + var fullWidth = view.fullWidth, + fullHeight = view.fullHeight; + + left += view.offsetX * width / fullWidth; + top -= view.offsetY * height / fullHeight; + width *= view.width / fullWidth; + height *= view.height / fullHeight; + + } + + var skew = this.filmOffset; + if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); this.projectionMatrix.makeFrustum( - left + this.x * width / this.fullWidth, - left + ( this.x + this.width ) * width / this.fullWidth, - top - ( this.y + this.height ) * height / this.fullHeight, - top - this.y * height / this.fullHeight, - this.near, - this.far - ); + left, left + width, top - height, top, near, this.far ); - } else { + }, - this.projectionMatrix.makePerspective( fov, this.aspect, this.near, this.far ); + toJSON: function ( meta ) { + + var data = THREE.Object3D.prototype.toJSON.call( this, meta ); + + data.object.fov = this.fov; + data.object.zoom = this.zoom; + + data.object.near = this.near; + data.object.far = this.far; + data.object.focus = this.focus; + + data.object.aspect = this.aspect; + + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + + data.object.filmGauge = this.filmGauge; + data.object.filmOffset = this.filmOffset; + + return data; } -}; - -THREE.PerspectiveCamera.prototype.copy = function ( source ) { - - THREE.Camera.prototype.copy.call( this, source ); - - this.focalLength = source.focalLength; - this.zoom = source.zoom; - - this.fov = source.fov; - this.aspect = source.aspect; - this.near = source.near; - this.far = source.far; - - return this; - -}; - -THREE.PerspectiveCamera.prototype.toJSON = function ( meta ) { - - var data = THREE.Object3D.prototype.toJSON.call( this, meta ); - - data.object.focalLength = this.focalLength; - data.object.zoom = this.zoom; - - data.object.fov = this.fov; - data.object.aspect = this.aspect; - data.object.near = this.near; - data.object.far = this.far; - - return data; - -}; +} ); // File:src/cameras/StereoCamera.js @@ -17088,26 +17408,24 @@ THREE.StereoCamera = function () { }; -THREE.StereoCamera.prototype = { - - constructor: THREE.StereoCamera, +Object.assign( THREE.StereoCamera.prototype, { update: ( function () { - var focalLength, fov, aspect, near, far; + var focus, fov, aspect, near, far; var eyeRight = new THREE.Matrix4(); var eyeLeft = new THREE.Matrix4(); return function update ( camera ) { - var needsUpdate = focalLength !== camera.focalLength || fov !== camera.fov || + var needsUpdate = focus !== camera.focus || fov !== camera.fov || aspect !== camera.aspect * this.aspect || near !== camera.near || far !== camera.far; if ( needsUpdate ) { - focalLength = camera.focalLength; + focus = camera.focus; fov = camera.fov; aspect = camera.aspect * this.aspect; near = camera.near; @@ -17118,8 +17436,8 @@ THREE.StereoCamera.prototype = { var projectionMatrix = camera.projectionMatrix.clone(); var eyeSep = 0.064 / 2; - var eyeSepOnProjection = eyeSep * near / focalLength; - var ymax = near * Math.tan( THREE.Math.degToRad( fov * 0.5 ) ); + var eyeSepOnProjection = eyeSep * near / focus; + var ymax = near * Math.tan( THREE.Math.DEG2RAD * fov * 0.5 ); var xmin, xmax; // translate xOffset @@ -17156,7 +17474,7 @@ THREE.StereoCamera.prototype = { } )() -}; +} ); // File:src/lights/Light.js @@ -17178,37 +17496,40 @@ THREE.Light = function ( color, intensity ) { }; -THREE.Light.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Light.prototype.constructor = THREE.Light; +THREE.Light.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.Light.prototype.copy = function ( source ) { + constructor: THREE.Light, - THREE.Object3D.prototype.copy.call( this, source ); + copy: function ( source ) { - this.color.copy( source.color ); - this.intensity = source.intensity; + THREE.Object3D.prototype.copy.call( this, source ); - return this; + this.color.copy( source.color ); + this.intensity = source.intensity; -}; + return this; -THREE.Light.prototype.toJSON = function ( meta ) { + }, - var data = THREE.Object3D.prototype.toJSON.call( this, meta ); + toJSON: function ( meta ) { - data.object.color = this.color.getHex(); - data.object.intensity = this.intensity; + var data = THREE.Object3D.prototype.toJSON.call( this, meta ); - if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); + data.object.color = this.color.getHex(); + data.object.intensity = this.intensity; - if ( this.distance !== undefined ) data.object.distance = this.distance; - if ( this.angle !== undefined ) data.object.angle = this.angle; - if ( this.decay !== undefined ) data.object.decay = this.decay; - if ( this.exponent !== undefined ) data.object.exponent = this.exponent; + if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); - return data; + if ( this.distance !== undefined ) data.object.distance = this.distance; + if ( this.angle !== undefined ) data.object.angle = this.angle; + if ( this.decay !== undefined ) data.object.decay = this.decay; + if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; -}; + return data; + + } + +} ); // File:src/lights/LightShadow.js @@ -17230,9 +17551,7 @@ THREE.LightShadow = function ( camera ) { }; -THREE.LightShadow.prototype = { - - constructor: THREE.LightShadow, +Object.assign( THREE.LightShadow.prototype, { copy: function ( source ) { @@ -17253,7 +17572,7 @@ THREE.LightShadow.prototype = { } -}; +} ); // File:src/lights/AmbientLight.js @@ -17271,8 +17590,11 @@ THREE.AmbientLight = function ( color, intensity ) { }; -THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype ); -THREE.AmbientLight.prototype.constructor = THREE.AmbientLight; +THREE.AmbientLight.prototype = Object.assign( Object.create( THREE.Light.prototype ), { + + constructor: THREE.AmbientLight + +} ); // File:src/lights/DirectionalLight.js @@ -17292,25 +17614,46 @@ THREE.DirectionalLight = function ( color, intensity ) { this.target = new THREE.Object3D(); - this.shadow = new THREE.LightShadow( new THREE.OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); + this.shadow = new THREE.DirectionalLightShadow(); }; -THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype ); -THREE.DirectionalLight.prototype.constructor = THREE.DirectionalLight; +THREE.DirectionalLight.prototype = Object.assign( Object.create( THREE.Light.prototype ), { -THREE.DirectionalLight.prototype.copy = function ( source ) { + constructor: THREE.DirectionalLight, - THREE.Light.prototype.copy.call( this, source ); + copy: function ( source ) { - this.target = source.target.clone(); + THREE.Light.prototype.copy.call( this, source ); - this.shadow = source.shadow.clone(); + this.target = source.target.clone(); - return this; + this.shadow = source.shadow.clone(); + + return this; + + } + +} ); + +// File:src/lights/DirectionalLightShadow.js + +/** + * @author mrdoob / http://mrdoob.com/ + */ + +THREE.DirectionalLightShadow = function ( light ) { + + THREE.LightShadow.call( this, new THREE.OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); }; +THREE.DirectionalLightShadow.prototype = Object.assign( Object.create( THREE.LightShadow.prototype ), { + + constructor: THREE.DirectionalLightShadow + +} ); + // File:src/lights/HemisphereLight.js /** @@ -17332,18 +17675,21 @@ THREE.HemisphereLight = function ( skyColor, groundColor, intensity ) { }; -THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype ); -THREE.HemisphereLight.prototype.constructor = THREE.HemisphereLight; +THREE.HemisphereLight.prototype = Object.assign( Object.create( THREE.Light.prototype ), { -THREE.HemisphereLight.prototype.copy = function ( source ) { + constructor: THREE.HemisphereLight, - THREE.Light.prototype.copy.call( this, source ); + copy: function ( source ) { - this.groundColor.copy( source.groundColor ); + THREE.Light.prototype.copy.call( this, source ); - return this; + this.groundColor.copy( source.groundColor ); -}; + return this; + + } + +} ); // File:src/lights/PointLight.js @@ -17358,6 +17704,20 @@ THREE.PointLight = function ( color, intensity, distance, decay ) { this.type = 'PointLight'; + Object.defineProperty( this, 'power', { + get: function () { + // intensity = power per solid angle. + // ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + return this.intensity * 4 * Math.PI; + + }, + set: function ( power ) { + // intensity = power per solid angle. + // ref: equation (15) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + this.intensity = power / ( 4 * Math.PI ); + } + } ); + this.distance = ( distance !== undefined ) ? distance : 0; this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. @@ -17365,21 +17725,24 @@ THREE.PointLight = function ( color, intensity, distance, decay ) { }; -THREE.PointLight.prototype = Object.create( THREE.Light.prototype ); -THREE.PointLight.prototype.constructor = THREE.PointLight; +THREE.PointLight.prototype = Object.assign( Object.create( THREE.Light.prototype ), { -THREE.PointLight.prototype.copy = function ( source ) { + constructor: THREE.PointLight, - THREE.Light.prototype.copy.call( this, source ); + copy: function ( source ) { - this.distance = source.distance; - this.decay = source.decay; + THREE.Light.prototype.copy.call( this, source ); - this.shadow = source.shadow.clone(); + this.distance = source.distance; + this.decay = source.decay; - return this; + this.shadow = source.shadow.clone(); -}; + return this; + + } + +} ); // File:src/lights/SpotLight.js @@ -17387,7 +17750,7 @@ THREE.PointLight.prototype.copy = function ( source ) { * @author alteredq / http://alteredqualia.com/ */ -THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decay ) { +THREE.SpotLight = function ( color, intensity, distance, angle, penumbra, decay ) { THREE.Light.call( this, color, intensity ); @@ -17398,32 +17761,121 @@ THREE.SpotLight = function ( color, intensity, distance, angle, exponent, decay this.target = new THREE.Object3D(); + Object.defineProperty( this, 'power', { + get: function () { + // intensity = power per solid angle. + // ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + return this.intensity * Math.PI; + }, + set: function ( power ) { + // intensity = power per solid angle. + // ref: equation (17) from http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr.pdf + this.intensity = power / Math.PI; + } + } ); + this.distance = ( distance !== undefined ) ? distance : 0; this.angle = ( angle !== undefined ) ? angle : Math.PI / 3; - this.exponent = ( exponent !== undefined ) ? exponent : 10; + this.penumbra = ( penumbra !== undefined ) ? penumbra : 0; this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2. - this.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 0.5, 500 ) ); + this.shadow = new THREE.SpotLightShadow(); }; -THREE.SpotLight.prototype = Object.create( THREE.Light.prototype ); -THREE.SpotLight.prototype.constructor = THREE.SpotLight; +THREE.SpotLight.prototype = Object.assign( Object.create( THREE.Light.prototype ), { -THREE.SpotLight.prototype.copy = function ( source ) { + constructor: THREE.SpotLight, - THREE.Light.prototype.copy.call( this, source ); + copy: function ( source ) { - this.distance = source.distance; - this.angle = source.angle; - this.exponent = source.exponent; - this.decay = source.decay; + THREE.Light.prototype.copy.call( this, source ); - this.target = source.target.clone(); + this.distance = source.distance; + this.angle = source.angle; + this.penumbra = source.penumbra; + this.decay = source.decay; - this.shadow = source.shadow.clone(); + this.target = source.target.clone(); - return this; + this.shadow = source.shadow.clone(); + + return this; + + } + +} ); + +// File:src/lights/SpotLightShadow.js + +/** + * @author mrdoob / http://mrdoob.com/ + */ + +THREE.SpotLightShadow = function () { + + THREE.LightShadow.call( this, new THREE.PerspectiveCamera( 50, 1, 0.5, 500 ) ); + +}; + +THREE.SpotLightShadow.prototype = Object.assign( Object.create( THREE.LightShadow.prototype ), { + + constructor: THREE.SpotLightShadow, + + update: function ( light ) { + + var fov = THREE.Math.RAD2DEG * 2 * light.angle; + var aspect = this.mapSize.width / this.mapSize.height; + var far = light.distance || 500; + + var camera = this.camera; + + if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) { + + camera.fov = fov; + camera.aspect = aspect; + camera.far = far; + camera.updateProjectionMatrix(); + + } + + } + +} ); + +// File:src/loaders/AudioLoader.js + +/** + * @author Reece Aaron Lecrivain / http://reecenotes.com/ + */ + +THREE.AudioLoader = function ( manager ) { + + this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; + +}; + +THREE.AudioLoader.prototype = { + + constructor: THREE.AudioLoader, + + load: function ( url, onLoad, onProgress, onError ) { + + var loader = new THREE.XHRLoader( this.manager ); + loader.setResponseType( 'arraybuffer' ); + loader.load( url, function ( buffer ) { + + var context = THREE.AudioContext; + + context.decodeAudioData( buffer, function ( audioBuffer ) { + + onLoad( audioBuffer ); + + } ); + + }, onProgress, onError ); + + } }; @@ -17614,7 +18066,8 @@ THREE.Loader.prototype = { json.blending = THREE[ value ]; break; case 'colorAmbient': - console.warn( 'THREE.Loader.createMaterial: colorAmbient is no longer supported' ); + case 'mapAmbient': + console.warn( 'THREE.Loader.createMaterial:', name, 'is no longer supported.' ); break; case 'colorDiffuse': json.color = color.fromArray( value ).getHex(); @@ -17917,13 +18370,36 @@ THREE.FontLoader.prototype = { load: function ( url, onLoad, onProgress, onError ) { + var scope = this; + var loader = new THREE.XHRLoader( this.manager ); loader.load( url, function ( text ) { - onLoad( new THREE.Font( JSON.parse( text.substring( 65, text.length - 2 ) ) ) ); + var json; + + try { + + json = JSON.parse( text ); + + } catch ( e ) { + + console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' ); + json = JSON.parse( text.substring( 65, text.length - 2 ) ); + + } + + var font = scope.parse( json ); + + if ( onLoad ) onLoad( font ); }, onProgress, onError ); + }, + + parse: function ( json ) { + + return new THREE.Font( json ); + } }; @@ -18433,7 +18909,7 @@ THREE.JSONLoader.prototype = { } - }; + } function parseSkin() { @@ -18478,7 +18954,7 @@ THREE.JSONLoader.prototype = { } - }; + } function parseMorphing( scale ) { @@ -18570,7 +19046,7 @@ THREE.JSONLoader.prototype = { if ( outputAnimations.length > 0 ) geometry.animations = outputAnimations; - }; + } if ( json.materials === undefined || json.materials.length === 0 ) { @@ -18722,7 +19198,7 @@ THREE.BufferGeometryLoader.prototype = { var attribute = attributes[ key ]; var typedArray = new TYPED_ARRAYS[ attribute.type ]( attribute.array ); - geometry.addAttribute( key, new THREE.BufferAttribute( typedArray, attribute.itemSize ) ); + geometry.addAttribute( key, new THREE.BufferAttribute( typedArray, attribute.itemSize, attribute.normalized ) ); } @@ -19028,9 +19504,10 @@ THREE.ObjectLoader.prototype = { break; case 'BoxGeometry': + case 'BoxBufferGeometry': case 'CubeGeometry': // backwards compatible - geometry = new THREE.BoxGeometry( + geometry = new THREE[ data.type ]( data.width, data.height, data.depth, @@ -19041,20 +19518,10 @@ THREE.ObjectLoader.prototype = { break; + case 'CircleGeometry': case 'CircleBufferGeometry': - geometry = new THREE.CircleBufferGeometry( - data.radius, - data.segments, - data.thetaStart, - data.thetaLength - ); - - break; - - case 'CircleGeometry': - - geometry = new THREE.CircleGeometry( + geometry = new THREE[ data.type ]( data.radius, data.segments, data.thetaStart, @@ -19064,8 +19531,9 @@ THREE.ObjectLoader.prototype = { break; case 'CylinderGeometry': + case 'CylinderBufferGeometry': - geometry = new THREE.CylinderGeometry( + geometry = new THREE[ data.type ]( data.radiusTop, data.radiusBottom, data.height, @@ -19078,23 +19546,25 @@ THREE.ObjectLoader.prototype = { break; - case 'SphereGeometry': + case 'ConeGeometry': + case 'ConeBufferGeometry': - geometry = new THREE.SphereGeometry( + geometry = new THREE [ data.type ]( data.radius, - data.widthSegments, + data.height, + data.radialSegments, data.heightSegments, - data.phiStart, - data.phiLength, + data.openEnded, data.thetaStart, data.thetaLength ); break; + case 'SphereGeometry': case 'SphereBufferGeometry': - geometry = new THREE.SphereBufferGeometry( + geometry = new THREE[ data.type ]( data.radius, data.widthSegments, data.heightSegments, @@ -19107,35 +19577,11 @@ THREE.ObjectLoader.prototype = { break; case 'DodecahedronGeometry': - - geometry = new THREE.DodecahedronGeometry( - data.radius, - data.detail - ); - - break; - case 'IcosahedronGeometry': - - geometry = new THREE.IcosahedronGeometry( - data.radius, - data.detail - ); - - break; - case 'OctahedronGeometry': - - geometry = new THREE.OctahedronGeometry( - data.radius, - data.detail - ); - - break; - case 'TetrahedronGeometry': - geometry = new THREE.TetrahedronGeometry( + geometry = new THREE[ data.type ]( data.radius, data.detail ); @@ -19143,8 +19589,9 @@ THREE.ObjectLoader.prototype = { break; case 'RingGeometry': + case 'RingBufferGeometry': - geometry = new THREE.RingGeometry( + geometry = new THREE[ data.type ]( data.innerRadius, data.outerRadius, data.thetaSegments, @@ -19156,8 +19603,9 @@ THREE.ObjectLoader.prototype = { break; case 'TorusGeometry': + case 'TorusBufferGeometry': - geometry = new THREE.TorusGeometry( + geometry = new THREE[ data.type ]( data.radius, data.tube, data.radialSegments, @@ -19168,22 +19616,23 @@ THREE.ObjectLoader.prototype = { break; case 'TorusKnotGeometry': + case 'TorusKnotBufferGeometry': - geometry = new THREE.TorusKnotGeometry( + geometry = new THREE[ data.type ]( data.radius, data.tube, - data.radialSegments, data.tubularSegments, + data.radialSegments, data.p, - data.q, - data.heightScale + data.q ); break; case 'LatheGeometry': + case 'LatheBufferGeometry': - geometry = new THREE.LatheGeometry( + geometry = new THREE[ data.type ]( data.points, data.segments, data.phiStart, @@ -19410,6 +19859,12 @@ THREE.ObjectLoader.prototype = { object = new THREE.PerspectiveCamera( data.fov, data.aspect, data.near, data.far ); + if ( data.focus !== undefined ) object.focus = data.focus; + if ( data.zoom !== undefined ) object.zoom = data.zoom; + if ( data.filmGauge !== undefined ) object.filmGauge = data.filmGauge; + if ( data.filmOffset !== undefined ) object.filmOffset = data.filmOffset; + if ( data.view !== undefined ) object.view = Object.assign( {}, data.view ); + break; case 'OrthographicCamera': @@ -19438,7 +19893,7 @@ THREE.ObjectLoader.prototype = { case 'SpotLight': - object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.exponent, data.decay ); + object = new THREE.SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay ); break; @@ -19555,7 +20010,7 @@ THREE.ObjectLoader.prototype = { return object; - } + }; }() @@ -19633,7 +20088,7 @@ THREE.CubeTextureLoader.prototype = { load: function ( urls, onLoad, onProgress, onError ) { - var texture = new THREE.CubeTexture( [] ); + var texture = new THREE.CubeTexture(); var loader = new THREE.ImageLoader( this.manager ); loader.setCrossOrigin( this.crossOrigin ); @@ -19931,13 +20386,17 @@ THREE.Material = function () { this.name = ''; this.type = 'Material'; + this.fog = true; + this.lights = true; + + this.blending = THREE.NormalBlending; this.side = THREE.FrontSide; + this.shading = THREE.SmoothShading; // THREE.FlatShading, THREE.SmoothShading + this.vertexColors = THREE.NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors this.opacity = 1; this.transparent = false; - this.blending = THREE.NormalBlending; - this.blendSrc = THREE.SrcAlphaFactor; this.blendDst = THREE.OneMinusSrcAlphaFactor; this.blendEquation = THREE.AddEquation; @@ -19949,6 +20408,9 @@ THREE.Material = function () { this.depthTest = true; this.depthWrite = true; + this.clippingPlanes = null; + this.clipShadows = false; + this.colorWrite = true; this.precision = null; // override the renderer's default precision for this material @@ -19958,6 +20420,7 @@ THREE.Material = function () { this.polygonOffsetUnits = 0; this.alphaTest = 0; + this.premultipliedAlpha = false; this.overdraw = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer @@ -19971,16 +20434,15 @@ THREE.Material.prototype = { constructor: THREE.Material, - get needsUpdate () { + get needsUpdate() { return this._needsUpdate; }, - set needsUpdate ( value ) { + set needsUpdate( value ) { if ( value === true ) this.update(); - this._needsUpdate = value; }, @@ -20056,12 +20518,13 @@ THREE.Material.prototype = { // standard Material serialization data.uuid = this.uuid; data.type = this.type; + if ( this.name !== '' ) data.name = this.name; if ( this.color instanceof THREE.Color ) data.color = this.color.getHex(); if ( this.roughness !== 0.5 ) data.roughness = this.roughness; - if ( this.metalness > 0 ) data.metalness = this.metalness; + if ( this.metalness !== 0.5 ) data.metalness = this.metalness; if ( this.emissive instanceof THREE.Color ) data.emissive = this.emissive.getHex(); if ( this.specular instanceof THREE.Color ) data.specular = this.specular.getHex(); @@ -20105,14 +20568,15 @@ THREE.Material.prototype = { if ( this.size !== undefined ) data.size = this.size; if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; - if ( this.vertexColors !== undefined && this.vertexColors !== THREE.NoColors ) data.vertexColors = this.vertexColors; - if ( this.shading !== undefined && this.shading !== THREE.SmoothShading ) data.shading = this.shading; - if ( this.blending !== undefined && this.blending !== THREE.NormalBlending ) data.blending = this.blending; - if ( this.side !== undefined && this.side !== THREE.FrontSide ) data.side = this.side; + if ( this.blending !== THREE.NormalBlending ) data.blending = this.blending; + if ( this.shading !== THREE.SmoothShading ) data.shading = this.shading; + if ( this.side !== THREE.FrontSide ) data.side = this.side; + if ( this.vertexColors !== THREE.NoColors ) data.vertexColors = this.vertexColors; if ( this.opacity < 1 ) data.opacity = this.opacity; if ( this.transparent === true ) data.transparent = this.transparent; if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; + if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; if ( this.wireframe === true ) data.wireframe = this.wireframe; if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; @@ -20158,13 +20622,16 @@ THREE.Material.prototype = { this.name = source.name; + this.fog = source.fog; + this.lights = source.lights; + + this.blending = source.blending; this.side = source.side; + this.vertexColors = source.vertexColors; this.opacity = source.opacity; this.transparent = source.transparent; - this.blending = source.blending; - this.blendSrc = source.blendSrc; this.blendDst = source.blendDst; this.blendEquation = source.blendEquation; @@ -20186,9 +20653,27 @@ THREE.Material.prototype = { this.alphaTest = source.alphaTest; + this.premultipliedAlpha = source.premultipliedAlpha; + this.overdraw = source.overdraw; this.visible = source.visible; + this.clipShadows = source.clipShadows; + + var srcPlanes = source.clippingPlanes, + dstPlanes = null; + + if ( srcPlanes !== null ) { + + var n = srcPlanes.length; + dstPlanes = new Array( n ); + + for ( var i = 0; i !== n; ++ i ) + dstPlanes[ i ] = srcPlanes[ i ].clone(); + + } + + this.clippingPlanes = dstPlanes; return this; @@ -20208,7 +20693,7 @@ THREE.Material.prototype = { }; -THREE.EventDispatcher.prototype.apply( THREE.Material.prototype ); +Object.assign( THREE.Material.prototype, THREE.EventDispatcher.prototype ); THREE.MaterialIdCount = 0; @@ -20222,17 +20707,9 @@ THREE.MaterialIdCount = 0; * color: , * opacity: , * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * * linewidth: , * linecap: "round", - * linejoin: "round", - * - * vertexColors: - * - * fog: + * linejoin: "round" * } */ @@ -20248,9 +20725,7 @@ THREE.LineBasicMaterial = function ( parameters ) { this.linecap = 'round'; this.linejoin = 'round'; - this.vertexColors = THREE.NoColors; - - this.fog = true; + this.lights = false; this.setValues( parameters ); @@ -20269,10 +20744,6 @@ THREE.LineBasicMaterial.prototype.copy = function ( source ) { this.linecap = source.linecap; this.linejoin = source.linejoin; - this.vertexColors = source.vertexColors; - - this.fog = source.fog; - return this; }; @@ -20286,19 +20757,11 @@ THREE.LineBasicMaterial.prototype.copy = function ( source ) { * color: , * opacity: , * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * * linewidth: , * * scale: , * dashSize: , - * gapSize: , - * - * vertexColors: THREE.NoColors / THREE.FaceColors / THREE.VertexColors - * - * fog: + * gapSize: * } */ @@ -20316,9 +20779,7 @@ THREE.LineDashedMaterial = function ( parameters ) { this.dashSize = 3; this.gapSize = 1; - this.vertexColors = THREE.NoColors; - - this.fog = true; + this.lights = false; this.setValues( parameters ); @@ -20332,17 +20793,13 @@ THREE.LineDashedMaterial.prototype.copy = function ( source ) { THREE.Material.prototype.copy.call( this, source ); this.color.copy( source.color ); - + this.linewidth = source.linewidth; this.scale = source.scale; this.dashSize = source.dashSize; this.gapSize = source.gapSize; - this.vertexColors = source.vertexColors; - - this.fog = source.fog; - return this; }; @@ -20371,19 +20828,14 @@ THREE.LineDashedMaterial.prototype.copy = function ( source ) { * refractionRatio: , * * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, * depthTest: , * depthWrite: , * * wireframe: , * wireframeLinewidth: , * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * * skinning: , - * morphTargets: , - * - * fog: + * morphTargets: * } */ @@ -20409,20 +20861,16 @@ THREE.MeshBasicMaterial = function ( parameters ) { this.reflectivity = 1; this.refractionRatio = 0.98; - this.fog = true; - - this.shading = THREE.SmoothShading; - this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; - this.vertexColors = THREE.NoColors; - this.skinning = false; this.morphTargets = false; + this.lights = false; + this.setValues( parameters ); }; @@ -20450,20 +20898,95 @@ THREE.MeshBasicMaterial.prototype.copy = function ( source ) { this.reflectivity = source.reflectivity; this.refractionRatio = source.refractionRatio; - this.fog = source.fog; - - this.shading = source.shading; - this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; - this.vertexColors = source.vertexColors; + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; + + return this; + +}; + +// File:src/materials/MeshDepthMaterial.js + +/** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author bhouston / https://clara.io + * @author WestLangley / http://github.com/WestLangley + * + * parameters = { + * + * opacity: , + * + * map: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * displacementMap: new THREE.Texture( ), + * displacementScale: , + * displacementBias: , + * + * wireframe: , + * wireframeLinewidth: + * } + */ + +THREE.MeshDepthMaterial = function ( parameters ) { + + THREE.Material.call( this ); + + this.type = 'MeshDepthMaterial'; + + this.depthPacking = THREE.BasicDepthPacking; + + this.skinning = false; + this.morphTargets = false; + + this.map = null; + + this.alphaMap = null; + + this.displacementMap = null; + this.displacementScale = 1; + this.displacementBias = 0; + + this.wireframe = false; + this.wireframeLinewidth = 1; + + this.fog = false; + this.lights = false; + + this.setValues( parameters ); + +}; + +THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype ); +THREE.MeshDepthMaterial.prototype.constructor = THREE.MeshDepthMaterial; + +THREE.MeshDepthMaterial.prototype.copy = function ( source ) { + + THREE.Material.prototype.copy.call( this, source ); + + this.depthPacking = source.depthPacking; this.skinning = source.skinning; this.morphTargets = source.morphTargets; + this.map = source.map; + + this.alphaMap = source.alphaMap; + + this.displacementMap = source.displacementMap; + this.displacementScale = source.displacementScale; + this.displacementBias = source.displacementBias; + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + return this; }; @@ -20499,20 +21022,12 @@ THREE.MeshBasicMaterial.prototype.copy = function ( source ) { * reflectivity: , * refractionRatio: , * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * * wireframe: , * wireframeLinewidth: , * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * * skinning: , * morphTargets: , - * morphNormals: , - * - * fog: + * morphNormals: * } */ @@ -20545,15 +21060,11 @@ THREE.MeshLambertMaterial = function ( parameters ) { this.reflectivity = 1; this.refractionRatio = 0.98; - this.fog = true; - this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; - this.vertexColors = THREE.NoColors; - this.skinning = false; this.morphTargets = false; this.morphNormals = false; @@ -20592,15 +21103,11 @@ THREE.MeshLambertMaterial.prototype.copy = function ( source ) { this.reflectivity = source.reflectivity; this.refractionRatio = source.refractionRatio; - this.fog = source.fog; - this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; - this.vertexColors = source.vertexColors; - this.skinning = source.skinning; this.morphTargets = source.morphTargets; this.morphNormals = source.morphNormals; @@ -20609,6 +21116,50 @@ THREE.MeshLambertMaterial.prototype.copy = function ( source ) { }; +// File:src/materials/MeshNormalMaterial.js + +/** + * @author mrdoob / http://mrdoob.com/ + * + * parameters = { + * opacity: , + * + * wireframe: , + * wireframeLinewidth: + * } + */ + +THREE.MeshNormalMaterial = function ( parameters ) { + + THREE.Material.call( this, parameters ); + + this.type = 'MeshNormalMaterial'; + + this.wireframe = false; + this.wireframeLinewidth = 1; + + this.fog = false; + this.lights = false; + this.morphTargets = false; + + this.setValues( parameters ); + +}; + +THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype ); +THREE.MeshNormalMaterial.prototype.constructor = THREE.MeshNormalMaterial; + +THREE.MeshNormalMaterial.prototype.copy = function ( source ) { + + THREE.Material.prototype.copy.call( this, source ); + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + + return this; + +}; + // File:src/materials/MeshPhongMaterial.js /** @@ -20652,21 +21203,12 @@ THREE.MeshLambertMaterial.prototype.copy = function ( source ) { * reflectivity: , * refractionRatio: , * - * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * * wireframe: , * wireframeLinewidth: , * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * * skinning: , * morphTargets: , - * morphNormals: , - * - * fog: + * morphNormals: * } */ @@ -20711,17 +21253,11 @@ THREE.MeshPhongMaterial = function ( parameters ) { this.reflectivity = 1; this.refractionRatio = 0.98; - this.fog = true; - - this.shading = THREE.SmoothShading; - this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; - this.vertexColors = THREE.NoColors; - this.skinning = false; this.morphTargets = false; this.morphNormals = false; @@ -20772,17 +21308,11 @@ THREE.MeshPhongMaterial.prototype.copy = function ( source ) { this.reflectivity = source.reflectivity; this.refractionRatio = source.refractionRatio; - this.fog = source.fog; - - this.shading = source.shading; - this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; - this.vertexColors = source.vertexColors; - this.skinning = source.skinning; this.morphTargets = source.morphTargets; this.morphNormals = source.morphNormals; @@ -20835,21 +21365,12 @@ THREE.MeshPhongMaterial.prototype.copy = function ( source ) { * * refractionRatio: , * - * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * * wireframe: , * wireframeLinewidth: , * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * * skinning: , * morphTargets: , - * morphNormals: , - * - * fog: + * morphNormals: * } */ @@ -20857,6 +21378,8 @@ THREE.MeshStandardMaterial = function ( parameters ) { THREE.Material.call( this ); + this.defines = { 'STANDARD': '' }; + this.type = 'MeshStandardMaterial'; this.color = new THREE.Color( 0xffffff ); // diffuse @@ -20896,17 +21419,11 @@ THREE.MeshStandardMaterial = function ( parameters ) { this.refractionRatio = 0.98; - this.fog = true; - - this.shading = THREE.SmoothShading; - this.wireframe = false; this.wireframeLinewidth = 1; this.wireframeLinecap = 'round'; this.wireframeLinejoin = 'round'; - this.vertexColors = THREE.NoColors; - this.skinning = false; this.morphTargets = false; this.morphNormals = false; @@ -20922,6 +21439,8 @@ THREE.MeshStandardMaterial.prototype.copy = function ( source ) { THREE.Material.prototype.copy.call( this, source ); + this.defines = { 'STANDARD': '' }; + this.color.copy( source.color ); this.roughness = source.roughness; this.metalness = source.metalness; @@ -20959,17 +21478,11 @@ THREE.MeshStandardMaterial.prototype.copy = function ( source ) { this.refractionRatio = source.refractionRatio; - this.fog = source.fog; - - this.shading = source.shading; - this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; this.wireframeLinecap = source.wireframeLinecap; this.wireframeLinejoin = source.wireframeLinejoin; - this.vertexColors = source.vertexColors; - this.skinning = source.skinning; this.morphTargets = source.morphTargets; this.morphNormals = source.morphNormals; @@ -20978,94 +21491,40 @@ THREE.MeshStandardMaterial.prototype.copy = function ( source ) { }; -// File:src/materials/MeshDepthMaterial.js +// File:src/materials/MeshPhysicalMaterial.js /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley * * parameters = { - * opacity: , - * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: + * reflectivity: * } */ -THREE.MeshDepthMaterial = function ( parameters ) { +THREE.MeshPhysicalMaterial = function ( parameters ) { - THREE.Material.call( this ); + THREE.MeshStandardMaterial.call( this ); - this.type = 'MeshDepthMaterial'; + this.defines = { 'PHYSICAL': '' }; - this.morphTargets = false; - this.wireframe = false; - this.wireframeLinewidth = 1; + this.type = 'MeshPhysicalMaterial'; + + this.reflectivity = 0.5; // maps to F0 = 0.04 this.setValues( parameters ); }; -THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype ); -THREE.MeshDepthMaterial.prototype.constructor = THREE.MeshDepthMaterial; +THREE.MeshPhysicalMaterial.prototype = Object.create( THREE.MeshStandardMaterial.prototype ); +THREE.MeshPhysicalMaterial.prototype.constructor = THREE.MeshPhysicalMaterial; -THREE.MeshDepthMaterial.prototype.copy = function ( source ) { +THREE.MeshPhysicalMaterial.prototype.copy = function ( source ) { - THREE.Material.prototype.copy.call( this, source ); + THREE.MeshStandardMaterial.prototype.copy.call( this, source ); - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; + this.defines = { 'PHYSICAL': '' }; - return this; - -}; - -// File:src/materials/MeshNormalMaterial.js - -/** - * @author mrdoob / http://mrdoob.com/ - * - * parameters = { - * opacity: , - * - * shading: THREE.FlatShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: - * } - */ - -THREE.MeshNormalMaterial = function ( parameters ) { - - THREE.Material.call( this, parameters ); - - this.type = 'MeshNormalMaterial'; - - this.wireframe = false; - this.wireframeLinewidth = 1; - - this.morphTargets = false; - - this.setValues( parameters ); - -}; - -THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype ); -THREE.MeshNormalMaterial.prototype.constructor = THREE.MeshNormalMaterial; - -THREE.MeshNormalMaterial.prototype.copy = function ( source ) { - - THREE.Material.prototype.copy.call( this, source ); - - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; + this.reflectivity = source.reflectivity; return this; @@ -21153,15 +21612,7 @@ THREE.MultiMaterial.prototype = { * map: new THREE.Texture( ), * * size: , - * sizeAttenuation: , - * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * - * vertexColors: , - * - * fog: + * sizeAttenuation: * } */ @@ -21178,9 +21629,7 @@ THREE.PointsMaterial = function ( parameters ) { this.size = 1; this.sizeAttenuation = true; - this.vertexColors = THREE.NoColors; - - this.fog = true; + this.lights = false; this.setValues( parameters ); @@ -21200,10 +21649,6 @@ THREE.PointsMaterial.prototype.copy = function ( source ) { this.size = source.size; this.sizeAttenuation = source.sizeAttenuation; - this.vertexColors = source.vertexColors; - - this.fog = source.fog; - return this; }; @@ -21215,28 +21660,19 @@ THREE.PointsMaterial.prototype.copy = function ( source ) { * * parameters = { * defines: { "label" : "value" }, - * uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } }, + * uniforms: { "parameter1": { type: "1f", value: 1.0 }, "parameter2": { type: "1i" value2: 2 } }, * * fragmentShader: , * vertexShader: , * - * shading: THREE.SmoothShading, - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * * wireframe: , * wireframeLinewidth: , * * lights: , * - * vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors, - * * skinning: , * morphTargets: , - * morphNormals: , - * - * fog: + * morphNormals: * } */ @@ -21252,21 +21688,16 @@ THREE.ShaderMaterial = function ( parameters ) { this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}'; this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}'; - this.shading = THREE.SmoothShading; - this.linewidth = 1; this.wireframe = false; this.wireframeLinewidth = 1; this.fog = false; // set to use scene fog - this.lights = false; // set to use scene lights - - this.vertexColors = THREE.NoColors; // set to use "color" attribute stream + this.clipping = false; // set to use user-defined clipping planes this.skinning = false; // set to use skinning attribute streams - this.morphTargets = false; // set to use morph targets this.morphNormals = false; // set to use morph normals @@ -21315,16 +21746,11 @@ THREE.ShaderMaterial.prototype.copy = function ( source ) { this.defines = source.defines; - this.shading = source.shading; - this.wireframe = source.wireframe; this.wireframeLinewidth = source.wireframeLinewidth; - this.fog = source.fog; - this.lights = source.lights; - - this.vertexColors = source.vertexColors; + this.clipping = source.clipping; this.skinning = source.skinning; @@ -21376,14 +21802,8 @@ THREE.RawShaderMaterial.prototype.constructor = THREE.RawShaderMaterial; * opacity: , * map: new THREE.Texture( ), * - * blending: THREE.NormalBlending, - * depthTest: , - * depthWrite: , - * * uvOffset: new THREE.Vector2(), - * uvScale: new THREE.Vector2(), - * - * fog: + * uvScale: new THREE.Vector2() * } */ @@ -21399,8 +21819,7 @@ THREE.SpriteMaterial = function ( parameters ) { this.rotation = 0; this.fog = false; - - // set parameters + this.lights = false; this.setValues( parameters ); @@ -21418,12 +21837,49 @@ THREE.SpriteMaterial.prototype.copy = function ( source ) { this.rotation = source.rotation; - this.fog = source.fog; - return this; }; +// File:src/materials/ShadowMaterial.js + +/** + * @author mrdoob / http://mrdoob.com/ + */ + +THREE.ShadowMaterial = function () { + + THREE.ShaderMaterial.call( this, { + uniforms: THREE.UniformsUtils.merge( [ + THREE.UniformsLib[ "lights" ], + { + opacity: { value: 1.0 } + } + ] ), + vertexShader: THREE.ShaderChunk[ 'shadow_vert' ], + fragmentShader: THREE.ShaderChunk[ 'shadow_frag' ] + } ); + + this.lights = true; + this.transparent = true; + + Object.defineProperties( this, { + opacity: { + enumerable: true, + get: function () { + return this.uniforms.opacity.value; + }, + set: function ( value ) { + this.uniforms.opacity.value = value; + } + } + } ); + +}; + +THREE.ShadowMaterial.prototype = Object.create( THREE.ShaderMaterial.prototype ); +THREE.ShadowMaterial.prototype.constructor = THREE.ShadowMaterial; + // File:src/textures/Texture.js /** @@ -21432,7 +21888,7 @@ THREE.SpriteMaterial.prototype.copy = function ( source ) { * @author szimek / https://github.com/szimek/ */ -THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { +THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { Object.defineProperty( this, 'id', { value: THREE.TextureIdCount ++ } ); @@ -21463,7 +21919,14 @@ THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, f this.generateMipmaps = true; this.premultiplyAlpha = false; this.flipY = true; - this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) + + + // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap. + // + // Also changing the encoding after already used by a Material will not automatically make the Material + // update. You need to explicitly call Material.needsUpdate to trigger it to recompile. + this.encoding = encoding !== undefined ? encoding : THREE.LinearEncoding; this.version = 0; this.onUpdate = null; @@ -21477,7 +21940,7 @@ THREE.Texture.prototype = { constructor: THREE.Texture, - set needsUpdate ( value ) { + set needsUpdate( value ) { if ( value === true ) this.version ++; @@ -21514,6 +21977,7 @@ THREE.Texture.prototype = { this.premultiplyAlpha = source.premultiplyAlpha; this.flipY = source.flipY; this.unpackAlignment = source.unpackAlignment; + this.encoding = source.encoding; return this; @@ -21694,10 +22158,35 @@ THREE.Texture.prototype = { }; -THREE.EventDispatcher.prototype.apply( THREE.Texture.prototype ); +Object.assign( THREE.Texture.prototype, THREE.EventDispatcher.prototype ); THREE.TextureIdCount = 0; +// File:src/textures/DepthTexture.js + +/** + * @author Matt DesLauriers / @mattdesl + */ + +THREE.DepthTexture = function ( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) { + + THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, THREE.DepthFormat, type, anisotropy ); + + this.image = { width: width, height: height }; + + this.type = type !== undefined ? type : THREE.UnsignedShortType; + + this.magFilter = magFilter !== undefined ? magFilter : THREE.NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : THREE.NearestFilter; + + this.flipY = false; + this.generateMipmaps = false; + +}; + +THREE.DepthTexture.prototype = Object.create( THREE.Texture.prototype ); +THREE.DepthTexture.prototype.constructor = THREE.DepthTexture; + // File:src/textures/CanvasTexture.js /** @@ -21721,13 +22210,13 @@ THREE.CanvasTexture.prototype.constructor = THREE.CanvasTexture; * @author mrdoob / http://mrdoob.com/ */ -THREE.CubeTexture = function ( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) { +THREE.CubeTexture = function ( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) { + images = images !== undefined ? images : []; mapping = mapping !== undefined ? mapping : THREE.CubeReflectionMapping; - THREE.Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + THREE.Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); - this.images = images; this.flipY = false; }; @@ -21735,15 +22224,21 @@ THREE.CubeTexture = function ( images, mapping, wrapS, wrapT, magFilter, minFilt THREE.CubeTexture.prototype = Object.create( THREE.Texture.prototype ); THREE.CubeTexture.prototype.constructor = THREE.CubeTexture; -THREE.CubeTexture.prototype.copy = function ( source ) { +Object.defineProperty( THREE.CubeTexture.prototype, 'images', { - THREE.Texture.prototype.copy.call( this, source ); + get: function () { - this.images = source.images; + return this.image; - return this; + }, -}; + set: function ( value ) { + + this.image = value; + + } + +} ); // File:src/textures/CompressedTexture.js @@ -21751,9 +22246,9 @@ THREE.CubeTexture.prototype.copy = function ( source ) { * @author alteredq / http://alteredqualia.com/ */ -THREE.CompressedTexture = function ( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) { +THREE.CompressedTexture = function ( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { - THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); this.image = { width: width, height: height }; this.mipmaps = mipmaps; @@ -21779,15 +22274,15 @@ THREE.CompressedTexture.prototype.constructor = THREE.CompressedTexture; * @author alteredq / http://alteredqualia.com/ */ -THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy ) { +THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { - THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ); + THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); 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; @@ -21814,7 +22309,7 @@ THREE.VideoTexture = function ( video, mapping, wrapS, wrapT, magFilter, minFilt requestAnimationFrame( update ); - if ( video.readyState === video.HAVE_ENOUGH_DATA ) { + if ( video.readyState >= video.HAVE_CURRENT_DATA ) { scope.needsUpdate = true; @@ -21843,8 +22338,12 @@ THREE.Group = function () { }; -THREE.Group.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Group.prototype.constructor = THREE.Group; +THREE.Group.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { + + constructor: THREE.Group + +} ); + // File:src/objects/Points.js /** @@ -21857,126 +22356,129 @@ THREE.Points = function ( geometry, material ) { this.type = 'Points'; - this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); + this.geometry = geometry !== undefined ? geometry : new THREE.BufferGeometry(); this.material = material !== undefined ? material : new THREE.PointsMaterial( { color: Math.random() * 0xffffff } ); }; -THREE.Points.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Points.prototype.constructor = THREE.Points; +THREE.Points.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.Points.prototype.raycast = ( function () { + constructor: THREE.Points, - var inverseMatrix = new THREE.Matrix4(); - var ray = new THREE.Ray(); - var sphere = new THREE.Sphere(); + raycast: ( function () { - return function raycast( raycaster, intersects ) { + var inverseMatrix = new THREE.Matrix4(); + var ray = new THREE.Ray(); + var sphere = new THREE.Sphere(); - var object = this; - var geometry = this.geometry; - var matrixWorld = this.matrixWorld; - var threshold = raycaster.params.Points.threshold; + return function raycast( raycaster, intersects ) { - // Checking boundingSphere distance to ray + var object = this; + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; + var threshold = raycaster.params.Points.threshold; - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + sphere.copy( geometry.boundingSphere ); + sphere.applyMatrix4( matrixWorld ); - // + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + // - var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); - var localThresholdSq = localThreshold * localThreshold; - var position = new THREE.Vector3(); + inverseMatrix.getInverse( matrixWorld ); + ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); - function testPoint( point, index ) { + var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 ); + var localThresholdSq = localThreshold * localThreshold; + var position = new THREE.Vector3(); - var rayPointDistanceSq = ray.distanceSqToPoint( point ); + function testPoint( point, index ) { - if ( rayPointDistanceSq < localThresholdSq ) { + var rayPointDistanceSq = ray.distanceSqToPoint( point ); - var intersectPoint = ray.closestPointToPoint( point ); - intersectPoint.applyMatrix4( matrixWorld ); + if ( rayPointDistanceSq < localThresholdSq ) { - var distance = raycaster.ray.origin.distanceTo( intersectPoint ); + var intersectPoint = ray.closestPointToPoint( point ); + intersectPoint.applyMatrix4( matrixWorld ); - if ( distance < raycaster.near || distance > raycaster.far ) return; + var distance = raycaster.ray.origin.distanceTo( intersectPoint ); - intersects.push( { + if ( distance < raycaster.near || distance > raycaster.far ) return; - distance: distance, - distanceToRay: Math.sqrt( rayPointDistanceSq ), - point: intersectPoint.clone(), - index: index, - face: null, - object: object + intersects.push( { - } ); + distance: distance, + distanceToRay: Math.sqrt( rayPointDistanceSq ), + point: intersectPoint.clone(), + index: index, + face: null, + object: object + + } ); + + } } - } + if ( geometry instanceof THREE.BufferGeometry ) { - if ( geometry instanceof THREE.BufferGeometry ) { + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; - var index = geometry.index; - var attributes = geometry.attributes; - var positions = attributes.position.array; + if ( index !== null ) { - if ( index !== null ) { + var indices = index.array; - var indices = index.array; + for ( var i = 0, il = indices.length; i < il; i ++ ) { - for ( var i = 0, il = indices.length; i < il; i ++ ) { + var a = indices[ i ]; - var a = indices[ i ]; + position.fromArray( positions, a * 3 ); - position.fromArray( positions, a * 3 ); + testPoint( position, a ); - testPoint( position, a ); + } + + } else { + + for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { + + position.fromArray( positions, i * 3 ); + + testPoint( position, i ); + + } } } else { - for ( var i = 0, l = positions.length / 3; i < l; i ++ ) { + var vertices = geometry.vertices; - position.fromArray( positions, i * 3 ); + for ( var i = 0, l = vertices.length; i < l; i ++ ) { - testPoint( position, i ); + testPoint( vertices[ i ], i ); } } - } else { + }; - var vertices = geometry.vertices; + }() ), - for ( var i = 0, l = vertices.length; i < l; i ++ ) { + clone: function () { - testPoint( vertices[ i ], i ); + return new this.constructor( this.geometry, this.material ).copy( this ); - } + } - } - - }; - -}() ); - -THREE.Points.prototype.clone = function () { - - return new this.constructor( this.geometry, this.material ).copy( this ); - -}; +} ); // File:src/objects/Line.js @@ -21997,99 +22499,134 @@ THREE.Line = function ( geometry, material, mode ) { this.type = 'Line'; - this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); + this.geometry = geometry !== undefined ? geometry : new THREE.BufferGeometry(); this.material = material !== undefined ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } ); }; -THREE.Line.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Line.prototype.constructor = THREE.Line; +THREE.Line.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.Line.prototype.raycast = ( function () { + constructor: THREE.Line, - var inverseMatrix = new THREE.Matrix4(); - var ray = new THREE.Ray(); - var sphere = new THREE.Sphere(); + raycast: ( function () { - return function raycast( raycaster, intersects ) { + var inverseMatrix = new THREE.Matrix4(); + var ray = new THREE.Ray(); + var sphere = new THREE.Sphere(); - var precision = raycaster.linePrecision; - var precisionSq = precision * precision; + return function raycast( raycaster, intersects ) { - var geometry = this.geometry; - var matrixWorld = this.matrixWorld; + var precision = raycaster.linePrecision; + var precisionSq = precision * precision; - // Checking boundingSphere distance to ray + var geometry = this.geometry; + var matrixWorld = this.matrixWorld; - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + // Checking boundingSphere distance to ray - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + sphere.copy( geometry.boundingSphere ); + sphere.applyMatrix4( matrixWorld ); - // + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + // - var vStart = new THREE.Vector3(); - var vEnd = new THREE.Vector3(); - var interSegment = new THREE.Vector3(); - var interRay = new THREE.Vector3(); - var step = this instanceof THREE.LineSegments ? 2 : 1; + inverseMatrix.getInverse( matrixWorld ); + ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); - if ( geometry instanceof THREE.BufferGeometry ) { + var vStart = new THREE.Vector3(); + var vEnd = new THREE.Vector3(); + var interSegment = new THREE.Vector3(); + var interRay = new THREE.Vector3(); + var step = this instanceof THREE.LineSegments ? 2 : 1; - var index = geometry.index; - var attributes = geometry.attributes; - var positions = attributes.position.array; + if ( geometry instanceof THREE.BufferGeometry ) { - if ( index !== null ) { + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; - var indices = index.array; + if ( index !== null ) { - for ( var i = 0, l = indices.length - 1; i < l; i += step ) { + var indices = index.array; - var a = indices[ i ]; - var b = indices[ i + 1 ]; + for ( var i = 0, l = indices.length - 1; i < l; i += step ) { - vStart.fromArray( positions, a * 3 ); - vEnd.fromArray( positions, b * 3 ); + var a = indices[ i ]; + var b = indices[ i + 1 ]; - var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); + vStart.fromArray( positions, a * 3 ); + vEnd.fromArray( positions, b * 3 ); - if ( distSq > precisionSq ) continue; + var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); - interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation + if ( distSq > precisionSq ) continue; - var distance = raycaster.ray.origin.distanceTo( interRay ); + interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation - if ( distance < raycaster.near || distance > raycaster.far ) continue; + var distance = raycaster.ray.origin.distanceTo( interRay ); - intersects.push( { + if ( distance < raycaster.near || distance > raycaster.far ) continue; - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( this.matrixWorld ), - index: i, - face: null, - faceIndex: null, - object: this + intersects.push( { - } ); + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this + + } ); + + } + + } else { + + for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { + + vStart.fromArray( positions, 3 * i ); + vEnd.fromArray( positions, 3 * i + 3 ); + + var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); + + if ( distSq > precisionSq ) continue; + + 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; + + intersects.push( { + + distance: distance, + // What do we want? intersection point on the ray or on the segment?? + // point: raycaster.ray.at( distance ), + point: interSegment.clone().applyMatrix4( this.matrixWorld ), + index: i, + face: null, + faceIndex: null, + object: this + + } ); + + } } - } else { + } else if ( geometry instanceof THREE.Geometry ) { - for ( var i = 0, l = positions.length / 3 - 1; i < l; i += step ) { + var vertices = geometry.vertices; + var nbVertices = vertices.length; - vStart.fromArray( positions, 3 * i ); - vEnd.fromArray( positions, 3 * i + 3 ); + for ( var i = 0; i < nbVertices - 1; i += step ) { - var distSq = ray.distanceSqToSegment( vStart, vEnd, interRay, interSegment ); + var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); if ( distSq > precisionSq ) continue; @@ -22116,54 +22653,17 @@ THREE.Line.prototype.raycast = ( function () { } - } else if ( geometry instanceof THREE.Geometry ) { + }; - var vertices = geometry.vertices; - var nbVertices = vertices.length; + }() ), - for ( var i = 0; i < nbVertices - 1; i += step ) { + clone: function () { - var distSq = ray.distanceSqToSegment( vertices[ i ], vertices[ i + 1 ], interRay, interSegment ); + return new this.constructor( this.geometry, this.material ).copy( this ); - if ( distSq > precisionSq ) continue; + } - 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; - - intersects.push( { - - distance: distance, - // What do we want? intersection point on the ray or on the segment?? - // point: raycaster.ray.at( distance ), - point: interSegment.clone().applyMatrix4( this.matrixWorld ), - index: i, - face: null, - faceIndex: null, - object: this - - } ); - - } - - } - - }; - -}() ); - -THREE.Line.prototype.clone = function () { - - return new this.constructor( this.geometry, this.material ).copy( this ); - -}; - -// DEPRECATED - -THREE.LineStrip = 0; -THREE.LinePieces = 1; +} ); // File:src/objects/LineSegments.js @@ -22179,8 +22679,11 @@ THREE.LineSegments = function ( geometry, material ) { }; -THREE.LineSegments.prototype = Object.create( THREE.Line.prototype ); -THREE.LineSegments.prototype.constructor = THREE.LineSegments; +THREE.LineSegments.prototype = Object.assign( Object.create( THREE.Line.prototype ), { + + constructor: THREE.LineSegments + +} ); // File:src/objects/Mesh.js @@ -22197,7 +22700,7 @@ THREE.Mesh = function ( geometry, material ) { this.type = 'Mesh'; - this.geometry = geometry !== undefined ? geometry : new THREE.Geometry(); + this.geometry = geometry !== undefined ? geometry : new THREE.BufferGeometry(); this.material = material !== undefined ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } ); this.drawMode = THREE.TrianglesDrawMode; @@ -22206,227 +22709,307 @@ THREE.Mesh = function ( geometry, material ) { }; -THREE.Mesh.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Mesh.prototype.constructor = THREE.Mesh; +THREE.Mesh.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.Mesh.prototype.setDrawMode = function ( value ) { + constructor: THREE.Mesh, - this.drawMode = value; + setDrawMode: function ( value ) { -}; + this.drawMode = value; -THREE.Mesh.prototype.updateMorphTargets = function () { + }, - if ( this.geometry.morphTargets !== undefined && this.geometry.morphTargets.length > 0 ) { + updateMorphTargets: function () { - this.morphTargetBase = - 1; - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + if ( this.geometry.morphTargets !== undefined && this.geometry.morphTargets.length > 0 ) { - for ( var m = 0, ml = this.geometry.morphTargets.length; m < ml; m ++ ) { + this.morphTargetBase = - 1; + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - this.morphTargetInfluences.push( 0 ); - this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m; + for ( var m = 0, ml = this.geometry.morphTargets.length; m < ml; m ++ ) { - } - - } - -}; - -THREE.Mesh.prototype.getMorphTargetIndexByName = function ( name ) { - - if ( this.morphTargetDictionary[ name ] !== undefined ) { - - return this.morphTargetDictionary[ name ]; - - } - - console.warn( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); - - return 0; - -}; - - -THREE.Mesh.prototype.raycast = ( function () { - - var inverseMatrix = new THREE.Matrix4(); - var ray = new THREE.Ray(); - var sphere = new THREE.Sphere(); - - var vA = new THREE.Vector3(); - var vB = new THREE.Vector3(); - var vC = new THREE.Vector3(); - - var tempA = new THREE.Vector3(); - var tempB = new THREE.Vector3(); - var tempC = new THREE.Vector3(); - - var uvA = new THREE.Vector2(); - var uvB = new THREE.Vector2(); - var uvC = new THREE.Vector2(); - - var barycoord = new THREE.Vector3(); - - var intersectionPoint = new THREE.Vector3(); - var intersectionPointWorld = new THREE.Vector3(); - - function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) { - - THREE.Triangle.barycoordFromPoint( point, p1, p2, p3, barycoord ); - - uv1.multiplyScalar( barycoord.x ); - uv2.multiplyScalar( barycoord.y ); - uv3.multiplyScalar( barycoord.z ); - - uv1.add( uv2 ).add( uv3 ); - - return uv1.clone(); - - } - - function checkIntersection( object, raycaster, ray, pA, pB, pC, point ) { - - var intersect; - var material = object.material; - - if ( material.side === THREE.BackSide ) { - - intersect = ray.intersectTriangle( pC, pB, pA, true, point ); - - } else { - - intersect = ray.intersectTriangle( pA, pB, pC, material.side !== THREE.DoubleSide, point ); - - } - - if ( intersect === null ) return null; - - intersectionPointWorld.copy( point ); - intersectionPointWorld.applyMatrix4( object.matrixWorld ); - - var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); - - if ( distance < raycaster.near || distance > raycaster.far ) return null; - - return { - distance: distance, - point: intersectionPointWorld.clone(), - object: object - }; - - } - - function checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) { - - vA.fromArray( positions, a * 3 ); - vB.fromArray( positions, b * 3 ); - vC.fromArray( positions, c * 3 ); - - var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint ); - - if ( intersection ) { - - if ( uvs ) { - - uvA.fromArray( uvs, a * 2 ); - uvB.fromArray( uvs, b * 2 ); - uvC.fromArray( uvs, c * 2 ); - - intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC ); + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m; } - intersection.face = new THREE.Face3( a, b, c, THREE.Triangle.normal( vA, vB, vC ) ); - intersection.faceIndex = a; + } + + }, + + getMorphTargetIndexByName: function ( name ) { + + if ( this.morphTargetDictionary[ name ] !== undefined ) { + + return this.morphTargetDictionary[ name ]; } - return intersection; + console.warn( 'THREE.Mesh.getMorphTargetIndexByName: morph target ' + name + ' does not exist. Returning 0.' ); - } + return 0; - return function raycast( raycaster, intersects ) { + }, - var geometry = this.geometry; - var material = this.material; - var matrixWorld = this.matrixWorld; + raycast: ( function () { - if ( material === undefined ) return; + var inverseMatrix = new THREE.Matrix4(); + var ray = new THREE.Ray(); + var sphere = new THREE.Sphere(); - // Checking boundingSphere distance to ray + var vA = new THREE.Vector3(); + var vB = new THREE.Vector3(); + var vC = new THREE.Vector3(); - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + var tempA = new THREE.Vector3(); + var tempB = new THREE.Vector3(); + var tempC = new THREE.Vector3(); - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); + var uvA = new THREE.Vector2(); + var uvB = new THREE.Vector2(); + var uvC = new THREE.Vector2(); - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + var barycoord = new THREE.Vector3(); - // + var intersectionPoint = new THREE.Vector3(); + var intersectionPointWorld = new THREE.Vector3(); - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + function uvIntersection( point, p1, p2, p3, uv1, uv2, uv3 ) { - // Check boundingBox before continuing + THREE.Triangle.barycoordFromPoint( point, p1, p2, p3, barycoord ); - if ( geometry.boundingBox !== null ) { + uv1.multiplyScalar( barycoord.x ); + uv2.multiplyScalar( barycoord.y ); + uv3.multiplyScalar( barycoord.z ); - if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; + uv1.add( uv2 ).add( uv3 ); + + return uv1.clone(); } - var uvs, intersection; + function checkIntersection( object, raycaster, ray, pA, pB, pC, point ) { - if ( geometry instanceof THREE.BufferGeometry ) { + var intersect; + var material = object.material; - var a, b, c; - var index = geometry.index; - var attributes = geometry.attributes; - var positions = attributes.position.array; + if ( material.side === THREE.BackSide ) { - if ( attributes.uv !== undefined ) { - - uvs = attributes.uv.array; - - } - - if ( index !== null ) { - - var indices = index.array; - - for ( var i = 0, l = indices.length; i < l; i += 3 ) { - - a = indices[ i ]; - b = indices[ i + 1 ]; - c = indices[ i + 2 ]; - - intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c ); - - if ( intersection ) { - - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics - intersects.push( intersection ); - - } - - } + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); } else { + intersect = ray.intersectTriangle( pA, pB, pC, material.side !== THREE.DoubleSide, point ); - for ( var i = 0, l = positions.length; i < l; i += 9 ) { + } - a = i / 3; - b = a + 1; - c = a + 2; + if ( intersect === null ) return null; - intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c ); + intersectionPointWorld.copy( point ); + intersectionPointWorld.applyMatrix4( object.matrixWorld ); + + var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); + + if ( distance < raycaster.near || distance > raycaster.far ) return null; + + return { + distance: distance, + point: intersectionPointWorld.clone(), + object: object + }; + + } + + function checkBufferGeometryIntersection( object, raycaster, ray, positions, uvs, a, b, c ) { + + vA.fromArray( positions, a * 3 ); + vB.fromArray( positions, b * 3 ); + vC.fromArray( positions, c * 3 ); + + var intersection = checkIntersection( object, raycaster, ray, vA, vB, vC, intersectionPoint ); + + if ( intersection ) { + + if ( uvs ) { + + uvA.fromArray( uvs, a * 2 ); + uvB.fromArray( uvs, b * 2 ); + uvC.fromArray( uvs, c * 2 ); + + intersection.uv = uvIntersection( intersectionPoint, vA, vB, vC, uvA, uvB, uvC ); + + } + + intersection.face = new THREE.Face3( a, b, c, THREE.Triangle.normal( vA, vB, vC ) ); + intersection.faceIndex = a; + + } + + return intersection; + + } + + return function raycast( raycaster, intersects ) { + + var geometry = this.geometry; + var material = this.material; + var matrixWorld = this.matrixWorld; + + if ( material === undefined ) return; + + // Checking boundingSphere distance to ray + + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + + sphere.copy( geometry.boundingSphere ); + sphere.applyMatrix4( matrixWorld ); + + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + + // + + inverseMatrix.getInverse( matrixWorld ); + ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + + // Check boundingBox before continuing + + if ( geometry.boundingBox !== null ) { + + if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; + + } + + var uvs, intersection; + + if ( geometry instanceof THREE.BufferGeometry ) { + + var a, b, c; + var index = geometry.index; + var attributes = geometry.attributes; + var positions = attributes.position.array; + + if ( attributes.uv !== undefined ) { + + uvs = attributes.uv.array; + + } + + if ( index !== null ) { + + var indices = index.array; + + for ( var i = 0, l = indices.length; i < l; i += 3 ) { + + a = indices[ i ]; + b = indices[ i + 1 ]; + c = indices[ i + 2 ]; + + intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c ); + + if ( intersection ) { + + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indices buffer semantics + intersects.push( intersection ); + + } + + } + + } else { + + + for ( var i = 0, l = positions.length; i < l; i += 9 ) { + + a = i / 3; + b = a + 1; + c = a + 2; + + intersection = checkBufferGeometryIntersection( this, raycaster, ray, positions, uvs, a, b, c ); + + if ( intersection ) { + + intersection.index = a; // triangle number in positions buffer semantics + intersects.push( intersection ); + + } + + } + + } + + } else if ( geometry instanceof THREE.Geometry ) { + + var fvA, fvB, fvC; + var isFaceMaterial = material instanceof THREE.MultiMaterial; + var materials = isFaceMaterial === true ? material.materials : null; + + var vertices = geometry.vertices; + var faces = geometry.faces; + var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; + if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; + + for ( var f = 0, fl = faces.length; f < fl; f ++ ) { + + var face = faces[ f ]; + var faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material; + + if ( faceMaterial === undefined ) continue; + + fvA = vertices[ face.a ]; + fvB = vertices[ face.b ]; + fvC = vertices[ face.c ]; + + if ( faceMaterial.morphTargets === true ) { + + var morphTargets = geometry.morphTargets; + var morphInfluences = this.morphTargetInfluences; + + vA.set( 0, 0, 0 ); + vB.set( 0, 0, 0 ); + vC.set( 0, 0, 0 ); + + for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { + + var influence = morphInfluences[ t ]; + + if ( influence === 0 ) continue; + + var targets = morphTargets[ t ].vertices; + + vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence ); + vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence ); + vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence ); + + } + + vA.add( fvA ); + vB.add( fvB ); + vC.add( fvC ); + + fvA = vA; + fvB = vB; + fvC = vC; + + } + + intersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); if ( intersection ) { - intersection.index = a; // triangle number in positions buffer semantics + if ( uvs ) { + + var uvs_f = uvs[ f ]; + uvA.copy( uvs_f[ 0 ] ); + uvB.copy( uvs_f[ 1 ] ); + uvC.copy( uvs_f[ 2 ] ); + + intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC ); + + } + + intersection.face = face; + intersection.faceIndex = f; intersects.push( intersection ); } @@ -22435,95 +23018,17 @@ THREE.Mesh.prototype.raycast = ( function () { } - } else if ( geometry instanceof THREE.Geometry ) { + }; - var fvA, fvB, fvC; - var isFaceMaterial = material instanceof THREE.MultiMaterial; - var materials = isFaceMaterial === true ? material.materials : null; + }() ), - var vertices = geometry.vertices; - var faces = geometry.faces; - var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; - if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; + clone: function () { - for ( var f = 0, fl = faces.length; f < fl; f ++ ) { + return new this.constructor( this.geometry, this.material ).copy( this ); - var face = faces[ f ]; - var faceMaterial = isFaceMaterial === true ? materials[ face.materialIndex ] : material; + } - if ( faceMaterial === undefined ) continue; - - fvA = vertices[ face.a ]; - fvB = vertices[ face.b ]; - fvC = vertices[ face.c ]; - - if ( faceMaterial.morphTargets === true ) { - - var morphTargets = geometry.morphTargets; - var morphInfluences = this.morphTargetInfluences; - - vA.set( 0, 0, 0 ); - vB.set( 0, 0, 0 ); - vC.set( 0, 0, 0 ); - - for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) { - - var influence = morphInfluences[ t ]; - - if ( influence === 0 ) continue; - - var targets = morphTargets[ t ].vertices; - - vA.addScaledVector( tempA.subVectors( targets[ face.a ], fvA ), influence ); - vB.addScaledVector( tempB.subVectors( targets[ face.b ], fvB ), influence ); - vC.addScaledVector( tempC.subVectors( targets[ face.c ], fvC ), influence ); - - } - - vA.add( fvA ); - vB.add( fvB ); - vC.add( fvC ); - - fvA = vA; - fvB = vB; - fvC = vC; - - } - - intersection = checkIntersection( this, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); - - if ( intersection ) { - - if ( uvs ) { - - var uvs_f = uvs[ f ]; - uvA.copy( uvs_f[ 0 ] ); - uvB.copy( uvs_f[ 1 ] ); - uvC.copy( uvs_f[ 2 ] ); - - intersection.uv = uvIntersection( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC ); - - } - - intersection.face = face; - intersection.faceIndex = f; - intersects.push( intersection ); - - } - - } - - } - - }; - -}() ); - -THREE.Mesh.prototype.clone = function () { - - return new this.constructor( this.geometry, this.material ).copy( this ); - -}; +} ); // File:src/objects/Bone.js @@ -22543,18 +23048,21 @@ THREE.Bone = function ( skin ) { }; -THREE.Bone.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Bone.prototype.constructor = THREE.Bone; +THREE.Bone.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.Bone.prototype.copy = function ( source ) { - - THREE.Object3D.prototype.copy.call( this, source ); - - this.skin = source.skin; - - return this; + constructor: THREE.Bone, -}; + copy: function ( source ) { + + THREE.Object3D.prototype.copy.call( this, source ); + + this.skin = source.skin; + + return this; + + } + +} ); // File:src/objects/Skeleton.js @@ -22588,7 +23096,7 @@ THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) { // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32) // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64) - + var size = Math.sqrt( this.bones.length * 4 ); // 4 pixels needed for 1 matrix size = THREE.Math.nextPowerOfTwo( Math.ceil( size ) ); size = Math.max( size, 4 ); @@ -22635,105 +23143,109 @@ THREE.Skeleton = function ( bones, boneInverses, useVertexTexture ) { }; -THREE.Skeleton.prototype.calculateInverses = function () { +Object.assign( THREE.Skeleton.prototype, { - this.boneInverses = []; + calculateInverses: function () { - for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { - - var inverse = new THREE.Matrix4(); - - if ( this.bones[ b ] ) { - - inverse.getInverse( this.bones[ b ].matrixWorld ); - - } - - this.boneInverses.push( inverse ); - - } - -}; - -THREE.Skeleton.prototype.pose = function () { - - var bone; - - // recover the bind-time world matrices - - for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { - - bone = this.bones[ b ]; - - if ( bone ) { - - bone.matrixWorld.getInverse( this.boneInverses[ b ] ); - - } - - } - - // compute the local matrices, positions, rotations and scales - - for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { - - bone = this.bones[ b ]; - - if ( bone ) { - - if ( bone.parent ) { - - bone.matrix.getInverse( bone.parent.matrixWorld ); - bone.matrix.multiply( bone.matrixWorld ); - - } else { - - bone.matrix.copy( bone.matrixWorld ); - - } - - bone.matrix.decompose( bone.position, bone.quaternion, bone.scale ); - - } - - } - -}; - -THREE.Skeleton.prototype.update = ( function () { - - var offsetMatrix = new THREE.Matrix4(); - - return function update() { - - // flatten bone matrices to array + this.boneInverses = []; for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { - // compute the offset between the current and the original transform + var inverse = new THREE.Matrix4(); - var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix; + if ( this.bones[ b ] ) { - offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] ); - offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 ); + inverse.getInverse( this.bones[ b ].matrixWorld ); + + } + + this.boneInverses.push( inverse ); } - if ( this.useVertexTexture ) { + }, - this.boneTexture.needsUpdate = true; + pose: function () { + + var bone; + + // recover the bind-time world matrices + + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { + + bone = this.bones[ b ]; + + if ( bone ) { + + bone.matrixWorld.getInverse( this.boneInverses[ b ] ); + + } } - }; + // compute the local matrices, positions, rotations and scales -} )(); + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { -THREE.Skeleton.prototype.clone = function () { + bone = this.bones[ b ]; - return new THREE.Skeleton( this.bones, this.boneInverses, this.useVertexTexture ); + if ( bone ) { -}; + if ( bone.parent ) { + + bone.matrix.getInverse( bone.parent.matrixWorld ); + bone.matrix.multiply( bone.matrixWorld ); + + } else { + + bone.matrix.copy( bone.matrixWorld ); + + } + + bone.matrix.decompose( bone.position, bone.quaternion, bone.scale ); + + } + + } + + }, + + update: ( function () { + + var offsetMatrix = new THREE.Matrix4(); + + return function update() { + + // flatten bone matrices to array + + for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) { + + // compute the offset between the current and the original transform + + var matrix = this.bones[ b ] ? this.bones[ b ].matrixWorld : this.identityMatrix; + + offsetMatrix.multiplyMatrices( matrix, this.boneInverses[ b ] ); + offsetMatrix.toArray( this.boneMatrices, b * 16 ); + + } + + if ( this.useVertexTexture ) { + + this.boneTexture.needsUpdate = true; + + } + + }; + + } )(), + + clone: function () { + + return new THREE.Skeleton( this.bones, this.boneInverses, this.useVertexTexture ); + + } + +} ); // File:src/objects/SkinnedMesh.js @@ -22782,7 +23294,8 @@ THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) { gbone = this.geometry.bones[ b ]; - if ( gbone.parent !== - 1 && gbone.parent !== null ) { + if ( gbone.parent !== - 1 && gbone.parent !== null && + bones[ gbone.parent ] !== undefined ) { bones[ gbone.parent ].add( bones[ b ] ); @@ -22804,114 +23317,117 @@ THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) { }; -THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype ); -THREE.SkinnedMesh.prototype.constructor = THREE.SkinnedMesh; +THREE.SkinnedMesh.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), { -THREE.SkinnedMesh.prototype.bind = function( skeleton, bindMatrix ) { + constructor: THREE.SkinnedMesh, - this.skeleton = skeleton; + bind: function( skeleton, bindMatrix ) { - if ( bindMatrix === undefined ) { + this.skeleton = skeleton; - this.updateMatrixWorld( true ); + if ( bindMatrix === undefined ) { - this.skeleton.calculateInverses(); + this.updateMatrixWorld( true ); - bindMatrix = this.matrixWorld; + this.skeleton.calculateInverses(); - } + bindMatrix = this.matrixWorld; - this.bindMatrix.copy( bindMatrix ); - this.bindMatrixInverse.getInverse( bindMatrix ); + } -}; + this.bindMatrix.copy( bindMatrix ); + this.bindMatrixInverse.getInverse( bindMatrix ); -THREE.SkinnedMesh.prototype.pose = function () { + }, - this.skeleton.pose(); + pose: function () { -}; + this.skeleton.pose(); -THREE.SkinnedMesh.prototype.normalizeSkinWeights = function () { + }, - if ( this.geometry instanceof THREE.Geometry ) { + normalizeSkinWeights: function () { - for ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) { + if ( this.geometry instanceof THREE.Geometry ) { - var sw = this.geometry.skinWeights[ i ]; + for ( var i = 0; i < this.geometry.skinWeights.length; i ++ ) { - var scale = 1.0 / sw.lengthManhattan(); + var sw = this.geometry.skinWeights[ i ]; - if ( scale !== Infinity ) { + var scale = 1.0 / sw.lengthManhattan(); - sw.multiplyScalar( scale ); + if ( scale !== Infinity ) { - } else { + sw.multiplyScalar( scale ); - sw.set( 1, 0, 0, 0 ); // do something reasonable + } else { + + sw.set( 1, 0, 0, 0 ); // do something reasonable + + } + + } + + } else if ( this.geometry instanceof THREE.BufferGeometry ) { + + var vec = new THREE.Vector4(); + + var skinWeight = this.geometry.attributes.skinWeight; + + for ( var i = 0; i < skinWeight.count; i ++ ) { + + vec.x = skinWeight.getX( i ); + vec.y = skinWeight.getY( i ); + vec.z = skinWeight.getZ( i ); + vec.w = skinWeight.getW( i ); + + var scale = 1.0 / vec.lengthManhattan(); + + if ( scale !== Infinity ) { + + vec.multiplyScalar( scale ); + + } else { + + vec.set( 1, 0, 0, 0 ); // do something reasonable + + } + + skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w ); } } - } else if ( this.geometry instanceof THREE.BufferGeometry ) { + }, - var vec = new THREE.Vector4(); + updateMatrixWorld: function( force ) { - var skinWeight = this.geometry.attributes.skinWeight; + THREE.Mesh.prototype.updateMatrixWorld.call( this, true ); - for ( var i = 0; i < skinWeight.count; i ++ ) { + if ( this.bindMode === "attached" ) { - vec.x = skinWeight.getX( i ); - vec.y = skinWeight.getY( i ); - vec.z = skinWeight.getZ( i ); - vec.w = skinWeight.getW( i ); + this.bindMatrixInverse.getInverse( this.matrixWorld ); - var scale = 1.0 / vec.lengthManhattan(); + } else if ( this.bindMode === "detached" ) { - if ( scale !== Infinity ) { + this.bindMatrixInverse.getInverse( this.bindMatrix ); - vec.multiplyScalar( scale ); + } else { - } else { - - vec.set( 1, 0, 0, 0 ); // do something reasonable - - } - - skinWeight.setXYZW( i, vec.x, vec.y, vec.z, vec.w ); + console.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode ); } - } + }, -}; + clone: function() { -THREE.SkinnedMesh.prototype.updateMatrixWorld = function( force ) { - - THREE.Mesh.prototype.updateMatrixWorld.call( this, true ); - - if ( this.bindMode === "attached" ) { - - this.bindMatrixInverse.getInverse( this.matrixWorld ); - - } else if ( this.bindMode === "detached" ) { - - this.bindMatrixInverse.getInverse( this.bindMatrix ); - - } else { - - console.warn( 'THREE.SkinnedMesh unrecognized bindMode: ' + this.bindMode ); + return new this.constructor( this.geometry, this.material, this.useVertexTexture ).copy( this ); } -}; - -THREE.SkinnedMesh.prototype.clone = function() { - - return new this.constructor( this.geometry, this.material, this.useVertexTexture ).copy( this ); - -}; +} ); // File:src/objects/LOD.js @@ -22931,166 +23447,161 @@ THREE.LOD = function () { levels: { enumerable: true, value: [] - }, - objects: { - get: function () { - - console.warn( 'THREE.LOD: .objects has been renamed to .levels.' ); - return this.levels; - - } } } ); }; -THREE.LOD.prototype = Object.create( THREE.Object3D.prototype ); -THREE.LOD.prototype.constructor = THREE.LOD; +THREE.LOD.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.LOD.prototype.addLevel = function ( object, distance ) { + constructor: THREE.LOD, - if ( distance === undefined ) distance = 0; + copy: function ( source ) { - distance = Math.abs( distance ); + THREE.Object3D.prototype.copy.call( this, source, false ); - var levels = this.levels; + var levels = source.levels; - for ( var l = 0; l < levels.length; l ++ ) { + for ( var i = 0, l = levels.length; i < l; i ++ ) { - if ( distance < levels[ l ].distance ) { + var level = levels[ i ]; - break; + this.addLevel( level.object.clone(), level.distance ); } - } + return this; - levels.splice( l, 0, { distance: distance, object: object } ); + }, - this.add( object ); + addLevel: function ( object, distance ) { -}; + if ( distance === undefined ) distance = 0; -THREE.LOD.prototype.getObjectForDistance = function ( distance ) { - - var levels = this.levels; - - for ( var i = 1, l = levels.length; i < l; i ++ ) { - - if ( distance < levels[ i ].distance ) { - - break; - - } - - } - - return levels[ i - 1 ].object; - -}; - -THREE.LOD.prototype.raycast = ( function () { - - var matrixPosition = new THREE.Vector3(); - - return function raycast( raycaster, intersects ) { - - matrixPosition.setFromMatrixPosition( this.matrixWorld ); - - var distance = raycaster.ray.origin.distanceTo( matrixPosition ); - - this.getObjectForDistance( distance ).raycast( raycaster, intersects ); - - }; - -}() ); - -THREE.LOD.prototype.update = function () { - - var v1 = new THREE.Vector3(); - var v2 = new THREE.Vector3(); - - return function update( camera ) { + distance = Math.abs( distance ); var levels = this.levels; - if ( levels.length > 1 ) { + for ( var l = 0; l < levels.length; l ++ ) { - v1.setFromMatrixPosition( camera.matrixWorld ); - v2.setFromMatrixPosition( this.matrixWorld ); + if ( distance < levels[ l ].distance ) { - var distance = v1.distanceTo( v2 ); + break; - levels[ 0 ].object.visible = true; + } - for ( var i = 1, l = levels.length; i < l; i ++ ) { + } - if ( distance >= levels[ i ].distance ) { + levels.splice( l, 0, { distance: distance, object: object } ); - levels[ i - 1 ].object.visible = false; - levels[ i ].object.visible = true; + this.add( object ); - } else { + }, - break; + getObjectForDistance: function ( distance ) { + + var levels = this.levels; + + for ( var i = 1, l = levels.length; i < l; i ++ ) { + + if ( distance < levels[ i ].distance ) { + + break; + + } + + } + + return levels[ i - 1 ].object; + + }, + + raycast: ( function () { + + var matrixPosition = new THREE.Vector3(); + + return function raycast( raycaster, intersects ) { + + matrixPosition.setFromMatrixPosition( this.matrixWorld ); + + var distance = raycaster.ray.origin.distanceTo( matrixPosition ); + + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + + }; + + }() ), + + update: function () { + + var v1 = new THREE.Vector3(); + var v2 = new THREE.Vector3(); + + return function update( camera ) { + + var levels = this.levels; + + if ( levels.length > 1 ) { + + v1.setFromMatrixPosition( camera.matrixWorld ); + v2.setFromMatrixPosition( this.matrixWorld ); + + var distance = v1.distanceTo( v2 ); + + levels[ 0 ].object.visible = true; + + for ( var i = 1, l = levels.length; i < l; i ++ ) { + + if ( distance >= levels[ i ].distance ) { + + levels[ i - 1 ].object.visible = false; + levels[ i ].object.visible = true; + + } else { + + break; + + } + + } + + for ( ; i < l; i ++ ) { + + levels[ i ].object.visible = false; } } - for ( ; i < l; i ++ ) { + }; - levels[ i ].object.visible = false; + }(), - } + toJSON: function ( meta ) { + + var data = THREE.Object3D.prototype.toJSON.call( this, meta ); + + data.object.levels = []; + + var levels = this.levels; + + for ( var i = 0, l = levels.length; i < l; i ++ ) { + + var level = levels[ i ]; + + data.object.levels.push( { + object: level.object.uuid, + distance: level.distance + } ); } - }; - -}(); - -THREE.LOD.prototype.copy = function ( source ) { - - THREE.Object3D.prototype.copy.call( this, source, false ); - - var levels = source.levels; - - for ( var i = 0, l = levels.length; i < l; i ++ ) { - - var level = levels[ i ]; - - this.addLevel( level.object.clone(), level.distance ); + return data; } - return this; - -}; - -THREE.LOD.prototype.toJSON = function ( meta ) { - - var data = THREE.Object3D.prototype.toJSON.call( this, meta ); - - data.object.levels = []; - - var levels = this.levels; - - for ( var i = 0, l = levels.length; i < l; i ++ ) { - - var level = levels[ i ]; - - data.object.levels.push( { - object: level.object.uuid, - distance: level.distance - } ); - - } - - return data; - -}; +} ); // File:src/objects/Sprite.js @@ -23099,72 +23610,57 @@ THREE.LOD.prototype.toJSON = function ( meta ) { * @author alteredq / http://alteredqualia.com/ */ -THREE.Sprite = ( function () { +THREE.Sprite = function ( material ) { - var indices = new Uint16Array( [ 0, 1, 2, 0, 2, 3 ] ); - var vertices = new Float32Array( [ - 0.5, - 0.5, 0, 0.5, - 0.5, 0, 0.5, 0.5, 0, - 0.5, 0.5, 0 ] ); - var uvs = new Float32Array( [ 0, 0, 1, 0, 1, 1, 0, 1 ] ); + THREE.Object3D.call( this ); - var geometry = new THREE.BufferGeometry(); - geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) ); - geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - geometry.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ) ); + this.type = 'Sprite'; - return function Sprite( material ) { - - THREE.Object3D.call( this ); - - this.type = 'Sprite'; - - this.geometry = geometry; - this.material = ( material !== undefined ) ? material : new THREE.SpriteMaterial(); - - }; - -} )(); - -THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype ); -THREE.Sprite.prototype.constructor = THREE.Sprite; - -THREE.Sprite.prototype.raycast = ( function () { - - var matrixPosition = new THREE.Vector3(); - - return function raycast( raycaster, intersects ) { - - matrixPosition.setFromMatrixPosition( this.matrixWorld ); - - var distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition ); - var guessSizeSq = this.scale.x * this.scale.y; - - if ( distanceSq > guessSizeSq ) { - - return; - - } - - intersects.push( { - - distance: Math.sqrt( distanceSq ), - point: this.position, - face: null, - object: this - - } ); - - }; - -}() ); - -THREE.Sprite.prototype.clone = function () { - - return new this.constructor( this.material ).copy( this ); + this.material = ( material !== undefined ) ? material : new THREE.SpriteMaterial(); }; -// Backwards compatibility +THREE.Sprite.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { -THREE.Particle = THREE.Sprite; + constructor: THREE.Sprite, + + raycast: ( function () { + + var matrixPosition = new THREE.Vector3(); + + return function raycast( raycaster, intersects ) { + + matrixPosition.setFromMatrixPosition( this.matrixWorld ); + + var distanceSq = raycaster.ray.distanceSqToPoint( matrixPosition ); + var guessSizeSq = this.scale.x * this.scale.y / 4; + + if ( distanceSq > guessSizeSq ) { + + return; + + } + + intersects.push( { + + distance: Math.sqrt( distanceSq ), + point: this.position, + face: null, + object: this + + } ); + + }; + + }() ), + + clone: function () { + + return new this.constructor( this.material ).copy( this ); + + } + +} ); // File:src/objects/LensFlare.js @@ -23190,80 +23686,78 @@ THREE.LensFlare = function ( texture, size, distance, blending, color ) { }; -THREE.LensFlare.prototype = Object.create( THREE.Object3D.prototype ); -THREE.LensFlare.prototype.constructor = THREE.LensFlare; +THREE.LensFlare.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), { + constructor: THREE.LensFlare, -/* - * Add: adds another flare - */ + copy: function ( source ) { -THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) { + THREE.Object3D.prototype.copy.call( this, source ); - if ( size === undefined ) size = - 1; - if ( distance === undefined ) distance = 0; - if ( opacity === undefined ) opacity = 1; - if ( color === undefined ) color = new THREE.Color( 0xffffff ); - if ( blending === undefined ) blending = THREE.NormalBlending; + this.positionScreen.copy( source.positionScreen ); + this.customUpdateCallback = source.customUpdateCallback; - distance = Math.min( distance, Math.max( 0, distance ) ); + for ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) { - this.lensFlares.push( { - texture: texture, // THREE.Texture - size: size, // size in pixels (-1 = use texture.width) - distance: distance, // distance (0-1) from light source (0=at light source) - x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is in front z = 1 is back - scale: 1, // scale - rotation: 0, // rotation - opacity: opacity, // opacity - color: color, // color - blending: blending // blending - } ); + this.lensFlares.push( source.lensFlares[ i ] ); -}; + } -/* - * Update lens flares update positions on all flares based on the screen position - * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way. - */ + return this; -THREE.LensFlare.prototype.updateLensFlares = function () { + }, - var f, fl = this.lensFlares.length; - var flare; - var vecX = - this.positionScreen.x * 2; - var vecY = - this.positionScreen.y * 2; + add: function ( texture, size, distance, blending, color, opacity ) { - for ( f = 0; f < fl; f ++ ) { + if ( size === undefined ) size = - 1; + if ( distance === undefined ) distance = 0; + if ( opacity === undefined ) opacity = 1; + if ( color === undefined ) color = new THREE.Color( 0xffffff ); + if ( blending === undefined ) blending = THREE.NormalBlending; - flare = this.lensFlares[ f ]; + distance = Math.min( distance, Math.max( 0, distance ) ); - flare.x = this.positionScreen.x + vecX * flare.distance; - flare.y = this.positionScreen.y + vecY * flare.distance; + this.lensFlares.push( { + texture: texture, // THREE.Texture + size: size, // size in pixels (-1 = use texture.width) + distance: distance, // distance (0-1) from light source (0=at light source) + x: 0, y: 0, z: 0, // screen position (-1 => 1) z = 0 is in front z = 1 is back + scale: 1, // scale + rotation: 0, // rotation + opacity: opacity, // opacity + color: color, // color + blending: blending // blending + } ); - flare.wantedRotation = flare.x * Math.PI * 0.25; - flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25; + }, + + /* + * Update lens flares update positions on all flares based on the screen position + * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way. + */ + + updateLensFlares: function () { + + var f, fl = this.lensFlares.length; + var flare; + var vecX = - this.positionScreen.x * 2; + var vecY = - this.positionScreen.y * 2; + + for ( f = 0; f < fl; f ++ ) { + + flare = this.lensFlares[ f ]; + + flare.x = this.positionScreen.x + vecX * flare.distance; + flare.y = this.positionScreen.y + vecY * flare.distance; + + flare.wantedRotation = flare.x * Math.PI * 0.25; + flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25; + + } } -}; - -THREE.LensFlare.prototype.copy = function ( source ) { - - THREE.Object3D.prototype.copy.call( this, source ); - - this.positionScreen.copy( source.positionScreen ); - this.customUpdateCallback = source.customUpdateCallback; - - for ( var i = 0, l = source.lensFlares.length; i < l; i ++ ) { - - this.lensFlares.push( source.lensFlares[ i ] ); - - } - - return this; - -}; +} ); // File:src/scenes/Scene.js @@ -23287,9 +23781,9 @@ THREE.Scene = function () { THREE.Scene.prototype = Object.create( THREE.Object3D.prototype ); THREE.Scene.prototype.constructor = THREE.Scene; -THREE.Scene.prototype.copy = function ( source ) { +THREE.Scene.prototype.copy = function ( source, recursive ) { - THREE.Object3D.prototype.copy.call( this, source ); + THREE.Object3D.prototype.copy.call( this, source, recursive ); if ( source.fog !== null ) this.fog = source.fog.clone(); if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); @@ -23363,13 +23857,9 @@ THREE.ShaderChunk[ 'alphamap_pars_fragment' ] = "#ifdef USE_ALPHAMAP\n uniform s THREE.ShaderChunk[ 'alphatest_fragment' ] = "#ifdef ALPHATEST\n if ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n"; -// File:src/renderers/shaders/ShaderChunk/ambient_pars.glsl - -THREE.ShaderChunk[ 'ambient_pars' ] = "uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n return PI * ambientLightColor;\n}\n"; - // File:src/renderers/shaders/ShaderChunk/aomap_fragment.glsl -THREE.ShaderChunk[ 'aomap_fragment' ] = "#ifdef USE_AOMAP\n reflectedLight.indirectDiffuse *= ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n#endif\n"; +THREE.ShaderChunk[ 'aomap_fragment' ] = "#ifdef USE_AOMAP\n float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n reflectedLight.indirectDiffuse *= ambientOcclusion;\n #if defined( USE_ENVMAP ) && defined( PHYSICAL )\n float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n #endif\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl @@ -23385,12 +23875,28 @@ THREE.ShaderChunk[ 'beginnormal_vertex' ] = "\nvec3 objectNormal = vec3( normal // File:src/renderers/shaders/ShaderChunk/bsdfs.glsl -THREE.ShaderChunk[ 'bsdfs' ] = "float calcLightAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n if ( decayExponent > 0.0 ) {\n return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n }\n return 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n return RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n return ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n float a2 = alpha * alpha;\n float gl = dotNL + pow( a2 + ( 1.0 - a2 ) * dotNL * dotNL, 0.5 );\n float gv = dotNV + pow( a2 + ( 1.0 - a2 ) * dotNV * dotNV, 0.5 );\n return 1.0 / ( gl * gv );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n float a2 = alpha * alpha;\n float denom = dotNH * dotNH * ( a2 - 1.0 ) + 1.0;\n return RECIPROCAL_PI * a2 / ( denom * denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n float alpha = roughness * roughness;\n vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n float dotNH = saturate( dot( geometry.normal, halfDir ) );\n float dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n vec3 F = F_Schlick( specularColor, dotLH );\n float G = G_GGX_Smith( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n return F * ( G * D );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n return specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n return 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n float dotNH = saturate( dot( geometry.normal, halfDir ) );\n float dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n vec3 F = F_Schlick( specularColor, dotLH );\n float G = G_BlinnPhong_Implicit( );\n float D = D_BlinnPhong( shininess, dotNH );\n return F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n return ( 2.0 / square( ggxRoughness + 0.0001 ) - 2.0 );\n}"; +THREE.ShaderChunk[ 'bsdfs' ] = "bool testLightInRange( const in float lightDistance, const in float cutoffDistance ) {\n return any( bvec2( cutoffDistance == 0.0, lightDistance < cutoffDistance ) );\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n if( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n float maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n return distanceFalloff * maxDistanceCutoffFactor;\n#else\n return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n }\n return 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n return RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n return ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n float a2 = pow2( alpha );\n float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n return 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n float a2 = pow2( alpha );\n float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n return 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n float a2 = pow2( alpha );\n float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n return RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n float alpha = pow2( roughness );\n vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n float dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n float dotNH = saturate( dot( geometry.normal, halfDir ) );\n float dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n vec3 F = F_Schlick( specularColor, dotLH );\n float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n float D = D_GGX( alpha, dotNH );\n return F * ( G * D );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n return specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n return 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n float dotNH = saturate( dot( geometry.normal, halfDir ) );\n float dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n vec3 F = F_Schlick( specularColor, dotLH );\n float G = G_BlinnPhong_Implicit( );\n float D = D_BlinnPhong( shininess, dotNH );\n return F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n return sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n"; // File:src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl THREE.ShaderChunk[ 'bumpmap_pars_fragment' ] = "#ifdef USE_BUMPMAP\n uniform sampler2D bumpMap;\n uniform float bumpScale;\n vec2 dHdxy_fwd() {\n vec2 dSTdx = dFdx( vUv );\n vec2 dSTdy = dFdy( vUv );\n float Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n return vec2( dBx, dBy );\n }\n vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n vec3 vSigmaX = dFdx( surf_pos );\n vec3 vSigmaY = dFdy( surf_pos );\n vec3 vN = surf_norm;\n vec3 R1 = cross( vSigmaY, vN );\n vec3 R2 = cross( vN, vSigmaX );\n float fDet = dot( vSigmaX, R1 );\n vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n return normalize( abs( fDet ) * surf_norm - vGrad );\n }\n#endif\n"; +// File:src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl + +THREE.ShaderChunk[ 'clipping_planes_fragment' ] = "#if NUM_CLIPPING_PLANES > 0\n for ( int i = 0; i < NUM_CLIPPING_PLANES; ++ i ) {\n vec4 plane = clippingPlanes[ i ];\n if ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n }\n#endif\n"; + +// File:src/renderers/shaders/ShaderChunk/clipping_planes_pars_fragment.glsl + +THREE.ShaderChunk[ 'clipping_planes_pars_fragment' ] = "#if NUM_CLIPPING_PLANES > 0\n #if ! defined( PHYSICAL ) && ! defined( PHONG )\n varying vec3 vViewPosition;\n #endif\n uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n"; + +// File:src/renderers/shaders/ShaderChunk/clipping_planes_pars_vertex.glsl + +THREE.ShaderChunk[ 'clipping_planes_pars_vertex' ] = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n varying vec3 vViewPosition;\n#endif\n"; + +// File:src/renderers/shaders/ShaderChunk/clipping_planes_vertex.glsl + +THREE.ShaderChunk[ 'clipping_planes_vertex' ] = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n vViewPosition = - mvPosition.xyz;\n#endif\n"; + // File:src/renderers/shaders/ShaderChunk/color_fragment.glsl THREE.ShaderChunk[ 'color_fragment' ] = "#ifdef USE_COLOR\n diffuseColor.rgb *= vColor;\n#endif"; @@ -23409,7 +23915,11 @@ THREE.ShaderChunk[ 'color_vertex' ] = "#ifdef USE_COLOR\n vColor.xyz = color.xyz // File:src/renderers/shaders/ShaderChunk/common.glsl -THREE.ShaderChunk[ 'common' ] = "#define PI 3.14159\n#define PI2 6.28318\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat square( const in float x ) { return x*x; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nstruct IncidentLight {\n vec3 color;\n vec3 direction;\n};\nstruct ReflectedLight {\n vec3 directDiffuse;\n vec3 directSpecular;\n vec3 indirectDiffuse;\n vec3 indirectSpecular;\n};\nstruct GeometricContext {\n vec3 position;\n vec3 normal;\n vec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n float distance = dot( planeNormal, point - pointOnPlane );\n return - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nvec3 inputToLinear( in vec3 a ) {\n #ifdef GAMMA_INPUT\n return pow( a, vec3( float( GAMMA_FACTOR ) ) );\n #else\n return a;\n #endif\n}\nvec3 linearToOutput( in vec3 a ) {\n #ifdef GAMMA_OUTPUT\n return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );\n #else\n return a;\n #endif\n}\n"; +THREE.ShaderChunk[ 'common' ] = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n return fract(sin(sn) * c);\n}\nstruct IncidentLight {\n vec3 color;\n vec3 direction;\n bool visible;\n};\nstruct ReflectedLight {\n vec3 directDiffuse;\n vec3 directSpecular;\n vec3 indirectDiffuse;\n vec3 indirectSpecular;\n};\nstruct GeometricContext {\n vec3 position;\n vec3 normal;\n vec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n float distance = dot( planeNormal, point - pointOnPlane );\n return - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\n"; + +// File:src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl + +THREE.ShaderChunk[ 'cube_uv_reflection_fragment' ] = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n vec3 absDirection = abs(direction);\n int face = -1;\n if( absDirection.x > absDirection.z ) {\n if(absDirection.x > absDirection.y )\n face = direction.x > 0.0 ? 0 : 3;\n else\n face = direction.y > 0.0 ? 1 : 4;\n }\n else {\n if(absDirection.z > absDirection.y )\n face = direction.z > 0.0 ? 2 : 5;\n else\n face = direction.y > 0.0 ? 1 : 4;\n }\n return face;\n}\n#define cubeUV_maxLods1 (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n float scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n float dxRoughness = dFdx(roughness);\n float dyRoughness = dFdy(roughness);\n vec3 dx = dFdx( vec * scale * dxRoughness );\n vec3 dy = dFdy( vec * scale * dyRoughness );\n float d = max( dot( dx, dx ), dot( dy, dy ) );\n d = clamp(d, 1.0, cubeUV_rangeClamp);\n float mipLevel = 0.5 * log2(d);\n return vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n mipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n float a = 16.0 * cubeUV_rcpTextureSize;\n vec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n vec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n float powScale = exp2_packed.x * exp2_packed.y;\n float scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n float mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n bool bRes = mipLevel == 0.0;\n scale = bRes && (scale < a) ? a : scale;\n vec3 r;\n vec2 offset;\n int face = getFaceFromDirection(direction);\n float rcpPowScale = 1.0 / powScale;\n if( face == 0) {\n r = vec3(direction.x, -direction.z, direction.y);\n offset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n }\n else if( face == 1) {\n r = vec3(direction.y, direction.x, direction.z);\n offset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n }\n else if( face == 2) {\n r = vec3(direction.z, direction.x, direction.y);\n offset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n offset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n }\n else if( face == 3) {\n r = vec3(direction.x, direction.z, direction.y);\n offset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n }\n else if( face == 4) {\n r = vec3(direction.y, direction.x, -direction.z);\n offset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n }\n else {\n r = vec3(direction.z, -direction.x, direction.y);\n offset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n offset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n }\n r = normalize(r);\n float texelOffset = 0.5 * cubeUV_rcpTextureSize;\n vec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n vec2 base = offset + vec2( texelOffset );\n return base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\n float roughnessVal = roughness* cubeUV_maxLods3;\n float r1 = floor(roughnessVal);\n float r2 = r1 + 1.0;\n float t = fract(roughnessVal);\n vec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n float s = mipInfo.y;\n float level0 = mipInfo.x;\n float level1 = level0 + 1.0;\n level1 = level1 > 5.0 ? 5.0 : level1;\n level0 += min( floor( s + 0.5 ), 5.0 );\n vec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n vec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n vec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n vec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n vec4 result = mix(color10, color20, t);\n return vec4(result.rgb, 1.0);\n}\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl @@ -23425,31 +23935,39 @@ THREE.ShaderChunk[ 'displacementmap_pars_vertex' ] = "#ifdef USE_DISPLACEMENTMAP // File:src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl -THREE.ShaderChunk[ 'emissivemap_fragment' ] = "#ifdef USE_EMISSIVEMAP\n vec4 emissiveColor = texture2D( emissiveMap, vUv );\n emissiveColor.rgb = inputToLinear( emissiveColor.rgb );\n totalEmissiveLight *= emissiveColor.rgb;\n#endif\n"; +THREE.ShaderChunk[ 'emissivemap_fragment' ] = "#ifdef USE_EMISSIVEMAP\n vec4 emissiveColor = texture2D( emissiveMap, vUv );\n emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n totalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/emissivemap_pars_fragment.glsl THREE.ShaderChunk[ 'emissivemap_pars_fragment' ] = "#ifdef USE_EMISSIVEMAP\n uniform sampler2D emissiveMap;\n#endif\n"; +// File:src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl + +THREE.ShaderChunk[ 'encodings_pars_fragment' ] = "\nvec4 LinearToLinear( in vec4 value ) {\n return value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n float maxComponent = max( max( value.r, value.g ), value.b );\n float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.x, max( value.g, value.b ) );\n float M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n M = ceil( M * 255.0 ) / 255.0;\n return vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n float maxRGB = max( value.x, max( value.g, value.b ) );\n float D = max( maxRange / maxRGB, 1.0 );\n D = min( floor( D ) / 255.0, 1.0 );\n return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n vec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n Xp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n vec4 vResult;\n vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n vResult.w = fract(Le);\n vResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n return vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n float Le = value.z * 255.0 + value.w;\n vec3 Xp_Y_XYZp;\n Xp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n vec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n return vec4( max(vRGB, 0.0), 1.0 );\n}\n"; + +// File:src/renderers/shaders/ShaderChunk/encodings_fragment.glsl + +THREE.ShaderChunk[ 'encodings_fragment' ] = " gl_FragColor = linearToOutputTexel( gl_FragColor );\n"; + // File:src/renderers/shaders/ShaderChunk/envmap_fragment.glsl -THREE.ShaderChunk[ 'envmap_fragment' ] = "#ifdef USE_ENVMAP\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vec3 reflectVec = reflect( cameraToVertex, worldNormal );\n #else\n vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n #endif\n #else\n vec3 reflectVec = vReflect;\n #endif\n #ifdef DOUBLE_SIDED\n float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n #else\n float flipNormal = 1.0;\n #endif\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n vec4 envColor = texture2D( envMap, sampleUV );\n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n #endif\n envColor.xyz = inputToLinear( envColor.xyz );\n #ifdef ENVMAP_BLENDING_MULTIPLY\n outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_MIX )\n outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_ADD )\n outgoingLight += envColor.xyz * specularStrength * reflectivity;\n #endif\n#endif\n"; +THREE.ShaderChunk[ 'envmap_fragment' ] = "#ifdef USE_ENVMAP\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vec3 reflectVec = reflect( cameraToVertex, worldNormal );\n #else\n vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n #endif\n #else\n vec3 reflectVec = vReflect;\n #endif\n #ifdef DOUBLE_SIDED\n float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n #else\n float flipNormal = 1.0;\n #endif\n #ifdef ENVMAP_TYPE_CUBE\n vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n vec4 envColor = texture2D( envMap, sampleUV );\n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n #endif\n envColor = envMapTexelToLinear( envColor );\n #ifdef ENVMAP_BLENDING_MULTIPLY\n outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_MIX )\n outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n #elif defined( ENVMAP_BLENDING_ADD )\n outgoingLight += envColor.xyz * specularStrength * reflectivity;\n #endif\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl -THREE.ShaderChunk[ 'envmap_pars_fragment' ] = "#if defined( USE_ENVMAP ) || defined( STANDARD )\n uniform float reflectivity;\n uniform float envMapIntenstiy;\n#endif\n#ifdef USE_ENVMAP\n #ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube envMap;\n #else\n uniform sampler2D envMap;\n #endif\n uniform float flipEnvMap;\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( STANDARD )\n uniform float refractionRatio;\n #else\n varying vec3 vReflect;\n #endif\n#endif\n"; +THREE.ShaderChunk[ 'envmap_pars_fragment' ] = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n uniform float reflectivity;\n uniform float envMapIntenstiy;\n#endif\n#ifdef USE_ENVMAP\n #if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n varying vec3 vWorldPosition;\n #endif\n #ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube envMap;\n #else\n uniform sampler2D envMap;\n #endif\n uniform float flipEnvMap;\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n uniform float refractionRatio;\n #else\n varying vec3 vReflect;\n #endif\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl -THREE.ShaderChunk[ 'envmap_pars_vertex' ] = "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG ) && ! defined( STANDARD )\n varying vec3 vReflect;\n uniform float refractionRatio;\n#endif\n"; +THREE.ShaderChunk[ 'envmap_pars_vertex' ] = "#ifdef USE_ENVMAP\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n varying vec3 vWorldPosition;\n #else\n varying vec3 vReflect;\n uniform float refractionRatio;\n #endif\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/envmap_vertex.glsl -THREE.ShaderChunk[ 'envmap_vertex' ] = "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG ) && ! defined( STANDARD )\n vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vReflect = reflect( cameraToVertex, worldNormal );\n #else\n vReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n #endif\n#endif\n"; +THREE.ShaderChunk[ 'envmap_vertex' ] = "#ifdef USE_ENVMAP\n #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n vWorldPosition = worldPosition.xyz;\n #else\n vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n #ifdef ENVMAP_MODE_REFLECTION\n vReflect = reflect( cameraToVertex, worldNormal );\n #else\n vReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n #endif\n #endif\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/fog_fragment.glsl -THREE.ShaderChunk[ 'fog_fragment' ] = "#ifdef USE_FOG\n #ifdef USE_LOGDEPTHBUF_EXT\n float depth = gl_FragDepthEXT / gl_FragCoord.w;\n #else\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n #endif\n #ifdef FOG_EXP2\n float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\n #else\n float fogFactor = smoothstep( fogNear, fogFar, depth );\n #endif\n \n outgoingLight = mix( outgoingLight, fogColor, fogFactor );\n#endif"; +THREE.ShaderChunk[ 'fog_fragment' ] = "#ifdef USE_FOG\n #ifdef USE_LOGDEPTHBUF_EXT\n float depth = gl_FragDepthEXT / gl_FragCoord.w;\n #else\n float depth = gl_FragCoord.z / gl_FragCoord.w;\n #endif\n #ifdef FOG_EXP2\n float fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * depth * depth * LOG2 ) );\n #else\n float fogFactor = smoothstep( fogNear, fogFar, depth );\n #endif\n gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl @@ -23465,11 +23983,11 @@ THREE.ShaderChunk[ 'lightmap_pars_fragment' ] = "#ifdef USE_LIGHTMAP\n uniform s // File:src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl -THREE.ShaderChunk[ 'lights_lambert_vertex' ] = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n vLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n directLight = getPointDirectLight( pointLights[ i ], geometry );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = PI * directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n #endif\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n directLight = getSpotDirectLight( spotLights[ i ], geometry );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = PI * directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n #endif\n }\n#endif\n#if NUM_DIR_LIGHTS > 0\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n directLight = getDirectionalDirectLight( directionalLights[ i ], geometry );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = PI * directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n #endif\n }\n#endif\n#if NUM_HEMI_LIGHTS > 0\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n vLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n #ifdef DOUBLE_SIDED\n vLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n #endif\n }\n#endif\n"; +THREE.ShaderChunk[ 'lights_lambert_vertex' ] = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n vLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n getPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = PI * directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n #endif\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n getSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = PI * directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n #endif\n }\n#endif\n#if NUM_DIR_LIGHTS > 0\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n getDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n dotNL = dot( geometry.normal, directLight.direction );\n directLightColor_Diffuse = PI * directLight.color;\n vLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n #ifdef DOUBLE_SIDED\n vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n #endif\n }\n#endif\n#if NUM_HEMI_LIGHTS > 0\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n vLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n #ifdef DOUBLE_SIDED\n vLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n #endif\n }\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/lights_pars.glsl -THREE.ShaderChunk[ 'lights_pars' ] = "#if NUM_DIR_LIGHTS > 0\n struct DirectionalLight {\n vec3 direction;\n vec3 color;\n int shadow;\n float shadowBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n IncidentLight getDirectionalDirectLight( const in DirectionalLight directionalLight, const in GeometricContext geometry ) {\n IncidentLight directLight;\n directLight.color = directionalLight.color;\n directLight.direction = directionalLight.direction;\n return directLight;\n }\n#endif\n#if NUM_POINT_LIGHTS > 0\n struct PointLight {\n vec3 position;\n vec3 color;\n float distance;\n float decay;\n int shadow;\n float shadowBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n IncidentLight getPointDirectLight( const in PointLight pointLight, const in GeometricContext geometry ) {\n IncidentLight directLight;\n vec3 lVector = pointLight.position - geometry.position;\n directLight.direction = normalize( lVector );\n directLight.color = pointLight.color;\n directLight.color *= calcLightAttenuation( length( lVector ), pointLight.distance, pointLight.decay );\n return directLight;\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float angleCos;\n float exponent;\n int shadow;\n float shadowBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n IncidentLight getSpotDirectLight( const in SpotLight spotLight, const in GeometricContext geometry ) {\n IncidentLight directLight;\n vec3 lVector = spotLight.position - geometry.position;\n directLight.direction = normalize( lVector );\n float spotEffect = dot( directLight.direction, spotLight.direction );\n if ( spotEffect > spotLight.angleCos ) {\n float spotEffect = dot( spotLight.direction, directLight.direction );\n spotEffect = saturate( pow( saturate( spotEffect ), spotLight.exponent ) );\n directLight.color = spotLight.color;\n directLight.color *= ( spotEffect * calcLightAttenuation( length( lVector ), spotLight.distance, spotLight.decay ) );\n } else {\n directLight.color = vec3( 0.0 );\n }\n return directLight;\n }\n#endif\n#if NUM_HEMI_LIGHTS > 0\n struct HemisphereLight {\n vec3 direction;\n vec3 skyColor;\n vec3 groundColor;\n };\n uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n float dotNL = dot( geometry.normal, hemiLight.direction );\n float hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n return PI * mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n }\n#endif\n#if defined( USE_ENVMAP ) && defined( STANDARD )\n vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n #ifdef DOUBLE_SIDED\n float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n #else\n float flipNormal = 1.0;\n #endif\n vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n #ifdef ENVMAP_TYPE_CUBE\n vec3 queryVec = flipNormal * vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n #else\n vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n #endif\n #else\n vec3 envMapColor = vec3( 0.0 );\n #endif\n envMapColor.rgb = inputToLinear( envMapColor.rgb );\n return PI * envMapColor.rgb * envMapIntensity;\n }\n float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n float maxMIPLevelScalar = float( maxMIPLevel );\n float desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( square( blinnShininessExponent ) + 1.0 );\n return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n }\n vec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n #ifdef ENVMAP_MODE_REFLECTION\n vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n #else\n vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n #endif\n #ifdef DOUBLE_SIDED\n float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n #else\n float flipNormal = 1.0;\n #endif\n reflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n #ifdef ENVMAP_TYPE_CUBE\n vec3 queryReflectVec = flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n #else\n vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n #endif\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n #else\n vec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n #endif\n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n #else\n vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n #endif\n #endif\n envMapColor.rgb = inputToLinear( envMapColor.rgb );\n return envMapColor.rgb * envMapIntensity;\n }\n#endif\n"; +THREE.ShaderChunk[ 'lights_pars' ] = "uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n vec3 irradiance = ambientLightColor;\n #ifndef PHYSICALLY_CORRECT_LIGHTS\n irradiance *= PI;\n #endif\n return irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n struct DirectionalLight {\n vec3 direction;\n vec3 color;\n int shadow;\n float shadowBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n directLight.color = directionalLight.color;\n directLight.direction = directionalLight.direction;\n directLight.visible = true;\n }\n#endif\n#if NUM_POINT_LIGHTS > 0\n struct PointLight {\n vec3 position;\n vec3 color;\n float distance;\n float decay;\n int shadow;\n float shadowBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n vec3 lVector = pointLight.position - geometry.position;\n directLight.direction = normalize( lVector );\n float lightDistance = length( lVector );\n if ( testLightInRange( lightDistance, pointLight.distance ) ) {\n directLight.color = pointLight.color;\n directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n directLight.visible = true;\n } else {\n directLight.color = vec3( 0.0 );\n directLight.visible = false;\n }\n }\n#endif\n#if NUM_SPOT_LIGHTS > 0\n struct SpotLight {\n vec3 position;\n vec3 direction;\n vec3 color;\n float distance;\n float decay;\n float coneCos;\n float penumbraCos;\n int shadow;\n float shadowBias;\n float shadowRadius;\n vec2 shadowMapSize;\n };\n uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n vec3 lVector = spotLight.position - geometry.position;\n directLight.direction = normalize( lVector );\n float lightDistance = length( lVector );\n float angleCos = dot( directLight.direction, spotLight.direction );\n if ( all( bvec2( angleCos > spotLight.coneCos, testLightInRange( lightDistance, spotLight.distance ) ) ) ) {\n float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n directLight.color = spotLight.color;\n directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n directLight.visible = true;\n } else {\n directLight.color = vec3( 0.0 );\n directLight.visible = false;\n }\n }\n#endif\n#if NUM_HEMI_LIGHTS > 0\n struct HemisphereLight {\n vec3 direction;\n vec3 skyColor;\n vec3 groundColor;\n };\n uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n float dotNL = dot( geometry.normal, hemiLight.direction );\n float hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n #ifndef PHYSICALLY_CORRECT_LIGHTS\n irradiance *= PI;\n #endif\n return irradiance;\n }\n#endif\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n #ifdef DOUBLE_SIDED\n float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n #else\n float flipNormal = 1.0;\n #endif\n vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n #ifdef ENVMAP_TYPE_CUBE\n vec3 queryVec = flipNormal * vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n #else\n vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n #endif\n envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n #elif defined( ENVMAP_TYPE_CUBE_UV )\n vec3 queryVec = flipNormal * vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n vec4 envMapColor = textureCubeUV( queryVec, 1.0 );\n #else\n vec4 envMapColor = vec4( 0.0 );\n #endif\n return PI * envMapColor.rgb * envMapIntensity;\n }\n float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n float maxMIPLevelScalar = float( maxMIPLevel );\n float desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n }\n vec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n #ifdef ENVMAP_MODE_REFLECTION\n vec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n #else\n vec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n #endif\n #ifdef DOUBLE_SIDED\n float flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n #else\n float flipNormal = 1.0;\n #endif\n reflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n #ifdef ENVMAP_TYPE_CUBE\n vec3 queryReflectVec = flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n #else\n vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n #endif\n envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n #elif defined( ENVMAP_TYPE_CUBE_UV )\n vec3 queryReflectVec = flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n vec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\n #elif defined( ENVMAP_TYPE_EQUIREC )\n vec2 sampleUV;\n sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 );\n sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n #else\n vec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n #endif\n envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n #elif defined( ENVMAP_TYPE_SPHERE )\n vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0));\n #ifdef TEXTURE_LOD_EXT\n vec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n #else\n vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n #endif\n envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n #endif\n return envMapColor.rgb * envMapIntensity;\n }\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl @@ -23477,31 +23995,19 @@ THREE.ShaderChunk[ 'lights_phong_fragment' ] = "BlinnPhongMaterial material;\nma // File:src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_pars_fragment' ] = "#ifdef USE_ENVMAP\n varying vec3 vWorldPosition;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n vec3 diffuseColor;\n vec3 specularColor;\n float specularShininess;\n float specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n vec3 irradiance = dotNL * PI * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_BlinnPhong\n#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material ) (0)\n"; +THREE.ShaderChunk[ 'lights_phong_pars_fragment' ] = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n vec3 diffuseColor;\n vec3 specularColor;\n float specularShininess;\n float specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n #ifndef PHYSICALLY_CORRECT_LIGHTS\n irradiance *= PI;\n #endif\n reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct RE_Direct_BlinnPhong\n#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material ) (0)\n"; -// File:src/renderers/shaders/ShaderChunk/lights_phong_pars_vertex.glsl +// File:src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_pars_vertex' ] = "#ifdef USE_ENVMAP\n varying vec3 vWorldPosition;\n#endif\n"; +THREE.ShaderChunk[ 'lights_physical_fragment' ] = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n#else\n material.specularColor = mix( vec3( 0.16 * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#endif\n"; -// File:src/renderers/shaders/ShaderChunk/lights_phong_vertex.glsl +// File:src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl -THREE.ShaderChunk[ 'lights_phong_vertex' ] = "#ifdef USE_ENVMAP\n vWorldPosition = worldPosition.xyz;\n#endif\n"; - -// File:src/renderers/shaders/ShaderChunk/lights_standard_fragment.glsl - -THREE.ShaderChunk[ 'lights_standard_fragment' ] = "StandardMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\nmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n"; - -// File:src/renderers/shaders/ShaderChunk/lights_standard_pars_fragment.glsl - -THREE.ShaderChunk[ 'lights_standard_pars_fragment' ] = "struct StandardMaterial {\n vec3 diffuseColor;\n float specularRoughness;\n vec3 specularColor;\n};\nvoid RE_Direct_Standard( const in IncidentLight directLight, const in GeometricContext geometry, const in StandardMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n vec3 irradiance = dotNL * PI * directLight.color;\n reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n}\nvoid RE_IndirectDiffuse_Standard( const in vec3 irradiance, const in GeometricContext geometry, const in StandardMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Standard( const in vec3 radiance, const in GeometricContext geometry, const in StandardMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectSpecular += radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n}\n#define RE_Direct RE_Direct_Standard\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Standard\n#define RE_IndirectSpecular RE_IndirectSpecular_Standard\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n"; +THREE.ShaderChunk[ 'lights_physical_pars_fragment' ] = "struct PhysicalMaterial {\n vec3 diffuseColor;\n float specularRoughness;\n vec3 specularColor;\n #ifndef STANDARD\n #endif\n};\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n float dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n vec3 irradiance = dotNL * directLight.color;\n #ifndef PHYSICALLY_CORRECT_LIGHTS\n irradiance *= PI;\n #endif\n reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n reflectedLight.directSpecular += irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n reflectedLight.indirectSpecular += radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n}\n#define RE_Direct RE_Direct_Physical\n#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular RE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n"; // File:src/renderers/shaders/ShaderChunk/lights_template.glsl -THREE.ShaderChunk[ 'lights_template' ] = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n PointLight pointLight;\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n pointLight = pointLights[ i ];\n directLight = getPointDirectLight( pointLight, geometry );\n #ifdef USE_SHADOWMAP\n directLight.color *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n SpotLight spotLight;\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n spotLight = spotLights[ i ];\n directLight = getSpotDirectLight( spotLight, geometry );\n #ifdef USE_SHADOWMAP\n directLight.color *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n DirectionalLight directionalLight;\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n directionalLight = directionalLights[ i ];\n directLight = getDirectionalDirectLight( directionalLight, geometry );\n #ifdef USE_SHADOWMAP\n directLight.color *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n#endif\n#if defined( RE_IndirectDiffuse )\n vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n #ifdef USE_LIGHTMAP\n irradiance += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n #endif\n #if ( NUM_HEMI_LIGHTS > 0 )\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n }\n #endif\n RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n vec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n RE_IndirectSpecular( radiance, geometry, material, reflectedLight );\n#endif\n"; - -// File:src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl - -THREE.ShaderChunk[ 'linear_to_gamma_fragment' ] = "\n outgoingLight = linearToOutput( outgoingLight );\n"; +THREE.ShaderChunk[ 'lights_template' ] = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n PointLight pointLight;\n for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n pointLight = pointLights[ i ];\n getPointDirectLightIrradiance( pointLight, geometry, directLight );\n #ifdef USE_SHADOWMAP\n directLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n SpotLight spotLight;\n for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n spotLight = spotLights[ i ];\n getSpotDirectLightIrradiance( spotLight, geometry, directLight );\n #ifdef USE_SHADOWMAP\n directLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n DirectionalLight directionalLight;\n for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n directionalLight = directionalLights[ i ];\n getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n #ifdef USE_SHADOWMAP\n directLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n #endif\n RE_Direct( directLight, geometry, material, reflectedLight );\n }\n#endif\n#if defined( RE_IndirectDiffuse )\n vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n #ifdef USE_LIGHTMAP\n vec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n #ifndef PHYSICALLY_CORRECT_LIGHTS\n lightMapIrradiance *= PI;\n #endif\n irradiance += lightMapIrradiance;\n #endif\n #if ( NUM_HEMI_LIGHTS > 0 )\n for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n }\n #endif\n #if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n irradiance += getLightProbeIndirectIrradiance( geometry, 8 );\n #endif\n RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n vec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n RE_IndirectSpecular( radiance, geometry, material, reflectedLight );\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl @@ -23521,15 +24027,15 @@ THREE.ShaderChunk[ 'logdepthbuf_vertex' ] = "#ifdef USE_LOGDEPTHBUF\n gl_Positio // File:src/renderers/shaders/ShaderChunk/map_fragment.glsl -THREE.ShaderChunk[ 'map_fragment' ] = "#ifdef USE_MAP\n vec4 texelColor = texture2D( map, vUv );\n texelColor.xyz = inputToLinear( texelColor.xyz );\n diffuseColor *= texelColor;\n#endif\n"; +THREE.ShaderChunk[ 'map_fragment' ] = "#ifdef USE_MAP\n vec4 texelColor = texture2D( map, vUv );\n texelColor = mapTexelToLinear( texelColor );\n diffuseColor *= texelColor;\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl -THREE.ShaderChunk[ 'map_pars_fragment' ] = "#ifdef USE_MAP\n uniform sampler2D map;\n#endif"; +THREE.ShaderChunk[ 'map_pars_fragment' ] = "#ifdef USE_MAP\n uniform sampler2D map;\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl -THREE.ShaderChunk[ 'map_particle_fragment' ] = "#ifdef USE_MAP\n diffuseColor *= texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n#endif\n"; +THREE.ShaderChunk[ 'map_particle_fragment' ] = "#ifdef USE_MAP\n vec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n diffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/map_particle_pars_fragment.glsl @@ -23557,12 +24063,20 @@ THREE.ShaderChunk[ 'morphtarget_vertex' ] = "#ifdef USE_MORPHTARGETS\n transform // File:src/renderers/shaders/ShaderChunk/normal_fragment.glsl -THREE.ShaderChunk[ 'normal_fragment' ] = "#ifdef FLAT_SHADED\n vec3 fdx = dFdx( vViewPosition );\n vec3 fdy = dFdy( vViewPosition );\n vec3 normal = normalize( cross( fdx, fdy ) );\n#else\n vec3 normal = normalize( vNormal );\n #ifdef DOUBLE_SIDED\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n #endif\n#endif\n#ifdef USE_NORMALMAP\n normal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n"; +THREE.ShaderChunk[ 'normal_fragment' ] = "#ifdef FLAT_SHADED\n vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n vec3 normal = normalize( cross( fdx, fdy ) );\n#else\n vec3 normal = normalize( vNormal );\n #ifdef DOUBLE_SIDED\n normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );\n #endif\n#endif\n#ifdef USE_NORMALMAP\n normal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl THREE.ShaderChunk[ 'normalmap_pars_fragment' ] = "#ifdef USE_NORMALMAP\n uniform sampler2D normalMap;\n uniform vec2 normalScale;\n vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n vec3 q0 = dFdx( eye_pos.xyz );\n vec3 q1 = dFdy( eye_pos.xyz );\n vec2 st0 = dFdx( vUv.st );\n vec2 st1 = dFdy( vUv.st );\n vec3 S = normalize( q0 * st1.t - q1 * st0.t );\n vec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n vec3 N = normalize( surf_norm );\n vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n mapN.xy = normalScale * mapN.xy;\n mat3 tsn = mat3( S, T, N );\n return normalize( tsn * mapN );\n }\n#endif\n"; +// File:src/renderers/shaders/ShaderChunk/packing.glsl + +THREE.ShaderChunk[ 'packing' ] = "vec3 packNormalToRGB( const in vec3 normal ) {\n return normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n return 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n vec4 r = vec4( fract( v * PackFactors ), v );\n r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n return dot( v, UnpackFactors );\n}\nfloat viewZToOrthoDepth( const in float viewZ, const in float near, const in float far ) {\n return ( viewZ + near ) / ( near - far );\n}\nfloat OrthoDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n return linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n return (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n return ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n"; + +// File:src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl + +THREE.ShaderChunk[ 'premultiplied_alpha_fragment' ] = "#ifdef PREMULTIPLIED_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n"; + // File:src/renderers/shaders/ShaderChunk/project_vertex.glsl THREE.ShaderChunk[ 'project_vertex' ] = "#ifdef USE_SKINNING\n vec4 mvPosition = modelViewMatrix * skinned;\n#else\n vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\n#endif\ngl_Position = projectionMatrix * mvPosition;\n"; @@ -23577,7 +24091,7 @@ THREE.ShaderChunk[ 'roughnessmap_pars_fragment' ] = "#ifdef USE_ROUGHNESSMAP\n u // File:src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl -THREE.ShaderChunk[ 'shadowmap_pars_fragment' ] = "#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHTS > 0\n uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n #endif\n #if NUM_SPOT_LIGHTS > 0\n uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n #endif\n #if NUM_POINT_LIGHTS > 0\n uniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n #endif\n float unpackDepth( const in vec4 rgba_depth ) {\n const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\n return dot( rgba_depth, bit_shift );\n }\n float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n return step( compare, unpackDepth( texture2D( depths, uv ) ) );\n }\n float texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n const vec2 offset = vec2( 0.0, 1.0 );\n vec2 texelSize = vec2( 1.0 ) / size;\n vec2 centroidUV = floor( uv * size + 0.5 ) / size;\n float lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n float lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n float rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n float rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n vec2 f = fract( uv * size + 0.5 );\n float a = mix( lb, lt, f.y );\n float b = mix( rb, rt, f.y );\n float c = mix( a, b, f.x );\n return c;\n }\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n shadowCoord.xyz /= shadowCoord.w;\n shadowCoord.z += shadowBias;\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n bool frustumTest = all( frustumTestVec );\n if ( frustumTest ) {\n #if defined( SHADOWMAP_TYPE_PCF )\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float dx0 = - texelSize.x * shadowRadius;\n float dy0 = - texelSize.y * shadowRadius;\n float dx1 = + texelSize.x * shadowRadius;\n float dy1 = + texelSize.y * shadowRadius;\n return (\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n ) * ( 1.0 / 9.0 );\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float dx0 = - texelSize.x * shadowRadius;\n float dy0 = - texelSize.y * shadowRadius;\n float dx1 = + texelSize.x * shadowRadius;\n float dy1 = + texelSize.y * shadowRadius;\n return (\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n ) * ( 1.0 / 9.0 );\n #else\n return texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n #endif\n }\n return 1.0;\n }\n vec2 cubeToUV( vec3 v, float texelSizeY ) {\n vec3 absV = abs( v );\n float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n absV *= scaleToCube;\n v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n vec2 planar = v.xy;\n float almostATexel = 1.5 * texelSizeY;\n float almostOne = 1.0 - almostATexel;\n if ( absV.z >= almostOne ) {\n if ( v.z > 0.0 )\n planar.x = 4.0 - v.x;\n } else if ( absV.x >= almostOne ) {\n float signX = sign( v.x );\n planar.x = v.z * signX + 2.0 * signX;\n } else if ( absV.y >= almostOne ) {\n float signY = sign( v.y );\n planar.x = v.x + 2.0 * signY + 2.0;\n planar.y = v.z * signY - 2.0;\n }\n return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n }\n float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 bd3D = normalize( lightToPosition );\n float dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\n #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n vec3 offset = vec3( - 1, 0, 1 ) * shadowRadius * 2.0 * texelSize.y;\n return (\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zzz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zxz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xzz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zzx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zxx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xzx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zzy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zxy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xzy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zyz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.zyx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yzz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxz, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yzx, texelSize.y ), dp )\n ) * ( 1.0 / 21.0 );\n #else\n return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n #endif\n }\n#endif\n"; +THREE.ShaderChunk[ 'shadowmap_pars_fragment' ] = "#ifdef USE_SHADOWMAP\n #if NUM_DIR_LIGHTS > 0\n uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n #endif\n #if NUM_SPOT_LIGHTS > 0\n uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n #endif\n #if NUM_POINT_LIGHTS > 0\n uniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n varying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n #endif\n float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n }\n float texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n const vec2 offset = vec2( 0.0, 1.0 );\n vec2 texelSize = vec2( 1.0 ) / size;\n vec2 centroidUV = floor( uv * size + 0.5 ) / size;\n float lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n float lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n float rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n float rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n vec2 f = fract( uv * size + 0.5 );\n float a = mix( lb, lt, f.y );\n float b = mix( rb, rt, f.y );\n float c = mix( a, b, f.x );\n return c;\n }\n float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n shadowCoord.xyz /= shadowCoord.w;\n shadowCoord.z += shadowBias;\n bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n bool inFrustum = all( inFrustumVec );\n bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n bool frustumTest = all( frustumTestVec );\n if ( frustumTest ) {\n #if defined( SHADOWMAP_TYPE_PCF )\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float dx0 = - texelSize.x * shadowRadius;\n float dy0 = - texelSize.y * shadowRadius;\n float dx1 = + texelSize.x * shadowRadius;\n float dy1 = + texelSize.y * shadowRadius;\n return (\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n ) * ( 1.0 / 9.0 );\n #elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n vec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n float dx0 = - texelSize.x * shadowRadius;\n float dy0 = - texelSize.y * shadowRadius;\n float dx1 = + texelSize.x * shadowRadius;\n float dy1 = + texelSize.y * shadowRadius;\n return (\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n texture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n ) * ( 1.0 / 9.0 );\n #else\n return texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n #endif\n }\n return 1.0;\n }\n vec2 cubeToUV( vec3 v, float texelSizeY ) {\n vec3 absV = abs( v );\n float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n absV *= scaleToCube;\n v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n vec2 planar = v.xy;\n float almostATexel = 1.5 * texelSizeY;\n float almostOne = 1.0 - almostATexel;\n if ( absV.z >= almostOne ) {\n if ( v.z > 0.0 )\n planar.x = 4.0 - v.x;\n } else if ( absV.x >= almostOne ) {\n float signX = sign( v.x );\n planar.x = v.z * signX + 2.0 * signX;\n } else if ( absV.y >= almostOne ) {\n float signY = sign( v.y );\n planar.x = v.x + 2.0 * signY + 2.0;\n planar.y = v.z * signY - 2.0;\n }\n return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n }\n float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n vec3 lightToPosition = shadowCoord.xyz;\n vec3 bd3D = normalize( lightToPosition );\n float dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\n #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n return (\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n ) * ( 1.0 / 9.0 );\n #else\n return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n #endif\n }\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl @@ -23597,7 +24111,7 @@ THREE.ShaderChunk[ 'skinbase_vertex' ] = "#ifdef USE_SKINNING\n mat4 boneMatX = // File:src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl -THREE.ShaderChunk[ 'skinning_pars_vertex' ] = "#ifdef USE_SKINNING\n uniform mat4 bindMatrix;\n uniform mat4 bindMatrixInverse;\n #ifdef BONE_TEXTURE\n uniform sampler2D boneTexture;\n uniform int boneTextureWidth;\n uniform int boneTextureHeight;\n mat4 getBoneMatrix( const in float i ) {\n float j = i * 4.0;\n float x = mod( j, float( boneTextureWidth ) );\n float y = floor( j / float( boneTextureWidth ) );\n float dx = 1.0 / float( boneTextureWidth );\n float dy = 1.0 / float( boneTextureHeight );\n y = dy * ( y + 0.5 );\n vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n mat4 bone = mat4( v1, v2, v3, v4 );\n return bone;\n }\n #else\n uniform mat4 boneGlobalMatrices[ MAX_BONES ];\n mat4 getBoneMatrix( const in float i ) {\n mat4 bone = boneGlobalMatrices[ int(i) ];\n return bone;\n }\n #endif\n#endif\n"; +THREE.ShaderChunk[ 'skinning_pars_vertex' ] = "#ifdef USE_SKINNING\n uniform mat4 bindMatrix;\n uniform mat4 bindMatrixInverse;\n #ifdef BONE_TEXTURE\n uniform sampler2D boneTexture;\n uniform int boneTextureWidth;\n uniform int boneTextureHeight;\n mat4 getBoneMatrix( const in float i ) {\n float j = i * 4.0;\n float x = mod( j, float( boneTextureWidth ) );\n float y = floor( j / float( boneTextureWidth ) );\n float dx = 1.0 / float( boneTextureWidth );\n float dy = 1.0 / float( boneTextureHeight );\n y = dy * ( y + 0.5 );\n vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n mat4 bone = mat4( v1, v2, v3, v4 );\n return bone;\n }\n #else\n uniform mat4 boneMatrices[ MAX_BONES ];\n mat4 getBoneMatrix( const in float i ) {\n mat4 bone = boneMatrices[ int(i) ];\n return bone;\n }\n #endif\n#endif\n"; // File:src/renderers/shaders/ShaderChunk/skinning_vertex.glsl @@ -23615,6 +24129,14 @@ THREE.ShaderChunk[ 'specularmap_fragment' ] = "float specularStrength;\n#ifdef U THREE.ShaderChunk[ 'specularmap_pars_fragment' ] = "#ifdef USE_SPECULARMAP\n uniform sampler2D specularMap;\n#endif"; +// File:src/renderers/shaders/ShaderChunk/tonemapping_fragment.glsl + +THREE.ShaderChunk[ 'tonemapping_fragment' ] = "#if defined( TONE_MAPPING )\n gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n"; + +// File:src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl + +THREE.ShaderChunk[ 'tonemapping_pars_fragment' ] = "#define saturate(a) clamp( a, 0.0, 1.0 )\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n return toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n color *= toneMappingExposure;\n color = max( vec3( 0.0 ), color - 0.004 );\n return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n"; + // File:src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl THREE.ShaderChunk[ 'uv2_pars_fragment' ] = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n varying vec2 vUv2;\n#endif"; @@ -23641,7 +24163,7 @@ THREE.ShaderChunk[ 'uv_vertex' ] = "#if defined( USE_MAP ) || defined( USE_BUMPM // File:src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl -THREE.ShaderChunk[ 'worldpos_vertex' ] = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( STANDARD ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n #ifdef USE_SKINNING\n vec4 worldPosition = modelMatrix * skinned;\n #else\n vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n #endif\n#endif\n"; +THREE.ShaderChunk[ 'worldpos_vertex' ] = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n #ifdef USE_SKINNING\n vec4 worldPosition = modelMatrix * skinned;\n #else\n vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n #endif\n#endif\n"; // File:src/renderers/shaders/UniformsUtils.js @@ -23724,7 +24246,7 @@ THREE.UniformsLib = { common: { "diffuse": { type: "c", value: new THREE.Color( 0xeeeeee ) }, - "opacity": { type: "f", value: 1.0 }, + "opacity": { type: "1f", value: 1.0 }, "map": { type: "t", value: null }, "offsetRepeat": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, @@ -23733,23 +24255,23 @@ THREE.UniformsLib = { "alphaMap": { type: "t", value: null }, "envMap": { type: "t", value: null }, - "flipEnvMap": { type: "f", value: - 1 }, - "reflectivity": { type: "f", value: 1.0 }, - "refractionRatio": { type: "f", value: 0.98 } + "flipEnvMap": { type: "1f", value: - 1 }, + "reflectivity": { type: "1f", value: 1.0 }, + "refractionRatio": { type: "1f", value: 0.98 } }, aomap: { "aoMap": { type: "t", value: null }, - "aoMapIntensity": { type: "f", value: 1 } + "aoMapIntensity": { type: "1f", value: 1 } }, lightmap: { "lightMap": { type: "t", value: null }, - "lightMapIntensity": { type: "f", value: 1 } + "lightMapIntensity": { type: "1f", value: 1 } }, @@ -23762,7 +24284,7 @@ THREE.UniformsLib = { bumpmap: { "bumpMap": { type: "t", value: null }, - "bumpScale": { type: "f", value: 1 } + "bumpScale": { type: "1f", value: 1 } }, @@ -23776,8 +24298,8 @@ THREE.UniformsLib = { displacementmap: { "displacementMap": { type: "t", value: null }, - "displacementScale": { type: "f", value: 1 }, - "displacementBias": { type: "f", value: 0 } + "displacementScale": { type: "1f", value: 1 }, + "displacementBias": { type: "1f", value: 0 } }, @@ -23795,28 +24317,24 @@ THREE.UniformsLib = { fog: { - "fogDensity": { type: "f", value: 0.00025 }, - "fogNear": { type: "f", value: 1 }, - "fogFar": { type: "f", value: 2000 }, + "fogDensity": { type: "1f", value: 0.00025 }, + "fogNear": { type: "1f", value: 1 }, + "fogFar": { type: "1f", value: 2000 }, "fogColor": { type: "c", value: new THREE.Color( 0xffffff ) } }, - ambient: { - - "ambientLightColor": { type: "fv", value: [] } - - }, - lights: { + "ambientLightColor": { type: "3fv", value: [] }, + "directionalLights": { type: "sa", value: [], properties: { "direction": { type: "v3" }, "color": { type: "c" }, - "shadow": { type: "i" }, - "shadowBias": { type: "f" }, - "shadowRadius": { type: "f" }, + "shadow": { type: "1i" }, + "shadowBias": { type: "1f" }, + "shadowRadius": { type: "1f" }, "shadowMapSize": { type: "v2" } } }, @@ -23827,14 +24345,14 @@ THREE.UniformsLib = { "color": { type: "c" }, "position": { type: "v3" }, "direction": { type: "v3" }, - "distance": { type: "f" }, - "angleCos": { type: "f" }, - "exponent": { type: "f" }, - "decay": { type: "f" }, + "distance": { type: "1f" }, + "coneCos": { type: "1f" }, + "penumbraCos": { type: "1f" }, + "decay": { type: "1f" }, - "shadow": { type: "i" }, - "shadowBias": { type: "f" }, - "shadowRadius": { type: "f" }, + "shadow": { type: "1i" }, + "shadowBias": { type: "1f" }, + "shadowRadius": { type: "1f" }, "shadowMapSize": { type: "v2" } } }, @@ -23844,12 +24362,12 @@ THREE.UniformsLib = { "pointLights": { type: "sa", value: [], properties: { "color": { type: "c" }, "position": { type: "v3" }, - "decay": { type: "f" }, - "distance": { type: "f" }, + "decay": { type: "1f" }, + "distance": { type: "1f" }, - "shadow": { type: "i" }, - "shadowBias": { type: "f" }, - "shadowRadius": { type: "f" }, + "shadow": { type: "1i" }, + "shadowBias": { type: "1f" }, + "shadowRadius": { type: "1f" }, "shadowMapSize": { type: "v2" } } }, @@ -23867,9 +24385,9 @@ THREE.UniformsLib = { points: { "diffuse": { type: "c", value: new THREE.Color( 0xeeeeee ) }, - "opacity": { type: "f", value: 1.0 }, - "size": { type: "f", value: 1.0 }, - "scale": { type: "f", value: 1.0 }, + "opacity": { type: "1f", value: 1.0 }, + "size": { type: "1f", value: 1.0 }, + "scale": { type: "1f", value: 1.0 }, "map": { type: "t", value: null }, "offsetRepeat": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) } @@ -23877,6 +24395,102 @@ THREE.UniformsLib = { }; +// File:src/renderers/shaders/ShaderLib/cube_frag.glsl + +THREE.ShaderChunk[ 'cube_frag' ] = "uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n #include \n gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/cube_vert.glsl + +THREE.ShaderChunk[ 'cube_vert' ] = "varying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n vWorldPosition = transformDirection( position, modelMatrix );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/depth_frag.glsl + +THREE.ShaderChunk[ 'depth_frag' ] = "#if DEPTH_PACKING == 3200\n uniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( 1.0 );\n #if DEPTH_PACKING == 3200\n diffuseColor.a = opacity;\n #endif\n #include \n #include \n #include \n #include \n #if DEPTH_PACKING == 3200\n gl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n #elif DEPTH_PACKING == 3201\n gl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n #endif\n}\n"; + +// File:src/renderers/shaders/ShaderLib/depth_vert.glsl + +THREE.ShaderChunk[ 'depth_vert' ] = "#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl + +THREE.ShaderChunk[ 'distanceRGBA_frag' ] = "uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include \n#include \n#include \nvoid main () {\n #include \n gl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n"; + +// File:src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl + +THREE.ShaderChunk[ 'distanceRGBA_vert' ] = "varying vec4 vWorldPosition;\n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vWorldPosition = worldPosition;\n}\n"; + +// File:src/renderers/shaders/ShaderLib/equirect_frag.glsl + +THREE.ShaderChunk[ 'equirect_frag' ] = "uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n #include \n vec3 direction = normalize( vWorldPosition );\n vec2 sampleUV;\n sampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n gl_FragColor = texture2D( tEquirect, sampleUV );\n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/equirect_vert.glsl + +THREE.ShaderChunk[ 'equirect_vert' ] = "varying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n vWorldPosition = transformDirection( position, modelMatrix );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/linedashed_frag.glsl + +THREE.ShaderChunk[ 'linedashed_frag' ] = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n if ( mod( vLineDistance, totalSize ) > dashSize ) {\n discard;\n }\n vec3 outgoingLight = vec3( 0.0 );\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n outgoingLight = diffuseColor.rgb;\n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/linedashed_vert.glsl + +THREE.ShaderChunk[ 'linedashed_vert' ] = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vLineDistance = scale * lineDistance;\n vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n gl_Position = projectionMatrix * mvPosition;\n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshbasic_frag.glsl + +THREE.ShaderChunk[ 'meshbasic_frag' ] = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n #include \n #include \n #include \n #include \n ReflectedLight reflectedLight;\n reflectedLight.directDiffuse = vec3( 0.0 );\n reflectedLight.directSpecular = vec3( 0.0 );\n reflectedLight.indirectDiffuse = diffuseColor.rgb;\n reflectedLight.indirectSpecular = vec3( 0.0 );\n #include \n vec3 outgoingLight = reflectedLight.indirectDiffuse;\n #include \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshbasic_vert.glsl + +THREE.ShaderChunk[ 'meshbasic_vert' ] = "#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #ifdef USE_ENVMAP\n #include \n #include \n #include \n #include \n #endif\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshlambert_frag.glsl + +THREE.ShaderChunk[ 'meshlambert_frag' ] = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n varying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n #include \n reflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n #ifdef DOUBLE_SIDED\n reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n #else\n reflectedLight.directDiffuse = vLightFront;\n #endif\n reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n #include \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n #include \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshlambert_vert.glsl + +THREE.ShaderChunk[ 'meshlambert_vert' ] = "#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n varying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshphong_frag.glsl + +THREE.ShaderChunk[ 'meshphong_frag' ] = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n #include \n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshphong_vert.glsl + +THREE.ShaderChunk[ 'meshphong_vert' ] = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n#ifndef FLAT_SHADED\n vNormal = normalize( transformedNormal );\n#endif\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vViewPosition = - mvPosition.xyz;\n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshphysical_frag.glsl + +THREE.ShaderChunk[ 'meshphysical_frag' ] = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\nuniform float envMapIntensity;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec4 diffuseColor = vec4( diffuse, opacity );\n ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n vec3 totalEmissiveRadiance = emissive;\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/meshphysical_vert.glsl + +THREE.ShaderChunk[ 'meshphysical_vert' ] = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n varying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n #include \n#ifndef FLAT_SHADED\n vNormal = normalize( transformedNormal );\n#endif\n #include \n #include \n #include \n #include \n #include \n #include \n #include \n vViewPosition = - mvPosition.xyz;\n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/normal_frag.glsl + +THREE.ShaderChunk[ 'normal_frag' ] = "uniform float opacity;\nvarying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n #include \n gl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/normal_vert.glsl + +THREE.ShaderChunk[ 'normal_vert' ] = "varying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n vNormal = normalize( normalMatrix * normal );\n #include \n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/points_frag.glsl + +THREE.ShaderChunk[ 'points_frag' ] = "uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n vec3 outgoingLight = vec3( 0.0 );\n vec4 diffuseColor = vec4( diffuse, opacity );\n #include \n #include \n #include \n #include \n outgoingLight = diffuseColor.rgb;\n gl_FragColor = vec4( outgoingLight, diffuseColor.a );\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/points_vert.glsl + +THREE.ShaderChunk[ 'points_vert' ] = "uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n #include \n #include \n #include \n #ifdef USE_SIZEATTENUATION\n gl_PointSize = size * ( scale / - mvPosition.z );\n #else\n gl_PointSize = size;\n #endif\n #include \n #include \n #include \n #include \n}\n"; + +// File:src/renderers/shaders/ShaderLib/shadow_frag.glsl + +THREE.ShaderChunk[ 'shadow_frag' ] = "uniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n gl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n"; + +// File:src/renderers/shaders/ShaderLib/shadow_vert.glsl + +THREE.ShaderChunk[ 'shadow_vert' ] = "#include \nvoid main() {\n #include \n #include \n #include \n #include \n}\n"; + // File:src/renderers/shaders/ShaderLib.js /** @@ -23894,108 +24508,14 @@ THREE.ShaderLib = { uniforms: THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "aomap" ], - THREE.UniformsLib[ "fog" ] + THREE.UniformsLib[ 'common' ], + THREE.UniformsLib[ 'aomap' ], + THREE.UniformsLib[ 'fog' ] ] ), - vertexShader: [ - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "uv_pars_vertex" ], - THREE.ShaderChunk[ "uv2_pars_vertex" ], - THREE.ShaderChunk[ "envmap_pars_vertex" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "uv_vertex" ], - THREE.ShaderChunk[ "uv2_vertex" ], - THREE.ShaderChunk[ "color_vertex" ], - THREE.ShaderChunk[ "skinbase_vertex" ], - - " #ifdef USE_ENVMAP", - - THREE.ShaderChunk[ "beginnormal_vertex" ], - THREE.ShaderChunk[ "morphnormal_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], - - " #endif", - - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "envmap_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform float opacity;", - - "#ifndef FLAT_SHADED", - - " varying vec3 vNormal;", - - "#endif", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "uv_pars_fragment" ], - THREE.ShaderChunk[ "uv2_pars_fragment" ], - THREE.ShaderChunk[ "map_pars_fragment" ], - THREE.ShaderChunk[ "alphamap_pars_fragment" ], - THREE.ShaderChunk[ "aomap_pars_fragment" ], - THREE.ShaderChunk[ "envmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "specularmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " vec4 diffuseColor = vec4( diffuse, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "alphamap_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "specularmap_fragment" ], - - " ReflectedLight reflectedLight;", - " reflectedLight.directDiffuse = vec3( 0.0 );", - " reflectedLight.directSpecular = vec3( 0.0 );", - " reflectedLight.indirectDiffuse = diffuseColor.rgb;", - " reflectedLight.indirectSpecular = vec3( 0.0 );", - - THREE.ShaderChunk[ "aomap_fragment" ], - - " vec3 outgoingLight = reflectedLight.indirectDiffuse;", - - THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - THREE.ShaderChunk[ "fog_fragment" ], - - " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'meshbasic_vert' ], + fragmentShader: THREE.ShaderChunk[ 'meshbasic_frag' ] }, @@ -24003,13 +24523,12 @@ THREE.ShaderLib = { uniforms: THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "aomap" ], - THREE.UniformsLib[ "lightmap" ], - THREE.UniformsLib[ "emissivemap" ], - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "ambient" ], - THREE.UniformsLib[ "lights" ], + THREE.UniformsLib[ 'common' ], + THREE.UniformsLib[ 'aomap' ], + THREE.UniformsLib[ 'lightmap' ], + THREE.UniformsLib[ 'emissivemap' ], + THREE.UniformsLib[ 'fog' ], + THREE.UniformsLib[ 'lights' ], { "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) } @@ -24017,139 +24536,8 @@ THREE.ShaderLib = { ] ), - vertexShader: [ - - "#define LAMBERT", - - "varying vec3 vLightFront;", - - "#ifdef DOUBLE_SIDED", - - " varying vec3 vLightBack;", - - "#endif", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "uv_pars_vertex" ], - THREE.ShaderChunk[ "uv2_pars_vertex" ], - THREE.ShaderChunk[ "envmap_pars_vertex" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "lights_pars" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "uv_vertex" ], - THREE.ShaderChunk[ "uv2_vertex" ], - THREE.ShaderChunk[ "color_vertex" ], - - THREE.ShaderChunk[ "beginnormal_vertex" ], - THREE.ShaderChunk[ "morphnormal_vertex" ], - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], - - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "envmap_vertex" ], - THREE.ShaderChunk[ "lights_lambert_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform vec3 emissive;", - "uniform float opacity;", - - "varying vec3 vLightFront;", - - "#ifdef DOUBLE_SIDED", - - " varying vec3 vLightBack;", - - "#endif", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "uv_pars_fragment" ], - THREE.ShaderChunk[ "uv2_pars_fragment" ], - THREE.ShaderChunk[ "map_pars_fragment" ], - THREE.ShaderChunk[ "alphamap_pars_fragment" ], - THREE.ShaderChunk[ "aomap_pars_fragment" ], - THREE.ShaderChunk[ "lightmap_pars_fragment" ], - THREE.ShaderChunk[ "emissivemap_pars_fragment" ], - THREE.ShaderChunk[ "envmap_pars_fragment" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "ambient_pars" ], - THREE.ShaderChunk[ "lights_pars" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "shadowmask_pars_fragment" ], - THREE.ShaderChunk[ "specularmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " vec4 diffuseColor = vec4( diffuse, opacity );", - " ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );", - " vec3 totalEmissiveLight = emissive;", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "alphamap_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "specularmap_fragment" ], - THREE.ShaderChunk[ "emissivemap_fragment" ], - - // accumulation - " reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );", - - THREE.ShaderChunk[ "lightmap_fragment" ], - - " reflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );", - - " #ifdef DOUBLE_SIDED", - - " reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;", - - " #else", - - " reflectedLight.directDiffuse = vLightFront;", - - " #endif", - - " reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();", - - // modulation - THREE.ShaderChunk[ "aomap_fragment" ], - - " vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveLight;", - - THREE.ShaderChunk[ "envmap_fragment" ], - - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - - THREE.ShaderChunk[ "fog_fragment" ], - - " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'meshlambert_vert' ], + fragmentShader: THREE.ShaderChunk[ 'meshlambert_frag' ] }, @@ -24157,150 +24545,26 @@ THREE.ShaderLib = { uniforms: THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "aomap" ], - THREE.UniformsLib[ "lightmap" ], - THREE.UniformsLib[ "emissivemap" ], - THREE.UniformsLib[ "bumpmap" ], - THREE.UniformsLib[ "normalmap" ], - THREE.UniformsLib[ "displacementmap" ], - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "ambient" ], - THREE.UniformsLib[ "lights" ], + THREE.UniformsLib[ 'common' ], + THREE.UniformsLib[ 'aomap' ], + THREE.UniformsLib[ 'lightmap' ], + THREE.UniformsLib[ 'emissivemap' ], + THREE.UniformsLib[ 'bumpmap' ], + THREE.UniformsLib[ 'normalmap' ], + THREE.UniformsLib[ 'displacementmap' ], + THREE.UniformsLib[ 'fog' ], + THREE.UniformsLib[ 'lights' ], { "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) }, "specular" : { type: "c", value: new THREE.Color( 0x111111 ) }, - "shininess": { type: "f", value: 30 } + "shininess": { type: "1f", value: 30 } } ] ), - vertexShader: [ - - "#define PHONG", - - "varying vec3 vViewPosition;", - - "#ifndef FLAT_SHADED", - - " varying vec3 vNormal;", - - "#endif", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "uv_pars_vertex" ], - THREE.ShaderChunk[ "uv2_pars_vertex" ], - THREE.ShaderChunk[ "displacementmap_pars_vertex" ], - THREE.ShaderChunk[ "envmap_pars_vertex" ], - THREE.ShaderChunk[ "lights_phong_pars_vertex" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "uv_vertex" ], - THREE.ShaderChunk[ "uv2_vertex" ], - THREE.ShaderChunk[ "color_vertex" ], - - THREE.ShaderChunk[ "beginnormal_vertex" ], - THREE.ShaderChunk[ "morphnormal_vertex" ], - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], - - "#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED - - " vNormal = normalize( transformedNormal );", - - "#endif", - - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "displacementmap_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - " vViewPosition = - mvPosition.xyz;", - - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "envmap_vertex" ], - THREE.ShaderChunk[ "lights_phong_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "#define PHONG", - - "uniform vec3 diffuse;", - "uniform vec3 emissive;", - "uniform vec3 specular;", - "uniform float shininess;", - "uniform float opacity;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "uv_pars_fragment" ], - THREE.ShaderChunk[ "uv2_pars_fragment" ], - THREE.ShaderChunk[ "map_pars_fragment" ], - THREE.ShaderChunk[ "alphamap_pars_fragment" ], - THREE.ShaderChunk[ "aomap_pars_fragment" ], - THREE.ShaderChunk[ "lightmap_pars_fragment" ], - THREE.ShaderChunk[ "emissivemap_pars_fragment" ], - THREE.ShaderChunk[ "envmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "ambient_pars" ], - THREE.ShaderChunk[ "lights_pars" ], - THREE.ShaderChunk[ "lights_phong_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "bumpmap_pars_fragment" ], - THREE.ShaderChunk[ "normalmap_pars_fragment" ], - THREE.ShaderChunk[ "specularmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " vec4 diffuseColor = vec4( diffuse, opacity );", - " ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );", - " vec3 totalEmissiveLight = emissive;", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "alphamap_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "specularmap_fragment" ], - THREE.ShaderChunk[ "normal_fragment" ], - THREE.ShaderChunk[ "emissivemap_fragment" ], - - // accumulation - THREE.ShaderChunk[ "lights_phong_fragment" ], - THREE.ShaderChunk[ "lights_template" ], - - // modulation - THREE.ShaderChunk[ "aomap_fragment" ], - - "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;", - - THREE.ShaderChunk[ "envmap_fragment" ], - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - - THREE.ShaderChunk[ "fog_fragment" ], - - " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'meshphong_vert' ], + fragmentShader: THREE.ShaderChunk[ 'meshphong_frag' ] }, @@ -24308,164 +24572,29 @@ THREE.ShaderLib = { uniforms: THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "aomap" ], - THREE.UniformsLib[ "lightmap" ], - THREE.UniformsLib[ "emissivemap" ], - THREE.UniformsLib[ "bumpmap" ], - THREE.UniformsLib[ "normalmap" ], - THREE.UniformsLib[ "displacementmap" ], - THREE.UniformsLib[ "roughnessmap" ], - THREE.UniformsLib[ "metalnessmap" ], - THREE.UniformsLib[ "fog" ], - THREE.UniformsLib[ "ambient" ], - THREE.UniformsLib[ "lights" ], + THREE.UniformsLib[ 'common' ], + THREE.UniformsLib[ 'aomap' ], + THREE.UniformsLib[ 'lightmap' ], + THREE.UniformsLib[ 'emissivemap' ], + THREE.UniformsLib[ 'bumpmap' ], + THREE.UniformsLib[ 'normalmap' ], + THREE.UniformsLib[ 'displacementmap' ], + THREE.UniformsLib[ 'roughnessmap' ], + THREE.UniformsLib[ 'metalnessmap' ], + THREE.UniformsLib[ 'fog' ], + THREE.UniformsLib[ 'lights' ], { "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) }, - "roughness": { type: "f", value: 0.5 }, - "metalness": { type: "f", value: 0 }, - "envMapIntensity" : { type: "f", value: 1 } // temporary + "roughness": { type: "1f", value: 0.5 }, + "metalness": { type: "1f", value: 0 }, + "envMapIntensity" : { type: "1f", value: 1 } // temporary } ] ), - vertexShader: [ - - "#define STANDARD", - - "varying vec3 vViewPosition;", - - "#ifndef FLAT_SHADED", - - " varying vec3 vNormal;", - - "#endif", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "uv_pars_vertex" ], - THREE.ShaderChunk[ "uv2_pars_vertex" ], - THREE.ShaderChunk[ "displacementmap_pars_vertex" ], - THREE.ShaderChunk[ "envmap_pars_vertex" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "specularmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", // STANDARD - - THREE.ShaderChunk[ "uv_vertex" ], - THREE.ShaderChunk[ "uv2_vertex" ], - THREE.ShaderChunk[ "color_vertex" ], - - THREE.ShaderChunk[ "beginnormal_vertex" ], - THREE.ShaderChunk[ "morphnormal_vertex" ], - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "skinnormal_vertex" ], - THREE.ShaderChunk[ "defaultnormal_vertex" ], - - "#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED - - " vNormal = normalize( transformedNormal );", - - "#endif", - - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "displacementmap_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - " vViewPosition = - mvPosition.xyz;", - - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "envmap_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "#define STANDARD", - - "uniform vec3 diffuse;", - "uniform vec3 emissive;", - "uniform float roughness;", - "uniform float metalness;", - "uniform float opacity;", - - "uniform float envMapIntensity;", // temporary - - "varying vec3 vViewPosition;", - - "#ifndef FLAT_SHADED", - - " varying vec3 vNormal;", - - "#endif", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "uv_pars_fragment" ], - THREE.ShaderChunk[ "uv2_pars_fragment" ], - THREE.ShaderChunk[ "map_pars_fragment" ], - THREE.ShaderChunk[ "alphamap_pars_fragment" ], - THREE.ShaderChunk[ "aomap_pars_fragment" ], - THREE.ShaderChunk[ "lightmap_pars_fragment" ], - THREE.ShaderChunk[ "emissivemap_pars_fragment" ], - THREE.ShaderChunk[ "envmap_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "bsdfs" ], - THREE.ShaderChunk[ "ambient_pars" ], - THREE.ShaderChunk[ "lights_pars" ], - THREE.ShaderChunk[ "lights_standard_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "bumpmap_pars_fragment" ], - THREE.ShaderChunk[ "normalmap_pars_fragment" ], - THREE.ShaderChunk[ "roughnessmap_pars_fragment" ], - THREE.ShaderChunk[ "metalnessmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " vec4 diffuseColor = vec4( diffuse, opacity );", - " ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );", - " vec3 totalEmissiveLight = emissive;", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "alphamap_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - THREE.ShaderChunk[ "specularmap_fragment" ], - THREE.ShaderChunk[ "roughnessmap_fragment" ], - THREE.ShaderChunk[ "metalnessmap_fragment" ], - THREE.ShaderChunk[ "normal_fragment" ], - THREE.ShaderChunk[ "emissivemap_fragment" ], - - // accumulation - THREE.ShaderChunk[ "lights_standard_fragment" ], - THREE.ShaderChunk[ "lights_template" ], - - // modulation - THREE.ShaderChunk[ "aomap_fragment" ], - - "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;", - - THREE.ShaderChunk[ "linear_to_gamma_fragment" ], - - THREE.ShaderChunk[ "fog_fragment" ], - - " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'meshphysical_vert' ], + fragmentShader: THREE.ShaderChunk[ 'meshphysical_frag' ] }, @@ -24473,72 +24602,13 @@ THREE.ShaderLib = { uniforms: THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "points" ], - THREE.UniformsLib[ "fog" ] + THREE.UniformsLib[ 'points' ], + THREE.UniformsLib[ 'fog' ] ] ), - vertexShader: [ - - "uniform float size;", - "uniform float scale;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "shadowmap_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "color_vertex" ], - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - - " #ifdef USE_SIZEATTENUATION", - " gl_PointSize = size * ( scale / - mvPosition.z );", - " #else", - " gl_PointSize = size;", - " #endif", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - THREE.ShaderChunk[ "worldpos_vertex" ], - THREE.ShaderChunk[ "shadowmap_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform float opacity;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "map_particle_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "shadowmap_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " vec3 outgoingLight = vec3( 0.0 );", - " vec4 diffuseColor = vec4( diffuse, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "map_particle_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - THREE.ShaderChunk[ "alphatest_fragment" ], - - " outgoingLight = diffuseColor.rgb;", - - THREE.ShaderChunk[ "fog_fragment" ], - - " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'points_vert' ], + fragmentShader: THREE.ShaderChunk[ 'points_frag' ] }, @@ -24546,140 +24616,33 @@ THREE.ShaderLib = { uniforms: THREE.UniformsUtils.merge( [ - THREE.UniformsLib[ "common" ], - THREE.UniformsLib[ "fog" ], + THREE.UniformsLib[ 'common' ], + THREE.UniformsLib[ 'fog' ], { - "scale" : { type: "f", value: 1 }, - "dashSize" : { type: "f", value: 1 }, - "totalSize": { type: "f", value: 2 } + "scale" : { type: "1f", value: 1 }, + "dashSize" : { type: "1f", value: 1 }, + "totalSize": { type: "1f", value: 2 } } ] ), - vertexShader: [ - - "uniform float scale;", - "attribute float lineDistance;", - - "varying float vLineDistance;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "color_vertex" ], - - " vLineDistance = scale * lineDistance;", - - " vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", - " gl_Position = projectionMatrix * mvPosition;", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform vec3 diffuse;", - "uniform float opacity;", - - "uniform float dashSize;", - "uniform float totalSize;", - - "varying float vLineDistance;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "color_pars_fragment" ], - THREE.ShaderChunk[ "fog_pars_fragment" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " if ( mod( vLineDistance, totalSize ) > dashSize ) {", - - " discard;", - - " }", - - " vec3 outgoingLight = vec3( 0.0 );", - " vec4 diffuseColor = vec4( diffuse, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - THREE.ShaderChunk[ "color_fragment" ], - - " outgoingLight = diffuseColor.rgb;", // simple shader - - THREE.ShaderChunk[ "fog_fragment" ], - - " gl_FragColor = vec4( outgoingLight, diffuseColor.a );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'linedashed_vert' ], + fragmentShader: THREE.ShaderChunk[ 'linedashed_frag' ] }, 'depth': { - uniforms: { + uniforms: THREE.UniformsUtils.merge( [ - "mNear": { type: "f", value: 1.0 }, - "mFar" : { type: "f", value: 2000.0 }, - "opacity" : { type: "f", value: 1.0 } + THREE.UniformsLib[ 'common' ], + THREE.UniformsLib[ 'displacementmap' ] - }, + ] ), - vertexShader: [ - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform float mNear;", - "uniform float mFar;", - "uniform float opacity;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " float depth = gl_FragDepthEXT / gl_FragCoord.w;", - - " #else", - - " float depth = gl_FragCoord.z / gl_FragCoord.w;", - - " #endif", - - " float color = 1.0 - smoothstep( mNear, mFar, depth );", - " gl_FragColor = vec4( vec3( color ), opacity );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'depth_vert' ], + fragmentShader: THREE.ShaderChunk[ 'depth_frag' ] }, @@ -24687,48 +24650,12 @@ THREE.ShaderLib = { uniforms: { - "opacity" : { type: "f", value: 1.0 } + "opacity" : { type: "1f", value: 1.0 } }, - vertexShader: [ - - "varying vec3 vNormal;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - " vNormal = normalize( normalMatrix * normal );", - - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform float opacity;", - "varying vec3 vNormal;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'normal_vert' ], + fragmentShader: THREE.ShaderChunk[ 'normal_frag' ] }, @@ -24740,47 +24667,11 @@ THREE.ShaderLib = { uniforms: { "tCube": { type: "t", value: null }, - "tFlip": { type: "f", value: - 1 } + "tFlip": { type: "1f", value: - 1 } }, - vertexShader: [ - - "varying vec3 vWorldPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - " vWorldPosition = transformDirection( position, modelMatrix );", - - " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform samplerCube tCube;", - "uniform float tFlip;", - - "varying vec3 vWorldPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - " gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'cube_vert' ], + fragmentShader: THREE.ShaderChunk[ 'cube_frag' ] }, @@ -24792,201 +24683,47 @@ THREE.ShaderLib = { uniforms: { "tEquirect": { type: "t", value: null }, - "tFlip": { type: "f", value: - 1 } + "tFlip": { type: "1f", value: - 1 } }, - vertexShader: [ - - "varying vec3 vWorldPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - " vWorldPosition = transformDirection( position, modelMatrix );", - - " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", - - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform sampler2D tEquirect;", - "uniform float tFlip;", - - "varying vec3 vWorldPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "void main() {", - - // " gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );", - "vec3 direction = normalize( vWorldPosition );", - "vec2 sampleUV;", - "sampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );", - "sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", - "gl_FragColor = texture2D( tEquirect, sampleUV );", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'equirect_vert' ], + fragmentShader: THREE.ShaderChunk[ 'equirect_frag' ] }, - /* Depth encoding into RGBA texture - * - * based on SpiderGL shadow map example - * http://spidergl.org/example.php?id=6 - * - * originally from - * http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD - * - * see also - * http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/ - */ - - 'depthRGBA': { - - uniforms: {}, - - vertexShader: [ - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "skinbase_vertex" ], - - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "logdepthbuf_vertex" ], - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ], - - "vec4 pack_depth( const in float depth ) {", - - " const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );", - " const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );", - " vec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );", - " res -= res.xxyz * bit_mask;", - " return res;", - - "}", - - "void main() {", - - THREE.ShaderChunk[ "logdepthbuf_fragment" ], - - " #ifdef USE_LOGDEPTHBUF_EXT", - - " gl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );", - - " #else", - - " gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );", - - " #endif", - - //"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );", - //"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );", - //"gl_FragData[ 0 ] = pack_depth( z );", - //"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );", - - "}" - - ].join( "\n" ) - - }, - - 'distanceRGBA': { uniforms: { - "lightPos": { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) } + "lightPos": { type: "v3", value: new THREE.Vector3() } }, - vertexShader: [ - - "varying vec4 vWorldPosition;", - - THREE.ShaderChunk[ "common" ], - THREE.ShaderChunk[ "morphtarget_pars_vertex" ], - THREE.ShaderChunk[ "skinning_pars_vertex" ], - - "void main() {", - - THREE.ShaderChunk[ "skinbase_vertex" ], - THREE.ShaderChunk[ "begin_vertex" ], - THREE.ShaderChunk[ "morphtarget_vertex" ], - THREE.ShaderChunk[ "skinning_vertex" ], - THREE.ShaderChunk[ "project_vertex" ], - THREE.ShaderChunk[ "worldpos_vertex" ], - - "vWorldPosition = worldPosition;", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "uniform vec3 lightPos;", - "varying vec4 vWorldPosition;", - - THREE.ShaderChunk[ "common" ], - - "vec4 pack1K ( float depth ) {", - - " depth /= 1000.0;", - " const vec4 bitSh = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );", - " const vec4 bitMsk = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );", - " vec4 res = mod( depth * bitSh * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );", - " res -= res.xxyz * bitMsk;", - " return res; ", - - "}", - - "float unpack1K ( vec4 color ) {", - - " const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );", - " return dot( color, bitSh ) * 1000.0;", - - "}", - - "void main () {", - - " gl_FragColor = pack1K( length( vWorldPosition.xyz - lightPos.xyz ) );", - - "}" - - ].join( "\n" ) + vertexShader: THREE.ShaderChunk[ 'distanceRGBA_vert' ], + fragmentShader: THREE.ShaderChunk[ 'distanceRGBA_frag' ] } }; +THREE.ShaderLib[ 'physical' ] = { + + uniforms: THREE.UniformsUtils.merge( [ + + THREE.ShaderLib[ 'standard' ].uniforms, + + { + // future + } + + ] ), + + vertexShader: THREE.ShaderChunk[ 'meshphysical_vert' ], + fragmentShader: THREE.ShaderChunk[ 'meshphysical_frag' ] + +}; + + // File:src/renderers/WebGLRenderer.js /** @@ -24994,6 +24731,7 @@ THREE.ShaderLib = { * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ * @author szimek / https://github.com/szimek/ + * @author tschw */ THREE.WebGLRenderer = function ( parameters ) { @@ -25040,12 +24778,27 @@ THREE.WebGLRenderer = function ( parameters ) { this.sortObjects = true; + // user-defined clipping + + this.clippingPlanes = []; + this.localClippingEnabled = false; + // physically based shading this.gammaFactor = 2.0; // for backwards compatibility this.gammaInput = false; this.gammaOutput = false; + // physical lights + + this.physicallyCorrectLights = false; + + // tone mapping + + this.toneMapping = THREE.LinearToneMapping; + this.toneMappingExposure = 1.0; + this.toneMappingWhitePoint = 1.0; + // morphs this.maxMorphTargets = 8; @@ -25096,6 +24849,14 @@ THREE.WebGLRenderer = function ( parameters ) { _frustum = new THREE.Frustum(), + // clipping + + _clipping = new THREE.WebGLClipping(), + _clippingEnabled = false, + _localClippingEnabled = false, + + _sphere = new THREE.Sphere(), + // camera matrices cache _projScreenMatrix = new THREE.Matrix4(), @@ -25120,8 +24881,7 @@ THREE.WebGLRenderer = function ( parameters ) { pointShadowMatrix: [], hemi: [], - shadows: [], - shadowsPointLight: 0 + shadows: [] }, @@ -25183,6 +24943,18 @@ THREE.WebGLRenderer = function ( parameters ) { } + // Some experimental-webgl implementations do not have getShaderPrecisionFormat + + if ( _gl.getShaderPrecisionFormat === undefined ) { + + _gl.getShaderPrecisionFormat = function () { + + return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 }; + + }; + + } + _canvas.addEventListener( 'webglcontextlost', onContextLost, false ); } catch ( error ) { @@ -25191,8 +24963,10 @@ THREE.WebGLRenderer = function ( parameters ) { } + var _isWebGL2 = (typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext); var extensions = new THREE.WebGLExtensions( _gl ); + extensions.get( 'WEBGL_depth_texture' ); extensions.get( 'OES_texture_float' ); extensions.get( 'OES_texture_float_linear' ); extensions.get( 'OES_texture_half_float' ); @@ -25555,23 +25329,33 @@ THREE.WebGLRenderer = function ( parameters ) { var renderTargetProperties = properties.get( renderTarget ); var textureProperties = properties.get( renderTarget.texture ); - if ( ! renderTarget || textureProperties.__webglTexture === undefined ) return; + if ( ! renderTarget ) return; - _gl.deleteTexture( textureProperties.__webglTexture ); + if ( textureProperties.__webglTexture !== undefined ) { + + _gl.deleteTexture( textureProperties.__webglTexture ); + + } + + if ( renderTarget.depthTexture ) { + + renderTarget.depthTexture.dispose(); + + } if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) { for ( var i = 0; i < 6; i ++ ) { _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] ); - _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); + if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); } } else { _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer ); - _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); + if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); } @@ -25632,7 +25416,7 @@ THREE.WebGLRenderer = function ( parameters ) { _gl.bindBuffer( _gl.ARRAY_BUFFER, buffers.normal ); - if ( material.type !== 'MeshPhongMaterial' && material.type !== 'MeshStandardMaterial' && material.shading === THREE.FlatShading ) { + if ( material.type !== 'MeshPhongMaterial' && material.type !== 'MeshStandardMaterial' && material.type !== 'MeshPhysicalMaterial' && material.shading === THREE.FlatShading ) { for ( var i = 0, l = object.count * 3; i < l; i += 9 ) { @@ -25758,13 +25542,8 @@ THREE.WebGLRenderer = function ( parameters ) { } - var uniforms = program.getUniforms(); - - if ( uniforms.morphTargetInfluences !== null ) { - - _gl.uniform1fv( uniforms.morphTargetInfluences, morphInfluences ); - - } + program.getUniforms().setValue( + _gl, 'morphTargetInfluences', morphInfluences ); updateBuffers = true; @@ -25886,9 +25665,13 @@ THREE.WebGLRenderer = function ( parameters ) { } - if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) { + if ( geometry instanceof THREE.InstancedBufferGeometry ) { - renderer.renderInstances( geometry, drawStart, drawCount ); + if ( geometry.maxInstancedCount > 0 ) { + + renderer.renderInstances( geometry, drawStart, drawCount ); + + } } else { @@ -25935,6 +25718,44 @@ THREE.WebGLRenderer = function ( parameters ) { if ( geometryAttribute !== undefined ) { + var type = _gl.FLOAT; + var array = geometryAttribute.array; + var normalized = geometryAttribute.normalized; + + if ( array instanceof Float32Array ) { + + type = _gl.FLOAT; + + } else if ( array instanceof Float64Array ) { + + console.warn("Unsupported data buffer format: Float64Array"); + + } else if ( array instanceof Uint16Array ) { + + type = _gl.UNSIGNED_SHORT; + + } else if ( array instanceof Int16Array ) { + + type = _gl.SHORT; + + } else if ( array instanceof Uint32Array ) { + + type = _gl.UNSIGNED_INT; + + } else if ( array instanceof Int32Array ) { + + type = _gl.INT; + + } else if ( array instanceof Int8Array ) { + + type = _gl.BYTE; + + } else if ( array instanceof Uint8Array ) { + + type = _gl.UNSIGNED_BYTE; + + } + var size = geometryAttribute.itemSize; var buffer = objects.getAttributeBuffer( geometryAttribute ); @@ -25961,7 +25782,7 @@ THREE.WebGLRenderer = function ( parameters ) { } _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); - _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT ); + _gl.vertexAttribPointer( programAttribute, size, type, normalized, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT ); } else { @@ -25982,7 +25803,7 @@ THREE.WebGLRenderer = function ( parameters ) { } _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer ); - _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 ); // 4 bytes per Float32 + _gl.vertexAttribPointer( programAttribute, size, type, normalized, 0, startIndex * size * geometryAttribute.array.BYTES_PER_ELEMENT ); } @@ -26111,8 +25932,13 @@ THREE.WebGLRenderer = function ( parameters ) { sprites.length = 0; lensFlares.length = 0; + _localClippingEnabled = this.localClippingEnabled; + _clippingEnabled = _clipping.init( + this.clippingPlanes, _localClippingEnabled, camera ); + projectObject( scene, camera ); + opaqueObjects.length = opaqueObjectsLastIndex + 1; transparentObjects.length = transparentObjectsLastIndex + 1; @@ -26123,12 +25949,18 @@ THREE.WebGLRenderer = function ( parameters ) { } - setupLights( lights, camera ); - // + if ( _clippingEnabled ) _clipping.beginShadows(); + + setupShadows( lights ); + shadowMap.render( scene, camera ); + setupLights( lights, camera ); + + if ( _clippingEnabled ) _clipping.endShadows(); + // _infoRender.calls = 0; @@ -26252,6 +26084,57 @@ THREE.WebGLRenderer = function ( parameters ) { } + // TODO Duplicated code (Frustum) + + function isObjectViewable( object ) { + + var geometry = object.geometry; + + if ( geometry.boundingSphere === null ) + geometry.computeBoundingSphere(); + + _sphere.copy( geometry.boundingSphere ). + applyMatrix4( object.matrixWorld ); + + return isSphereViewable( _sphere ); + + } + + function isSpriteViewable( sprite ) { + + _sphere.center.set( 0, 0, 0 ); + _sphere.radius = 0.7071067811865476; + _sphere.applyMatrix4( sprite.matrixWorld ); + + return isSphereViewable( _sphere ); + + } + + function isSphereViewable( sphere ) { + + if ( ! _frustum.intersectsSphere( sphere ) ) return false; + + var numPlanes = _clipping.numPlanes; + + if ( numPlanes === 0 ) return true; + + var planes = _this.clippingPlanes, + + center = sphere.center, + negRad = - sphere.radius, + i = 0; + + do { + + // out when deeper than radius in the negative halfspace + if ( planes[ i ].distanceToPoint( center ) < negRad ) return false; + + } while ( ++ i !== numPlanes ); + + return true; + + } + function projectObject( object, camera ) { if ( object.visible === false ) return; @@ -26264,7 +26147,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else if ( object instanceof THREE.Sprite ) { - if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) { + if ( object.frustumCulled === false || isSpriteViewable( object ) === true ) { sprites.push( object ); @@ -26293,7 +26176,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) { + if ( object.frustumCulled === false || isObjectViewable( object ) === true ) { var material = object.material; @@ -26392,7 +26275,9 @@ THREE.WebGLRenderer = function ( parameters ) { var materialProperties = properties.get( material ); - var parameters = programCache.getParameters( material, _lights, fog, object ); + var parameters = programCache.getParameters( + material, _lights, fog, _clipping.numPlanes, object ); + var code = programCache.getProgramCode( material, parameters ); var program = materialProperties.program; @@ -26487,27 +26372,18 @@ THREE.WebGLRenderer = function ( parameters ) { } - materialProperties.uniformsList = []; + var uniforms = materialProperties.__webglShader.uniforms; - var uniforms = materialProperties.__webglShader.uniforms, - uniformLocations = materialProperties.program.getUniforms(); + if ( ! ( material instanceof THREE.ShaderMaterial ) && + ! ( material instanceof THREE.RawShaderMaterial ) || + material.clipping === true ) { - for ( var u in uniforms ) { - - var location = uniformLocations[ u ]; - - if ( location ) { - - materialProperties.uniformsList.push( [ materialProperties.__webglShader.uniforms[ u ], location ] ); - - } + materialProperties.numClippingPlanes = _clipping.numPlanes; + uniforms.clippingPlanes = _clipping.uniform; } - if ( material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.MeshStandardMaterial || - material.lights ) { + if ( material.lights ) { // store the light setup it was created for @@ -26530,32 +26406,28 @@ THREE.WebGLRenderer = function ( parameters ) { } - // detect dynamic uniforms + var progUniforms = materialProperties.program.getUniforms(), + uniformsList = + THREE.WebGLUniforms.seqWithValue( progUniforms.seq, uniforms ); - materialProperties.hasDynamicUniforms = false; - - for ( var j = 0, jl = materialProperties.uniformsList.length; j < jl; j ++ ) { - - var uniform = materialProperties.uniformsList[ j ][ 0 ]; - - if ( uniform.dynamic === true ) { - - materialProperties.hasDynamicUniforms = true; - break; - - } - - } + materialProperties.uniformsList = uniformsList; + materialProperties.dynamicUniforms = + THREE.WebGLUniforms.splitDynamic( uniformsList, uniforms ); } function setMaterial( material ) { - setMaterialFaces( material ); + if ( material.side !== THREE.DoubleSide ) + state.enable( _gl.CULL_FACE ); + else + state.disable( _gl.CULL_FACE ); + + state.setFlipSided( material.side === THREE.BackSide ); if ( material.transparent === true ) { - state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha ); + state.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha ); } else { @@ -26571,19 +26443,38 @@ THREE.WebGLRenderer = function ( parameters ) { } - function setMaterialFaces( material ) { - - material.side !== THREE.DoubleSide ? state.enable( _gl.CULL_FACE ) : state.disable( _gl.CULL_FACE ); - state.setFlipSided( material.side === THREE.BackSide ); - - } - function setProgram( camera, fog, material, object ) { _usedTextureUnits = 0; var materialProperties = properties.get( material ); + if ( _clippingEnabled ) { + + if ( _localClippingEnabled || camera !== _currentCamera ) { + + var useCache = + camera === _currentCamera && + material.id === _currentMaterialId; + + // we might want to call this function with some ClippingGroup + // object instead of the material, once it becomes feasible + // (#8465, #8379) + _clipping.setState( + material.clippingPlanes, material.clipShadows, + camera, materialProperties, useCache ); + + } + + if ( materialProperties.numClippingPlanes !== undefined && + materialProperties.numClippingPlanes !== _clipping.numPlanes ) { + + material.needsUpdate = true; + + } + + } + if ( materialProperties.program === undefined ) { material.needsUpdate = true; @@ -26633,11 +26524,12 @@ THREE.WebGLRenderer = function ( parameters ) { if ( refreshProgram || camera !== _currentCamera ) { - _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera.projectionMatrix.elements ); + p_uniforms.set( _gl, camera, 'projectionMatrix' ); if ( capabilities.logarithmicDepthBuffer ) { - _gl.uniform1f( p_uniforms.logDepthBufFC, 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); + p_uniforms.setValue( _gl, 'logDepthBufFC', + 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) ); } @@ -26663,10 +26555,12 @@ THREE.WebGLRenderer = function ( parameters ) { material instanceof THREE.MeshStandardMaterial || material.envMap ) { - if ( p_uniforms.cameraPosition !== undefined ) { + var uCamPos = p_uniforms.map.cameraPosition; - _vector3.setFromMatrixPosition( camera.matrixWorld ); - _gl.uniform3f( p_uniforms.cameraPosition, _vector3.x, _vector3.y, _vector3.z ); + if ( uCamPos !== undefined ) { + + uCamPos.setValue( _gl, + _vector3.setFromMatrixPosition( camera.matrixWorld ) ); } @@ -26679,14 +26573,13 @@ THREE.WebGLRenderer = function ( parameters ) { material instanceof THREE.ShaderMaterial || material.skinning ) { - if ( p_uniforms.viewMatrix !== undefined ) { - - _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera.matrixWorldInverse.elements ); - - } + p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse ); } + p_uniforms.set( _gl, _this, 'toneMappingExposure' ); + p_uniforms.set( _gl, _this, 'toneMappingWhitePoint' ); + } // skinning uniforms must be set even if material didn't change @@ -26695,46 +26588,22 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material.skinning ) { - if ( object.bindMatrix && p_uniforms.bindMatrix !== undefined ) { + p_uniforms.setOptional( _gl, object, 'bindMatrix' ); + p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' ); - _gl.uniformMatrix4fv( p_uniforms.bindMatrix, false, object.bindMatrix.elements ); + var skeleton = object.skeleton; - } + if ( skeleton ) { - if ( object.bindMatrixInverse && p_uniforms.bindMatrixInverse !== undefined ) { + if ( capabilities.floatVertexTextures && skeleton.useVertexTexture ) { - _gl.uniformMatrix4fv( p_uniforms.bindMatrixInverse, false, object.bindMatrixInverse.elements ); + p_uniforms.set( _gl, skeleton, 'boneTexture' ); + p_uniforms.set( _gl, skeleton, 'boneTextureWidth' ); + p_uniforms.set( _gl, skeleton, 'boneTextureHeight' ); - } + } else { - if ( capabilities.floatVertexTextures && object.skeleton && object.skeleton.useVertexTexture ) { - - if ( p_uniforms.boneTexture !== undefined ) { - - var textureUnit = getTextureUnit(); - - _gl.uniform1i( p_uniforms.boneTexture, textureUnit ); - _this.setTexture( object.skeleton.boneTexture, textureUnit ); - - } - - if ( p_uniforms.boneTextureWidth !== undefined ) { - - _gl.uniform1i( p_uniforms.boneTextureWidth, object.skeleton.boneTextureWidth ); - - } - - if ( p_uniforms.boneTextureHeight !== undefined ) { - - _gl.uniform1i( p_uniforms.boneTextureHeight, object.skeleton.boneTextureHeight ); - - } - - } else if ( object.skeleton && object.skeleton.boneMatrices ) { - - if ( p_uniforms.boneGlobalMatrices !== undefined ) { - - _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.skeleton.boneMatrices ); + p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' ); } @@ -26744,10 +26613,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( refreshMaterial ) { - if ( material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshLambertMaterial || - material instanceof THREE.MeshStandardMaterial || - material.lights ) { + if ( material.lights ) { // the current material requires lighting info @@ -26773,7 +26639,8 @@ THREE.WebGLRenderer = function ( parameters ) { if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial || - material instanceof THREE.MeshStandardMaterial ) { + material instanceof THREE.MeshStandardMaterial || + material instanceof THREE.MeshDepthMaterial ) { refreshUniformsCommon( m_uniforms, material ); @@ -26802,15 +26669,23 @@ THREE.WebGLRenderer = function ( parameters ) { refreshUniformsPhong( m_uniforms, material ); + } else if ( material instanceof THREE.MeshPhysicalMaterial ) { + + refreshUniformsPhysical( m_uniforms, material ); + } else if ( material instanceof THREE.MeshStandardMaterial ) { refreshUniformsStandard( m_uniforms, material ); } else if ( material instanceof THREE.MeshDepthMaterial ) { - m_uniforms.mNear.value = camera.near; - m_uniforms.mFar.value = camera.far; - m_uniforms.opacity.value = material.opacity; + if ( material.displacementMap ) { + + m_uniforms.displacementMap.value = material.displacementMap; + m_uniforms.displacementScale.value = material.displacementScale; + m_uniforms.displacementBias.value = material.displacementBias; + + } } else if ( material instanceof THREE.MeshNormalMaterial ) { @@ -26818,23 +26693,29 @@ THREE.WebGLRenderer = function ( parameters ) { } - // load common uniforms - - loadUniformsGeneric( materialProperties.uniformsList ); + THREE.WebGLUniforms.upload( + _gl, materialProperties.uniformsList, m_uniforms, _this ); } - loadUniformsMatrices( p_uniforms, object ); - if ( p_uniforms.modelMatrix !== undefined ) { + // common matrices - _gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements ); + p_uniforms.set( _gl, object, 'modelViewMatrix' ); + p_uniforms.set( _gl, object, 'normalMatrix' ); + p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld ); - } - if ( materialProperties.hasDynamicUniforms === true ) { + // dynamic uniforms - updateDynamicUniforms( materialProperties.uniformsList, object, camera ); + var dynUniforms = materialProperties.dynamicUniforms; + + if ( dynUniforms !== null ) { + + THREE.WebGLUniforms.evalDynamic( + dynUniforms, m_uniforms, object, camera ); + + THREE.WebGLUniforms.upload( _gl, dynUniforms, m_uniforms, _this ); } @@ -26842,28 +26723,6 @@ THREE.WebGLRenderer = function ( parameters ) { } - function updateDynamicUniforms ( uniforms, object, camera ) { - - var dynamicUniforms = []; - - for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) { - - var uniform = uniforms[ j ][ 0 ]; - var onUpdateCallback = uniform.onUpdateCallback; - - if ( onUpdateCallback !== undefined ) { - - onUpdateCallback.bind( uniform )( object, camera ); - dynamicUniforms.push( uniforms[ j ] ); - - } - - } - - loadUniformsGeneric( dynamicUniforms ); - - } - // Uniforms (refresh uniforms objects) function refreshUniformsCommon ( uniforms, material ) { @@ -26939,6 +26798,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( uvScaleMap !== undefined ) { + // backwards compatibility if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) { uvScaleMap = uvScaleMap.texture; @@ -26953,7 +26813,12 @@ THREE.WebGLRenderer = function ( parameters ) { } uniforms.envMap.value = material.envMap; - uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : - 1; + + // don't flip CubeTexture envMaps, flip everything else: + // WebGLRenderTargetCube will be flipped for backwards compatibility + // WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture + // this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future + uniforms.flipEnvMap.value = ( ! ( material.envMap instanceof THREE.CubeTexture ) ) ? 1 : - 1; uniforms.reflectivity.value = material.reflectivity; uniforms.refractionRatio.value = material.refractionRatio; @@ -26980,7 +26845,7 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.diffuse.value = material.color; uniforms.opacity.value = material.opacity; uniforms.size.value = material.size * _pixelRatio; - uniforms.scale.value = _canvas.clientHeight / 2.0; // TODO: Cache this. + uniforms.scale.value = _canvas.clientHeight * 0.5; uniforms.map.value = material.map; @@ -27132,6 +26997,12 @@ THREE.WebGLRenderer = function ( parameters ) { } + function refreshUniformsPhysical ( uniforms, material ) { + + refreshUniformsStandard( uniforms, material ); + + } + // If uniforms are marked as clean, they don't need to be loaded to the GPU. function markUniformsLightsNeedsUpdate ( uniforms, value ) { @@ -27145,477 +27016,26 @@ THREE.WebGLRenderer = function ( parameters ) { } - // Uniforms (load to GPU) + // Lighting - function loadUniformsMatrices ( uniforms, object ) { + function setupShadows ( lights ) { - _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object.modelViewMatrix.elements ); + var lightShadowsLength = 0; - if ( uniforms.normalMatrix ) { + for ( var i = 0, l = lights.length; i < l; i ++ ) { - _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object.normalMatrix.elements ); + var light = lights[ i ]; - } + if ( light.castShadow ) { - } - - function getTextureUnit() { - - var textureUnit = _usedTextureUnits; - - if ( textureUnit >= capabilities.maxTextures ) { - - console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); - - } - - _usedTextureUnits += 1; - - return textureUnit; - - } - - function loadUniformsGeneric ( uniforms ) { - - var texture, textureUnit; - - for ( var j = 0, jl = uniforms.length; j < jl; j ++ ) { - - var uniform = uniforms[ j ][ 0 ]; - - // needsUpdate property is not added to all uniforms. - if ( uniform.needsUpdate === false ) continue; - - var type = uniform.type; - var value = uniform.value; - var location = uniforms[ j ][ 1 ]; - - switch ( type ) { - - case '1i': - _gl.uniform1i( location, value ); - break; - - case '1f': - _gl.uniform1f( location, value ); - break; - - case '2f': - _gl.uniform2f( location, value[ 0 ], value[ 1 ] ); - break; - - case '3f': - _gl.uniform3f( location, value[ 0 ], value[ 1 ], value[ 2 ] ); - break; - - case '4f': - _gl.uniform4f( location, value[ 0 ], value[ 1 ], value[ 2 ], value[ 3 ] ); - break; - - case '1iv': - _gl.uniform1iv( location, value ); - break; - - case '3iv': - _gl.uniform3iv( location, value ); - break; - - case '1fv': - _gl.uniform1fv( location, value ); - break; - - case '2fv': - _gl.uniform2fv( location, value ); - break; - - case '3fv': - _gl.uniform3fv( location, value ); - break; - - case '4fv': - _gl.uniform4fv( location, value ); - break; - - case 'Matrix2fv': - _gl.uniformMatrix2fv( location, false, value ); - break; - - case 'Matrix3fv': - _gl.uniformMatrix3fv( location, false, value ); - break; - - case 'Matrix4fv': - _gl.uniformMatrix4fv( location, false, value ); - break; - - // - - case 'i': - - // single integer - _gl.uniform1i( location, value ); - - break; - - case 'f': - - // single float - _gl.uniform1f( location, value ); - - break; - - case 'v2': - - // single THREE.Vector2 - _gl.uniform2f( location, value.x, value.y ); - - break; - - case 'v3': - - // single THREE.Vector3 - _gl.uniform3f( location, value.x, value.y, value.z ); - - break; - - case 'v4': - - // single THREE.Vector4 - _gl.uniform4f( location, value.x, value.y, value.z, value.w ); - - break; - - case 'c': - - // single THREE.Color - _gl.uniform3f( location, value.r, value.g, value.b ); - - break; - - /* - case 's': - - // TODO: Optimize this. - for( var propertyName in uniform.properties ) { - - var property = uniform.properties[ propertyName ]; - var locationProperty = location[ propertyName ]; - var valueProperty = value[ propertyName ]; - - switch( property.type ) { - case 'i': - _gl.uniform1i( locationProperty, valueProperty ); - break; - case 'f': - _gl.uniform1f( locationProperty, valueProperty ); - break; - case 'v2': - _gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y ); - break; - case 'v3': - _gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z ); - break; - case 'v4': - _gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); - break; - case 'c': - _gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b ); - break; - }; - - } - - break; - */ - - case 'sa': - - // TODO: Optimize this. - for ( var i = 0; i < value.length; i ++ ) { - - for ( var propertyName in uniform.properties ) { - - var property = uniform.properties[ propertyName ]; - var locationProperty = location[ i ][ propertyName ]; - var valueProperty = value[ i ][ propertyName ]; - - switch ( property.type ) { - case 'i': - _gl.uniform1i( locationProperty, valueProperty ); - break; - case 'f': - _gl.uniform1f( locationProperty, valueProperty ); - break; - case 'v2': - _gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y ); - break; - case 'v3': - _gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z ); - break; - case 'v4': - _gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w ); - break; - case 'c': - _gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b ); - break; - case 'm4': - _gl.uniformMatrix4fv( locationProperty, false, valueProperty.elements ); - break; - } - - } - - } - - break; - - case 'iv1': - - // flat array of integers (JS or typed array) - _gl.uniform1iv( location, value ); - - break; - - case 'iv': - - // flat array of integers with 3 x N size (JS or typed array) - _gl.uniform3iv( location, value ); - - break; - - case 'fv1': - - // flat array of floats (JS or typed array) - _gl.uniform1fv( location, value ); - - break; - - case 'fv': - - // flat array of floats with 3 x N size (JS or typed array) - _gl.uniform3fv( location, value ); - - break; - - case 'v2v': - - // array of THREE.Vector2 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 2 * value.length ); - - } - - for ( var i = 0, i2 = 0, il = value.length; i < il; i ++, i2 += 2 ) { - - uniform._array[ i2 + 0 ] = value[ i ].x; - uniform._array[ i2 + 1 ] = value[ i ].y; - - } - - _gl.uniform2fv( location, uniform._array ); - - break; - - case 'v3v': - - // array of THREE.Vector3 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 3 * value.length ); - - } - - for ( var i = 0, i3 = 0, il = value.length; i < il; i ++, i3 += 3 ) { - - uniform._array[ i3 + 0 ] = value[ i ].x; - uniform._array[ i3 + 1 ] = value[ i ].y; - uniform._array[ i3 + 2 ] = value[ i ].z; - - } - - _gl.uniform3fv( location, uniform._array ); - - break; - - case 'v4v': - - // array of THREE.Vector4 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 4 * value.length ); - - } - - for ( var i = 0, i4 = 0, il = value.length; i < il; i ++, i4 += 4 ) { - - uniform._array[ i4 + 0 ] = value[ i ].x; - uniform._array[ i4 + 1 ] = value[ i ].y; - uniform._array[ i4 + 2 ] = value[ i ].z; - uniform._array[ i4 + 3 ] = value[ i ].w; - - } - - _gl.uniform4fv( location, uniform._array ); - - break; - - case 'm2': - - // single THREE.Matrix2 - _gl.uniformMatrix2fv( location, false, value.elements ); - - break; - - case 'm3': - - // single THREE.Matrix3 - _gl.uniformMatrix3fv( location, false, value.elements ); - - break; - - case 'm3v': - - // array of THREE.Matrix3 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 9 * value.length ); - - } - - for ( var i = 0, il = value.length; i < il; i ++ ) { - - value[ i ].flattenToArrayOffset( uniform._array, i * 9 ); - - } - - _gl.uniformMatrix3fv( location, false, uniform._array ); - - break; - - case 'm4': - - // single THREE.Matrix4 - _gl.uniformMatrix4fv( location, false, value.elements ); - - break; - - case 'm4v': - - // array of THREE.Matrix4 - - if ( uniform._array === undefined ) { - - uniform._array = new Float32Array( 16 * value.length ); - - } - - for ( var i = 0, il = value.length; i < il; i ++ ) { - - value[ i ].flattenToArrayOffset( uniform._array, i * 16 ); - - } - - _gl.uniformMatrix4fv( location, false, uniform._array ); - - break; - - case 't': - - // single THREE.Texture (2d or cube) - - texture = value; - textureUnit = getTextureUnit(); - - _gl.uniform1i( location, textureUnit ); - - if ( ! texture ) continue; - - if ( texture instanceof THREE.CubeTexture || - ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { - - // CompressedTexture can have Array in image :/ - - setCubeTexture( texture, textureUnit ); - - } else if ( texture instanceof THREE.WebGLRenderTargetCube ) { - - setCubeTextureDynamic( texture.texture, textureUnit ); - - } else if ( texture instanceof THREE.WebGLRenderTarget ) { - - _this.setTexture( texture.texture, textureUnit ); - - } else { - - _this.setTexture( texture, textureUnit ); - - } - - break; - - case 'tv': - - // array of THREE.Texture (2d or cube) - - if ( uniform._array === undefined ) { - - uniform._array = []; - - } - - for ( var i = 0, il = uniform.value.length; i < il; i ++ ) { - - uniform._array[ i ] = getTextureUnit(); - - } - - _gl.uniform1iv( location, uniform._array ); - - for ( var i = 0, il = uniform.value.length; i < il; i ++ ) { - - texture = uniform.value[ i ]; - textureUnit = uniform._array[ i ]; - - if ( ! texture ) continue; - - if ( texture instanceof THREE.CubeTexture || - ( texture.image instanceof Array && texture.image.length === 6 ) ) { - - // CompressedTexture can have Array in image :/ - - setCubeTexture( texture, textureUnit ); - - } else if ( texture instanceof THREE.WebGLRenderTarget ) { - - _this.setTexture( texture.texture, textureUnit ); - - } else if ( texture instanceof THREE.WebGLRenderTargetCube ) { - - setCubeTextureDynamic( texture.texture, textureUnit ); - - } else { - - _this.setTexture( texture, textureUnit ); - - } - - } - - break; - - default: - - console.warn( 'THREE.WebGLRenderer: Unknown uniform type: ' + type ); + _lights.shadows[ lightShadowsLength ++ ] = light; } } + _lights.shadows.length = lightShadowsLength; + } function setupLights ( lights, camera ) { @@ -27625,17 +27045,14 @@ THREE.WebGLRenderer = function ( parameters ) { color, intensity, distance, + shadowMap, viewMatrix = camera.matrixWorldInverse, directionalLength = 0, pointLength = 0, spotLength = 0, - hemiLength = 0, - - shadowsLength = 0; - - _lights.shadowsPointLight = 0; + hemiLength = 0; for ( l = 0, ll = lights.length; l < ll; l ++ ) { @@ -27645,6 +27062,8 @@ THREE.WebGLRenderer = function ( parameters ) { intensity = light.intensity; distance = light.distance; + shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null; + if ( light instanceof THREE.AmbientLight ) { r += color.r * intensity; @@ -27669,11 +27088,9 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.shadowRadius = light.shadow.radius; uniforms.shadowMapSize = light.shadow.mapSize; - _lights.shadows[ shadowsLength ++ ] = light; - } - _lights.directionalShadowMap[ directionalLength ] = light.shadow.map; + _lights.directionalShadowMap[ directionalLength ] = shadowMap; _lights.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix; _lights.directional[ directionalLength ++ ] = uniforms; @@ -27692,8 +27109,8 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.direction.sub( _vector3 ); uniforms.direction.transformDirection( viewMatrix ); - uniforms.angleCos = Math.cos( light.angle ); - uniforms.exponent = light.exponent; + uniforms.coneCos = Math.cos( light.angle ); + uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) ); uniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay; uniforms.shadow = light.castShadow; @@ -27704,11 +27121,9 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.shadowRadius = light.shadow.radius; uniforms.shadowMapSize = light.shadow.mapSize; - _lights.shadows[ shadowsLength ++ ] = light; - } - _lights.spotShadowMap[ spotLength ] = light.shadow.map; + _lights.spotShadowMap[ spotLength ] = shadowMap; _lights.spotShadowMatrix[ spotLength ] = light.shadow.matrix; _lights.spot[ spotLength ++ ] = uniforms; @@ -27731,11 +27146,9 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms.shadowRadius = light.shadow.radius; uniforms.shadowMapSize = light.shadow.mapSize; - _lights.shadows[ shadowsLength ++ ] = light; - } - _lights.pointShadowMap[ pointLength ] = light.shadow.map; + _lights.pointShadowMap[ pointLength ] = shadowMap; if ( _lights.pointShadowMatrix[ pointLength ] === undefined ) { @@ -27776,9 +27189,7 @@ THREE.WebGLRenderer = function ( parameters ) { _lights.point.length = pointLength; _lights.hemi.length = hemiLength; - _lights.shadows.length = shadowsLength; - - _lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + shadowsLength; + _lights.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + hemiLength + ',' + _lights.shadows.length; } @@ -27786,44 +27197,29 @@ THREE.WebGLRenderer = function ( parameters ) { this.setFaceCulling = function ( cullFace, frontFaceDirection ) { - if ( cullFace === THREE.CullFaceNone ) { - - state.disable( _gl.CULL_FACE ); - - } else { - - if ( frontFaceDirection === THREE.FrontFaceDirectionCW ) { - - _gl.frontFace( _gl.CW ); - - } else { - - _gl.frontFace( _gl.CCW ); - - } - - if ( cullFace === THREE.CullFaceBack ) { - - _gl.cullFace( _gl.BACK ); - - } else if ( cullFace === THREE.CullFaceFront ) { - - _gl.cullFace( _gl.FRONT ); - - } else { - - _gl.cullFace( _gl.FRONT_AND_BACK ); - - } - - state.enable( _gl.CULL_FACE ); - - } + state.setCullFace( cullFace ); + state.setFlipSided( frontFaceDirection === THREE.FrontFaceDirectionCW ); }; // Textures + function allocTextureUnit() { + + var textureUnit = _usedTextureUnits; + + if ( textureUnit >= capabilities.maxTextures ) { + + console.warn( 'WebGLRenderer: trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures ); + + } + + _usedTextureUnits += 1; + + return textureUnit; + + } + function setTextureParameters ( textureType, texture, isPowerOfTwoImage ) { var extension; @@ -27913,7 +27309,27 @@ THREE.WebGLRenderer = function ( parameters ) { var mipmap, mipmaps = texture.mipmaps; - if ( texture instanceof THREE.DataTexture ) { + if ( texture instanceof THREE.DepthTexture ) { + + // populate depth texture with dummy data + + var internalFormat = _gl.DEPTH_COMPONENT; + + if ( texture.type === THREE.FloatType ) { + + if ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0'); + internalFormat = _gl.DEPTH_COMPONENT32F; + + } else if ( _isWebGL2 ) { + + // WebGL 2.0 requires signed internalformat for glTexImage2D + internalFormat = _gl.DEPTH_COMPONENT16; + + } + + state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null ); + + } else if ( texture instanceof THREE.DataTexture ) { // use manually created mipmaps if available // if there are no manual mipmaps @@ -27997,7 +27413,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - this.setTexture = function ( texture, slot ) { + function setTexture2D( texture, slot ) { var textureProperties = properties.get( texture ); @@ -28028,7 +27444,7 @@ THREE.WebGLRenderer = function ( parameters ) { state.activeTexture( _gl.TEXTURE0 + slot ); state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture ); - }; + } function clampToMaxSize ( image, maxSize ) { @@ -28092,7 +27508,7 @@ THREE.WebGLRenderer = function ( parameters ) { } - function setCubeTexture ( texture, slot ) { + function setTextureCube ( texture, slot ) { var textureProperties = properties.get( texture ); @@ -28171,7 +27587,7 @@ THREE.WebGLRenderer = function ( parameters ) { } else { - console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()" ); + console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()" ); } @@ -28208,13 +27624,103 @@ THREE.WebGLRenderer = function ( parameters ) { } - function setCubeTextureDynamic ( texture, slot ) { + function setTextureCubeDynamic ( texture, slot ) { state.activeTexture( _gl.TEXTURE0 + slot ); state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture ); } + this.allocTextureUnit = allocTextureUnit; + + //this.setTexture2D = setTexture2D; + this.setTexture2D = ( function() { + + var warned = false; + + // backwards compatibility: peel texture.texture + return function( texture, slot ) { + + if ( texture instanceof THREE.WebGLRenderTarget ) { + + if ( ! warned ) { + + console.warn( "THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead." ); + warned = true; + + } + + texture = texture.texture; + + } + + setTexture2D( texture, slot ); + + }; + + }() ); + + this.setTexture = ( function() { + + var warned = false; + + return function( texture, slot ) { + + if ( ! warned ) { + + console.warn( "THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead." ); + warned = true; + + } + + _this.setTexture2D( texture, slot ); + + }; + + }() ); + + this.setTextureCube = ( function() { + + var warned = false; + + return function( texture, slot ) { + + // backwards compatibility: peel texture.texture + if ( texture instanceof THREE.WebGLRenderTargetCube ) { + + if ( ! warned ) { + + console.warn( "THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead." ); + warned = true; + + } + + texture = texture.texture; + + } + + // currently relying on the fact that WebGLRenderTargetCube.texture is a Texture and NOT a CubeTexture + // TODO: unify these code paths + if ( texture instanceof THREE.CubeTexture || + ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) { + + // CompressedTexture can have Array in image :/ + + // this function alone should take care of cube textures + setTextureCube( texture, slot ); + + } else { + + // assumed: texture property of THREE.WebGLRenderTargetCube + + setTextureCubeDynamic( texture, slot ); + + } + + }; + + }() ); + // Render targets // Setup storage for target texture and bind it to correct framebuffer @@ -28255,6 +27761,36 @@ THREE.WebGLRenderer = function ( parameters ) { } + // Setup resources for a Depth Texture for a FBO (needs an extension) + function setupDepthTexture ( framebuffer, renderTarget ) { + + var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); + if ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!'); + + _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer ); + + if ( !( renderTarget.depthTexture instanceof THREE.DepthTexture ) ) { + + throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture'); + + } + + // upload an empty depth texture with framebuffer size + if ( !properties.get( renderTarget.depthTexture ).__webglTexture || + renderTarget.depthTexture.image.width !== renderTarget.width || + renderTarget.depthTexture.image.height !== renderTarget.height ) { + renderTarget.depthTexture.image.width = renderTarget.width; + renderTarget.depthTexture.image.height = renderTarget.height; + renderTarget.depthTexture.needsUpdate = true; + } + + _this.setTexture2D( renderTarget.depthTexture, 0 ); + + var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture; + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 ); + + } + // Setup GL resources for a non-texture depth buffer function setupDepthRenderbuffer( renderTarget ) { @@ -28262,23 +27798,33 @@ THREE.WebGLRenderer = function ( parameters ) { var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube ); - if ( isCube ) { + if ( renderTarget.depthTexture ) { - renderTargetProperties.__webglDepthbuffer = []; + if ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets'); - for ( var i = 0; i < 6; i ++ ) { - - _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] ); - renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); - setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget ); - - } + setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget ); } else { - _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); - renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); - setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget ); + if ( isCube ) { + + renderTargetProperties.__webglDepthbuffer = []; + + for ( var i = 0; i < 6; i ++ ) { + + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] ); + renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget ); + + } + + } else { + + _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer ); + renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget ); + + } } @@ -28356,6 +27902,12 @@ THREE.WebGLRenderer = function ( parameters ) { } + this.getCurrentRenderTarget = function() { + + return _currentRenderTarget; + + }; + this.setRenderTarget = function ( renderTarget ) { _currentRenderTarget = renderTarget; @@ -28414,7 +27966,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( isCube ) { var textureProperties = properties.get( renderTarget.texture ); - _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, 0 ); + _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, renderTarget.activeMipMapLevel ); } @@ -28447,18 +27999,17 @@ THREE.WebGLRenderer = function ( parameters ) { var texture = renderTarget.texture; - if ( texture.format !== THREE.RGBAFormat - && paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) { + if ( texture.format !== THREE.RGBAFormat && paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) { console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' ); return; } - if ( texture.type !== THREE.UnsignedByteType - && paramThreeToGL( texture.type ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) - && ! ( texture.type === THREE.FloatType && extensions.get( 'WEBGL_color_buffer_float' ) ) - && ! ( texture.type === THREE.HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) { + if ( texture.type !== THREE.UnsignedByteType && + paramThreeToGL( texture.type ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && + ! ( texture.type === THREE.FloatType && extensions.get( 'WEBGL_color_buffer_float' ) ) && + ! ( texture.type === THREE.HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) { console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' ); return; @@ -28467,7 +28018,13 @@ THREE.WebGLRenderer = function ( parameters ) { if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) { - _gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer ); + // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) + + if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) { + + _gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer ); + + } } else { @@ -28557,6 +28114,7 @@ THREE.WebGLRenderer = function ( parameters ) { if ( p === THREE.RGBAFormat ) return _gl.RGBA; if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE; if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA; + if ( p === THREE.DepthFormat ) return _gl.DEPTH_COMPONENT; if ( p === THREE.AddEquation ) return _gl.FUNC_ADD; if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT; @@ -28649,16 +28207,15 @@ THREE.WebGLRenderTarget = function ( width, height, options ) { if ( options.minFilter === undefined ) options.minFilter = THREE.LinearFilter; - this.texture = new THREE.Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy ); + this.texture = new THREE.Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true; this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true; + this.depthTexture = null; }; -THREE.WebGLRenderTarget.prototype = { - - constructor: THREE.WebGLRenderTarget, +Object.assign( THREE.WebGLRenderTarget.prototype, THREE.EventDispatcher.prototype, { setSize: function ( width, height ) { @@ -28693,8 +28250,7 @@ THREE.WebGLRenderTarget.prototype = { this.depthBuffer = source.depthBuffer; this.stencilBuffer = source.stencilBuffer; - - this.shareDepthFrom = source.shareDepthFrom; + this.depthTexture = source.depthTexture; return this; @@ -28706,9 +28262,7 @@ THREE.WebGLRenderTarget.prototype = { } -}; - -THREE.EventDispatcher.prototype.apply( THREE.WebGLRenderTarget.prototype ); +} ); // File:src/renderers/WebGLRenderTargetCube.js @@ -28721,6 +28275,7 @@ THREE.WebGLRenderTargetCube = function ( width, height, options ) { THREE.WebGLRenderTarget.call( this, width, height, options ); this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5 + this.activeMipMapLevel = 0; }; @@ -28794,6 +28349,161 @@ THREE.WebGLBufferRenderer = function ( _gl, extensions, _infoRender ) { }; +// File:src/renderers/webgl/WebGLClipping.js + +THREE.WebGLClipping = function() { + + var scope = this, + + globalState = null, + numGlobalPlanes = 0, + localClippingEnabled = false, + renderingShadows = false, + + plane = new THREE.Plane(), + viewNormalMatrix = new THREE.Matrix3(), + + uniform = { value: null, needsUpdate: false }; + + this.uniform = uniform; + this.numPlanes = 0; + + this.init = function( planes, enableLocalClipping, camera ) { + + var enabled = + planes.length !== 0 || + enableLocalClipping || + // enable state of previous frame - the clipping code has to + // run another frame in order to reset the state: + numGlobalPlanes !== 0 || + localClippingEnabled; + + localClippingEnabled = enableLocalClipping; + + globalState = projectPlanes( planes, camera, 0 ); + numGlobalPlanes = planes.length; + + return enabled; + + }; + + this.beginShadows = function() { + + renderingShadows = true; + projectPlanes( null ); + + }; + + this.endShadows = function() { + + renderingShadows = false; + resetGlobalState(); + + }; + + this.setState = function( planes, clipShadows, camera, cache, fromCache ) { + + if ( ! localClippingEnabled || + planes === null || planes.length === 0 || + renderingShadows && ! clipShadows ) { + // there's no local clipping + + if ( renderingShadows ) { + // there's no global clipping + + projectPlanes( null ); + + } else { + + resetGlobalState(); + } + + } else { + + var nGlobal = renderingShadows ? 0 : numGlobalPlanes, + lGlobal = nGlobal * 4, + + dstArray = cache.clippingState || null; + + uniform.value = dstArray; // ensure unique state + + dstArray = projectPlanes( planes, camera, lGlobal, fromCache ); + + for ( var i = 0; i !== lGlobal; ++ i ) { + + dstArray[ i ] = globalState[ i ]; + + } + + cache.clippingState = dstArray; + this.numPlanes += nGlobal; + + } + + + }; + + function resetGlobalState() { + + if ( uniform.value !== globalState ) { + + uniform.value = globalState; + uniform.needsUpdate = numGlobalPlanes > 0; + + } + + scope.numPlanes = numGlobalPlanes; + + } + + function projectPlanes( planes, camera, dstOffset, skipTransform ) { + + var nPlanes = planes !== null ? planes.length : 0, + dstArray = null; + + if ( nPlanes !== 0 ) { + + dstArray = uniform.value; + + if ( skipTransform !== true || dstArray === null ) { + + var flatSize = dstOffset + nPlanes * 4, + viewMatrix = camera.matrixWorldInverse; + + viewNormalMatrix.getNormalMatrix( viewMatrix ); + + if ( dstArray === null || dstArray.length < flatSize ) { + + dstArray = new Float32Array( flatSize ); + + } + + for ( var i = 0, i4 = dstOffset; + i !== nPlanes; ++ i, i4 += 4 ) { + + plane.copy( planes[ i ] ). + applyMatrix4( viewMatrix, viewNormalMatrix ); + + plane.normal.toArray( dstArray, i4 ); + dstArray[ i4 + 3 ] = plane.constant; + + } + + } + + uniform.value = dstArray; + uniform.needsUpdate = true; + + } + + scope.numPlanes = nPlanes; + return dstArray; + + } + +}; + + // File:src/renderers/webgl/WebGLIndexedBufferRenderer.js /** @@ -28885,6 +28595,10 @@ THREE.WebGLExtensions = function ( gl ) { switch ( name ) { + case 'WEBGL_depth_texture': + extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' ); + break; + case 'EXT_texture_filter_anisotropic': extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' ); break; @@ -28956,7 +28670,7 @@ THREE.WebGLCapabilities = function ( gl, extensions, parameters ) { this.getMaxPrecision = getMaxPrecision; - this.precision = parameters.precision !== undefined ? parameters.precision : 'highp', + 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 ); @@ -29176,8 +28890,8 @@ THREE.WebGLLights = function () { direction: new THREE.Vector3(), color: new THREE.Color(), distance: 0, - angleCos: 0, - exponent: 0, + coneCos: 0, + penumbraCos: 0, decay: 0, shadow: false, @@ -29453,17 +29167,82 @@ THREE.WebGLProgram = ( function () { var programIdCount = 0; - // TODO: Combine the regex - var structRe = /^([\w\d_]+)\.([\w\d_]+)$/; - var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; - var arrayRe = /^([\w\d_]+)\[0\]$/; + function getEncodingComponents( encoding ) { + + switch ( encoding ) { + + case THREE.LinearEncoding: + return [ 'Linear','( value )' ]; + case THREE.sRGBEncoding: + return [ 'sRGB','( value )' ]; + case THREE.RGBEEncoding: + return [ 'RGBE','( value )' ]; + case THREE.RGBM7Encoding: + return [ 'RGBM','( value, 7.0 )' ]; + case THREE.RGBM16Encoding: + return [ 'RGBM','( value, 16.0 )' ]; + case THREE.RGBDEncoding: + return [ 'RGBD','( value, 256.0 )' ]; + case THREE.GammaEncoding: + return [ 'Gamma','( value, float( GAMMA_FACTOR ) )' ]; + default: + throw new Error( 'unsupported encoding: ' + encoding ); + + } + + } + + function getTexelDecodingFunction( functionName, encoding ) { + + var components = getEncodingComponents( encoding ); + return "vec4 " + functionName + "( vec4 value ) { return " + components[ 0 ] + "ToLinear" + components[ 1 ] + "; }"; + + } + + function getTexelEncodingFunction( functionName, encoding ) { + + var components = getEncodingComponents( encoding ); + return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[ 0 ] + components[ 1 ] + "; }"; + + } + + function getToneMappingFunction( functionName, toneMapping ) { + + var toneMappingName; + + switch ( toneMapping ) { + + case THREE.LinearToneMapping: + toneMappingName = "Linear"; + break; + + case THREE.ReinhardToneMapping: + toneMappingName = "Reinhard"; + break; + + case THREE.Uncharted2ToneMapping: + toneMappingName = "Uncharted2"; + break; + + case THREE.CineonToneMapping: + toneMappingName = "OptimizedCineon"; + break; + + default: + throw new Error( 'unsupported toneMapping: ' + toneMapping ); + + } + + return "vec3 " + functionName + "( vec3 color ) { return " + toneMappingName + "ToneMapping( color ); }"; + + } function generateExtensions( extensions, parameters, rendererExtensions ) { extensions = extensions || {}; var chunks = [ - ( extensions.derivatives || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', + ( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.normalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '', ( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '', ( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '', ( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : '', @@ -29491,90 +29270,6 @@ THREE.WebGLProgram = ( function () { } - function fetchUniformLocations( gl, program, identifiers ) { - - var uniforms = {}; - - var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); - - for ( var i = 0; i < n; i ++ ) { - - var info = gl.getActiveUniform( program, i ); - var name = info.name; - var location = gl.getUniformLocation( program, name ); - - //console.log("THREE.WebGLProgram: ACTIVE UNIFORM:", name); - - var matches = structRe.exec( name ); - if ( matches ) { - - var structName = matches[ 1 ]; - var structProperty = matches[ 2 ]; - - var uniformsStruct = uniforms[ structName ]; - - if ( ! uniformsStruct ) { - - uniformsStruct = uniforms[ structName ] = {}; - - } - - uniformsStruct[ structProperty ] = location; - - continue; - - } - - matches = arrayStructRe.exec( name ); - - if ( matches ) { - - var arrayName = matches[ 1 ]; - var arrayIndex = matches[ 2 ]; - var arrayProperty = matches[ 3 ]; - - var uniformsArray = uniforms[ arrayName ]; - - if ( ! uniformsArray ) { - - uniformsArray = uniforms[ arrayName ] = []; - - } - - var uniformsArrayIndex = uniformsArray[ arrayIndex ]; - - if ( ! uniformsArrayIndex ) { - - uniformsArrayIndex = uniformsArray[ arrayIndex ] = {}; - - } - - uniformsArrayIndex[ arrayProperty ] = location; - - continue; - - } - - matches = arrayRe.exec( name ); - - if ( matches ) { - - var arrayName = matches[ 1 ]; - - uniforms[ arrayName ] = location; - - continue; - - } - - uniforms[ name ] = location; - - } - - return uniforms; - - } - function fetchAttributeLocations( gl, program, identifiers ) { var attributes = {}; @@ -29612,6 +29307,28 @@ THREE.WebGLProgram = ( function () { } + function parseIncludes( string ) { + + var pattern = /#include +<([\w\d.]+)>/g; + + function replace( match, include ) { + + var replace = THREE.ShaderChunk[ include ]; + + if ( replace === undefined ) { + + throw new Error( 'Can not resolve #include <' + include + '>' ); + + } + + return parseIncludes( replace ); + + } + + return string.replace( pattern, replace ); + + } + function unrollLoops( string ) { var pattern = /for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g; @@ -29669,6 +29386,11 @@ THREE.WebGLProgram = ( function () { envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; break; + case THREE.CubeUVReflectionMapping: + case THREE.CubeUVRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; + break; + case THREE.EquirectangularReflectionMapping: case THREE.EquirectangularRefractionMapping: envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC'; @@ -29741,8 +29463,6 @@ THREE.WebGLProgram = ( function () { parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', - renderer.gammaInput ? '#define GAMMA_INPUT' : '', - renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '', '#define GAMMA_FACTOR ' + gammaFactorDefine, '#define MAX_BONES ' + parameters.maxBones, @@ -29772,16 +29492,16 @@ THREE.WebGLProgram = ( function () { parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', + '#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes, + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', - parameters.pointLightShadows > 0 ? '#define POINT_LIGHT_SHADOWS' : '', parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '', - 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', @@ -29835,7 +29555,6 @@ THREE.WebGLProgram = ( function () { ].filter( filterEmptyLine ).join( '\n' ); - prefixFragment = [ customExtensions, @@ -29849,8 +29568,6 @@ THREE.WebGLProgram = ( function () { parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest : '', - renderer.gammaInput ? '#define GAMMA_INPUT' : '', - renderer.gammaOutput ? '#define GAMMA_OUTPUT' : '', '#define GAMMA_FACTOR ' + gammaFactorDefine, ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '', @@ -29877,9 +29594,14 @@ THREE.WebGLProgram = ( function () { parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', + '#define NUM_CLIPPING_PLANES ' + parameters.numClippingPlanes, + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', - parameters.pointLightShadows > 0 ? '#define POINT_LIGHT_SHADOWS' : '', + + parameters.premultipliedAlpha ? "#define PREMULTIPLIED_ALPHA" : '', + + parameters.physicallyCorrectLights ? "#define PHYSICALLY_CORRECT_LIGHTS" : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '', @@ -29889,13 +29611,28 @@ THREE.WebGLProgram = ( function () { 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', + ( parameters.toneMapping !== THREE.NoToneMapping ) ? "#define TONE_MAPPING" : '', + ( parameters.toneMapping !== THREE.NoToneMapping ) ? THREE.ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below + ( parameters.toneMapping !== THREE.NoToneMapping ) ? getToneMappingFunction( "toneMapping", parameters.toneMapping ) : '', + + ( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? THREE.ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below + parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '', + parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '', + parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '', + parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '', + + parameters.depthPacking ? "#define DEPTH_PACKING " + material.depthPacking : '', + '\n' ].filter( filterEmptyLine ).join( '\n' ); } + vertexShader = parseIncludes( vertexShader, parameters ); vertexShader = replaceLightNums( vertexShader, parameters ); + + fragmentShader = parseIncludes( fragmentShader, parameters ); fragmentShader = replaceLightNums( fragmentShader, parameters ); if ( material instanceof THREE.ShaderMaterial === false ) { @@ -29998,7 +29735,8 @@ THREE.WebGLProgram = ( function () { if ( cachedUniforms === undefined ) { - cachedUniforms = fetchUniformLocations( gl, program ); + cachedUniforms = + new THREE.WebGLUniforms( gl, program, renderer ); } @@ -30083,24 +29821,24 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { MeshBasicMaterial: 'basic', MeshLambertMaterial: 'lambert', MeshPhongMaterial: 'phong', - MeshStandardMaterial: 'standard', + MeshStandardMaterial: 'physical', + MeshPhysicalMaterial: 'physical', LineBasicMaterial: 'basic', LineDashedMaterial: 'dashed', PointsMaterial: 'points' }; var parameterNames = [ - "precision", "supportsVertexTextures", "map", "envMap", "envMapMode", - "lightMap", "aoMap", "emissiveMap", "bumpMap", "normalMap", "displacementMap", "specularMap", + "precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding", + "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "displacementMap", "specularMap", "roughnessMap", "metalnessMap", "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp", "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", "maxBones", "useVertexTexture", "morphTargets", "morphNormals", - "maxMorphTargets", "maxMorphNormals", + "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", - "shadowMapEnabled", "pointLightShadows", - "shadowMapType", - "alphaTest", "doubleSided", "flipSided" + "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights', + "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "depthPacking" ]; @@ -30142,9 +29880,40 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { } - this.getParameters = function ( material, lights, fog, object ) { + function getTextureEncodingFromMap( map, gammaOverrideLinear ) { + + var encoding; + + if ( ! map ) { + + encoding = THREE.LinearEncoding; + + } else if ( map instanceof THREE.Texture ) { + + encoding = map.encoding; + + } else if ( map instanceof THREE.WebGLRenderTarget ) { + + console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." ); + encoding = map.texture.encoding; + + } + + // add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point. + if ( encoding === THREE.LinearEncoding && gammaOverrideLinear ) { + + encoding = THREE.GammaEncoding; + + } + + return encoding; + + } + + this.getParameters = function ( material, lights, fog, nClipPlanes, object ) { var shaderID = shaderIDs[ material.type ]; + // heuristics to create shader parameters according to lights in the scene // (not to blow over maxLights budget) @@ -30163,19 +29932,25 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { } + var currentRenderTarget = renderer.getCurrentRenderTarget(); + var parameters = { shaderID: shaderID, precision: precision, supportsVertexTextures: capabilities.vertexTextures, - + outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ), map: !! material.map, + mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ), envMap: !! material.envMap, envMapMode: material.envMap && material.envMap.mapping, + envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ), + envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === THREE.CubeUVReflectionMapping ) || ( material.envMap.mapping === THREE.CubeUVRefractionMapping ) ), lightMap: !! material.lightMap, aoMap: !! material.aoMap, emissiveMap: !! material.emissiveMap, + emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ), bumpMap: !! material.bumpMap, normalMap: !! material.normalMap, displacementMap: !! material.displacementMap, @@ -30211,14 +29986,21 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { numSpotLights: lights.spot.length, numHemiLights: lights.hemi.length, - pointLightShadows: lights.shadowsPointLight, + numClippingPlanes: nClipPlanes, shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0, shadowMapType: renderer.shadowMap.type, + toneMapping: renderer.toneMapping, + physicallyCorrectLights: renderer.physicallyCorrectLights, + + premultipliedAlpha: material.premultipliedAlpha, + alphaTest: material.alphaTest, doubleSided: material.side === THREE.DoubleSide, - flipSided: material.side === THREE.BackSide + flipSided: material.side === THREE.BackSide, + + depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false }; @@ -30228,16 +30010,16 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { this.getProgramCode = function ( material, parameters ) { - var chunks = []; + var array = []; if ( parameters.shaderID ) { - chunks.push( parameters.shaderID ); + array.push( parameters.shaderID ); } else { - chunks.push( material.fragmentShader ); - chunks.push( material.vertexShader ); + array.push( material.fragmentShader ); + array.push( material.vertexShader ); } @@ -30245,8 +30027,8 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { for ( var name in material.defines ) { - chunks.push( name ); - chunks.push( material.defines[ name ] ); + array.push( name ); + array.push( material.defines[ name ] ); } @@ -30254,13 +30036,11 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { for ( var i = 0; i < parameterNames.length; i ++ ) { - var parameterName = parameterNames[ i ]; - chunks.push( parameterName ); - chunks.push( parameters[ parameterName ] ); + array.push( parameters[ parameterNames[ i ] ] ); } - return chunks.join(); + return array.join(); }; @@ -30416,6 +30196,10 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { _frustum = new THREE.Frustum(), _projScreenMatrix = new THREE.Matrix4(), + _lightShadows = _lights.shadows, + + _shadowMapSize = new THREE.Vector2(), + _lookTarget = new THREE.Vector3(), _lightPositionWorld = new THREE.Vector3(), @@ -30427,7 +30211,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { _NumberOfMaterialVariants = ( _MorphingFlag | _SkinningFlag ) + 1, _depthMaterials = new Array( _NumberOfMaterialVariants ), - _distanceMaterials = new Array( _NumberOfMaterialVariants ); + _distanceMaterials = new Array( _NumberOfMaterialVariants ), + + _materialCache = {}; var cubeDirections = [ new THREE.Vector3( 1, 0, 0 ), new THREE.Vector3( - 1, 0, 0 ), new THREE.Vector3( 0, 0, 1 ), @@ -30446,8 +30232,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { // init - var depthShader = THREE.ShaderLib[ "depthRGBA" ]; - var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms ); + var depthMaterialTemplate = new THREE.MeshDepthMaterial(); + depthMaterialTemplate.depthPacking = THREE.RGBADepthPacking; + depthMaterialTemplate.clipping = true; var distanceShader = THREE.ShaderLib[ "distanceRGBA" ]; var distanceUniforms = THREE.UniformsUtils.clone( distanceShader.uniforms ); @@ -30457,28 +30244,24 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { var useMorphing = ( i & _MorphingFlag ) !== 0; var useSkinning = ( i & _SkinningFlag ) !== 0; - var depthMaterial = new THREE.ShaderMaterial( { - uniforms: depthUniforms, - vertexShader: depthShader.vertexShader, - fragmentShader: depthShader.fragmentShader, - morphTargets: useMorphing, - skinning: useSkinning - } ); - - depthMaterial._shadowPass = true; + var depthMaterial = depthMaterialTemplate.clone(); + depthMaterial.morphTargets = useMorphing; + depthMaterial.skinning = useSkinning; _depthMaterials[ i ] = depthMaterial; var distanceMaterial = new THREE.ShaderMaterial( { + defines: { + 'USE_SHADOWMAP': '' + }, uniforms: distanceUniforms, vertexShader: distanceShader.vertexShader, fragmentShader: distanceShader.fragmentShader, morphTargets: useMorphing, - skinning: useSkinning + skinning: useSkinning, + clipping: true } ); - distanceMaterial._shadowPass = true; - _distanceMaterials[ i ] = distanceMaterial; } @@ -30493,43 +30276,50 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { this.needsUpdate = false; this.type = THREE.PCFShadowMap; - this.cullFace = THREE.CullFaceFront; + + this.renderReverseSided = true; + this.renderSingleSided = true; this.render = function ( scene, camera ) { - var faceCount, isPointLight; - if ( scope.enabled === false ) return; if ( scope.autoUpdate === false && scope.needsUpdate === false ) return; + if ( _lightShadows.length === 0 ) return; + // Set GL state for depth map. _state.clearColor( 1, 1, 1, 1 ); _state.disable( _gl.BLEND ); - _state.enable( _gl.CULL_FACE ); - _gl.frontFace( _gl.CCW ); - _gl.cullFace( scope.cullFace === THREE.CullFaceFront ? _gl.FRONT : _gl.BACK ); _state.setDepthTest( true ); _state.setScissorTest( false ); // render depth map - var shadows = _lights.shadows; + var faceCount, isPointLight; - for ( var i = 0, il = shadows.length; i < il; i ++ ) { - - var light = shadows[ i ]; + for ( var i = 0, il = _lightShadows.length; i < il; i ++ ) { + var light = _lightShadows[ i ]; var shadow = light.shadow; + + if ( shadow === undefined ) { + + console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' ); + continue; + + } + var shadowCamera = shadow.camera; - var shadowMapSize = shadow.mapSize; + + _shadowMapSize.copy( shadow.mapSize ); if ( light instanceof THREE.PointLight ) { faceCount = 6; isPointLight = true; - var vpWidth = shadowMapSize.x / 4.0; - var vpHeight = shadowMapSize.y / 2.0; + var vpWidth = _shadowMapSize.x; + var vpHeight = _shadowMapSize.y; // These viewports map a cube-map onto a 2D texture with the // following orientation: @@ -30557,6 +30347,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { // negative Y cube2DViewPorts[ 5 ].set( vpWidth, 0, vpWidth, vpHeight ); + _shadowMapSize.x *= 4.0; + _shadowMapSize.y *= 2.0; + } else { faceCount = 1; @@ -30566,22 +30359,20 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { if ( shadow.map === null ) { - var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat }; + var pars = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat }; - shadow.map = new THREE.WebGLRenderTarget( shadowMapSize.x, shadowMapSize.y, pars ); - - // - - if ( light instanceof THREE.SpotLight ) { - - shadowCamera.aspect = shadowMapSize.x / shadowMapSize.y; - - } + shadow.map = new THREE.WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars ); shadowCamera.updateProjectionMatrix(); } + if ( shadow instanceof THREE.SpotLightShadow ) { + + shadow.update( light ); + + } + var shadowMap = shadow.map; var shadowMatrix = shadow.matrix; @@ -30678,10 +30469,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { } - // We must call _renderer.resetGLState() at the end of each iteration of - // the light loop in order to force material updates for each light. - _renderer.resetGLState(); - } // Restore GL state. @@ -30689,16 +30476,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { clearAlpha = _renderer.getClearAlpha(); _renderer.setClearColor( clearColor, clearAlpha ); - _state.enable( _gl.BLEND ); - - if ( scope.cullFace === THREE.CullFaceFront ) { - - _gl.cullFace( _gl.BACK ); - - } - - _renderer.resetGLState(); - scope.needsUpdate = false; }; @@ -30707,7 +30484,7 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { var geometry = object.geometry; - var newMaterial = null; + var result = null; var materialVariants = _depthMaterials; var customMaterial = object.customDepthMaterial; @@ -30731,25 +30508,78 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) { if ( useMorphing ) variantIndex |= _MorphingFlag; if ( useSkinning ) variantIndex |= _SkinningFlag; - newMaterial = materialVariants[ variantIndex ]; + result = materialVariants[ variantIndex ]; } else { - newMaterial = customMaterial; + result = customMaterial; } - newMaterial.visible = material.visible; - newMaterial.wireframe = material.wireframe; - newMaterial.wireframeLinewidth = material.wireframeLinewidth; + if ( _renderer.localClippingEnabled && + material.clipShadows === true && + material.clippingPlanes.length !== 0 ) { - if ( isPointLight && newMaterial.uniforms.lightPos !== undefined ) { + // in this case we need a unique material instance reflecting the + // appropriate state - newMaterial.uniforms.lightPos.value.copy( lightPositionWorld ); + var keyA = result.uuid, keyB = material.uuid; + + var materialsForVariant = _materialCache[ keyA ]; + + if ( materialsForVariant === undefined ) { + + materialsForVariant = {}; + _materialCache[ keyA ] = materialsForVariant; + + } + + var cachedMaterial = materialsForVariant[ keyB ]; + + if ( cachedMaterial === undefined ) { + + cachedMaterial = result.clone(); + materialsForVariant[ keyB ] = cachedMaterial; + + } + + result = cachedMaterial; } - return newMaterial; + result.visible = material.visible; + result.wireframe = material.wireframe; + + var side = material.side; + + if ( scope.renderSingleSided && side == THREE.DoubleSide ) { + + side = THREE.FrontSide; + + } + + if ( scope.renderReverseSided ) { + + if ( side === THREE.FrontSide ) side = THREE.BackSide; + else if ( side === THREE.BackSide ) side = THREE.FrontSide; + + } + + result.side = side; + + result.clipShadows = material.clipShadows; + result.clippingPlanes = material.clippingPlanes; + + result.wireframeLinewidth = material.wireframeLinewidth; + result.linewidth = material.linewidth; + + if ( isPointLight && result.uniforms.lightPos !== undefined ) { + + result.uniforms.lightPos.value.copy( lightPositionWorld ); + + } + + return result; } @@ -30796,11 +30626,16 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { var _this = this; - var color = new THREE.Vector4(); + this.buffers = { + color: new THREE.WebGLColorBuffer( gl, this ), + depth: new THREE.WebGLDepthBuffer( gl, this ), + stencil: new THREE.WebGLStencilBuffer( gl, this ) + }; - var newAttributes = new Uint8Array( 16 ); - var enabledAttributes = new Uint8Array( 16 ); - var attributeDivisors = new Uint8Array( 16 ); + var maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS ); + var newAttributes = new Uint8Array( maxVertexAttributes ); + var enabledAttributes = new Uint8Array( maxVertexAttributes ); + var attributeDivisors = new Uint8Array( maxVertexAttributes ); var capabilities = {}; @@ -30813,21 +30648,10 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { var currentBlendEquationAlpha = null; var currentBlendSrcAlpha = null; var currentBlendDstAlpha = null; - - var currentDepthFunc = null; - var currentDepthWrite = null; - - var currentColorWrite = null; - - var currentStencilWrite = null; - var currentStencilFunc = null; - var currentStencilRef = null; - var currentStencilMask = null; - var currentStencilFail = null; - var currentStencilZFail = null; - var currentStencilZPass = null; + var currentPremultipledAlpha = false; var currentFlipSided = null; + var currentCullFace = null; var currentLineWidth = null; @@ -30838,16 +30662,37 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS ); - var currentTextureSlot = undefined; + var currentTextureSlot = null; var currentBoundTextures = {}; - var currentClearColor = new THREE.Vector4(); - var currentClearDepth = null; - var currentClearStencil = null; - var currentScissor = new THREE.Vector4(); var currentViewport = new THREE.Vector4(); + function createTexture( type, target, count ) { + + var data = new Uint8Array( 3 ); + var texture = gl.createTexture(); + + gl.bindTexture( type, texture ); + gl.texParameteri( type, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); + gl.texParameteri( type, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); + + for ( var i = 0; i < count; i ++ ) { + + gl.texImage2D( target + i, 0, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, data ); + + } + + return texture; + + } + + var emptyTextures = {}; + emptyTextures[ gl.TEXTURE_2D ] = createTexture( gl.TEXTURE_2D, gl.TEXTURE_2D, 1 ); + emptyTextures[ gl.TEXTURE_CUBE_MAP ] = createTexture( gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6 ); + + // + this.init = function () { this.clearColor( 0, 0, 0, 1 ); @@ -30855,15 +30700,14 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { this.clearStencil( 0 ); this.enable( gl.DEPTH_TEST ); - gl.depthFunc( gl.LEQUAL ); + this.setDepthFunc( THREE.LessEqualDepth ); - gl.frontFace( gl.CCW ); - gl.cullFace( gl.BACK ); + this.setFlipSided( false ); + this.setCullFace( THREE.CullFaceBack ); this.enable( gl.CULL_FACE ); this.enable( gl.BLEND ); - gl.blendEquation( gl.FUNC_ADD ); - gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA ); + this.setBlending( THREE.NormalBlending ); }; @@ -30921,7 +30765,7 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { this.disableUnusedAttributes = function () { - for ( var i = 0, l = enabledAttributes.length; i < l; i ++ ) { + for ( var i = 0, l = enabledAttributes.length; i !== l; ++ i ) { if ( enabledAttributes[ i ] !== newAttributes[ i ] ) { @@ -30964,7 +30808,7 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { if ( extensions.get( 'WEBGL_compressed_texture_pvrtc' ) || extensions.get( 'WEBGL_compressed_texture_s3tc' ) || - extensions.get( 'WEBGL_compressed_texture_etc1' )) { + extensions.get( 'WEBGL_compressed_texture_etc1' ) ) { var formats = gl.getParameter( gl.COMPRESSED_TEXTURE_FORMATS ); @@ -30982,47 +30826,82 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { }; - this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) { + this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) { - if ( blending === THREE.NoBlending ) { - - this.disable( gl.BLEND ); - - } else { + if ( blending !== THREE.NoBlending ) { this.enable( gl.BLEND ); + } else { + + this.disable( gl.BLEND ); + currentBlending = blending; // no blending, that is + return; + } - if ( blending !== currentBlending ) { + if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) { if ( blending === THREE.AdditiveBlending ) { - gl.blendEquation( gl.FUNC_ADD ); - gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); + if ( premultipliedAlpha ) { + + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ONE, gl.ONE, gl.ONE, gl.ONE ); + + } else { + + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.SRC_ALPHA, gl.ONE ); + + } } else if ( blending === THREE.SubtractiveBlending ) { - // TODO: Find blendFuncSeparate() combination + if ( premultipliedAlpha ) { - gl.blendEquation( gl.FUNC_ADD ); - gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA ); + + } else { + + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR ); + + } } else if ( blending === THREE.MultiplyBlending ) { - // TODO: Find blendFuncSeparate() combination + if ( premultipliedAlpha ) { - gl.blendEquation( gl.FUNC_ADD ); - gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA ); + + } else { + + gl.blendEquation( gl.FUNC_ADD ); + gl.blendFunc( gl.ZERO, gl.SRC_COLOR ); + + } } else { - gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); - gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + if ( premultipliedAlpha ) { + + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + + } else { + + gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD ); + gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA ); + + } } currentBlending = blending; + currentPremultipledAlpha = premultipliedAlpha; } @@ -31065,8 +30944,403 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { }; + // TODO Deprecate + + this.setColorWrite = function ( colorWrite ) { + + this.buffers.color.setMask( colorWrite ); + + }; + + this.setDepthTest = function ( depthTest ) { + + this.buffers.depth.setTest( depthTest ); + + }; + + this.setDepthWrite = function ( depthWrite ) { + + this.buffers.depth.setMask( depthWrite ); + + }; + this.setDepthFunc = function ( depthFunc ) { + this.buffers.depth.setFunc( depthFunc ); + + }; + + this.setStencilTest = function ( stencilTest ) { + + this.buffers.stencil.setTest( stencilTest ); + + }; + + this.setStencilWrite = function ( stencilWrite ) { + + this.buffers.stencil.setMask( stencilWrite ); + + }; + + this.setStencilFunc = function ( stencilFunc, stencilRef, stencilMask ) { + + this.buffers.stencil.setFunc( stencilFunc, stencilRef, stencilMask ); + + }; + + this.setStencilOp = function ( stencilFail, stencilZFail, stencilZPass ) { + + this.buffers.stencil.setOp( stencilFail, stencilZFail, stencilZPass ); + + }; + + // + + this.setFlipSided = function ( flipSided ) { + + if ( currentFlipSided !== flipSided ) { + + if ( flipSided ) { + + gl.frontFace( gl.CW ); + + } else { + + gl.frontFace( gl.CCW ); + + } + + currentFlipSided = flipSided; + + } + + }; + + this.setCullFace = function ( cullFace ) { + + if ( cullFace !== THREE.CullFaceNone ) { + + this.enable( gl.CULL_FACE ); + + if ( cullFace !== currentCullFace ) { + + if ( cullFace === THREE.CullFaceBack ) { + + gl.cullFace( gl.BACK ); + + } else if ( cullFace === THREE.CullFaceFront ) { + + gl.cullFace( gl.FRONT ); + + } else { + + gl.cullFace( gl.FRONT_AND_BACK ); + + } + + } + + } else { + + this.disable( gl.CULL_FACE ); + + } + + currentCullFace = cullFace; + + }; + + this.setLineWidth = function ( width ) { + + if ( width !== currentLineWidth ) { + + gl.lineWidth( width ); + + currentLineWidth = width; + + } + + }; + + this.setPolygonOffset = function ( polygonOffset, factor, units ) { + + if ( polygonOffset ) { + + this.enable( gl.POLYGON_OFFSET_FILL ); + + if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) { + + gl.polygonOffset( factor, units ); + + currentPolygonOffsetFactor = factor; + currentPolygonOffsetUnits = units; + + } + + } else { + + this.disable( gl.POLYGON_OFFSET_FILL ); + + } + + }; + + this.getScissorTest = function () { + + return currentScissorTest; + + }; + + this.setScissorTest = function ( scissorTest ) { + + currentScissorTest = scissorTest; + + if ( scissorTest ) { + + this.enable( gl.SCISSOR_TEST ); + + } else { + + this.disable( gl.SCISSOR_TEST ); + + } + + }; + + // texture + + this.activeTexture = function ( webglSlot ) { + + if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; + + if ( currentTextureSlot !== webglSlot ) { + + gl.activeTexture( webglSlot ); + currentTextureSlot = webglSlot; + + } + + }; + + this.bindTexture = function ( webglType, webglTexture ) { + + if ( currentTextureSlot === null ) { + + _this.activeTexture(); + + } + + var boundTexture = currentBoundTextures[ currentTextureSlot ]; + + if ( boundTexture === undefined ) { + + boundTexture = { type: undefined, texture: undefined }; + currentBoundTextures[ currentTextureSlot ] = boundTexture; + + } + + if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { + + gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] ); + + boundTexture.type = webglType; + boundTexture.texture = webglTexture; + + } + + }; + + this.compressedTexImage2D = function () { + + try { + + gl.compressedTexImage2D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( error ); + + } + + }; + + this.texImage2D = function () { + + try { + + gl.texImage2D.apply( gl, arguments ); + + } catch ( error ) { + + console.error( error ); + + } + + }; + + // TODO Deprecate + + this.clearColor = function ( r, g, b, a ) { + + this.buffers.color.setClear( r, g, b, a ); + + }; + + this.clearDepth = function ( depth ) { + + this.buffers.depth.setClear( depth ); + + }; + + this.clearStencil = function ( stencil ) { + + this.buffers.stencil.setClear( stencil ); + + }; + + // + + this.scissor = function ( scissor ) { + + if ( currentScissor.equals( scissor ) === false ) { + + gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); + currentScissor.copy( scissor ); + + } + + }; + + this.viewport = function ( viewport ) { + + if ( currentViewport.equals( viewport ) === false ) { + + gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); + currentViewport.copy( viewport ); + + } + + }; + + // + + this.reset = function () { + + for ( var i = 0; i < enabledAttributes.length; i ++ ) { + + if ( enabledAttributes[ i ] === 1 ) { + + gl.disableVertexAttribArray( i ); + enabledAttributes[ i ] = 0; + + } + + } + + capabilities = {}; + + compressedTextureFormats = null; + + currentTextureSlot = null; + currentBoundTextures = {}; + + currentBlending = null; + + currentFlipSided = null; + currentCullFace = null; + + this.buffers.color.reset(); + this.buffers.depth.reset(); + this.buffers.stencil.reset(); + + }; + +}; + +THREE.WebGLColorBuffer = function ( gl, state ) { + + var locked = false; + + var color = new THREE.Vector4(); + var currentColorMask = null; + var currentColorClear = new THREE.Vector4(); + + this.setMask = function ( colorMask ) { + + if ( currentColorMask !== colorMask && ! locked ) { + + gl.colorMask( colorMask, colorMask, colorMask, colorMask ); + currentColorMask = colorMask; + + } + + }; + + this.setLocked = function ( lock ) { + + locked = lock; + + }; + + this.setClear = function ( r, g, b, a ) { + + color.set( r, g, b, a ); + + if ( currentColorClear.equals( color ) === false ) { + + gl.clearColor( r, g, b, a ); + currentColorClear.copy( color ); + + } + + }; + + this.reset = function () { + + locked = false; + + currentColorMask = null; + currentColorClear = new THREE.Vector4(); + + }; + +}; + +THREE.WebGLDepthBuffer = function( gl, state ) { + + var locked = false; + + var currentDepthMask = null; + var currentDepthFunc = null; + var currentDepthClear = null; + + this.setTest = function ( depthTest ) { + + if ( depthTest ) { + + state.enable( gl.DEPTH_TEST ); + + } else { + + state.disable( gl.DEPTH_TEST ); + + } + + }; + + this.setMask = function( depthMask ){ + + if ( currentDepthMask !== depthMask && ! locked ) { + + gl.depthMask( depthMask ); + currentDepthMask = depthMask; + + } + + }; + + this.setFunc = function ( depthFunc ) { + if ( currentDepthFunc !== depthFunc ) { if ( depthFunc ) { @@ -31131,67 +31405,94 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { }; - this.setDepthTest = function ( depthTest ) { + this.setLocked = function ( lock ) { - if ( depthTest ) { + locked = lock; - this.enable( gl.DEPTH_TEST ); + }; + + this.setClear = function ( depth ) { + + if ( currentDepthClear !== depth ) { + + gl.clearDepth( depth ); + currentDepthClear = depth; + + } + + }; + + this.reset = function () { + + locked = false; + + currentDepthMask = null; + currentDepthFunc = null; + currentDepthClear = null; + + }; + +}; + +THREE.WebGLStencilBuffer = function ( gl, state ) { + + var locked = false; + + var currentStencilMask = null; + var currentStencilFunc = null; + var currentStencilRef = null; + var currentStencilFuncMask = null; + var currentStencilFail = null; + var currentStencilZFail = null; + var currentStencilZPass = null; + var currentStencilClear = null; + + this.setTest = function ( stencilTest ) { + + if ( stencilTest ) { + + state.enable( gl.STENCIL_TEST ); } else { - this.disable( gl.DEPTH_TEST ); + state.disable( gl.STENCIL_TEST ); } }; - this.setDepthWrite = function ( depthWrite ) { + this.setMask = function ( stencilMask ) { - // TODO: Rename to setDepthMask + if ( currentStencilMask !== stencilMask && ! locked ) { - if ( currentDepthWrite !== depthWrite ) { - - gl.depthMask( depthWrite ); - currentDepthWrite = depthWrite; - - } - - }; - - this.setColorWrite = function ( colorWrite ) { - - // TODO: Rename to setColorMask - - if ( currentColorWrite !== colorWrite ) { - - gl.colorMask( colorWrite, colorWrite, colorWrite, colorWrite ); - currentColorWrite = colorWrite; - - } - - }; - - this.setStencilFunc = function ( stencilFunc, stencilRef, stencilMask ) { - - if ( currentStencilFunc !== stencilFunc || - currentStencilRef !== stencilRef || - currentStencilMask !== stencilMask ) { - - gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); - - currentStencilFunc = stencilFunc; - currentStencilRef = stencilRef; + gl.stencilMask( stencilMask ); currentStencilMask = stencilMask; } }; - this.setStencilOp = function ( stencilFail, stencilZFail, stencilZPass ) { + this.setFunc = function ( stencilFunc, stencilRef, stencilMask ) { + + if ( currentStencilFunc !== stencilFunc || + currentStencilRef !== stencilRef || + currentStencilFuncMask !== stencilMask ) { + + gl.stencilFunc( stencilFunc, stencilRef, stencilMask ); + + currentStencilFunc = stencilFunc; + currentStencilRef = stencilRef; + currentStencilFuncMask = stencilMask; + + } + + }; + + this.setOp = function ( stencilFail, stencilZFail, stencilZPass ) { if ( currentStencilFail !== stencilFail || - currentStencilZFail !== stencilZFail || - currentStencilZPass !== stencilZPass ) { + currentStencilZFail !== stencilZFail || + currentStencilZPass !== stencilZPass ) { gl.stencilOp( stencilFail, stencilZFail, stencilZPass ); @@ -31203,273 +31504,645 @@ THREE.WebGLState = function ( gl, extensions, paramThreeToGL ) { }; - this.setStencilTest = function ( stencilTest ) { + this.setLocked = function ( lock ) { - if ( stencilTest ) { - - this.enable( gl.STENCIL_TEST ); - - } else { - - this.disable( gl.STENCIL_TEST ); - - } + locked = lock; }; - this.setStencilWrite = function ( stencilWrite ) { + this.setClear = function ( stencil ) { - // TODO: Rename to setStencilMask - - if ( currentStencilWrite !== stencilWrite ) { - - gl.stencilMask( stencilWrite ); - currentStencilWrite = stencilWrite; - - } - - }; - - this.setFlipSided = function ( flipSided ) { - - if ( currentFlipSided !== flipSided ) { - - if ( flipSided ) { - - gl.frontFace( gl.CW ); - - } else { - - gl.frontFace( gl.CCW ); - - } - - currentFlipSided = flipSided; - - } - - }; - - this.setLineWidth = function ( width ) { - - if ( width !== currentLineWidth ) { - - gl.lineWidth( width ); - - currentLineWidth = width; - - } - - }; - - this.setPolygonOffset = function ( polygonOffset, factor, units ) { - - if ( polygonOffset ) { - - this.enable( gl.POLYGON_OFFSET_FILL ); - - } else { - - this.disable( gl.POLYGON_OFFSET_FILL ); - - } - - if ( polygonOffset && ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) ) { - - gl.polygonOffset( factor, units ); - - currentPolygonOffsetFactor = factor; - currentPolygonOffsetUnits = units; - - } - - }; - - this.getScissorTest = function () { - - return currentScissorTest; - - }; - - this.setScissorTest = function ( scissorTest ) { - - currentScissorTest = scissorTest; - - if ( scissorTest ) { - - this.enable( gl.SCISSOR_TEST ); - - } else { - - this.disable( gl.SCISSOR_TEST ); - - } - - }; - - // texture - - this.activeTexture = function ( webglSlot ) { - - if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1; - - if ( currentTextureSlot !== webglSlot ) { - - gl.activeTexture( webglSlot ); - currentTextureSlot = webglSlot; - - } - - }; - - this.bindTexture = function ( webglType, webglTexture ) { - - if ( currentTextureSlot === undefined ) { - - _this.activeTexture(); - - } - - var boundTexture = currentBoundTextures[ currentTextureSlot ]; - - if ( boundTexture === undefined ) { - - boundTexture = { type: undefined, texture: undefined }; - currentBoundTextures[ currentTextureSlot ] = boundTexture; - - } - - if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) { - - gl.bindTexture( webglType, webglTexture ); - - boundTexture.type = webglType; - boundTexture.texture = webglTexture; - - } - - }; - - this.compressedTexImage2D = function () { - - try { - - gl.compressedTexImage2D.apply( gl, arguments ); - - } catch ( error ) { - - console.error( error ); - - } - - }; - - this.texImage2D = function () { - - try { - - gl.texImage2D.apply( gl, arguments ); - - } catch ( error ) { - - console.error( error ); - - } - - }; - - // clear values - - this.clearColor = function ( r, g, b, a ) { - - color.set( r, g, b, a ); - - if ( currentClearColor.equals( color ) === false ) { - - gl.clearColor( r, g, b, a ); - currentClearColor.copy( color ); - - } - - }; - - this.clearDepth = function ( depth ) { - - if ( currentClearDepth !== depth ) { - - gl.clearDepth( depth ); - currentClearDepth = depth; - - } - - }; - - this.clearStencil = function ( stencil ) { - - if ( currentClearStencil !== stencil ) { + if ( currentStencilClear !== stencil ) { gl.clearStencil( stencil ); - currentClearStencil = stencil; + currentStencilClear = stencil; } }; - // - - this.scissor = function ( scissor ) { - - if ( currentScissor.equals( scissor ) === false ) { - - gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w ); - currentScissor.copy( scissor ); - - } - - }; - - this.viewport = function ( viewport ) { - - if ( currentViewport.equals( viewport ) === false ) { - - gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w ); - currentViewport.copy( viewport ); - - } - - }; - - // - this.reset = function () { - for ( var i = 0; i < enabledAttributes.length; i ++ ) { + locked = false; - if ( enabledAttributes[ i ] === 1 ) { - - gl.disableVertexAttribArray( i ); - enabledAttributes[ i ] = 0; - - } - - } - - capabilities = {}; - - compressedTextureFormats = null; - - currentBlending = null; - - currentColorWrite = null; - currentDepthWrite = null; - currentStencilWrite = null; - - currentFlipSided = null; + currentStencilMask = null; + currentStencilFunc = null; + currentStencilRef = null; + currentStencilFuncMask = null; + currentStencilFail = null; + currentStencilZFail = null; + currentStencilZPass = null; + currentStencilClear = null; }; }; +// File:src/renderers/webgl/WebGLUniforms.js + +/** + * + * Uniforms of a program. + * Those form a tree structure with a special top-level container for the root, + * which you get by calling 'new WebGLUniforms( gl, program, renderer )'. + * + * + * Properties of inner nodes including the top-level container: + * + * .seq - array of nested uniforms + * .map - nested uniforms by name + * + * + * Methods of all nodes except the top-level container: + * + * .setValue( gl, value, [renderer] ) + * + * uploads a uniform value(s) + * the 'renderer' parameter is needed for sampler uniforms + * + * + * Static methods of the top-level container (renderer factorizations): + * + * .upload( gl, seq, values, renderer ) + * + * sets uniforms in 'seq' to 'values[id].value' + * + * .seqWithValue( seq, values ) : filteredSeq + * + * filters 'seq' entries with corresponding entry in values + * + * .splitDynamic( seq, values ) : filteredSeq + * + * filters 'seq' entries with dynamic entry and removes them from 'seq' + * + * + * Methods of the top-level container (renderer factorizations): + * + * .setValue( gl, name, value ) + * + * sets uniform with name 'name' to 'value' + * + * .set( gl, obj, prop ) + * + * sets uniform from object and property with same name than uniform + * + * .setOptional( gl, obj, prop ) + * + * like .set for an optional property of the object + * + * + * @author tschw + * + */ + +THREE.WebGLUniforms = ( function() { // scope + + // --- Base for inner nodes (including the root) --- + + var UniformContainer = function() { + + this.seq = []; + this.map = {}; + + }, + + // --- Utilities --- + + // Array Caches (provide typed arrays for temporary by size) + + arrayCacheF32 = [], + arrayCacheI32 = [], + + uncacheTemporaryArrays = function() { + + arrayCacheF32.length = 0; + arrayCacheI32.length = 0; + + }, + + // Flattening for arrays of vectors and matrices + + flatten = function( array, nBlocks, blockSize ) { + + var firstElem = array[ 0 ]; + + if ( firstElem <= 0 || firstElem > 0 ) return array; + // unoptimized: ! isNaN( firstElem ) + // see http://jacksondunstan.com/articles/983 + + var n = nBlocks * blockSize, + r = arrayCacheF32[ n ]; + + if ( r === undefined ) { + + r = new Float32Array( n ); + arrayCacheF32[ n ] = r; + + } + + if ( nBlocks !== 0 ) { + + firstElem.toArray( r, 0 ); + + for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) { + + offset += blockSize; + array[ i ].toArray( r, offset ); + + } + + } + + return r; + + }, + + // Texture unit allocation + + allocTexUnits = function( renderer, n ) { + + var r = arrayCacheI32[ n ]; + + if ( r === undefined ) { + + r = new Int32Array( n ); + arrayCacheI32[ n ] = r; + + } + + for ( var i = 0; i !== n; ++ i ) + r[ i ] = renderer.allocTextureUnit(); + + return r; + + }, + + // --- Setters --- + + // Note: Defining these methods externally, because they come in a bunch + // and this way their names minify. + + // Single scalar + + setValue1f = function( gl, v ) { gl.uniform1f( this.addr, v ); }, + setValue1i = function( gl, v ) { gl.uniform1i( this.addr, v ); }, + + // Single float vector (from flat array or THREE.VectorN) + + setValue2fv = function( gl, v ) { + + if ( v.x === undefined ) gl.uniform2fv( this.addr, v ); + else gl.uniform2f( this.addr, v.x, v.y ); + + }, + + setValue3fv = function( gl, v ) { + + if ( v.x !== undefined ) + gl.uniform3f( this.addr, v.x, v.y, v.z ); + else if ( v.r !== undefined ) + gl.uniform3f( this.addr, v.r, v.g, v.b ); + else + gl.uniform3fv( this.addr, v ); + + }, + + setValue4fv = function( gl, v ) { + + if ( v.x === undefined ) gl.uniform4fv( this.addr, v ); + else gl.uniform4f( this.addr, v.x, v.y, v.z, v.w ); + + }, + + // Single matrix (from flat array or MatrixN) + + setValue2fm = function( gl, v ) { + + gl.uniformMatrix2fv( this.addr, false, v.elements || v ); + + }, + + setValue3fm = function( gl, v ) { + + gl.uniformMatrix3fv( this.addr, false, v.elements || v ); + + }, + + setValue4fm = function( gl, v ) { + + gl.uniformMatrix4fv( this.addr, false, v.elements || v ); + + }, + + // Single texture (2D / Cube) + + setValueT1 = function( gl, v, renderer ) { + + var unit = renderer.allocTextureUnit(); + gl.uniform1i( this.addr, unit ); + if ( v ) renderer.setTexture2D( v, unit ); + + }, + + setValueT6 = function( gl, v, renderer ) { + + var unit = renderer.allocTextureUnit(); + gl.uniform1i( this.addr, unit ); + if ( v ) renderer.setTextureCube( v, unit ); + + }, + + // Integer / Boolean vectors or arrays thereof (always flat arrays) + + setValue2iv = function( gl, v ) { gl.uniform2iv( this.addr, v ); }, + setValue3iv = function( gl, v ) { gl.uniform3iv( this.addr, v ); }, + setValue4iv = function( gl, v ) { gl.uniform4iv( this.addr, v ); }, + + // Helper to pick the right setter for the singular case + + getSingularSetter = function( type ) { + + switch ( type ) { + + case 0x1406: return setValue1f; // FLOAT + case 0x8b50: return setValue2fv; // _VEC2 + case 0x8b51: return setValue3fv; // _VEC3 + case 0x8b52: return setValue4fv; // _VEC4 + + case 0x8b5a: return setValue2fm; // _MAT2 + case 0x8b5b: return setValue3fm; // _MAT3 + case 0x8b5c: return setValue4fm; // _MAT4 + + case 0x8b5e: return setValueT1; // SAMPLER_2D + case 0x8b60: return setValueT6; // SAMPLER_CUBE + + case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL + case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 + case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 + case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 + + } + + }, + + // Array of scalars + + setValue1fv = function( gl, v ) { gl.uniform1fv( this.addr, v ); }, + setValue1iv = function( gl, v ) { gl.uniform1iv( this.addr, v ); }, + + // Array of vectors (flat or from THREE classes) + + setValueV2a = function( gl, v ) { + + gl.uniform2fv( this.addr, flatten( v, this.size, 2 ) ); + + }, + + setValueV3a = function( gl, v ) { + + gl.uniform3fv( this.addr, flatten( v, this.size, 3 ) ); + + }, + + setValueV4a = function( gl, v ) { + + gl.uniform4fv( this.addr, flatten( v, this.size, 4 ) ); + + }, + + // Array of matrices (flat or from THREE clases) + + setValueM2a = function( gl, v ) { + + gl.uniformMatrix2fv( this.addr, false, flatten( v, this.size, 4 ) ); + + }, + + setValueM3a = function( gl, v ) { + + gl.uniformMatrix3fv( this.addr, false, flatten( v, this.size, 9 ) ); + + }, + + setValueM4a = function( gl, v ) { + + gl.uniformMatrix4fv( this.addr, false, flatten( v, this.size, 16 ) ); + + }, + + // Array of textures (2D / Cube) + + setValueT1a = function( gl, v, renderer ) { + + var n = v.length, + units = allocTexUnits( renderer, n ); + + gl.uniform1iv( this.addr, units ); + + for ( var i = 0; i !== n; ++ i ) { + + var tex = v[ i ]; + if ( tex ) renderer.setTexture2D( tex, units[ i ] ); + + } + + }, + + setValueT6a = function( gl, v, renderer ) { + + var n = v.length, + units = allocTexUnits( renderer, n ); + + gl.uniform1iv( this.addr, units ); + + for ( var i = 0; i !== n; ++ i ) { + + var tex = v[ i ]; + if ( tex ) renderer.setTextureCube( tex, units[ i ] ); + + } + + }, + + + // Helper to pick the right setter for a pure (bottom-level) array + + getPureArraySetter = function( type ) { + + switch ( type ) { + + case 0x1406: return setValue1fv; // FLOAT + case 0x8b50: return setValueV2a; // _VEC2 + case 0x8b51: return setValueV3a; // _VEC3 + case 0x8b52: return setValueV4a; // _VEC4 + + case 0x8b5a: return setValueM2a; // _MAT2 + case 0x8b5b: return setValueM3a; // _MAT3 + case 0x8b5c: return setValueM4a; // _MAT4 + + case 0x8b5e: return setValueT1a; // SAMPLER_2D + case 0x8b60: return setValueT6a; // SAMPLER_CUBE + + case 0x1404: case 0x8b56: return setValue1iv; // INT, BOOL + case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 + case 0x8b54: case 0x8b58: return setValue3iv; // _VEC3 + case 0x8b55: case 0x8b59: return setValue4iv; // _VEC4 + + } + + }, + + // --- Uniform Classes --- + + SingleUniform = function SingleUniform( id, activeInfo, addr ) { + + this.id = id; + this.addr = addr; + this.setValue = getSingularSetter( activeInfo.type ); + + // this.path = activeInfo.name; // DEBUG + + }, + + PureArrayUniform = function( id, activeInfo, addr ) { + + this.id = id; + this.addr = addr; + this.size = activeInfo.size; + this.setValue = getPureArraySetter( activeInfo.type ); + + // this.path = activeInfo.name; // DEBUG + + }, + + StructuredUniform = function( id ) { + + this.id = id; + + UniformContainer.call( this ); // mix-in + + }; + + StructuredUniform.prototype.setValue = function( gl, value ) { + + // Note: Don't need an extra 'renderer' parameter, since samplers + // are not allowed in structured uniforms. + + var seq = this.seq; + + for ( var i = 0, n = seq.length; i !== n; ++ i ) { + + var u = seq[ i ]; + u.setValue( gl, value[ u.id ] ); + + } + + }; + + // --- Top-level --- + + // Parser - builds up the property tree from the path strings + + var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g, + // extracts + // - the identifier (member name or array index) + // - followed by an optional right bracket (found when array index) + // - followed by an optional left bracket or dot (type of subscript) + // + // Note: These portions can be read in a non-overlapping fashion and + // allow straightforward parsing of the hierarchy that WebGL encodes + // in the uniform names. + + addUniform = function( container, uniformObject ) { + + container.seq.push( uniformObject ); + container.map[ uniformObject.id ] = uniformObject; + + }, + + parseUniform = function( activeInfo, addr, container ) { + + var path = activeInfo.name, + pathLength = path.length; + + // reset RegExp object, because of the early exit of a previous run + RePathPart.lastIndex = 0; + + for (; ;) { + + var match = RePathPart.exec( path ), + matchEnd = RePathPart.lastIndex, + + id = match[ 1 ], + idIsIndex = match[ 2 ] === ']', + subscript = match[ 3 ]; + + if ( idIsIndex ) id = id | 0; // convert to integer + + if ( subscript === undefined || + subscript === '[' && matchEnd + 2 === pathLength ) { + // bare name or "pure" bottom-level array "[0]" suffix + + addUniform( container, subscript === undefined ? + new SingleUniform( id, activeInfo, addr ) : + new PureArrayUniform( id, activeInfo, addr ) ); + + break; + + } else { + // step into inner node / create it in case it doesn't exist + + var map = container.map, + next = map[ id ]; + + if ( next === undefined ) { + + next = new StructuredUniform( id ); + addUniform( container, next ); + + } + + container = next; + + } + + } + + }, + + // Root Container + + WebGLUniforms = function WebGLUniforms( gl, program, renderer ) { + + UniformContainer.call( this ); + + this.renderer = renderer; + + var n = gl.getProgramParameter( program, gl.ACTIVE_UNIFORMS ); + + for ( var i = 0; i !== n; ++ i ) { + + var info = gl.getActiveUniform( program, i ), + path = info.name, + addr = gl.getUniformLocation( program, path ); + + parseUniform( info, addr, this ); + + } + + }; + + + WebGLUniforms.prototype.setValue = function( gl, name, value ) { + + var u = this.map[ name ]; + + if ( u !== undefined ) u.setValue( gl, value, this.renderer ); + + }; + + WebGLUniforms.prototype.set = function( gl, object, name ) { + + var u = this.map[ name ]; + + if ( u !== undefined ) u.setValue( gl, object[ name ], this.renderer ); + + }; + + WebGLUniforms.prototype.setOptional = function( gl, object, name ) { + + var v = object[ name ]; + + if ( v !== undefined ) this.setValue( gl, name, v ); + + }; + + + // Static interface + + WebGLUniforms.upload = function( gl, seq, values, renderer ) { + + for ( var i = 0, n = seq.length; i !== n; ++ i ) { + + var u = seq[ i ], + v = values[ u.id ]; + + if ( v.needsUpdate !== false ) { + // note: always updating when .needsUpdate is undefined + + u.setValue( gl, v.value, renderer ); + + } + + } + + }; + + WebGLUniforms.seqWithValue = function( seq, values ) { + + var r = []; + + for ( var i = 0, n = seq.length; i !== n; ++ i ) { + + var u = seq[ i ]; + if ( u.id in values ) r.push( u ); + + } + + return r; + + }; + + WebGLUniforms.splitDynamic = function( seq, values ) { + + var r = null, + n = seq.length, + w = 0; + + for ( var i = 0; i !== n; ++ i ) { + + var u = seq[ i ], + v = values[ u.id ]; + + if ( v && v.dynamic === true ) { + + if ( r === null ) r = []; + r.push( u ); + + } else { + + // in-place compact 'seq', removing the matches + if ( w < i ) seq[ w ] = u; + ++ w; + + } + + } + + if ( w < n ) seq.length = w; + + return r; + + }; + + WebGLUniforms.evalDynamic = function( seq, values, object, camera ) { + + for ( var i = 0, n = seq.length; i !== n; ++ i ) { + + var v = values[ seq[ i ].id ], + f = v.onUpdateCallback; + + if ( f !== undefined ) f.call( v, object, camera ); + + } + + }; + + return WebGLUniforms; + +} )(); + + // File:src/renderers/webgl/plugins/LensFlarePlugin.js /** @@ -31483,8 +32156,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { var state = renderer.state; var vertexBuffer, elementBuffer; - var program, attributes, uniforms; - var hasVertexTexture; + var shader, program, attributes, uniforms; var tempTexture, occlusionTexture; @@ -31532,193 +32204,99 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST ); gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST ); - hasVertexTexture = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) > 0; + shader = { - var shader; + vertexShader: [ - if ( hasVertexTexture ) { + "uniform lowp int renderType;", - shader = { + "uniform vec3 screenPosition;", + "uniform vec2 scale;", + "uniform float rotation;", - vertexShader: [ + "uniform sampler2D occlusionMap;", - "uniform lowp int renderType;", + "attribute vec2 position;", + "attribute vec2 uv;", - "uniform vec3 screenPosition;", - "uniform vec2 scale;", - "uniform float rotation;", + "varying vec2 vUV;", + "varying float vVisibility;", - "uniform sampler2D occlusionMap;", + "void main() {", - "attribute vec2 position;", - "attribute vec2 uv;", + "vUV = uv;", - "varying vec2 vUV;", - "varying float vVisibility;", + "vec2 pos = position;", - "void main() {", + "if ( renderType == 2 ) {", - "vUV = uv;", + "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );", + "visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );", - "vec2 pos = position;", + "vVisibility = visibility.r / 9.0;", + "vVisibility *= 1.0 - visibility.g / 9.0;", + "vVisibility *= visibility.b / 9.0;", + "vVisibility *= 1.0 - visibility.a / 9.0;", - "if ( renderType == 2 ) {", + "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;", + "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;", - "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );", + "}", - "vVisibility = visibility.r / 9.0;", - "vVisibility *= 1.0 - visibility.g / 9.0;", - "vVisibility *= visibility.b / 9.0;", - "vVisibility *= 1.0 - visibility.a / 9.0;", + "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );", - "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;", - "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;", + "}" - "}", + ].join( "\n" ), - "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );", + fragmentShader: [ - "}" + "uniform lowp int renderType;", - ].join( "\n" ), + "uniform sampler2D map;", + "uniform float opacity;", + "uniform vec3 color;", - fragmentShader: [ + "varying vec2 vUV;", + "varying float vVisibility;", - "uniform lowp int renderType;", + "void main() {", - "uniform sampler2D map;", - "uniform float opacity;", - "uniform vec3 color;", + // pink square - "varying vec2 vUV;", - "varying float vVisibility;", + "if ( renderType == 0 ) {", - "void main() {", + "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );", - // pink square + // restore - "if ( renderType == 0 ) {", + "} else if ( renderType == 1 ) {", - "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );", + "gl_FragColor = texture2D( map, vUV );", - // restore + // flare - "} else if ( renderType == 1 ) {", + "} else {", - "gl_FragColor = texture2D( map, vUV );", + "vec4 texture = texture2D( map, vUV );", + "texture.a *= opacity * vVisibility;", + "gl_FragColor = texture;", + "gl_FragColor.rgb *= color;", - // flare + "}", - "} else {", + "}" - "vec4 texture = texture2D( map, vUV );", - "texture.a *= opacity * vVisibility;", - "gl_FragColor = texture;", - "gl_FragColor.rgb *= color;", + ].join( "\n" ) - "}", - - "}" - - ].join( "\n" ) - - }; - - } else { - - shader = { - - vertexShader: [ - - "uniform lowp int renderType;", - - "uniform vec3 screenPosition;", - "uniform vec2 scale;", - "uniform float rotation;", - - "attribute vec2 position;", - "attribute vec2 uv;", - - "varying vec2 vUV;", - - "void main() {", - - "vUV = uv;", - - "vec2 pos = position;", - - "if ( renderType == 2 ) {", - - "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;", - "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;", - - "}", - - "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );", - - "}" - - ].join( "\n" ), - - fragmentShader: [ - - "precision mediump float;", - - "uniform lowp int renderType;", - - "uniform sampler2D map;", - "uniform sampler2D occlusionMap;", - "uniform float opacity;", - "uniform vec3 color;", - - "varying vec2 vUV;", - - "void main() {", - - // pink square - - "if ( renderType == 0 ) {", - - "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );", - - // restore - - "} else if ( renderType == 1 ) {", - - "gl_FragColor = texture2D( map, vUV );", - - // flare - - "} else {", - - "float visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a;", - "visibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a;", - "visibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a;", - "visibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;", - "visibility = ( 1.0 - visibility / 4.0 );", - - "vec4 texture = texture2D( map, vUV );", - "texture.a *= opacity * visibility;", - "gl_FragColor = texture;", - "gl_FragColor.rgb *= color;", - - "}", - - "}" - - ].join( "\n" ) - - }; - - } + }; program = createProgram( shader ); @@ -31762,6 +32340,11 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { var screenPosition = new THREE.Vector3( 1, 1, 0 ), screenPositionPixels = new THREE.Vector2( 1, 1 ); + var validArea = new THREE.Box2(); + + validArea.min.set( 0, 0 ); + validArea.max.set( viewport.z - 16, viewport.w - 16 ); + if ( program === undefined ) { init(); @@ -31808,16 +32391,14 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { screenPosition.copy( tempPosition ); - screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth; - screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight; + // horizontal and vertical coordinate of the lower left corner of the pixels to copy + + screenPositionPixels.x = viewport.x + ( screenPosition.x * halfViewportWidth ) + halfViewportWidth - 8; + screenPositionPixels.y = viewport.y + ( screenPosition.y * halfViewportHeight ) + halfViewportHeight - 8; // screen cull - if ( hasVertexTexture || ( - screenPositionPixels.x > 0 && - screenPositionPixels.x < viewport.z && - screenPositionPixels.y > 0 && - screenPositionPixels.y < viewport.w ) ) { + if ( validArea.containsPoint( screenPositionPixels ) === true ) { // save current RGB to temp texture @@ -31825,7 +32406,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { state.bindTexture( gl.TEXTURE_2D, null ); state.activeTexture( gl.TEXTURE1 ); state.bindTexture( gl.TEXTURE_2D, tempTexture ); - gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, viewport.x + screenPositionPixels.x - 8, viewport.y + screenPositionPixels.y - 8, 16, 16, 0 ); + gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGB, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 ); // render pink quad @@ -31844,7 +32425,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { state.activeTexture( gl.TEXTURE0 ); state.bindTexture( gl.TEXTURE_2D, occlusionTexture ); - gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, viewport.x + screenPositionPixels.x - 8, viewport.y + screenPositionPixels.y - 8, 16, 16, 0 ); + gl.copyTexImage2D( gl.TEXTURE_2D, 0, gl.RGBA, screenPositionPixels.x, screenPositionPixels.y, 16, 16, 0 ); // restore graphics @@ -31899,7 +32480,7 @@ THREE.LensFlarePlugin = function ( renderer, flares ) { gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b ); state.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst ); - renderer.setTexture( sprite.texture, 1 ); + renderer.setTexture2D( sprite.texture, 1 ); gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); @@ -32172,13 +32753,13 @@ THREE.SpritePlugin = function ( renderer, sprites ) { state.setDepthTest( material.depthTest ); state.setDepthWrite( material.depthWrite ); - if ( material.map && material.map.image && material.map.image.width ) { + if ( material.map ) { - renderer.setTexture( material.map, 0 ); + renderer.setTexture2D( material.map, 0 ); } else { - renderer.setTexture( texture, 0 ); + renderer.setTexture2D( texture, 0 ); } @@ -32327,208 +32908,192 @@ THREE.SpritePlugin = function ( renderer, sprites ) { * @author mrdoob / http://mrdoob.com/ */ -Object.defineProperties( THREE.Box2.prototype, { - empty: { - value: function () { - console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' ); - return this.isEmpty(); - } +Object.assign( THREE, { + Face4: function ( a, b, c, d, normal, color, materialIndex ) { + console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ); + return new THREE.Face3( a, b, c, normal, color, materialIndex ); }, - isIntersectionBox: { - value: function ( box ) { - console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' ); - return this.intersectsBox( box ); - } - } -} ); - -Object.defineProperties( THREE.Box3.prototype, { - empty: { - value: function () { - console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' ); - return this.isEmpty(); - } + LineStrip: 0, + LinePieces: 1, + MeshFaceMaterial: THREE.MultiMaterial, + PointCloud: function ( geometry, material ) { + console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' ); + return new THREE.Points( geometry, material ); }, - isIntersectionBox: { - value: function ( box ) { - console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' ); - return this.intersectsBox( box ); - } + Particle: THREE.Sprite, + ParticleSystem: function ( geometry, material ) { + console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' ); + return new THREE.Points( geometry, material ); }, - isIntersectionSphere: { - value: function ( sphere ) { - console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); - return this.intersectsSphere( sphere ); - } - } -} ); - -Object.defineProperties( THREE.Matrix3.prototype, { - multiplyVector3: { - value: function ( vector ) { - console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); - return vector.applyMatrix3( this ); - } + PointCloudMaterial: function ( parameters ) { + console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' ); + return new THREE.PointsMaterial( parameters ); }, - multiplyVector3Array: { - value: function ( a ) { - console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); - return this.applyToVector3Array( a ); - } - } -} ); - -Object.defineProperties( THREE.Matrix4.prototype, { - extractPosition: { - value: function ( m ) { - console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); - return this.copyPosition( m ); - } + ParticleBasicMaterial: function ( parameters ) { + console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' ); + return new THREE.PointsMaterial( parameters ); }, - setRotationFromQuaternion: { - value: function ( q ) { - console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); - return this.makeRotationFromQuaternion( q ); - } + ParticleSystemMaterial: function ( parameters ) { + console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' ); + return new THREE.PointsMaterial( parameters ); }, - multiplyVector3: { - value: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); - return vector.applyProjection( this ); - } - }, - multiplyVector4: { - value: function ( vector ) { - console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); - return vector.applyMatrix4( this ); - } - }, - multiplyVector3Array: { - value: function ( a ) { - console.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); - return this.applyToVector3Array( a ); - } - }, - rotateAxis: { - value: function ( v ) { - console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); - v.transformDirection( this ); - } - }, - crossVector: { - value: function ( vector ) { - console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); - return vector.applyMatrix4( this ); - } - }, - translate: { - value: function ( v ) { - console.error( 'THREE.Matrix4: .translate() has been removed.' ); - } - }, - rotateX: { - value: function ( angle ) { - console.error( 'THREE.Matrix4: .rotateX() has been removed.' ); - } - }, - rotateY: { - value: function ( angle ) { - console.error( 'THREE.Matrix4: .rotateY() has been removed.' ); - } - }, - rotateZ: { - value: function ( angle ) { - console.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); - } - }, - rotateByAxis: { - value: function ( axis, angle ) { - console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); - } - } -} ); - -Object.defineProperties( THREE.Plane.prototype, { - isIntersectionLine: { - value: function ( line ) { - console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' ); - return this.intersectsLine( line ); - } - } -} ); - -Object.defineProperties( THREE.Quaternion.prototype, { - multiplyVector3: { - value: function ( vector ) { - console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); - return vector.applyQuaternion( this ); - } - } -} ); - -Object.defineProperties( THREE.Ray.prototype, { - isIntersectionBox: { - value: function ( box ) { - console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' ); - return this.intersectsBox( box ); - } - }, - isIntersectionPlane: { - value: function ( plane ) { - console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' ); - return this.intersectsPlane( plane ); - } - }, - isIntersectionSphere: { - value: function ( sphere ) { - console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); - return this.intersectsSphere( sphere ); - } - } -} ); - -Object.defineProperties( THREE.Vector3.prototype, { - setEulerFromRotationMatrix: { - value: function () { - console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); - } - }, - setEulerFromQuaternion: { - value: function () { - console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); - } - }, - getPositionFromMatrix: { - value: function ( m ) { - console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); - return this.setFromMatrixPosition( m ); - } - }, - getScaleFromMatrix: { - value: function ( m ) { - console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); - return this.setFromMatrixScale( m ); - } - }, - getColumnFromMatrix: { - value: function ( index, matrix ) { - console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); - return this.setFromMatrixColumn( index, matrix ); - } + Vertex: function ( x, y, z ) { + console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' ); + return new THREE.Vector3( x, y, z ); } } ); // -THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) { +Object.assign( THREE.Box2.prototype, { + empty: function () { + console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' ); + return this.isEmpty(); + }, + isIntersectionBox: function ( box ) { + console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' ); + return this.intersectsBox( box ); + } +} ); - console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' ); - return new THREE.Face3( a, b, c, normal, color, materialIndex ); +Object.assign( THREE.Box3.prototype, { + empty: function () { + console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' ); + return this.isEmpty(); + }, + isIntersectionBox: function ( box ) { + console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' ); + return this.intersectsBox( box ); + }, + isIntersectionSphere: function ( sphere ) { + console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); + return this.intersectsSphere( sphere ); + } +} ); -}; +Object.assign( THREE.Matrix3.prototype, { + multiplyVector3: function ( vector ) { + console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' ); + return vector.applyMatrix3( this ); + }, + multiplyVector3Array: function ( a ) { + console.warn( 'THREE.Matrix3: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + return this.applyToVector3Array( a ); + } +} ); + +Object.assign( THREE.Matrix4.prototype, { + extractPosition: function ( m ) { + console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' ); + return this.copyPosition( m ); + }, + setRotationFromQuaternion: function ( q ) { + console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' ); + return this.makeRotationFromQuaternion( q ); + }, + multiplyVector3: function ( vector ) { + console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) or vector.applyProjection( matrix ) instead.' ); + return vector.applyProjection( this ); + }, + multiplyVector4: function ( vector ) { + console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + return vector.applyMatrix4( this ); + }, + multiplyVector3Array: function ( a ) { + console.warn( 'THREE.Matrix4: .multiplyVector3Array() has been renamed. Use matrix.applyToVector3Array( array ) instead.' ); + return this.applyToVector3Array( a ); + }, + rotateAxis: function ( v ) { + console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' ); + v.transformDirection( this ); + }, + crossVector: function ( vector ) { + console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' ); + return vector.applyMatrix4( this ); + }, + translate: function ( v ) { + console.error( 'THREE.Matrix4: .translate() has been removed.' ); + }, + rotateX: function ( angle ) { + console.error( 'THREE.Matrix4: .rotateX() has been removed.' ); + }, + rotateY: function ( angle ) { + console.error( 'THREE.Matrix4: .rotateY() has been removed.' ); + }, + rotateZ: function ( angle ) { + console.error( 'THREE.Matrix4: .rotateZ() has been removed.' ); + }, + rotateByAxis: function ( axis, angle ) { + console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' ); + } +} ); + +Object.assign( THREE.Plane.prototype, { + isIntersectionLine: function ( line ) { + console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' ); + return this.intersectsLine( line ); + } +} ); + +Object.assign( THREE.Quaternion.prototype, { + multiplyVector3: function ( vector ) { + console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' ); + return vector.applyQuaternion( this ); + } +} ); + +Object.assign( THREE.Ray.prototype, { + isIntersectionBox: function ( box ) { + console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' ); + return this.intersectsBox( box ); + }, + isIntersectionPlane: function ( plane ) { + console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' ); + return this.intersectsPlane( plane ); + }, + isIntersectionSphere: function ( sphere ) { + console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' ); + return this.intersectsSphere( sphere ); + } +} ); + +Object.assign( THREE.Vector3.prototype, { + setEulerFromRotationMatrix: function () { + console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' ); + }, + setEulerFromQuaternion: function () { + console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' ); + }, + getPositionFromMatrix: function ( m ) { + console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' ); + return this.setFromMatrixPosition( m ); + }, + getScaleFromMatrix: function ( m ) { + console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' ); + return this.setFromMatrixScale( m ); + }, + getColumnFromMatrix: function ( index, matrix ) { + console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' ); + return this.setFromMatrixColumn( matrix, index ); + } +} ); // +Object.assign( THREE.Object3D.prototype, { + getChildByName: function ( name ) { + console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); + return this.getObjectByName( name ); + }, + renderDepth: function ( value ) { + console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' ); + }, + translate: function ( distance, axis ) { + console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); + return this.translateOnAxis( axis, distance ); + } +} ); + Object.defineProperties( THREE.Object3D.prototype, { eulerOrder: { get: function () { @@ -32540,23 +33105,6 @@ Object.defineProperties( THREE.Object3D.prototype, { this.rotation.order = value; } }, - getChildByName: { - value: function ( name ) { - console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' ); - return this.getObjectByName( name ); - } - }, - renderDepth: { - set: function ( value ) { - console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' ); - } - }, - translate: { - value: function ( distance, axis ) { - console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' ); - return this.translateOnAxis( axis, distance ); - } - }, useQuaternion: { get: function () { console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' ); @@ -32567,25 +33115,29 @@ Object.defineProperties( THREE.Object3D.prototype, { } } ); -// - -Object.defineProperties( THREE, { - PointCloud: { - value: function ( geometry, material ) { - console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' ); - return new THREE.Points( geometry, material ); - } - }, - ParticleSystem: { - value: function ( geometry, material ) { - console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' ); - return new THREE.Points( geometry, material ); +Object.defineProperties( THREE.LOD.prototype, { + objects: { + get: function () { + console.warn( 'THREE.LOD: .objects has been renamed to .levels.' ); + return this.levels; } } } ); // +THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) { + + console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " + + "Use .setFocalLength and .filmGauge for a photographic setup." ); + + if ( filmGauge !== undefined ) this.filmGauge = filmGauge; + this.setFocalLength( focalLength ); + +}; + +// + Object.defineProperties( THREE.Light.prototype, { onlyShadow: { set: function ( value ) { @@ -32675,6 +33227,30 @@ Object.defineProperties( THREE.BufferAttribute.prototype, { } } ); +Object.assign( THREE.BufferGeometry.prototype, { + addIndex: function ( index ) { + console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); + this.setIndex( index ); + }, + addDrawCall: function ( start, count, indexOffset ) { + if ( indexOffset !== undefined ) { + console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' ); + } + console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' ); + this.addGroup( start, count ); + }, + clearDrawCalls: function () { + console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' ); + this.clearGroups(); + }, + computeTangents: function () { + console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' ); + }, + computeOffsets: function () { + console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); + } +} ); + Object.defineProperties( THREE.BufferGeometry.prototype, { drawcalls: { get: function () { @@ -32687,37 +33263,6 @@ Object.defineProperties( THREE.BufferGeometry.prototype, { console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' ); return this.groups; } - }, - addIndex: { - value: function ( index ) { - console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' ); - this.setIndex( index ); - } - }, - addDrawCall: { - value: function ( start, count, indexOffset ) { - if ( indexOffset !== undefined ) { - console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' ); - } - console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' ); - this.addGroup( start, count ); - } - }, - clearDrawCalls: { - value: function () { - console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' ); - this.clearGroups(); - } - }, - computeTangents: { - value: function () { - console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' ); - } - }, - computeOffsets: { - value: function () { - console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' ); - } } } ); @@ -32740,27 +33285,6 @@ Object.defineProperties( THREE.Material.prototype, { } } ); -Object.defineProperties( THREE, { - PointCloudMaterial: { - value: function ( parameters ) { - console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' ); - return new THREE.PointsMaterial( parameters ); - } - }, - ParticleBasicMaterial: { - value: function ( parameters ) { - console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' ); - return new THREE.PointsMaterial( parameters ); - } - }, - ParticleSystemMaterial:{ - value: function ( parameters ) { - console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' ); - return new THREE.PointsMaterial( parameters ); - } - } -} ); - Object.defineProperties( THREE.MeshPhongMaterial.prototype, { metal: { get: function () { @@ -32788,80 +33312,76 @@ Object.defineProperties( THREE.ShaderMaterial.prototype, { // +THREE.EventDispatcher.prototype = Object.assign( Object.create( { + + // Note: Extra base ensures these properties are not 'assign'ed. + + constructor: THREE.EventDispatcher, + + apply: function ( target ) { + + console.warn( "THREE.EventDispatcher: .apply is deprecated, " + + "just inherit or Object.assign the prototype to mix-in." ); + + Object.assign( target, this ); + + } + +} ), THREE.EventDispatcher.prototype ); + +// + +Object.assign( THREE.WebGLRenderer.prototype, { + supportsFloatTextures: function () { + console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' ); + return this.extensions.get( 'OES_texture_float' ); + }, + supportsHalfFloatTextures: function () { + console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' ); + return this.extensions.get( 'OES_texture_half_float' ); + }, + supportsStandardDerivatives: function () { + console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' ); + return this.extensions.get( 'OES_standard_derivatives' ); + }, + supportsCompressedTextureS3TC: function () { + console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' ); + return this.extensions.get( 'WEBGL_compressed_texture_s3tc' ); + }, + supportsCompressedTexturePVRTC: function () { + console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' ); + return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' ); + }, + supportsBlendMinMax: function () { + console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' ); + return this.extensions.get( 'EXT_blend_minmax' ); + }, + supportsVertexTextures: function () { + return this.capabilities.vertexTextures; + }, + supportsInstancedArrays: function () { + console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' ); + return this.extensions.get( 'ANGLE_instanced_arrays' ); + }, + enableScissorTest: function ( boolean ) { + console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' ); + this.setScissorTest( boolean ); + }, + initMaterial: function () { + console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); + }, + addPrePlugin: function () { + console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); + }, + addPostPlugin: function () { + console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); + }, + updateShadowMap: function () { + console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); + } +} ); + Object.defineProperties( THREE.WebGLRenderer.prototype, { - supportsFloatTextures: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' ); - return this.extensions.get( 'OES_texture_float' ); - } - }, - supportsHalfFloatTextures: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' ); - return this.extensions.get( 'OES_texture_half_float' ); - } - }, - supportsStandardDerivatives: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' ); - return this.extensions.get( 'OES_standard_derivatives' ); - } - }, - supportsCompressedTextureS3TC: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' ); - return this.extensions.get( 'WEBGL_compressed_texture_s3tc' ); - } - }, - supportsCompressedTexturePVRTC: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' ); - return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' ); - } - }, - supportsBlendMinMax: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' ); - return this.extensions.get( 'EXT_blend_minmax' ); - } - }, - supportsVertexTextures: { - value: function () { - return this.capabilities.vertexTextures; - } - }, - supportsInstancedArrays: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' ); - return this.extensions.get( 'ANGLE_instanced_arrays' ); - } - }, - enableScissorTest: { - value: function ( boolean ) { - console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' ); - this.setScissorTest( boolean ); - } - }, - initMaterial: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' ); - } - }, - addPrePlugin: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' ); - } - }, - addPostPlugin: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' ); - } - }, - updateShadowMap: { - value: function () { - console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' ); - } - }, shadowMapEnabled: { get: function () { return this.shadowMap.enabled; @@ -32891,6 +33411,19 @@ Object.defineProperties( THREE.WebGLRenderer.prototype, { } } ); +Object.defineProperties( THREE.WebGLShadowMap.prototype, { + cullFace: { + get: function () { + return this.renderReverseSided ? THREE.CullFaceFront : THREE.CullFaceBack; + }, + set: function ( cullFace ) { + var value = ( cullFace !== THREE.CullFaceBack ); + console.warn( "WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to " + value + "." ); + this.renderReverseSided = value; + } + } +} ); + // Object.defineProperties( THREE.WebGLRenderTarget.prototype, { @@ -32998,6 +33531,27 @@ Object.defineProperties( THREE.WebGLRenderTarget.prototype, { // +Object.assign( THREE.Audio.prototype, { + load: function ( file ) { + console.warn( 'THREE.Audio: .load has been deprecated. Please use THREE.AudioLoader.' ); + var scope = this; + var audioLoader = new THREE.AudioLoader(); + audioLoader.load( file, function ( buffer ) { + scope.setBuffer( buffer ); + } ); + return this; + } +} ); + +Object.assign( THREE.AudioAnalyser.prototype, { + getData: function ( file ) { + console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' ); + return this.getFrequencyData(); + } +} ); + +// + THREE.GeometryUtils = { merge: function ( geometry1, geometry2, materialIndexOffset ) { @@ -33118,10 +33672,6 @@ THREE.CanvasRenderer = function () { }; -// - -THREE.MeshFaceMaterial = THREE.MultiMaterial; - // File:src/extras/CurveUtils.js /** @@ -33998,7 +34548,6 @@ THREE.ShapeUtils = { * THREE.QuadraticBezierCurve3 * THREE.CubicBezierCurve3 * THREE.SplineCurve3 - * THREE.ClosedSplineCurve3 * * A series of curves can be represented as a THREE.CurvePath * @@ -34278,164 +34827,152 @@ THREE.CurvePath = function () { }; -THREE.CurvePath.prototype = Object.create( THREE.Curve.prototype ); -THREE.CurvePath.prototype.constructor = THREE.CurvePath; +THREE.CurvePath.prototype = Object.assign( Object.create( THREE.Curve.prototype ), { -THREE.CurvePath.prototype.add = function ( curve ) { + constructor: THREE.CurvePath, - this.curves.push( curve ); + add: function ( curve ) { -}; + this.curves.push( curve ); -/* -THREE.CurvePath.prototype.checkConnection = function() { - // TODO - // If the ending of curve is not connected to the starting - // or the next curve, then, this is not a real path -}; -*/ + }, -THREE.CurvePath.prototype.closePath = function() { + closePath: function () { - // TODO Test - // and verify for vector3 (needs to implement equals) - // Add a line curve if start and end of lines are not connected - var startPoint = this.curves[ 0 ].getPoint( 0 ); - var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); + // TODO Test + // and verify for vector3 (needs to implement equals) + // Add a line curve if start and end of lines are not connected + var startPoint = this.curves[ 0 ].getPoint( 0 ); + var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 ); - if ( ! startPoint.equals( endPoint ) ) { + if ( ! startPoint.equals( endPoint ) ) { - this.curves.push( new THREE.LineCurve( endPoint, startPoint ) ); - - } - -}; - -// To get accurate point with reference to -// entire path distance at time t, -// following has to be done: - -// 1. Length of each sub path have to be known -// 2. Locate and identify type of curve -// 3. Get t for the curve -// 4. Return curve.getPointAt(t') - -THREE.CurvePath.prototype.getPoint = function( t ) { - - var d = t * this.getLength(); - var curveLengths = this.getCurveLengths(); - var i = 0; - - // To think about boundaries points. - - while ( i < curveLengths.length ) { - - if ( curveLengths[ i ] >= d ) { - - var diff = curveLengths[ i ] - d; - var curve = this.curves[ i ]; - - var u = 1 - diff / curve.getLength(); - - return curve.getPointAt( u ); + this.curves.push( new THREE.LineCurve( endPoint, startPoint ) ); } - i ++; + }, + + // To get accurate point with reference to + // entire path distance at time t, + // following has to be done: + + // 1. Length of each sub path have to be known + // 2. Locate and identify type of curve + // 3. Get t for the curve + // 4. Return curve.getPointAt(t') + + getPoint: function ( t ) { + + var d = t * this.getLength(); + var curveLengths = this.getCurveLengths(); + var i = 0; + + // To think about boundaries points. + + while ( i < curveLengths.length ) { + + if ( curveLengths[ i ] >= d ) { + + var diff = curveLengths[ i ] - d; + var curve = this.curves[ i ]; + + var u = 1 - diff / curve.getLength(); + + return curve.getPointAt( u ); + + } + + i ++; + + } + + return null; + + // loop where sum != 0, sum > d , sum+1 d , sum+1 0 ) { - cpx = args[ 2 ]; - cpy = args[ 3 ]; + laste = points[ points.length - 1 ]; - cpx1 = args[ 0 ]; - cpy1 = args[ 1 ]; + cpx0 = laste.x; + cpy0 = laste.y; - if ( points.length > 0 ) { + } else { - laste = points[ points.length - 1 ]; + laste = this.actions[ i - 1 ].args; - cpx0 = laste.x; - cpy0 = laste.y; - - } else { - - laste = this.actions[ i - 1 ].args; - - cpx0 = laste[ laste.length - 2 ]; - cpy0 = laste[ laste.length - 1 ]; - - } - - for ( var j = 1; j <= divisions; j ++ ) { - - var t = j / divisions; - - tx = b2( t, cpx0, cpx1, cpx ); - ty = b2( t, cpy0, cpy1, cpy ); - - points.push( new THREE.Vector2( tx, ty ) ); - - } - - break; - - case 'bezierCurveTo': - - cpx = args[ 4 ]; - cpy = args[ 5 ]; - - cpx1 = args[ 0 ]; - cpy1 = args[ 1 ]; - - cpx2 = args[ 2 ]; - cpy2 = args[ 3 ]; - - if ( points.length > 0 ) { - - laste = points[ points.length - 1 ]; - - cpx0 = laste.x; - cpy0 = laste.y; - - } else { - - laste = this.actions[ i - 1 ].args; - - cpx0 = laste[ laste.length - 2 ]; - cpy0 = laste[ laste.length - 1 ]; - - } - - - for ( var j = 1; j <= divisions; j ++ ) { - - var t = j / divisions; - - tx = b3( t, cpx0, cpx1, cpx2, cpx ); - ty = b3( t, cpy0, cpy1, cpy2, cpy ); - - points.push( new THREE.Vector2( tx, ty ) ); - - } - - break; - - case 'splineThru': - - laste = this.actions[ i - 1 ].args; - - var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] ); - var spts = [ last ]; - - var n = divisions * args[ 0 ].length; - - spts = spts.concat( args[ 0 ] ); - - var spline = new THREE.SplineCurve( spts ); - - for ( var j = 1; j <= n; j ++ ) { - - points.push( spline.getPointAt( j / n ) ); - - } - - break; - - case 'arc': - - var aX = args[ 0 ], aY = args[ 1 ], - aRadius = args[ 2 ], - aStartAngle = args[ 3 ], aEndAngle = args[ 4 ], - aClockwise = !! args[ 5 ]; - - var deltaAngle = aEndAngle - aStartAngle; - var angle; - var tdivisions = divisions * 2; - - for ( var j = 1; j <= tdivisions; j ++ ) { - - var t = j / tdivisions; - - if ( ! aClockwise ) { - - t = 1 - t; + cpx0 = laste[ laste.length - 2 ]; + cpy0 = laste[ laste.length - 1 ]; } - angle = aStartAngle + t * deltaAngle; + for ( var j = 1; j <= divisions; j ++ ) { - tx = aX + aRadius * Math.cos( angle ); - ty = aY + aRadius * Math.sin( angle ); + var t = j / divisions; - //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); + tx = b2( t, cpx0, cpx1, cpx ); + ty = b2( t, cpy0, cpy1, cpy ); - points.push( new THREE.Vector2( tx, ty ) ); - - } - - //console.log(points); - - break; - - case 'ellipse': - - var aX = args[ 0 ], aY = args[ 1 ], - xRadius = args[ 2 ], - yRadius = args[ 3 ], - aStartAngle = args[ 4 ], aEndAngle = args[ 5 ], - aClockwise = !! args[ 6 ], - aRotation = args[ 7 ]; - - - var deltaAngle = aEndAngle - aStartAngle; - var angle; - var tdivisions = divisions * 2; - - var cos, sin; - if ( aRotation !== 0 ) { - - cos = Math.cos( aRotation ); - sin = Math.sin( aRotation ); - - } - - for ( var j = 1; j <= tdivisions; j ++ ) { - - var t = j / tdivisions; - - if ( ! aClockwise ) { - - t = 1 - t; + points.push( new THREE.Vector2( tx, ty ) ); } - angle = aStartAngle + t * deltaAngle; + break; - tx = aX + xRadius * Math.cos( angle ); - ty = aY + yRadius * Math.sin( angle ); + case 'bezierCurveTo': + cpx = args[ 4 ]; + cpy = args[ 5 ]; + + cpx1 = args[ 0 ]; + cpy1 = args[ 1 ]; + + cpx2 = args[ 2 ]; + cpy2 = args[ 3 ]; + + if ( points.length > 0 ) { + + laste = points[ points.length - 1 ]; + + cpx0 = laste.x; + cpy0 = laste.y; + + } else { + + laste = this.actions[ i - 1 ].args; + + cpx0 = laste[ laste.length - 2 ]; + cpy0 = laste[ laste.length - 1 ]; + + } + + + for ( var j = 1; j <= divisions; j ++ ) { + + var t = j / divisions; + + tx = b3( t, cpx0, cpx1, cpx2, cpx ); + ty = b3( t, cpy0, cpy1, cpy2, cpy ); + + points.push( new THREE.Vector2( tx, ty ) ); + + } + + break; + + case 'splineThru': + + laste = this.actions[ i - 1 ].args; + + var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] ); + var spts = [ last ]; + + var n = divisions * args[ 0 ].length; + + spts = spts.concat( args[ 0 ] ); + + var spline = new THREE.SplineCurve( spts ); + + for ( var j = 1; j <= n; j ++ ) { + + points.push( spline.getPointAt( j / n ) ); + + } + + break; + + case 'arc': + + var aX = args[ 0 ], aY = args[ 1 ], + aRadius = args[ 2 ], + aStartAngle = args[ 3 ], aEndAngle = args[ 4 ], + aClockwise = !! args[ 5 ]; + + var deltaAngle = aEndAngle - aStartAngle; + var angle; + var tdivisions = divisions * 2; + + for ( var j = 1; j <= tdivisions; j ++ ) { + + var t = j / tdivisions; + + if ( ! aClockwise ) { + + t = 1 - t; + + } + + angle = aStartAngle + t * deltaAngle; + + tx = aX + aRadius * Math.cos( angle ); + ty = aY + aRadius * Math.sin( angle ); + + //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); + + points.push( new THREE.Vector2( tx, ty ) ); + + } + + //console.log(points); + + break; + + case 'ellipse': + + var aX = args[ 0 ], aY = args[ 1 ], + xRadius = args[ 2 ], + yRadius = args[ 3 ], + aStartAngle = args[ 4 ], aEndAngle = args[ 5 ], + aClockwise = !! args[ 6 ], + aRotation = args[ 7 ]; + + + var deltaAngle = aEndAngle - aStartAngle; + var angle; + var tdivisions = divisions * 2; + + var cos, sin; if ( aRotation !== 0 ) { - var x = tx, y = ty; - - // Rotate the point about the center of the ellipse. - tx = ( x - aX ) * cos - ( y - aY ) * sin + aX; - ty = ( x - aX ) * sin + ( y - aY ) * cos + aY; + cos = Math.cos( aRotation ); + sin = Math.sin( aRotation ); } - //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); + for ( var j = 1; j <= tdivisions; j ++ ) { - points.push( new THREE.Vector2( tx, ty ) ); + var t = j / tdivisions; + + if ( ! aClockwise ) { + + t = 1 - t; + + } + + angle = aStartAngle + t * deltaAngle; + + tx = aX + xRadius * Math.cos( angle ); + ty = aY + yRadius * Math.sin( angle ); + + if ( aRotation !== 0 ) { + + var x = tx, y = ty; + + // Rotate the point about the center of the ellipse. + tx = ( x - aX ) * cos - ( y - aY ) * sin + aX; + ty = ( x - aX ) * sin + ( y - aY ) * cos + aY; + + } + + //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty); + + points.push( new THREE.Vector2( tx, ty ) ); + + } + + //console.log(points); + + break; + + } // end switch + + } + + + + // Normalize to remove the closing point by default. + var lastPoint = points[ points.length - 1 ]; + if ( Math.abs( lastPoint.x - points[ 0 ].x ) < Number.EPSILON && + Math.abs( lastPoint.y - points[ 0 ].y ) < Number.EPSILON ) + points.splice( points.length - 1, 1 ); + + if ( this.autoClose ) { + + points.push( points[ 0 ] ); + + } + + return points; + + }, + + toShapes: function ( isCCW, noHoles ) { + + function extractSubpaths( inActions ) { + + var subPaths = [], lastPath = new THREE.Path(); + + for ( var i = 0, l = inActions.length; i < l; i ++ ) { + + var item = inActions[ i ]; + + var args = item.args; + var action = item.action; + + if ( action === 'moveTo' ) { + + if ( lastPath.actions.length !== 0 ) { + + subPaths.push( lastPath ); + lastPath = new THREE.Path(); + + } + + } + + lastPath[ action ].apply( lastPath, args ); } - //console.log(points); + if ( lastPath.actions.length !== 0 ) { - break; + subPaths.push( lastPath ); - } // end switch + } - } + // console.log(subPaths); + return subPaths; + } - // Normalize to remove the closing point by default. - var lastPoint = points[ points.length - 1 ]; - if ( Math.abs( lastPoint.x - points[ 0 ].x ) < Number.EPSILON && - Math.abs( lastPoint.y - points[ 0 ].y ) < Number.EPSILON ) - points.splice( points.length - 1, 1 ); + function toShapesNoHoles( inSubpaths ) { - if ( this.autoClose ) { + var shapes = []; - points.push( points[ 0 ] ); + for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { - } + var tmpPath = inSubpaths[ i ]; - return points; + var tmpShape = new THREE.Shape(); + tmpShape.actions = tmpPath.actions; + tmpShape.curves = tmpPath.curves; -}; + shapes.push( tmpShape ); -// -// Breaks path into shapes -// -// Assumptions (if parameter isCCW==true the opposite holds): -// - solid shapes are defined clockwise (CW) -// - holes are defined counterclockwise (CCW) -// -// If parameter noHoles==true: -// - all subPaths are regarded as solid shapes -// - definition order CW/CCW has no relevance -// + } -THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { + //console.log("shape", shapes); - function extractSubpaths( inActions ) { + return shapes; - var subPaths = [], lastPath = new THREE.Path(); + } - for ( var i = 0, l = inActions.length; i < l; i ++ ) { + function isPointInsidePolygon( inPt, inPolygon ) { - var item = inActions[ i ]; + var polyLen = inPolygon.length; - var args = item.args; - var action = item.action; + // inPt on polygon contour => immediate success or + // toggling of inside/outside at every single! intersection point of an edge + // with the horizontal line through inPt, left of inPt + // not counting lowerY endpoints of edges and whole edges on that line + var inside = false; + for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { - if ( action === 'moveTo' ) { + var edgeLowPt = inPolygon[ p ]; + var edgeHighPt = inPolygon[ q ]; - if ( lastPath.actions.length !== 0 ) { + var edgeDx = edgeHighPt.x - edgeLowPt.x; + var edgeDy = edgeHighPt.y - edgeLowPt.y; - subPaths.push( lastPath ); - lastPath = new THREE.Path(); + if ( Math.abs( edgeDy ) > Number.EPSILON ) { + + // not parallel + if ( edgeDy < 0 ) { + + edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; + edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; + + } + if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; + + if ( inPt.y === edgeLowPt.y ) { + + if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? + // continue; // no intersection or edgeLowPt => doesn't count !!! + + } else { + + var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); + if ( perpEdge === 0 ) return true; // inPt is on contour ? + if ( perpEdge < 0 ) continue; + inside = ! inside; // true intersection left of inPt + + } + + } else { + + // parallel or collinear + if ( inPt.y !== edgeLowPt.y ) continue; // parallel + // edge lies on the same horizontal line as inPt + if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || + ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! + // continue; } } - lastPath[ action ].apply( lastPath, args ); + return inside; } - if ( lastPath.actions.length !== 0 ) { + var isClockWise = THREE.ShapeUtils.isClockWise; - subPaths.push( lastPath ); + var subPaths = extractSubpaths( this.actions ); + if ( subPaths.length === 0 ) return []; - } + if ( noHoles === true ) return toShapesNoHoles( subPaths ); - // console.log(subPaths); - return subPaths; + var solid, tmpPath, tmpShape, shapes = []; - } + if ( subPaths.length === 1 ) { - function toShapesNoHoles( inSubpaths ) { - - var shapes = []; - - for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) { - - var tmpPath = inSubpaths[ i ]; - - var tmpShape = new THREE.Shape(); + tmpPath = subPaths[ 0 ]; + tmpShape = new THREE.Shape(); tmpShape.actions = tmpPath.actions; tmpShape.curves = tmpPath.curves; - shapes.push( tmpShape ); + return shapes; + + } + + var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); + holesFirst = isCCW ? ! holesFirst : holesFirst; + + // console.log("Holes first", holesFirst); + + var betterShapeHoles = []; + var newShapes = []; + var newShapeHoles = []; + var mainIdx = 0; + var tmpPoints; + + newShapes[ mainIdx ] = undefined; + newShapeHoles[ mainIdx ] = []; + + for ( var i = 0, l = subPaths.length; i < l; i ++ ) { + + tmpPath = subPaths[ i ]; + tmpPoints = tmpPath.getPoints(); + solid = isClockWise( tmpPoints ); + solid = isCCW ? ! solid : solid; + + if ( solid ) { + + if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; + + newShapes[ mainIdx ] = { s: new THREE.Shape(), p: tmpPoints }; + newShapes[ mainIdx ].s.actions = tmpPath.actions; + newShapes[ mainIdx ].s.curves = tmpPath.curves; + + if ( holesFirst ) mainIdx ++; + newShapeHoles[ mainIdx ] = []; + + //console.log('cw', i); + + } else { + + newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); + + //console.log('ccw', i); + + } + + } + + // only Holes? -> probably all Shapes with wrong orientation + if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); + + + if ( newShapes.length > 1 ) { + + var ambiguous = false; + var toChange = []; + + for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { + + betterShapeHoles[ sIdx ] = []; + + } + + for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { + + var sho = newShapeHoles[ sIdx ]; + + for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { + + var ho = sho[ hIdx ]; + var hole_unassigned = true; + + for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { + + if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { + + if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); + if ( hole_unassigned ) { + + hole_unassigned = false; + betterShapeHoles[ s2Idx ].push( ho ); + + } else { + + ambiguous = true; + + } + + } + + } + if ( hole_unassigned ) { + + betterShapeHoles[ sIdx ].push( ho ); + + } + + } + + } + // console.log("ambiguous: ", ambiguous); + if ( toChange.length > 0 ) { + + // console.log("to change: ", toChange); + if ( ! ambiguous ) newShapeHoles = betterShapeHoles; + + } + + } + + var tmpHoles; + + for ( var i = 0, il = newShapes.length; i < il; i ++ ) { + + tmpShape = newShapes[ i ].s; + shapes.push( tmpShape ); + tmpHoles = newShapeHoles[ i ]; + + for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { + + tmpShape.holes.push( tmpHoles[ j ].h ); + + } } @@ -35126,213 +35851,7 @@ THREE.Path.prototype.toShapes = function( isCCW, noHoles ) { } - function isPointInsidePolygon( inPt, inPolygon ) { - - var polyLen = inPolygon.length; - - // inPt on polygon contour => immediate success or - // toggling of inside/outside at every single! intersection point of an edge - // with the horizontal line through inPt, left of inPt - // not counting lowerY endpoints of edges and whole edges on that line - var inside = false; - for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) { - - var edgeLowPt = inPolygon[ p ]; - var edgeHighPt = inPolygon[ q ]; - - var edgeDx = edgeHighPt.x - edgeLowPt.x; - var edgeDy = edgeHighPt.y - edgeLowPt.y; - - if ( Math.abs( edgeDy ) > Number.EPSILON ) { - - // not parallel - if ( edgeDy < 0 ) { - - edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx; - edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy; - - } - if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue; - - if ( inPt.y === edgeLowPt.y ) { - - if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ? - // continue; // no intersection or edgeLowPt => doesn't count !!! - - } else { - - var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y ); - if ( perpEdge === 0 ) return true; // inPt is on contour ? - if ( perpEdge < 0 ) continue; - inside = ! inside; // true intersection left of inPt - - } - - } else { - - // parallel or collinear - if ( inPt.y !== edgeLowPt.y ) continue; // parallel - // edge lies on the same horizontal line as inPt - if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) || - ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour ! - // continue; - - } - - } - - return inside; - - } - - var isClockWise = THREE.ShapeUtils.isClockWise; - - var subPaths = extractSubpaths( this.actions ); - if ( subPaths.length === 0 ) return []; - - if ( noHoles === true ) return toShapesNoHoles( subPaths ); - - - var solid, tmpPath, tmpShape, shapes = []; - - if ( subPaths.length === 1 ) { - - tmpPath = subPaths[ 0 ]; - tmpShape = new THREE.Shape(); - tmpShape.actions = tmpPath.actions; - tmpShape.curves = tmpPath.curves; - shapes.push( tmpShape ); - return shapes; - - } - - var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() ); - holesFirst = isCCW ? ! holesFirst : holesFirst; - - // console.log("Holes first", holesFirst); - - var betterShapeHoles = []; - var newShapes = []; - var newShapeHoles = []; - var mainIdx = 0; - var tmpPoints; - - newShapes[ mainIdx ] = undefined; - newShapeHoles[ mainIdx ] = []; - - for ( var i = 0, l = subPaths.length; i < l; i ++ ) { - - tmpPath = subPaths[ i ]; - tmpPoints = tmpPath.getPoints(); - solid = isClockWise( tmpPoints ); - solid = isCCW ? ! solid : solid; - - if ( solid ) { - - if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++; - - newShapes[ mainIdx ] = { s: new THREE.Shape(), p: tmpPoints }; - newShapes[ mainIdx ].s.actions = tmpPath.actions; - newShapes[ mainIdx ].s.curves = tmpPath.curves; - - if ( holesFirst ) mainIdx ++; - newShapeHoles[ mainIdx ] = []; - - //console.log('cw', i); - - } else { - - newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } ); - - //console.log('ccw', i); - - } - - } - - // only Holes? -> probably all Shapes with wrong orientation - if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths ); - - - if ( newShapes.length > 1 ) { - - var ambiguous = false; - var toChange = []; - - for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - - betterShapeHoles[ sIdx ] = []; - - } - - for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) { - - var sho = newShapeHoles[ sIdx ]; - - for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) { - - var ho = sho[ hIdx ]; - var hole_unassigned = true; - - for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) { - - if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) { - - if ( sIdx !== s2Idx ) toChange.push( { froms: sIdx, tos: s2Idx, hole: hIdx } ); - if ( hole_unassigned ) { - - hole_unassigned = false; - betterShapeHoles[ s2Idx ].push( ho ); - - } else { - - ambiguous = true; - - } - - } - - } - if ( hole_unassigned ) { - - betterShapeHoles[ sIdx ].push( ho ); - - } - - } - - } - // console.log("ambiguous: ", ambiguous); - if ( toChange.length > 0 ) { - - // console.log("to change: ", toChange); - if ( ! ambiguous ) newShapeHoles = betterShapeHoles; - - } - - } - - var tmpHoles; - - for ( var i = 0, il = newShapes.length; i < il; i ++ ) { - - tmpShape = newShapes[ i ].s; - shapes.push( tmpShape ); - tmpHoles = newShapeHoles[ i ]; - - for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) { - - tmpShape.holes.push( tmpHoles[ j ].h ); - - } - - } - - //console.log("shape", shapes); - - return shapes; - -}; +} ); // File:src/extras/core/Shape.js @@ -35355,60 +35874,60 @@ THREE.Shape = function () { }; -THREE.Shape.prototype = Object.create( THREE.Path.prototype ); -THREE.Shape.prototype.constructor = THREE.Shape; +THREE.Shape.prototype = Object.assign( Object.create( THREE.Path.prototype ), { -// Convenience method to return ExtrudeGeometry + constructor: THREE.Shape, -THREE.Shape.prototype.extrude = function ( options ) { + // Convenience method to return ExtrudeGeometry - return new THREE.ExtrudeGeometry( this, options ); + extrude: function ( options ) { -}; + return new THREE.ExtrudeGeometry( this, options ); -// Convenience method to return ShapeGeometry + }, -THREE.Shape.prototype.makeGeometry = function ( options ) { + // Convenience method to return ShapeGeometry - return new THREE.ShapeGeometry( this, options ); + makeGeometry: function ( options ) { -}; + return new THREE.ShapeGeometry( this, options ); -// Get points of holes + }, -THREE.Shape.prototype.getPointsHoles = function ( divisions ) { + getPointsHoles: function ( divisions ) { - var holesPts = []; + var holesPts = []; - for ( var i = 0, l = this.holes.length; i < l; i ++ ) { + for ( var i = 0, l = this.holes.length; i < l; i ++ ) { - holesPts[ i ] = this.holes[ i ].getPoints( divisions ); + holesPts[ i ] = this.holes[ i ].getPoints( divisions ); + + } + + return holesPts; + + }, + + // Get points of shape and holes (keypoints based on segments parameter) + + extractAllPoints: function ( divisions ) { + + return { + + shape: this.getPoints( divisions ), + holes: this.getPointsHoles( divisions ) + + }; + + }, + + extractPoints: function ( divisions ) { + + return this.extractAllPoints( divisions ); } - return holesPts; - -}; - - -// Get points of shape and holes (keypoints based on segments parameter) - -THREE.Shape.prototype.extractAllPoints = function ( divisions ) { - - return { - - shape: this.getPoints( divisions ), - holes: this.getPointsHoles( divisions ) - - }; - -}; - -THREE.Shape.prototype.extractPoints = function ( divisions ) { - - return this.extractAllPoints( divisions ); - -}; +} ); // File:src/extras/curves/LineCurve.js @@ -36007,107 +36526,7 @@ THREE.BoxGeometry = function ( width, height, depth, widthSegments, heightSegmen depthSegments: depthSegments }; - this.widthSegments = widthSegments || 1; - this.heightSegments = heightSegments || 1; - this.depthSegments = depthSegments || 1; - - var scope = this; - - var width_half = width / 2; - var height_half = height / 2; - var depth_half = depth / 2; - - buildPlane( 'z', 'y', - 1, - 1, depth, height, width_half, 0 ); // px - buildPlane( 'z', 'y', 1, - 1, depth, height, - width_half, 1 ); // nx - buildPlane( 'x', 'z', 1, 1, width, depth, height_half, 2 ); // py - buildPlane( 'x', 'z', 1, - 1, width, depth, - height_half, 3 ); // ny - buildPlane( 'x', 'y', 1, - 1, width, height, depth_half, 4 ); // pz - buildPlane( 'x', 'y', - 1, - 1, width, height, - depth_half, 5 ); // nz - - function buildPlane( u, v, udir, vdir, width, height, depth, materialIndex ) { - - var w, ix, iy, - gridX = scope.widthSegments, - gridY = scope.heightSegments, - width_half = width / 2, - height_half = height / 2, - offset = scope.vertices.length; - - if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) { - - w = 'z'; - - } else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) { - - w = 'y'; - gridY = scope.depthSegments; - - } else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) { - - w = 'x'; - gridX = scope.depthSegments; - - } - - var gridX1 = gridX + 1, - gridY1 = gridY + 1, - segment_width = width / gridX, - segment_height = height / gridY, - normal = new THREE.Vector3(); - - normal[ w ] = depth > 0 ? 1 : - 1; - - for ( iy = 0; iy < gridY1; iy ++ ) { - - for ( ix = 0; ix < gridX1; ix ++ ) { - - var vector = new THREE.Vector3(); - vector[ u ] = ( ix * segment_width - width_half ) * udir; - vector[ v ] = ( iy * segment_height - height_half ) * vdir; - vector[ w ] = depth; - - scope.vertices.push( vector ); - - } - - } - - for ( iy = 0; iy < gridY; iy ++ ) { - - for ( ix = 0; ix < gridX; ix ++ ) { - - var a = ix + gridX1 * iy; - var b = ix + gridX1 * ( iy + 1 ); - var c = ( ix + 1 ) + gridX1 * ( iy + 1 ); - var d = ( ix + 1 ) + gridX1 * iy; - - var uva = new THREE.Vector2( ix / gridX, 1 - iy / gridY ); - var uvb = new THREE.Vector2( ix / gridX, 1 - ( iy + 1 ) / gridY ); - var uvc = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - ( iy + 1 ) / gridY ); - var uvd = new THREE.Vector2( ( ix + 1 ) / gridX, 1 - iy / gridY ); - - var face = new THREE.Face3( a + offset, b + offset, d + offset ); - face.normal.copy( normal ); - face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() ); - face.materialIndex = materialIndex; - - scope.faces.push( face ); - scope.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] ); - - face = new THREE.Face3( b + offset, c + offset, d + offset ); - face.normal.copy( normal ); - face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone() ); - face.materialIndex = materialIndex; - - scope.faces.push( face ); - scope.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] ); - - } - - } - - } - + this.fromBufferGeometry( new THREE.BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) ); this.mergeVertices(); }; @@ -36117,6 +36536,203 @@ THREE.BoxGeometry.prototype.constructor = THREE.BoxGeometry; THREE.CubeGeometry = THREE.BoxGeometry; +// File:src/extras/geometries/BoxBufferGeometry.js + +/** + * @author Mugen87 / https://github.com/Mugen87 + */ + +THREE.BoxBufferGeometry = function ( width, height, depth, widthSegments, heightSegments, depthSegments ) { + + THREE.BufferGeometry.call( this ); + + this.type = 'BoxBufferGeometry'; + + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; + + var scope = this; + + // segments + widthSegments = Math.floor( widthSegments ) || 1; + heightSegments = Math.floor( heightSegments ) || 1; + depthSegments = Math.floor( depthSegments ) || 1; + + // these are used to calculate buffer length + var vertexCount = calculateVertexCount( widthSegments, heightSegments, depthSegments ); + var indexCount = calculateIndexCount( widthSegments, heightSegments, depthSegments ); + + // buffers + var indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ); + var vertices = new Float32Array( vertexCount * 3 ); + var normals = new Float32Array( vertexCount * 3 ); + var uvs = new Float32Array( vertexCount * 2 ); + + // offset variables + var vertexBufferOffset = 0; + var uvBufferOffset = 0; + var indexBufferOffset = 0; + var numberOfVertices = 0; + + // group variables + var groupStart = 0; + + // build each side of the box geometry + buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px + buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx + buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py + buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny + buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz + buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + + // build geometry + this.setIndex( 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 ) ); + + // helper functions + + function calculateVertexCount ( w, h, d ) { + + var vertices = 0; + + // calculate the amount of vertices for each side (plane) + vertices += (w + 1) * (h + 1) * 2; // xy + vertices += (w + 1) * (d + 1) * 2; // xz + vertices += (d + 1) * (h + 1) * 2; // zy + + return vertices; + + } + + function calculateIndexCount ( w, h, d ) { + + var index = 0; + + // calculate the amount of squares for each side + index += w * h * 2; // xy + index += w * d * 2; // xz + index += d * h * 2; // zy + + return index * 6; // two triangles per square => six vertices per square + + } + + function buildPlane ( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + + var segmentWidth = width / gridX; + var segmentHeight = height / gridY; + + var widthHalf = width / 2; + var heightHalf = height / 2; + var depthHalf = depth / 2; + + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; + + var vertexCounter = 0; + var groupCount = 0; + + var vector = new THREE.Vector3(); + + // generate vertices, normals and uvs + + for ( var iy = 0; iy < gridY1; iy ++ ) { + + var y = iy * segmentHeight - heightHalf; + + for ( var ix = 0; ix < gridX1; ix ++ ) { + + var x = ix * segmentWidth - widthHalf; + + // set values to correct vector component + vector[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; + + // now apply vector to vertex buffer + vertices[ vertexBufferOffset ] = vector.x; + vertices[ vertexBufferOffset + 1 ] = vector.y; + vertices[ vertexBufferOffset + 2 ] = vector.z; + + // set values to correct vector component + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : - 1; + + // now apply vector to normal buffer + normals[ vertexBufferOffset ] = vector.x; + normals[ vertexBufferOffset + 1 ] = vector.y; + normals[ vertexBufferOffset + 2 ] = vector.z; + + // uvs + uvs[ uvBufferOffset ] = ix / gridX; + uvs[ uvBufferOffset + 1 ] = 1 - ( iy / gridY ); + + // update offsets and counters + vertexBufferOffset += 3; + uvBufferOffset += 2; + vertexCounter += 1; + + } + + } + + // 1. you need three indices to draw a single face + // 2. a single segment consists of two faces + // 3. so we need to generate six (2*3) indices per segment + + for ( iy = 0; iy < gridY; iy ++ ) { + + for ( ix = 0; ix < gridX; ix ++ ) { + + // indices + var a = numberOfVertices + ix + gridX1 * iy; + var b = numberOfVertices + ix + gridX1 * ( iy + 1 ); + var c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); + var d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + + // face one + indices[ indexBufferOffset ] = a; + indices[ indexBufferOffset + 1 ] = b; + indices[ indexBufferOffset + 2 ] = d; + + // face two + indices[ indexBufferOffset + 3 ] = b; + indices[ indexBufferOffset + 4 ] = c; + indices[ indexBufferOffset + 5 ] = d; + + // update offsets and counters + indexBufferOffset += 6; + groupCount += 6; + + } + + } + + // add a group to the geometry. this will ensure multi material support + scope.addGroup( groupStart, groupCount, materialIndex ); + + // calculate new start value for groups + groupStart += groupCount; + + // update total number of vertices + numberOfVertices += vertexCounter; + + } + +}; + +THREE.BoxBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.BoxBufferGeometry.prototype.constructor = THREE.BoxBufferGeometry; + // File:src/extras/geometries/CircleGeometry.js /** @@ -36213,6 +36829,332 @@ THREE.CircleBufferGeometry = function ( radius, segments, thetaStart, thetaLengt THREE.CircleBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); THREE.CircleBufferGeometry.prototype.constructor = THREE.CircleBufferGeometry; +// File:src/extras/geometries/CylinderBufferGeometry.js + +/** + * @author Mugen87 / https://github.com/Mugen87 + */ + +THREE.CylinderBufferGeometry = function( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) { + + THREE.BufferGeometry.call( this ); + + this.type = 'CylinderBufferGeometry'; + + this.parameters = { + radiusTop: radiusTop, + radiusBottom: radiusBottom, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + var scope = this; + + radiusTop = radiusTop !== undefined ? radiusTop : 20; + radiusBottom = radiusBottom !== undefined ? radiusBottom : 20; + height = height !== undefined ? height : 100; + + radialSegments = Math.floor( radialSegments ) || 8; + heightSegments = Math.floor( heightSegments ) || 1; + + openEnded = openEnded !== undefined ? openEnded : false; + thetaStart = thetaStart !== undefined ? thetaStart : 0.0; + thetaLength = thetaLength !== undefined ? thetaLength : 2.0 * Math.PI; + + // used to calculate buffer length + + var nbCap = 0; + + if ( openEnded === false ) { + + if ( radiusTop > 0 ) nbCap ++; + if ( radiusBottom > 0 ) nbCap ++; + + } + + var vertexCount = calculateVertexCount(); + var indexCount = calculateIndexCount(); + + // buffers + + var indices = new THREE.BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ), 1 ); + var vertices = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var normals = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new THREE.BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // helper variables + + var index = 0, + indexOffset = 0, + indexArray = [], + halfHeight = height / 2; + + // group variables + var groupStart = 0; + + // generate geometry + + generateTorso(); + + if ( openEnded === false ) { + + if ( radiusTop > 0 ) generateCap( true ); + if ( radiusBottom > 0 ) generateCap( false ); + + } + + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', vertices ); + this.addAttribute( 'normal', normals ); + this.addAttribute( 'uv', uvs ); + + // helper functions + + function calculateVertexCount() { + + var count = ( radialSegments + 1 ) * ( heightSegments + 1 ); + + if ( openEnded === false ) { + + count += ( ( radialSegments + 1 ) * nbCap ) + ( radialSegments * nbCap ); + + } + + return count; + + } + + function calculateIndexCount() { + + var count = radialSegments * heightSegments * 2 * 3; + + if ( openEnded === false ) { + + count += radialSegments * nbCap * 3; + + } + + return count; + + } + + function generateTorso() { + + var x, y; + var normal = new THREE.Vector3(); + var vertex = new THREE.Vector3(); + + var groupCount = 0; + + // this will be used to calculate the normal + var tanTheta = ( radiusBottom - radiusTop ) / height; + + // generate vertices, normals and uvs + + for ( y = 0; y <= heightSegments; y ++ ) { + + var indexRow = []; + + var v = y / heightSegments; + + // calculate the radius of the current row + var radius = v * ( radiusBottom - radiusTop ) + radiusTop; + + for ( x = 0; x <= radialSegments; x ++ ) { + + var u = x / radialSegments; + + // vertex + vertex.x = radius * Math.sin( u * thetaLength + thetaStart ); + vertex.y = - v * height + halfHeight; + vertex.z = radius * Math.cos( u * thetaLength + thetaStart ); + vertices.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // normal + normal.copy( vertex ); + + // handle special case if radiusTop/radiusBottom is zero + + if ( ( radiusTop === 0 && y === 0 ) || ( radiusBottom === 0 && y === heightSegments ) ) { + + normal.x = Math.sin( u * thetaLength + thetaStart ); + normal.z = Math.cos( u * thetaLength + thetaStart ); + + } + + normal.setY( Math.sqrt( normal.x * normal.x + normal.z * normal.z ) * tanTheta ).normalize(); + normals.setXYZ( index, normal.x, normal.y, normal.z ); + + // uv + uvs.setXY( index, u, 1 - v ); + + // save index of vertex in respective row + indexRow.push( index ); + + // increase index + index ++; + + } + + // now save vertices of the row in our index array + indexArray.push( indexRow ); + + } + + // generate indices + + for ( x = 0; x < radialSegments; x ++ ) { + + for ( y = 0; y < heightSegments; y ++ ) { + + // we use the index array to access the correct indices + var i1 = indexArray[ y ][ x ]; + var i2 = indexArray[ y + 1 ][ x ]; + var i3 = indexArray[ y + 1 ][ x + 1 ]; + var i4 = indexArray[ y ][ x + 1 ]; + + // face one + indices.setX( indexOffset, i1 ); indexOffset ++; + indices.setX( indexOffset, i2 ); indexOffset ++; + indices.setX( indexOffset, i4 ); indexOffset ++; + + // face two + indices.setX( indexOffset, i2 ); indexOffset ++; + indices.setX( indexOffset, i3 ); indexOffset ++; + indices.setX( indexOffset, i4 ); indexOffset ++; + + // update counters + groupCount += 6; + + } + + } + + // add a group to the geometry. this will ensure multi material support + scope.addGroup( groupStart, groupCount, 0 ); + + // calculate new start value for groups + groupStart += groupCount; + + } + + function generateCap( top ) { + + var x, centerIndexStart, centerIndexEnd; + + var uv = new THREE.Vector2(); + var vertex = new THREE.Vector3(); + + var groupCount = 0; + + var radius = ( top === true ) ? radiusTop : radiusBottom; + var sign = ( top === true ) ? 1 : - 1; + + // save the index of the first center vertex + centerIndexStart = index; + + // first we generate the center vertex data of the cap. + // because the geometry needs one set of uvs per face, + // we must generate a center vertex per face/segment + + for ( x = 1; x <= radialSegments; x ++ ) { + + // vertex + vertices.setXYZ( index, 0, halfHeight * sign, 0 ); + + // normal + normals.setXYZ( index, 0, sign, 0 ); + + // uv + uv.x = 0.5; + uv.y = 0.5; + + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index ++; + + } + + // save the index of the last center vertex + centerIndexEnd = index; + + // now we generate the surrounding vertices, normals and uvs + + for ( x = 0; x <= radialSegments; x ++ ) { + + var u = x / radialSegments; + var theta = u * thetaLength + thetaStart; + + var cosTheta = Math.cos( theta ); + var sinTheta = Math.sin( theta ); + + // vertex + vertex.x = radius * sinTheta; + vertex.y = halfHeight * sign; + vertex.z = radius * cosTheta; + vertices.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // normal + normals.setXYZ( index, 0, sign, 0 ); + + // uv + uv.x = ( cosTheta * 0.5 ) + 0.5; + uv.y = ( sinTheta * 0.5 * sign ) + 0.5; + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index ++; + + } + + // generate indices + + for ( x = 0; x < radialSegments; x ++ ) { + + var c = centerIndexStart + x; + var i = centerIndexEnd + x; + + if ( top === true ) { + + // face top + indices.setX( indexOffset, i ); indexOffset ++; + indices.setX( indexOffset, i + 1 ); indexOffset ++; + indices.setX( indexOffset, c ); indexOffset ++; + + } else { + + // face bottom + indices.setX( indexOffset, i + 1 ); indexOffset ++; + indices.setX( indexOffset, i ); indexOffset ++; + indices.setX( indexOffset, c ); indexOffset ++; + + } + + // update counters + groupCount += 3; + + } + + // add a group to the geometry. this will ensure multi material support + scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 ); + + // calculate new start value for groups + groupStart += groupCount; + + } + +}; + +THREE.CylinderBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.CylinderBufferGeometry.prototype.constructor = THREE.CylinderBufferGeometry; + // File:src/extras/geometries/CylinderGeometry.js /** @@ -36236,158 +37178,79 @@ THREE.CylinderGeometry = function ( radiusTop, radiusBottom, height, radialSegme thetaLength: thetaLength }; - radiusTop = radiusTop !== undefined ? radiusTop : 20; - radiusBottom = radiusBottom !== undefined ? radiusBottom : 20; - height = height !== undefined ? height : 100; - - radialSegments = radialSegments || 8; - heightSegments = heightSegments || 1; - - openEnded = openEnded !== undefined ? openEnded : false; - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : 2 * Math.PI; - - var heightHalf = height / 2; - - var x, y, vertices = [], uvs = []; - - for ( y = 0; y <= heightSegments; y ++ ) { - - var verticesRow = []; - var uvsRow = []; - - var v = y / heightSegments; - var radius = v * ( radiusBottom - radiusTop ) + radiusTop; - - for ( x = 0; x <= radialSegments; x ++ ) { - - var u = x / radialSegments; - - var vertex = new THREE.Vector3(); - vertex.x = radius * Math.sin( u * thetaLength + thetaStart ); - vertex.y = - v * height + heightHalf; - vertex.z = radius * Math.cos( u * thetaLength + thetaStart ); - - this.vertices.push( vertex ); - - verticesRow.push( this.vertices.length - 1 ); - uvsRow.push( new THREE.Vector2( u, 1 - v ) ); - - } - - vertices.push( verticesRow ); - uvs.push( uvsRow ); - - } - - var tanTheta = ( radiusBottom - radiusTop ) / height; - var na, nb; - - for ( x = 0; x < radialSegments; x ++ ) { - - if ( radiusTop !== 0 ) { - - na = this.vertices[ vertices[ 0 ][ x ] ].clone(); - nb = this.vertices[ vertices[ 0 ][ x + 1 ] ].clone(); - - } else { - - na = this.vertices[ vertices[ 1 ][ x ] ].clone(); - nb = this.vertices[ vertices[ 1 ][ x + 1 ] ].clone(); - - } - - na.setY( Math.sqrt( na.x * na.x + na.z * na.z ) * tanTheta ).normalize(); - nb.setY( Math.sqrt( nb.x * nb.x + nb.z * nb.z ) * tanTheta ).normalize(); - - for ( y = 0; y < heightSegments; y ++ ) { - - var v1 = vertices[ y ][ x ]; - var v2 = vertices[ y + 1 ][ x ]; - var v3 = vertices[ y + 1 ][ x + 1 ]; - var v4 = vertices[ y ][ x + 1 ]; - - var n1 = na.clone(); - var n2 = na.clone(); - var n3 = nb.clone(); - var n4 = nb.clone(); - - var uv1 = uvs[ y ][ x ].clone(); - var uv2 = uvs[ y + 1 ][ x ].clone(); - var uv3 = uvs[ y + 1 ][ x + 1 ].clone(); - var uv4 = uvs[ y ][ x + 1 ].clone(); - - this.faces.push( new THREE.Face3( v1, v2, v4, [ n1, n2, n4 ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv4 ] ); - - this.faces.push( new THREE.Face3( v2, v3, v4, [ n2.clone(), n3, n4.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uv2.clone(), uv3, uv4.clone() ] ); - - } - - } - - // top cap - - if ( openEnded === false && radiusTop > 0 ) { - - this.vertices.push( new THREE.Vector3( 0, heightHalf, 0 ) ); - - for ( x = 0; x < radialSegments; x ++ ) { - - var v1 = vertices[ 0 ][ x ]; - var v2 = vertices[ 0 ][ x + 1 ]; - var v3 = this.vertices.length - 1; - - var n1 = new THREE.Vector3( 0, 1, 0 ); - var n2 = new THREE.Vector3( 0, 1, 0 ); - var n3 = new THREE.Vector3( 0, 1, 0 ); - - var uv1 = uvs[ 0 ][ x ].clone(); - var uv2 = uvs[ 0 ][ x + 1 ].clone(); - var uv3 = new THREE.Vector2( uv2.x, 0 ); - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ], undefined, 1 ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] ); - - } - - } - - // bottom cap - - if ( openEnded === false && radiusBottom > 0 ) { - - this.vertices.push( new THREE.Vector3( 0, - heightHalf, 0 ) ); - - for ( x = 0; x < radialSegments; x ++ ) { - - var v1 = vertices[ heightSegments ][ x + 1 ]; - var v2 = vertices[ heightSegments ][ x ]; - var v3 = this.vertices.length - 1; - - var n1 = new THREE.Vector3( 0, - 1, 0 ); - var n2 = new THREE.Vector3( 0, - 1, 0 ); - var n3 = new THREE.Vector3( 0, - 1, 0 ); - - var uv1 = uvs[ heightSegments ][ x + 1 ].clone(); - var uv2 = uvs[ heightSegments ][ x ].clone(); - var uv3 = new THREE.Vector2( uv2.x, 1 ); - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ], undefined, 2 ) ); - this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] ); - - } - - } - - this.computeFaceNormals(); + this.fromBufferGeometry( new THREE.CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) ); + this.mergeVertices(); }; THREE.CylinderGeometry.prototype = Object.create( THREE.Geometry.prototype ); THREE.CylinderGeometry.prototype.constructor = THREE.CylinderGeometry; +// File:src/extras/geometries/ConeBufferGeometry.js + +/* + * @author: abelnation / http://github.com/abelnation + */ + +THREE.ConeBufferGeometry = function ( + radius, height, + radialSegments, heightSegments, + openEnded, thetaStart, thetaLength ) { + + THREE.CylinderBufferGeometry.call( this, + 0, radius, height, + radialSegments, heightSegments, + openEnded, thetaStart, thetaLength ); + + this.type = 'ConeBufferGeometry'; + + this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + +}; + +THREE.ConeBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.ConeBufferGeometry.prototype.constructor = THREE.ConeBufferGeometry; + +// File:src/extras/geometries/ConeGeometry.js + +/** + * @author abelnation / http://github.com/abelnation + */ + +THREE.ConeGeometry = function ( + radius, height, + radialSegments, heightSegments, + openEnded, thetaStart, thetaLength ) { + + THREE.CylinderGeometry.call( this, + 0, radius, height, + radialSegments, heightSegments, + openEnded, thetaStart, thetaLength ); + + this.type = 'ConeGeometry'; + + this.parameters = { + radius: radius, + height: height, + radialSegments: radialSegments, + heightSegments: heightSegments, + openEnded: openEnded, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + +}; + +THREE.ConeGeometry.prototype = Object.create( THREE.CylinderGeometry.prototype ); +THREE.ConeGeometry.prototype.constructor = THREE.ConeGeometry; + // File:src/extras/geometries/EdgesGeometry.js /** @@ -36400,7 +37263,7 @@ THREE.EdgesGeometry = function ( geometry, thresholdAngle ) { thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1; - var thresholdDot = Math.cos( THREE.Math.degToRad( thresholdAngle ) ); + var thresholdDot = Math.cos( THREE.Math.DEG2RAD * thresholdAngle ); var edge = [ 0, 0 ], hash = {}; @@ -37327,6 +38190,165 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) { }; +// File:src/extras/geometries/LatheBufferGeometry.js + +/** + * @author Mugen87 / https://github.com/Mugen87 + */ + + // points - to create a closed torus, one must use a set of points + // like so: [ a, b, c, d, a ], see first is the same as last. + // segments - the number of circumference segments to create + // phiStart - the starting radian + // phiLength - the radian (0 to 2PI) range of the lathed section + // 2PI is a closed lathe, less than 2PI is a portion. + +THREE.LatheBufferGeometry = function ( points, segments, phiStart, phiLength ) { + + THREE.BufferGeometry.call( this ); + + this.type = 'LatheBufferGeometry'; + + this.parameters = { + points: points, + segments: segments, + phiStart: phiStart, + phiLength: phiLength + }; + + segments = Math.floor( segments ) || 12; + phiStart = phiStart || 0; + phiLength = phiLength || Math.PI * 2; + + // clamp phiLength so it's in range of [ 0, 2PI ] + phiLength = THREE.Math.clamp( phiLength, 0, Math.PI * 2 ); + + // these are used to calculate buffer length + var vertexCount = ( segments + 1 ) * points.length; + var indexCount = segments * points.length * 2 * 3; + + // buffers + var indices = new THREE.BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 ); + var vertices = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new THREE.BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // helper variables + var index = 0, indexOffset = 0, base; + var inversePointLength = 1.0 / ( points.length - 1 ); + var inverseSegments = 1.0 / segments; + var vertex = new THREE.Vector3(); + var uv = new THREE.Vector2(); + var i, j; + + // generate vertices and uvs + + for ( i = 0; i <= segments; i ++ ) { + + var phi = phiStart + i * inverseSegments * phiLength; + + var sin = Math.sin( phi ); + var cos = Math.cos( phi ); + + for ( j = 0; j <= ( points.length - 1 ); j ++ ) { + + // vertex + vertex.x = points[ j ].x * sin; + vertex.y = points[ j ].y; + vertex.z = points[ j ].x * cos; + vertices.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // uv + uv.x = i / segments; + uv.y = j / ( points.length - 1 ); + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index ++; + + } + + } + + // generate indices + + for ( i = 0; i < segments; i ++ ) { + + for ( j = 0; j < ( points.length - 1 ); j ++ ) { + + base = j + i * points.length; + + // indices + var a = base; + var b = base + points.length; + var c = base + points.length + 1; + var d = base + 1; + + // face one + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + // face two + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + } + + } + + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', vertices ); + this.addAttribute( 'uv', uvs ); + + // generate normals + + this.computeVertexNormals(); + + // if the geometry is closed, we need to average the normals along the seam. + // because the corresponding vertices are identical (but still have different UVs). + + if( phiLength === Math.PI * 2 ) { + + var normals = this.attributes.normal.array; + var n1 = new THREE.Vector3(); + var n2 = new THREE.Vector3(); + var n = new THREE.Vector3(); + + // this is the buffer offset for the last line of vertices + base = segments * points.length * 3; + + for( i = 0, j = 0; i < points.length; i ++, j += 3 ) { + + // select the normal of the vertex in the first line + n1.x = normals[ j + 0 ]; + n1.y = normals[ j + 1 ]; + n1.z = normals[ j + 2 ]; + + // select the normal of the vertex in the last line + n2.x = normals[ base + j + 0 ]; + n2.y = normals[ base + j + 1 ]; + n2.z = normals[ base + j + 2 ]; + + // average normals + n.addVectors( n1, n2 ).normalize(); + + // assign the new values to both normals + normals[ j + 0 ] = normals[ base + j + 0 ] = n.x; + normals[ j + 1 ] = normals[ base + j + 1 ] = n.y; + normals[ j + 2 ] = normals[ base + j + 2 ] = n.z; + + } // next row + + } + +}; + +THREE.LatheBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.LatheBufferGeometry.prototype.constructor = THREE.LatheBufferGeometry; + // File:src/extras/geometries/LatheGeometry.js /** @@ -37339,8 +38361,8 @@ THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) { // like so: [ a, b, c, d, a ], see first is the same as last. // segments - the number of circumference segments to create // phiStart - the starting radian -// phiLength - the radian (0 to 2*PI) range of the lathed section -// 2*pi is a closed lathe, less than 2PI is a portion. +// phiLength - the radian (0 to 2PI) range of the lathed section +// 2PI is a closed lathe, less than 2PI is a portion. THREE.LatheGeometry = function ( points, segments, phiStart, phiLength ) { @@ -37355,81 +38377,8 @@ THREE.LatheGeometry = function ( points, segments, phiStart, phiLength ) { phiLength: phiLength }; - segments = segments || 12; - phiStart = phiStart || 0; - phiLength = phiLength || 2 * Math.PI; - - var inversePointLength = 1.0 / ( points.length - 1 ); - var inverseSegments = 1.0 / segments; - - for ( var i = 0, il = segments; i <= il; i ++ ) { - - var phi = phiStart + i * inverseSegments * phiLength; - - var sin = Math.sin( phi ); - var cos = Math.cos( phi ); - - for ( var j = 0, jl = points.length; j < jl; j ++ ) { - - var point = points[ j ]; - - var vertex = new THREE.Vector3(); - - vertex.x = point.x * sin; - vertex.y = point.y; - vertex.z = point.x * cos; - - this.vertices.push( vertex ); - - } - - } - - var np = points.length; - - for ( var i = 0, il = segments; i < il; i ++ ) { - - for ( var j = 0, jl = points.length - 1; j < jl; j ++ ) { - - var base = j + np * i; - var a = base; - var b = base + np; - var c = base + 1 + np; - var d = base + 1; - - var u0 = i * inverseSegments; - var v0 = j * inversePointLength; - var u1 = u0 + inverseSegments; - var v1 = v0 + inversePointLength; - - this.faces.push( new THREE.Face3( a, b, d ) ); - - this.faceVertexUvs[ 0 ].push( [ - - new THREE.Vector2( u0, v0 ), - new THREE.Vector2( u1, v0 ), - new THREE.Vector2( u0, v1 ) - - ] ); - - this.faces.push( new THREE.Face3( b, c, d ) ); - - this.faceVertexUvs[ 0 ].push( [ - - new THREE.Vector2( u1, v0 ), - new THREE.Vector2( u1, v1 ), - new THREE.Vector2( u0, v1 ) - - ] ); - - - } - - } - + this.fromBufferGeometry( new THREE.LatheBufferGeometry( points, segments, phiStart, phiLength ) ); this.mergeVertices(); - this.computeFaceNormals(); - this.computeVertexNormals(); }; @@ -37562,6 +38511,129 @@ THREE.PlaneBufferGeometry = function ( width, height, widthSegments, heightSegme THREE.PlaneBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); THREE.PlaneBufferGeometry.prototype.constructor = THREE.PlaneBufferGeometry; +// File:src/extras/geometries/RingBufferGeometry.js + +/** + * @author Mugen87 / https://github.com/Mugen87 + */ + +THREE.RingBufferGeometry = function ( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) { + + THREE.BufferGeometry.call( this ); + + this.type = 'RingBufferGeometry'; + + this.parameters = { + innerRadius: innerRadius, + outerRadius: outerRadius, + thetaSegments: thetaSegments, + phiSegments: phiSegments, + thetaStart: thetaStart, + thetaLength: thetaLength + }; + + innerRadius = innerRadius || 20; + outerRadius = outerRadius || 50; + + thetaStart = thetaStart !== undefined ? thetaStart : 0; + thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; + + thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8; + phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1; + + // these are used to calculate buffer length + var vertexCount = ( thetaSegments + 1 ) * ( phiSegments + 1 ); + var indexCount = thetaSegments * phiSegments * 2 * 3; + + // buffers + var indices = new THREE.BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 ); + var vertices = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var normals = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new THREE.BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // some helper variables + var index = 0, indexOffset = 0, segment; + var radius = innerRadius; + var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments ); + var vertex = new THREE.Vector3(); + var uv = new THREE.Vector2(); + var j, i; + + // generate vertices, normals and uvs + + // values are generate from the inside of the ring to the outside + + for ( j = 0; j <= phiSegments; j ++ ) { + + for ( i = 0; i <= thetaSegments; i ++ ) { + + segment = thetaStart + i / thetaSegments * thetaLength; + + // vertex + vertex.x = radius * Math.cos( segment ); + vertex.y = radius * Math.sin( segment ); + vertices.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // normal + normals.setXYZ( index, 0, 0, 1 ); + + // uv + uv.x = ( vertex.x / outerRadius + 1 ) / 2; + uv.y = ( vertex.y / outerRadius + 1 ) / 2; + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index++; + + } + + // increase the radius for next row of vertices + radius += radiusStep; + + } + + // generate indices + + for ( j = 0; j < phiSegments; j ++ ) { + + var thetaSegmentLevel = j * ( thetaSegments + 1 ); + + for ( i = 0; i < thetaSegments; i ++ ) { + + segment = i + thetaSegmentLevel; + + // indices + var a = segment; + var b = segment + thetaSegments + 1; + var c = segment + thetaSegments + 2; + var d = segment + 1; + + // face one + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + + // face two + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + } + + } + + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', vertices ); + this.addAttribute( 'normal', normals ); + this.addAttribute( 'uv', uvs ); + +}; + +THREE.RingBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.RingBufferGeometry.prototype.constructor = THREE.RingBufferGeometry; + // File:src/extras/geometries/RingGeometry.js /** @@ -37583,74 +38655,7 @@ THREE.RingGeometry = function ( innerRadius, outerRadius, thetaSegments, phiSegm thetaLength: thetaLength }; - innerRadius = innerRadius || 0; - outerRadius = outerRadius || 50; - - thetaStart = thetaStart !== undefined ? thetaStart : 0; - thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2; - - thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8; - phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 8; - - var i, o, uvs = [], radius = innerRadius, radiusStep = ( ( outerRadius - innerRadius ) / phiSegments ); - - for ( i = 0; i < phiSegments + 1; i ++ ) { - - // concentric circles inside ring - - for ( o = 0; o < thetaSegments + 1; o ++ ) { - - // number of segments per circle - - var vertex = new THREE.Vector3(); - var segment = thetaStart + o / thetaSegments * thetaLength; - vertex.x = radius * Math.cos( segment ); - vertex.y = radius * Math.sin( segment ); - - this.vertices.push( vertex ); - uvs.push( new THREE.Vector2( ( vertex.x / outerRadius + 1 ) / 2, ( vertex.y / outerRadius + 1 ) / 2 ) ); - - } - - radius += radiusStep; - - } - - var n = new THREE.Vector3( 0, 0, 1 ); - - for ( i = 0; i < phiSegments; i ++ ) { - - // concentric circles inside ring - - var thetaSegment = i * ( thetaSegments + 1 ); - - for ( o = 0; o < thetaSegments ; o ++ ) { - - // number of segments per circle - - var segment = o + thetaSegment; - - var v1 = segment; - var v2 = segment + thetaSegments + 1; - var v3 = segment + thetaSegments + 2; - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n.clone(), n.clone(), n.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uvs[ v1 ].clone(), uvs[ v2 ].clone(), uvs[ v3 ].clone() ] ); - - v1 = segment; - v2 = segment + thetaSegments + 2; - v3 = segment + 1; - - this.faces.push( new THREE.Face3( v1, v2, v3, [ n.clone(), n.clone(), n.clone() ] ) ); - this.faceVertexUvs[ 0 ].push( [ uvs[ v1 ].clone(), uvs[ v2 ].clone(), uvs[ v3 ].clone() ] ); - - } - - } - - this.computeFaceNormals(); - - this.boundingSphere = new THREE.Sphere( new THREE.Vector3(), radius ); + this.fromBufferGeometry( new THREE.RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) ); }; @@ -37845,6 +38850,135 @@ THREE.TextGeometry = function ( text, parameters ) { THREE.TextGeometry.prototype = Object.create( THREE.ExtrudeGeometry.prototype ); THREE.TextGeometry.prototype.constructor = THREE.TextGeometry; +// File:src/extras/geometries/TorusBufferGeometry.js + +/** + * @author Mugen87 / https://github.com/Mugen87 + */ + +THREE.TorusBufferGeometry = function ( radius, tube, radialSegments, tubularSegments, arc ) { + + THREE.BufferGeometry.call( this ); + + this.type = 'TorusBufferGeometry'; + + this.parameters = { + radius: radius, + tube: tube, + radialSegments: radialSegments, + tubularSegments: tubularSegments, + arc: arc + }; + + radius = radius || 100; + tube = tube || 40; + radialSegments = Math.floor( radialSegments ) || 8; + tubularSegments = Math.floor( tubularSegments ) || 6; + arc = arc || Math.PI * 2; + + // used to calculate buffer length + var vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) ); + var indexCount = radialSegments * tubularSegments * 2 * 3; + + // buffers + var indices = new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ); + var vertices = new Float32Array( vertexCount * 3 ); + var normals = new Float32Array( vertexCount * 3 ); + var uvs = new Float32Array( vertexCount * 2 ); + + // offset variables + var vertexBufferOffset = 0; + var uvBufferOffset = 0; + var indexBufferOffset = 0; + + // helper variables + var center = new THREE.Vector3(); + var vertex = new THREE.Vector3(); + var normal = new THREE.Vector3(); + + var j, i; + + // generate vertices, normals and uvs + + for ( j = 0; j <= radialSegments; j ++ ) { + + for ( i = 0; i <= tubularSegments; i ++ ) { + + var u = i / tubularSegments * arc; + var v = j / radialSegments * Math.PI * 2; + + // vertex + vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); + vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); + vertex.z = tube * Math.sin( v ); + + vertices[ vertexBufferOffset ] = vertex.x; + vertices[ vertexBufferOffset + 1 ] = vertex.y; + vertices[ vertexBufferOffset + 2 ] = vertex.z; + + // this vector is used to calculate the normal + center.x = radius * Math.cos( u ); + center.y = radius * Math.sin( u ); + + // normal + normal.subVectors( vertex, center ).normalize(); + + normals[ vertexBufferOffset ] = normal.x; + normals[ vertexBufferOffset + 1 ] = normal.y; + normals[ vertexBufferOffset + 2 ] = normal.z; + + // uv + uvs[ uvBufferOffset ] = i / tubularSegments; + uvs[ uvBufferOffset + 1 ] = j / radialSegments; + + // update offsets + vertexBufferOffset += 3; + uvBufferOffset += 2; + + } + + } + + // generate indices + + for ( j = 1; j <= radialSegments; j ++ ) { + + for ( i = 1; i <= tubularSegments; i ++ ) { + + // indices + var a = ( tubularSegments + 1 ) * j + i - 1; + var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; + var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; + var d = ( tubularSegments + 1 ) * j + i; + + // face one + indices[ indexBufferOffset ] = a; + indices[ indexBufferOffset + 1 ] = b; + indices[ indexBufferOffset + 2 ] = d; + + // face two + indices[ indexBufferOffset + 3 ] = b; + indices[ indexBufferOffset + 4 ] = c; + indices[ indexBufferOffset + 5 ] = d; + + // update offset + indexBufferOffset += 6; + + } + + } + + // build geometry + this.setIndex( 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 ) ); + +}; + +THREE.TorusBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.TorusBufferGeometry.prototype.constructor = THREE.TorusBufferGeometry; + // File:src/extras/geometries/TorusGeometry.js /** @@ -37867,74 +39001,187 @@ THREE.TorusGeometry = function ( radius, tube, radialSegments, tubularSegments, arc: arc }; - radius = radius || 100; - tube = tube || 40; - radialSegments = radialSegments || 8; - tubularSegments = tubularSegments || 6; - arc = arc || Math.PI * 2; - - var center = new THREE.Vector3(), uvs = [], normals = []; - - for ( var j = 0; j <= radialSegments; j ++ ) { - - for ( var i = 0; i <= tubularSegments; i ++ ) { - - var u = i / tubularSegments * arc; - var v = j / radialSegments * Math.PI * 2; - - center.x = radius * Math.cos( u ); - center.y = radius * Math.sin( u ); - - var vertex = new THREE.Vector3(); - vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); - vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); - vertex.z = tube * Math.sin( v ); - - this.vertices.push( vertex ); - - uvs.push( new THREE.Vector2( i / tubularSegments, j / radialSegments ) ); - normals.push( vertex.clone().sub( center ).normalize() ); - - } - - } - - for ( var j = 1; j <= radialSegments; j ++ ) { - - for ( var i = 1; i <= tubularSegments; i ++ ) { - - var a = ( tubularSegments + 1 ) * j + i - 1; - var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; - var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; - var d = ( tubularSegments + 1 ) * j + i; - - var face = new THREE.Face3( a, b, d, [ normals[ a ].clone(), normals[ b ].clone(), normals[ d ].clone() ] ); - this.faces.push( face ); - this.faceVertexUvs[ 0 ].push( [ uvs[ a ].clone(), uvs[ b ].clone(), uvs[ d ].clone() ] ); - - face = new THREE.Face3( b, c, d, [ normals[ b ].clone(), normals[ c ].clone(), normals[ d ].clone() ] ); - this.faces.push( face ); - this.faceVertexUvs[ 0 ].push( [ uvs[ b ].clone(), uvs[ c ].clone(), uvs[ d ].clone() ] ); - - } - - } - - this.computeFaceNormals(); + this.fromBufferGeometry( new THREE.TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) ); }; THREE.TorusGeometry.prototype = Object.create( THREE.Geometry.prototype ); THREE.TorusGeometry.prototype.constructor = THREE.TorusGeometry; +// File:src/extras/geometries/TorusKnotBufferGeometry.js + +/** + * @author Mugen87 / https://github.com/Mugen87 + * + * see: http://www.blackpawn.com/texts/pqtorus/ + */ +THREE.TorusKnotBufferGeometry = function ( radius, tube, tubularSegments, radialSegments, p, q ) { + + THREE.BufferGeometry.call( this ); + + this.type = 'TorusKnotBufferGeometry'; + + this.parameters = { + radius: radius, + tube: tube, + tubularSegments: tubularSegments, + radialSegments: radialSegments, + p: p, + q: q + }; + + radius = radius || 100; + tube = tube || 40; + tubularSegments = Math.floor( tubularSegments ) || 64; + radialSegments = Math.floor( radialSegments ) || 8; + p = p || 2; + q = q || 3; + + // used to calculate buffer length + var vertexCount = ( ( radialSegments + 1 ) * ( tubularSegments + 1 ) ); + var indexCount = radialSegments * tubularSegments * 2 * 3; + + // buffers + var indices = new THREE.BufferAttribute( new ( indexCount > 65535 ? Uint32Array : Uint16Array )( indexCount ) , 1 ); + var vertices = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var normals = new THREE.BufferAttribute( new Float32Array( vertexCount * 3 ), 3 ); + var uvs = new THREE.BufferAttribute( new Float32Array( vertexCount * 2 ), 2 ); + + // helper variables + var i, j, index = 0, indexOffset = 0; + + var vertex = new THREE.Vector3(); + var normal = new THREE.Vector3(); + var uv = new THREE.Vector2(); + + var P1 = new THREE.Vector3(); + var P2 = new THREE.Vector3(); + + var B = new THREE.Vector3(); + var T = new THREE.Vector3(); + var N = new THREE.Vector3(); + + // generate vertices, normals and uvs + + for ( i = 0; i <= tubularSegments; ++ i ) { + + // the radian "u" is used to calculate the position on the torus curve of the current tubular segement + + var u = i / tubularSegments * p * Math.PI * 2; + + // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead. + // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions + + calculatePositionOnCurve( u, p, q, radius, P1 ); + calculatePositionOnCurve( u + 0.01, p, q, radius, P2 ); + + // calculate orthonormal basis + + T.subVectors( P2, P1 ); + N.addVectors( P2, P1 ); + B.crossVectors( T, N ); + N.crossVectors( B, T ); + + // normalize B, N. T can be ignored, we don't use it + + B.normalize(); + N.normalize(); + + for ( j = 0; j <= radialSegments; ++ j ) { + + // now calculate the vertices. they are nothing more than an extrusion of the torus curve. + // because we extrude a shape in the xy-plane, there is no need to calculate a z-value. + + var v = j / radialSegments * Math.PI * 2; + var cx = - tube * Math.cos( v ); + var cy = tube * Math.sin( v ); + + // now calculate the final vertex position. + // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve + + vertex.x = P1.x + ( cx * N.x + cy * B.x ); + vertex.y = P1.y + ( cx * N.y + cy * B.y ); + vertex.z = P1.z + ( cx * N.z + cy * B.z ); + + // vertex + vertices.setXYZ( index, vertex.x, vertex.y, vertex.z ); + + // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal) + normal.subVectors( vertex, P1 ).normalize(); + normals.setXYZ( index, normal.x, normal.y, normal.z ); + + // uv + uv.x = i / tubularSegments; + uv.y = j / radialSegments; + uvs.setXY( index, uv.x, uv.y ); + + // increase index + index ++; + + } + + } + + // generate indices + + for ( j = 1; j <= tubularSegments; j ++ ) { + + for ( i = 1; i <= radialSegments; i ++ ) { + + // indices + var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 ); + var b = ( radialSegments + 1 ) * j + ( i - 1 ); + var c = ( radialSegments + 1 ) * j + i; + var d = ( radialSegments + 1 ) * ( j - 1 ) + i; + + // face one + indices.setX( indexOffset, a ); indexOffset++; + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + // face two + indices.setX( indexOffset, b ); indexOffset++; + indices.setX( indexOffset, c ); indexOffset++; + indices.setX( indexOffset, d ); indexOffset++; + + } + + } + + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', vertices ); + this.addAttribute( 'normal', normals ); + this.addAttribute( 'uv', uvs ); + + // this function calculates the current position on the torus curve + + function calculatePositionOnCurve( u, p, q, radius, position ) { + + var cu = Math.cos( u ); + var su = Math.sin( u ); + var quOverP = q / p * u; + var cs = Math.cos( quOverP ); + + position.x = radius * ( 2 + cs ) * 0.5 * cu; + position.y = radius * ( 2 + cs ) * su * 0.5; + position.z = radius * Math.sin( quOverP ) * 0.5; + + } + +}; + +THREE.TorusKnotBufferGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +THREE.TorusKnotBufferGeometry.prototype.constructor = THREE.TorusKnotBufferGeometry; + // File:src/extras/geometries/TorusKnotGeometry.js /** * @author oosmoxiecode - * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473 */ -THREE.TorusKnotGeometry = function ( radius, tube, radialSegments, tubularSegments, p, q, heightScale ) { +THREE.TorusKnotGeometry = function ( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) { THREE.Geometry.call( this ); @@ -37943,101 +39190,16 @@ THREE.TorusKnotGeometry = function ( radius, tube, radialSegments, tubularSegmen this.parameters = { radius: radius, tube: tube, - radialSegments: radialSegments, tubularSegments: tubularSegments, + radialSegments: radialSegments, p: p, - q: q, - heightScale: heightScale + q: q }; - radius = radius || 100; - tube = tube || 40; - radialSegments = radialSegments || 64; - tubularSegments = tubularSegments || 8; - p = p || 2; - q = q || 3; - heightScale = heightScale || 1; + if( heightScale !== undefined ) console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); - var grid = new Array( radialSegments ); - var tang = new THREE.Vector3(); - var n = new THREE.Vector3(); - var bitan = new THREE.Vector3(); - - for ( var i = 0; i < radialSegments; ++ i ) { - - grid[ i ] = new Array( tubularSegments ); - var u = i / radialSegments * 2 * p * Math.PI; - var p1 = getPos( u, q, p, radius, heightScale ); - var p2 = getPos( u + 0.01, q, p, radius, heightScale ); - tang.subVectors( p2, p1 ); - n.addVectors( p2, p1 ); - - bitan.crossVectors( tang, n ); - n.crossVectors( bitan, tang ); - bitan.normalize(); - n.normalize(); - - for ( var j = 0; j < tubularSegments; ++ j ) { - - var v = j / tubularSegments * 2 * Math.PI; - var cx = - tube * Math.cos( v ); // TODO: Hack: Negating it so it faces outside. - var cy = tube * Math.sin( v ); - - var pos = new THREE.Vector3(); - pos.x = p1.x + cx * n.x + cy * bitan.x; - pos.y = p1.y + cx * n.y + cy * bitan.y; - pos.z = p1.z + cx * n.z + cy * bitan.z; - - grid[ i ][ j ] = this.vertices.push( pos ) - 1; - - } - - } - - for ( var i = 0; i < radialSegments; ++ i ) { - - for ( var j = 0; j < tubularSegments; ++ j ) { - - var ip = ( i + 1 ) % radialSegments; - var jp = ( j + 1 ) % tubularSegments; - - var a = grid[ i ][ j ]; - var b = grid[ ip ][ j ]; - var c = grid[ ip ][ jp ]; - var d = grid[ i ][ jp ]; - - var uva = new THREE.Vector2( i / radialSegments, j / tubularSegments ); - var uvb = new THREE.Vector2( ( i + 1 ) / radialSegments, j / tubularSegments ); - var uvc = new THREE.Vector2( ( i + 1 ) / radialSegments, ( j + 1 ) / tubularSegments ); - var uvd = new THREE.Vector2( i / radialSegments, ( j + 1 ) / tubularSegments ); - - this.faces.push( new THREE.Face3( a, b, d ) ); - this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvd ] ); - - this.faces.push( new THREE.Face3( b, c, d ) ); - this.faceVertexUvs[ 0 ].push( [ uvb.clone(), uvc, uvd.clone() ] ); - - } - - } - - this.computeFaceNormals(); - this.computeVertexNormals(); - - function getPos( u, in_q, in_p, radius, heightScale ) { - - var cu = Math.cos( u ); - var su = Math.sin( u ); - var quOverP = in_q / in_p * u; - var cs = Math.cos( quOverP ); - - var tx = radius * ( 2 + cs ) * 0.5 * cu; - var ty = radius * ( 2 + cs ) * su * 0.5; - var tz = heightScale * radius * Math.sin( quOverP ) * 0.5; - - return new THREE.Vector3( tx, ty, tz ); - - } + this.fromBufferGeometry( new THREE.TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) ); + this.mergeVertices(); }; @@ -39083,10 +40245,10 @@ THREE.AxisHelper.prototype.constructor = THREE.AxisHelper; THREE.ArrowHelper = ( function () { - var lineGeometry = new THREE.Geometry(); - lineGeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 1, 0 ) ); + var lineGeometry = new THREE.BufferGeometry(); + lineGeometry.addAttribute( 'position', new THREE.Float32Attribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) ); - var coneGeometry = new THREE.CylinderGeometry( 0, 0.5, 1, 5, 1 ); + var coneGeometry = new THREE.CylinderBufferGeometry( 0, 0.5, 1, 5, 1 ); coneGeometry.translate( 0, - 0.5, 0 ); return function ArrowHelper( dir, origin, length, color, headLength, headWidth ) { @@ -39101,7 +40263,7 @@ THREE.ArrowHelper = ( function () { if ( headWidth === undefined ) headWidth = 0.2 * headLength; this.position.copy( origin ); - + this.line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: color } ) ); this.line.matrixAutoUpdate = false; this.add( this.line ); @@ -39113,7 +40275,7 @@ THREE.ArrowHelper = ( function () { this.setDirection( dir ); this.setLength( length, headLength, headWidth ); - } + }; }() ); @@ -39167,8 +40329,8 @@ THREE.ArrowHelper.prototype.setLength = function ( length, headLength, headWidth THREE.ArrowHelper.prototype.setColor = function ( color ) { - this.line.material.color.set( color ); - this.cone.material.color.set( color ); + this.line.material.color.copy( color ); + this.cone.material.color.copy( color ); }; @@ -39206,7 +40368,15 @@ THREE.BoxHelper.prototype.update = ( function () { return function ( object ) { - box.setFromObject( object ); + if ( object instanceof THREE.Box3 ) { + + box.copy( object ); + + } else { + + box.setFromObject( object ); + + } if ( box.isEmpty() ) return; @@ -39492,34 +40662,25 @@ THREE.DirectionalLightHelper = function ( light, size ) { this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; - size = size || 1; + if ( size === undefined ) size = 1; - var geometry = new THREE.Geometry(); - geometry.vertices.push( - new THREE.Vector3( - size, size, 0 ), - new THREE.Vector3( size, size, 0 ), - new THREE.Vector3( size, - size, 0 ), - new THREE.Vector3( - size, - size, 0 ), - new THREE.Vector3( - size, size, 0 ) - ); + var geometry = new THREE.BufferGeometry(); + geometry.addAttribute( 'position', new THREE.Float32Attribute( [ + - size, size, 0, + size, size, 0, + size, - size, 0, + - size, - size, 0, + - size, size, 0 + ], 3 ) ); var material = new THREE.LineBasicMaterial( { fog: false } ); - material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - this.lightPlane = new THREE.Line( geometry, material ); - this.add( this.lightPlane ); + this.add( new THREE.Line( geometry, material ) ); - geometry = new THREE.Geometry(); - geometry.vertices.push( - new THREE.Vector3(), - new THREE.Vector3() - ); + geometry = new THREE.BufferGeometry(); + geometry.addAttribute( 'position', new THREE.Float32Attribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) ); - material = new THREE.LineBasicMaterial( { fog: false } ); - material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); - - this.targetLine = new THREE.Line( geometry, material ); - this.add( this.targetLine ); + this.add( new THREE.Line( geometry, material )); this.update(); @@ -39530,10 +40691,13 @@ THREE.DirectionalLightHelper.prototype.constructor = THREE.DirectionalLightHelpe THREE.DirectionalLightHelper.prototype.dispose = function () { - this.lightPlane.geometry.dispose(); - this.lightPlane.material.dispose(); - this.targetLine.geometry.dispose(); - this.targetLine.material.dispose(); + var lightPlane = this.children[ 0 ]; + var targetLine = this.children[ 1 ]; + + lightPlane.geometry.dispose(); + lightPlane.material.dispose(); + targetLine.geometry.dispose(); + targetLine.material.dispose(); }; @@ -39549,12 +40713,14 @@ THREE.DirectionalLightHelper.prototype.update = function () { v2.setFromMatrixPosition( this.light.target.matrixWorld ); v3.subVectors( v2, v1 ); - this.lightPlane.lookAt( v3 ); - this.lightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); + var lightPlane = this.children[ 0 ]; + var targetLine = this.children[ 1 ]; - this.targetLine.geometry.vertices[ 1 ].copy( v3 ); - this.targetLine.geometry.verticesNeedUpdate = true; - this.targetLine.material.color.copy( this.lightPlane.material.color ); + lightPlane.lookAt( v3 ); + lightPlane.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); + + targetLine.lookAt( v3 ); + targetLine.scale.z = v3.length(); }; @@ -39695,7 +40861,7 @@ THREE.FaceNormalsHelper.prototype.update = ( function () { return this; - } + }; }() ); @@ -39705,27 +40871,34 @@ THREE.FaceNormalsHelper.prototype.update = ( function () { * @author mrdoob / http://mrdoob.com/ */ -THREE.GridHelper = function ( size, step ) { +THREE.GridHelper = function ( size, step, color1, color2 ) { - var geometry = new THREE.Geometry(); - var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } ); + color1 = new THREE.Color( color1 !== undefined ? color1 : 0x444444 ); + color2 = new THREE.Color( color2 !== undefined ? color2 : 0x888888 ); - this.color1 = new THREE.Color( 0x444444 ); - this.color2 = new THREE.Color( 0x888888 ); + var vertices = []; + var colors = []; - for ( var i = - size; i <= size; i += step ) { + for ( var i = - size, j = 0; i <= size; i += step ) { - geometry.vertices.push( - new THREE.Vector3( - size, 0, i ), new THREE.Vector3( size, 0, i ), - new THREE.Vector3( i, 0, - size ), new THREE.Vector3( i, 0, size ) - ); + vertices.push( - size, 0, i, size, 0, i ); + vertices.push( i, 0, - size, i, 0, size ); - var color = i === 0 ? this.color1 : this.color2; + var color = i === 0 ? color1 : color2; - geometry.colors.push( color, color, color, color ); + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; + color.toArray( colors, j ); j += 3; } + var geometry = new THREE.BufferGeometry(); + geometry.addAttribute( 'position', new THREE.Float32Attribute( vertices, 3 ) ); + geometry.addAttribute( 'color', new THREE.Float32Attribute( colors, 3 ) ); + + var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } ); + THREE.LineSegments.call( this, geometry, material ); }; @@ -39733,12 +40906,9 @@ THREE.GridHelper = function ( size, step ) { THREE.GridHelper.prototype = Object.create( THREE.LineSegments.prototype ); THREE.GridHelper.prototype.constructor = THREE.GridHelper; -THREE.GridHelper.prototype.setColors = function( colorCenterLine, colorGrid ) { +THREE.GridHelper.prototype.setColors = function () { - this.color1.set( colorCenterLine ); - this.color2.set( colorGrid ); - - this.geometry.colorsNeedUpdate = true; + console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' ); }; @@ -39801,7 +40971,7 @@ THREE.HemisphereLightHelper.prototype.update = function () { this.lightSphere.lookAt( vector.setFromMatrixPosition( this.light.matrixWorld ).negate() ); this.lightSphere.geometry.colorsNeedUpdate = true; - } + }; }(); @@ -39817,7 +40987,7 @@ THREE.PointLightHelper = function ( light, sphereSize ) { this.light = light; this.light.updateMatrixWorld(); - var geometry = new THREE.SphereGeometry( sphereSize, 4, 2 ); + var geometry = new THREE.SphereBufferGeometry( sphereSize, 4, 2 ); var material = new THREE.MeshBasicMaterial( { wireframe: true, fog: false } ); material.color.copy( this.light.color ).multiplyScalar( this.light.intensity ); @@ -40002,14 +41172,33 @@ THREE.SpotLightHelper = function ( light ) { this.matrix = light.matrixWorld; this.matrixAutoUpdate = false; - var geometry = new THREE.CylinderGeometry( 0, 1, 1, 8, 1, true ); + var geometry = new THREE.BufferGeometry(); - geometry.translate( 0, - 0.5, 0 ); - geometry.rotateX( - Math.PI / 2 ); + var positions = [ + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 1, + 0, 0, 0, - 1, 0, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, - 1, 1 + ]; - var material = new THREE.MeshBasicMaterial( { wireframe: true, fog: false } ); + for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) { - this.cone = new THREE.Mesh( geometry, material ); + var p1 = ( i / l ) * Math.PI * 2; + var p2 = ( j / l ) * Math.PI * 2; + + positions.push( + Math.cos( p1 ), Math.sin( p1 ), 1, + Math.cos( p2 ), Math.sin( p2 ), 1 + ); + + } + + geometry.addAttribute( 'position', new THREE.Float32Attribute( positions, 3 ) ); + + var material = new THREE.LineBasicMaterial( { fog: false } ); + + this.cone = new THREE.LineSegments( geometry, material ); this.add( this.cone ); this.update(); @@ -40033,7 +41222,7 @@ THREE.SpotLightHelper.prototype.update = function () { return function () { - var coneLength = this.light.distance ? this.light.distance : 10000; + var coneLength = this.light.distance ? this.light.distance : 1000; var coneWidth = coneLength * Math.tan( this.light.angle ); this.cone.scale.set( coneWidth, coneWidth, coneLength ); @@ -40078,7 +41267,7 @@ THREE.VertexNormalsHelper = function ( object, size, hex, linewidth ) { } else if ( objGeometry instanceof THREE.BufferGeometry ) { - nNormals = objGeometry.attributes.normal.count + nNormals = objGeometry.attributes.normal.count; } @@ -40193,7 +41382,7 @@ THREE.VertexNormalsHelper.prototype.update = ( function () { return this; - } + }; }() ); diff --git a/examples/vendor/three.min.js b/examples/vendor/three.min.js index 74aa67b..050cf06 100644 --- a/examples/vendor/three.min.js +++ b/examples/vendor/three.min.js @@ -1,12 +1,12 @@ // threejs.org/license -'use strict';var THREE={REVISION:"74"};"function"===typeof define&&define.amd?define("three",THREE):"undefined"!==typeof exports&&"undefined"!==typeof module&&(module.exports=THREE);void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52));void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0a?-1:0>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(){function a(a,c,d){0>d&&(d+=1);1d?c:d<2/3?a+6*(c-a)*(2/3-d):a}return function(b,c,d){b=THREE.Math.euclideanModulo(b,1);c=THREE.Math.clamp(c,0,1);d=THREE.Math.clamp(d,0,1);0===c?this.r=this.g=this.b=d:(c=.5>=d?d*(1+c):d+c-d*c,d=2*d-c,this.r=a(d,c,b+1/3),this.g=a(d,c,b),this.b=a(d,c,b-1/3));return this}}(),setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c= /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){var d= @@ -25,56 +25,57 @@ tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215, THREE.Quaternion.prototype={constructor:THREE.Quaternion,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get w(){return this._w},set w(a){this._w=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._w=d;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)}, copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z;this._w=a.w;this.onChangeCallback();return this},setFromEuler:function(a,b){if(!1===a instanceof THREE.Euler)throw Error("THREE.Quaternion: .setFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var c=Math.cos(a._x/2),d=Math.cos(a._y/2),e=Math.cos(a._z/2),f=Math.sin(a._x/2),g=Math.sin(a._y/2),h=Math.sin(a._z/2),k=a.order;"XYZ"===k?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"YXZ"=== k?(this._x=f*d*e+c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e+f*g*h):"ZXY"===k?(this._x=f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e-f*g*h):"ZYX"===k?(this._x=f*d*e-c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e+f*g*h):"YZX"===k?(this._x=f*d*e+c*g*h,this._y=c*g*e+f*d*h,this._z=c*d*h-f*g*e,this._w=c*d*e-f*g*h):"XZY"===k&&(this._x=f*d*e-c*g*h,this._y=c*g*e-f*d*h,this._z=c*d*h+f*g*e,this._w=c*d*e+f*g*h);if(!1!==b)this.onChangeCallback();return this},setFromAxisAngle:function(a, -b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],m=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= -.25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;this.normalize();return this}}(),inverse:function(){this.conjugate().normalize();return this},conjugate:function(){this._x*= +b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],l=c+f+b;0f&&c>b?(c=2*Math.sqrt(1+c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y= +.25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=a.y;this._z=a.z;this._w=b;return this.normalize()}}(),inverse:function(){return this.conjugate().normalize()},conjugate:function(){this._x*= -1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this}, -multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,m=b._w;this._x=c*m+f*g+d*k-e*h;this._y=d*m+f*h+e*g-c*k;this._z=e*m+f*k+c*h-d*g;this._w=f*m-c*g-d*h-e*k;this.onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1=== -b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;var h=Math.sqrt(1-g*g);if(.001>Math.abs(h))return this._w=.5*(f+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;var k=Math.atan2(h,g),g=Math.sin((1-b)*k)/h,h=Math.sin(b*k)/h;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+ -this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}}; -Object.assign(THREE.Quaternion,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h=c[d+0],k=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var n=e[f+1],p=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==n||m!==p){f=1-g;var l=h*d+k*n+m*p+c*e,q=0<=l?1:-1,t=1-l*l;t>Number.EPSILON&&(t=Math.sqrt(t),l=Math.atan2(t,l*q),f=Math.sin(f*l)/t,g=Math.sin(g*l)/t);q*=g;h=h*f+d*q;k=k*f+n*q;m=m*f+p*q;c=c*f+e*q;f===1-g&&(g=1/Math.sqrt(h*h+k*k+m*m+c*c),h*=g,k*=g,m*=g,c*=g)}a[b]=h;a[b+1]=k;a[b+2]=m; +multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,k=b._z,l=b._w;this._x=c*l+f*g+d*k-e*h;this._y=d*l+f*h+e*g-c*k;this._z=e*l+f*k+c*h-d*g;this._w=f*l-c*g-d*h-e*k;this.onChangeCallback(); +return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;var h=Math.sqrt(1-g*g);if(.001>Math.abs(h))return this._w=.5*(f+this._w),this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;var k=Math.atan2(h,g),g=Math.sin((1-b)*k)/h,h=Math.sin(b* +k)/h;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback= +a;return this},onChangeCallback:function(){}}; +Object.assign(THREE.Quaternion,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h=c[d+0],k=c[d+1],l=c[d+2];c=c[d+3];d=e[f+0];var n=e[f+1],p=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==n||l!==p){f=1-g;var m=h*d+k*n+l*p+c*e,q=0<=m?1:-1,r=1-m*m;r>Number.EPSILON&&(r=Math.sqrt(r),m=Math.atan2(r,m*q),f=Math.sin(f*m)/r,g=Math.sin(g*m)/r);q*=g;h=h*f+d*q;k=k*f+n*q;l=l*f+p*q;c=c*f+e*q;f===1-g&&(g=1/Math.sqrt(h*h+k*k+l*l+c*c),h*=g,k*=g,l*=g,c*=g)}a[b]=h;a[b+1]=k;a[b+2]=l; a[b+3]=c}});THREE.Vector2=function(a,b){this.x=a||0;this.y=b||0}; THREE.Vector2.prototype={constructor:THREE.Vector2,get width(){return this.x},set width(a){this.x=a},get height(){return this.y},set height(a){this.y=a},set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x; case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this}, addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a, this.y*=a):this.y=this.x=0;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(){var a,b;return function(c,d){void 0=== -a&&(a=new THREE.Vector2,b=new THREE.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();this.multiplyScalar(Math.max(a,Math.min(b,c))/c);return this},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x): -Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length())},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+= -2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b]; -this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];return this},rotateAround:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=this.x-a.x,f=this.y-a.y;this.x=e*c-f*d+a.x;this.y=e*d+f*c+a.y;return this}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; +a&&(a=new THREE.Vector2,b=new THREE.Vector2);a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.multiplyScalar(Math.max(a,Math.min(b,c))/c)},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x); +this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length())},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a}, +distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this}, +toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];return this},rotateAround:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=this.x-a.x,f=this.y-a.y;this.x=e*c-f*d+a.x;this.y=e*d+f*c+a.y;return this}};THREE.Vector3=function(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}; THREE.Vector3.prototype={constructor:THREE.Vector3,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y; case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a, b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this}, multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a,this.z*=a):this.z=this.y=this.x=0;return this},multiplyVectors:function(a,b){this.x=a.x*b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a;return function(b){!1===b instanceof THREE.Euler&& -console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromEuler(b));return this}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);this.applyQuaternion(a.setFromAxisAngle(b,c));return this}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]* -d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x, -f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,m=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-m*-f;this.y=k*a+b*-f+m*-e-h*-g;this.z=m*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(), -transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;this.normalize();return this},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y); -this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();this.multiplyScalar(Math.max(a,Math.min(b,c))/c);return this},floor:function(){this.x=Math.floor(this.x); -this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x; -this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)* -b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},cross:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c=a.x,d=a.y,e=a.z,f=b.x,g=b.y,h=b.z;this.x=d*h-e*g; -this.y=e*f-c*h;this.z=c*g-d*f;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new THREE.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a= -this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setFromMatrixPosition:function(a){this.x=a.elements[12];this.y=a.elements[13];this.z=a.elements[14];return this},setFromMatrixScale:function(a){var b=this.set(a.elements[0],a.elements[1],a.elements[2]).length(),c=this.set(a.elements[4],a.elements[5], -a.elements[6]).length();a=this.set(a.elements[8],a.elements[9],a.elements[10]).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){var c=4*a,d=b.elements;this.x=d[c];this.y=d[c+1];this.z=d[c+2];return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a}, -fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; +console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");void 0===a&&(a=new THREE.Quaternion);return this.applyQuaternion(a.setFromEuler(b))}}(),applyAxisAngle:function(){var a;return function(b,c){void 0===a&&(a=new THREE.Quaternion);return this.applyQuaternion(a.setFromAxisAngle(b,c))}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this}, +applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12];this.y=a[1]*b+a[5]*c+a[9]*d+a[13];this.z=a[2]*b+a[6]*c+a[10]*d+a[14];return this},applyProjection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a= +a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,l=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-l*-f;this.y=k*a+b*-f+l*-e-h*-g;this.z=l*a+b*-g+h*-f-k*-e;return this},project:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyProjection(a)}}(),unproject:function(){var a;return function(b){void 0===a&&(a=new THREE.Matrix4);a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyProjection(a)}}(), +transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z= +Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector3,b=new THREE.Vector3);a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.multiplyScalar(Math.max(a,Math.min(b,c))/c)},floor:function(){this.x=Math.floor(this.x);this.y= +Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y= +-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+= +(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c=a.x,d=a.y,e=a.z,f=b.x,g=b.y,h=b.z;this.x=d*h-e*g;this.y=e*f-c*h; +this.z=c*g-d*f;return this},projectOnVector:function(){var a,b;return function(c){void 0===a&&(a=new THREE.Vector3);a.copy(c).normalize();b=this.dot(a);return this.copy(a).multiplyScalar(b)}}(),projectOnPlane:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);return this.sub(a.copy(b).multiplyScalar(2*this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/ +Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(THREE.Math.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},setFromSpherical:function(a){var b=Math.sin(a.phi)*a.radius;this.x=b*Math.sin(a.theta);this.y=Math.cos(a.phi)*a.radius;this.z=b*Math.cos(a.theta);return this},setFromMatrixPosition:function(a){return this.setFromMatrixColumn(a,3)},setFromMatrixScale:function(a){var b= +this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){if("number"===typeof a){console.warn("THREE.Vector3: setFromMatrixColumn now expects ( matrix, index ).");var c=a;a=b;b=c}return this.fromArray(a.elements,4*b)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+ +2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];return this}};THREE.Vector4=function(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}; THREE.Vector4.prototype={constructor:THREE.Vector4,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+ a);}},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z,this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b); this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-= a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){isFinite(a)?(this.x*=a,this.y*=a,this.z*=a,this.w*=a):this.w=this.z=this.y=this.x=0;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z= -a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var m=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01> -Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+m-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;m=(m+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>m?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>m?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h),b=d/c,d=k/c):.01>m?(c=b=.707106781,d=0):(d=Math.sqrt(m),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/ -a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z)); +a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var l=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01> +Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+l-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;l=(l+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>l?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>l?.01>h?(b=.707106781,c=0,d=.707106781):(c=Math.sqrt(h),b=d/c,d=k/c):.01>l?(c=b=.707106781,d=0):(d=Math.sqrt(l),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/ +a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+l-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z)); this.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new THREE.Vector4,b=new THREE.Vector4);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x= Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z* a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length())},setLength:function(a){return this.multiplyScalar(a/this.length())},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z- -this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){this.subVectors(b,a).multiplyScalar(c).add(a);return this},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+ +this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromAttribute:function(a,b,c){void 0===c&&(c=0);b=b*a.itemSize+ c;this.x=a.array[b];this.y=a.array[b+1];this.z=a.array[b+2];this.w=a.array[b+3];return this}};THREE.Euler=function(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||THREE.Euler.DefaultOrder};THREE.Euler.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");THREE.Euler.DefaultOrder="XYZ"; THREE.Euler.prototype={constructor:THREE.Euler,get x(){return this._x},set x(a){this._x=a;this.onChangeCallback()},get y(){return this._y},set y(a){this._y=a;this.onChangeCallback()},get z(){return this._z},set z(a){this._z=a;this.onChangeCallback()},get order(){return this._order},set order(a){this._order=a;this.onChangeCallback()},set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x, -this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],m=e[9],n=e[2],p=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(p,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.99999>Math.abs(m)? -(this._y=Math.atan2(g,e),this._z=Math.atan2(h,k)):(this._y=Math.atan2(-n,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(-n,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._x=Math.atan2(p,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-m,k),this._y=Math.atan2(-n,a)):(this._x= -0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(p,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);this.setFromRotationMatrix(a,c,d);return this}}(),setFromVector3:function(a, -b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+ -3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new THREE.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; +this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=THREE.Math.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],l=e[9],n=e[2],p=e[6],e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-l,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(p,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(l,-1,1)),.99999>Math.abs(l)? +(this._y=Math.atan2(g,e),this._z=Math.atan2(h,k)):(this._y=Math.atan2(-n,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(-n,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(n,-1,1)),.99999>Math.abs(n)?(this._x=Math.atan2(p,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-l,k),this._y=Math.atan2(-n,a)):(this._x= +0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(p,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-l,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a;return function(b,c,d){void 0===a&&(a=new THREE.Matrix4);a.makeRotationFromQuaternion(b);return this.setFromRotationMatrix(a,c,d)}}(),setFromVector3:function(a, +b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(){var a=new THREE.Quaternion;return function(b){a.setFromEuler(this);return this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z; +a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new THREE.Vector3(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}};THREE.Line3=function(a,b){this.start=void 0!==a?a:new THREE.Vector3;this.end=void 0!==b?b:new THREE.Vector3}; THREE.Line3.prototype={constructor:THREE.Line3,set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},center:function(a){return(a||new THREE.Vector3).addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){return(a||new THREE.Vector3).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)}, at:function(a,b){var c=b||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);var e=b.dot(b),e=b.dot(a)/e;d&&(e=THREE.Math.clamp(e,0,1));return e}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);c=c||new THREE.Vector3;return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a); this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}};THREE.Box2=function(a,b){this.min=void 0!==a?a:new THREE.Vector2(Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector2(-Infinity,-Infinity)}; @@ -83,45 +84,46 @@ return this},makeEmpty:function(){this.min.x=this.min.y=Infinity;this.max.x=this this.max.addScalar(a);return this},containsPoint:function(a){return a.xthis.max.x||a.ythis.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y?!0:!1},getParameter:function(a,b){return(b||new THREE.Vector2).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.y this.max.y?!1:!0},clampPoint:function(a,b){return(b||new THREE.Vector2).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new THREE.Vector2;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&& a.max.equals(this.max)}};THREE.Box3=function(a,b){this.min=void 0!==a?a:new THREE.Vector3(Infinity,Infinity,Infinity);this.max=void 0!==b?b:new THREE.Vector3(-Infinity,-Infinity,-Infinity)}; -THREE.Box3.prototype={constructor:THREE.Box3,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromArray:function(a){this.makeEmpty();for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.length;hthis.max.x||a.ythis.max.y||a.zthis.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<= -a.min.z&&a.max.z<=this.max.z?!0:!1},getParameter:function(a,b){return(b||new THREE.Vector3).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.zthis.max.z?!1:!0},intersectsSphere:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<= -b.radius*b.radius}}(),intersectsPlane:function(a){var b,c;0=a.constant},clampPoint:function(a,b){return(b||new THREE.Vector3).copy(a).clamp(this.min, -this.max)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new THREE.Vector3;return function(b){b=b||new THREE.Sphere;b.center=this.center();b.radius=.5*this.size(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new THREE.Vector3, -new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];return function(b){a[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x, -this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.makeEmpty();this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}};THREE.Matrix3=function(){this.elements=new Float32Array([1,0,0,0,1,0,0,0,1]);0this.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.elements.set(this.elements); -c=1/g;var f=1/h,m=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=m;b.elements[9]*=m;b.elements[10]*=m;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c);g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makePerspective:function(a, -b,c,d){a=c*Math.tan(THREE.Math.degToRad(.5*a));var e=-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=b-a,k=c-d,m=f-e;g[0]=2/h;g[4]=0;g[8]=0;g[12]=-((b+a)/h);g[1]=0;g[5]=2/k;g[9]=0;g[13]=-((c+d)/k);g[2]=0;g[6]=0;g[10]=-2/m;g[14]=-((f+e)/m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a){this.elements.set(a);return this}, -toArray:function(){var a=this.elements;return[a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]]}};THREE.Ray=function(a,b){this.origin=void 0!==a?a:new THREE.Vector3;this.direction=void 0!==b?b:new THREE.Vector3}; -THREE.Ray.prototype={constructor:THREE.Ray,set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){return(b||new THREE.Vector3).copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize()},recast:function(){var a=new THREE.Vector3;return function(b){this.origin.copy(this.at(b, +THREE.Box3.prototype={constructor:THREE.Box3,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromArray:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.length;he&&(e=l);n>f&&(f=n);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g)},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.max.x||a.ythis.max.y||a.z< +this.min.z||a.z>this.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z?!0:!1},getParameter:function(a,b){return(b||new THREE.Vector3).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.xthis.max.x||a.max.ythis.max.y||a.max.z< +this.min.z||a.min.z>this.max.z?!1:!0},intersectsSphere:function(){var a;return function(b){void 0===a&&(a=new THREE.Vector3);this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){var b,c;0=a.constant},clampPoint:function(a,b){return(b||new THREE.Vector3).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new THREE.Vector3;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new THREE.Vector3;return function(b){b=b||new THREE.Sphere;b.center=this.center();b.radius=.5*this.size(a).length();return b}}(), +intersect:function(a){this.min.max(a.min);this.max.min(a.max);this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new THREE.Vector3];return function(b){if(this.isEmpty())return this;a[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b); +a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&& +a.max.equals(this.max)}};THREE.Matrix3=function(){this.elements=new Float32Array([1,0,0,0,1,0,0,0,1]);0this.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.elements.set(this.elements);c=1/g;var f=1/h,l=1/k;b.elements[0]*=c;b.elements[1]*=c; +b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=l;b.elements[9]*=l;b.elements[10]*=l;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makeFrustum:function(a,b,c,d,e,f){var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(d-c);g[9]=(d+c)/(d-c);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makePerspective:function(a,b,c,d){a=c*Math.tan(THREE.Math.DEG2RAD*a*.5);var e= +-a;return this.makeFrustum(e*b,a*b,e,a,c,d)},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),k=1/(c-d),l=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*k;g[9]=0;g[13]=-((c+d)*k);g[2]=0;g[6]=0;g[10]=-2*l;g[14]=-((f+e)*l);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a){this.elements.set(a);return this},toArray:function(a,b){void 0===a&&(a=[]); +void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}};THREE.Ray=function(a,b){this.origin=void 0!==a?a:new THREE.Vector3;this.direction=void 0!==b?b:new THREE.Vector3}; +THREE.Ray.prototype={constructor:THREE.Ray,set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){return(b||new THREE.Vector3).copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(){var a=new THREE.Vector3;return function(b){this.origin.copy(this.at(b, a));return this}}(),closestPointToPoint:function(a,b){var c=b||new THREE.Vector3;c.subVectors(a,this.origin);var d=c.dot(this.direction);return 0>d?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new THREE.Vector3;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceToSquared(b);a.copy(this.direction).multiplyScalar(c).add(this.origin); -return a.distanceToSquared(b)}}(),distanceSqToSegment:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);var h=.5*d.distanceTo(e),k=-this.direction.dot(b),m=c.dot(this.direction),n=-c.dot(b),p=c.lengthSq(),l=Math.abs(1-k*k),q;0=-q?e<=q?(h=1/l,d*=h,e*=h,k=d*(d+k*e+2*m)+e*(k*d+e+2*n)+p):(e=h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2* -n)+p):(e=-h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*n)+p):e<=-q?(d=Math.max(0,-(-k*h+m)),e=0=-q?e<=q?(h=1/m,d*=h,e*=h,k=d*(d+k*e+2*l)+e*(k*d+e+2*n)+p):(e=h,d=Math.max(0,-(k*e+l)),k=-d*d+e*(e+2* +n)+p):(e=-h,d=Math.max(0,-(k*e+l)),k=-d*d+e*(e+2*n)+p):e<=-q?(d=Math.max(0,-(-k*h+l)),e=0f)return null;f=Math.sqrt(f-e);e=d-f;d+=f;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceToPoint(a.center)<=a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c= this.distanceToPlane(a);return null===c?null:this.at(c,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c,d,e,f,g;d=1/this.direction.x;f=1/this.direction.y;g=1/this.direction.z;var h=this.origin;0<=d?(c=(a.min.x-h.x)*d,d*=a.max.x-h.x):(c=(a.max.x-h.x)*d,d*=a.min.x-h.x);0<=f?(e=(a.min.y-h.y)*f,f*=a.max.y-h.y):(e=(a.max.y-h.y)*f,f*=a.min.y-h.y);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(fg||e>d)return null;if(e>c||c!==c)c=e;if(gd?null:this.at(0<=c?c:d,b)},intersectsBox:function(){var a=new THREE.Vector3;return function(b){return null!==this.intersectBox(b,a)}}(),intersectTriangle:function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Vector3,d=new THREE.Vector3;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d); @@ -131,46 +133,48 @@ THREE.Sphere.prototype={constructor:THREE.Sphere,set:function(a,b){this.center.c empty:function(){return 0>=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(this.center.dot(a.normal)-a.constant)<=this.radius},clampPoint:function(a,b){var c= this.center.distanceToSquared(a),d=b||new THREE.Vector3;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=a||new THREE.Box3;a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&& a.radius===this.radius}};THREE.Frustum=function(a,b,c,d,e,f){this.planes=[void 0!==a?a:new THREE.Plane,void 0!==b?b:new THREE.Plane,void 0!==c?c:new THREE.Plane,void 0!==d?d:new THREE.Plane,void 0!==e?e:new THREE.Plane,void 0!==f?f:new THREE.Plane]}; -THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],m=c[7],n=c[8],p=c[9],l=c[10],q=c[11],t=c[12],u=c[13],s=c[14], -c=c[15];b[0].setComponents(f-a,m-g,q-n,c-t).normalize();b[1].setComponents(f+a,m+g,q+n,c+t).normalize();b[2].setComponents(f+d,m+h,q+p,c+u).normalize();b[3].setComponents(f-d,m-h,q-p,c-u).normalize();b[4].setComponents(f-e,m-k,q-l,c-s).normalize();b[5].setComponents(f+e,m+k,q+l,c+s).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere);a.applyMatrix4(b.matrixWorld); -return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0g&&0>f)return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; +THREE.Frustum.prototype={constructor:THREE.Frustum,set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){for(var b=this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],l=c[7],n=c[8],p=c[9],m=c[10],q=c[11],r=c[12],s=c[13],u=c[14], +c=c[15];b[0].setComponents(f-a,l-g,q-n,c-r).normalize();b[1].setComponents(f+a,l+g,q+n,c+r).normalize();b[2].setComponents(f+d,l+h,q+p,c+s).normalize();b[3].setComponents(f-d,l-h,q-p,c-s).normalize();b[4].setComponents(f-e,l-k,q-m,c-u).normalize();b[5].setComponents(f+e,l+k,q+m,c+u).normalize();return this},intersectsObject:function(){var a=new THREE.Sphere;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere).applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(), +intersectsSprite:function(){var a=new THREE.Sphere;return function(b){a.center.set(0,0,0);a.radius=.7071067811865476;a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=0;6>d;d++)if(b[d].distanceToPoint(c)e;e++){var f=d[e];a.x=0g&&0>f)return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}};THREE.Plane=function(a,b){this.normal=void 0!==a?a:new THREE.Vector3(1,0,0);this.constant=void 0!==b?b:0}; THREE.Plane.prototype={constructor:THREE.Plane,set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d, c);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a, b){return this.orthoPoint(a,b).sub(a).negate()},orthoPoint:function(a,b){var c=this.distanceToPoint(a);return(b||new THREE.Vector3).copy(this.normal).multiplyScalar(c)},intersectLine:function(){var a=new THREE.Vector3;return function(b,c){var d=c||new THREE.Vector3,e=b.delta(a),f=this.normal.dot(e);if(0===f){if(0===this.distanceToPoint(b.start))return d.copy(b.start)}else return f=-(b.start.dot(this.normal)+this.constant)/f,0>f||1b&&0a&&0e;e++)8===e||13===e||18===e||23===e?b[e]="-":14===e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19===e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},smoothstep:function(a, -b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){console.warn("THREE.Math.random16() has been deprecated. Use Math.random() instead.");return Math.random()},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(){var a= -Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a=180/Math.PI;return function(b){return b*a}}(),isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nearestPowerOfTwo:function(a){return Math.pow(2,Math.round(Math.log(a)/Math.LN2))},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}}; -THREE.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,h,k,m,n,p,l;this.initFromArray=function(a){this.points=[];for(var b=0;bthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ -2;m=this.points[c[0]];n=this.points[c[1]];p=this.points[c[2]];l=this.points[c[3]];h=g*g;k=g*h;d.x=b(m.x,n.x,p.x,l.x,g,h,k);d.y=b(m.y,n.y,p.y,l.y,g,h,k);d.z=b(m.z,n.z,p.z,l.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;ab&&0a&&0e;e++)8===e||13===e||18===e||23===e?b[e]="-":14===e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19===e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c, +d,e){return d+(a-b)*(e-d)/(c-b)},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},random16:function(){console.warn("THREE.Math.random16() has been deprecated. Use Math.random() instead.");return Math.random()},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a* +(.5-Math.random())},degToRad:function(a){return a*THREE.Math.DEG2RAD},radToDeg:function(a){return a*THREE.Math.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},nearestPowerOfTwo:function(a){return Math.pow(2,Math.round(Math.log(a)/Math.LN2))},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}}; +THREE.Spline=function(a){function b(a,b,c,d,e,f,g){a=.5*(c-a);d=.5*(d-b);return(2*(b-c)+a+d)*g+(-3*(b-c)-2*a-d)*f+a*e+b}this.points=a;var c=[],d={x:0,y:0,z:0},e,f,g,h,k,l,n,p,m;this.initFromArray=function(a){this.points=[];for(var b=0;bthis.points.length-2?this.points.length-1:f+1;c[3]=f>this.points.length-3?this.points.length-1:f+ +2;l=this.points[c[0]];n=this.points[c[1]];p=this.points[c[2]];m=this.points[c[3]];h=g*g;k=g*h;d.x=b(l.x,n.x,p.x,m.x,g,h,k);d.y=b(l.y,n.y,p.y,m.y,g,h,k);d.z=b(l.z,n.z,p.z,m.z,g,h,k);return d};this.getControlPointsArray=function(){var a,b,c=this.points.length,d=[];for(a=0;a=b.x+b.y}}(); THREE.Triangle.prototype={constructor:THREE.Triangle,set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a, this.b);return.5*a.cross(b).length()}}(),midpoint:function(a){return(a||new THREE.Vector3).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return THREE.Triangle.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new THREE.Plane).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return THREE.Triangle.barycoordFromPoint(a,this.a,this.b,this.c,b)},containsPoint:function(a){return THREE.Triangle.containsPoint(a,this.a,this.b,this.c)}, -equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}};THREE.Interpolant=function(a,b,c,d){this.parameterPositions=a;this._cachedIndex=0;this.resultBuffer=void 0!==d?d:new b.constructor(c);this.sampleValues=b;this.valueSize=c}; +closestPointToPoint:function(){var a,b,c,d;return function(e,f){void 0===a&&(a=new THREE.Plane,b=[new THREE.Line3,new THREE.Line3,new THREE.Line3],c=new THREE.Vector3,d=new THREE.Vector3);var g=f||new THREE.Vector3,h=Infinity;a.setFromCoplanarPoints(this.a,this.b,this.c);a.projectPoint(e,c);if(!0===this.containsPoint(c))g.copy(c);else{b[0].set(this.a,this.b);b[1].set(this.b,this.c);b[2].set(this.c,this.a);for(var k=0;k=e)break a;else{f=b[1];a=e)break b}d= c;c=0}}for(;c>>1,ad;d++)if(e[d]===e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e, 1),c=0,g=this.faceVertexUvs.length;cthis.duration&&this.resetDuration();this.trim();this.optimize()}; -THREE.AnimationClip.prototype={constructor:THREE.AnimationClip,resetDuration:function(){for(var a=0,b=0,c=this.tracks.length;b!==c;++b)var d=this.tracks[b],a=Math.max(a,d.times[d.times.length-1]);this.duration=a},trim:function(){for(var a=0;ab||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){var b=this.timeScale,c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0],b=b*d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.pause=!0:this.timeScale=b)}}return this._effectiveTimeScale= -b},_updateTime:function(a){var b=this.time+a;if(0===a)return b;var c=this._clip.duration,d=this.loop,e=this._loopCount,f=!1;switch(d){case THREE.LoopOnce:-1===e&&(this.loopCount=0,this._setEndings(!0,!0,!1));if(b>=c)b=c;else if(0>b)b=0;else break;this.clampWhenFinished?this.pause=!0:this.enabled=!1;this._mixer.dispatchEvent({type:"finished",action:this,direction:0>a?-1:1});break;case THREE.LoopPingPong:f=!0;case THREE.LoopRepeat:-1===e&&(0=c||0>b){var g=Math.floor(b/c),b=b-c*g,e=e+Math.abs(g),h=this.repetitions-e;if(0>h){this.clampWhenFinished?this.paused=!0:this.enabled=!1;b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f);this._loopCount=e;this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:g})}if(d===THREE.LoopPingPong&&1===(e&1))return this.time=b,c-b}return this.time=b},_setEndings:function(a, +a;return this.stopWarping()},syncWith:function(a){this.time=a.time;this.timeScale=a.timeScale;return this.stopWarping()},halt:function(a){return this.warp(this._effectiveTimeScale,0,a)},warp:function(a,b,c){var d=this._mixer,e=d.time,f=this._timeScaleInterpolant,g=this.timeScale;null===f&&(this._timeScaleInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;d[1]=e+c;f[0]=a/g;f[1]=b/g;return this},stopWarping:function(){var a=this._timeScaleInterpolant;null!==a&& +(this._timeScaleInterpolant=null,this._mixer._takeBackControlInterpolant(a));return this},getMixer:function(){return this._mixer},getClip:function(){return this._clip},getRoot:function(){return this._localRoot||this._mixer._root},_update:function(a,b,c,d){var e=this._startTime;if(null!==e){b=(a-e)*c;if(0>b||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){var b=this.timeScale,c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0],b=b*d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0: +this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a;if(0===a)return b;var c=this._clip.duration,d=this.loop,e=this._loopCount;if(d===THREE.LoopOnce)a:{if(-1===e&&(this.loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else break a;this.clampWhenFinished?this.paused=!0:this.enabled=!1;this._mixer.dispatchEvent({type:"finished",action:this,direction:0>a?-1:1})}else{d=d===THREE.LoopPingPong;-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions, +d)):this._setEndings(0===this.repetitions,!0,d));if(b>=c||0>b){var f=Math.floor(b/c),b=b-c*f,e=e+Math.abs(f),g=this.repetitions-e;0>g?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,b=0a,this._setEndings(a,!a,d)):this._setEndings(!1,!1,d),this._loopCount=e,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:f}))}if(d&&1===(e&1))return this.time=b,c-b}return this.time=b},_setEndings:function(a, b,c){var d=this._interpolantSettings;c?(d.endingStart=THREE.ZeroSlopeEnding,d.endingEnd=THREE.ZeroSlopeEnding):(d.endingStart=a?this.zeroSlopeAtStart?THREE.ZeroSlopeEnding:THREE.ZeroCurvatureEnding:THREE.WrapAroundEnding,d.endingEnd=b?this.zeroSlopeAtEnd?THREE.ZeroSlopeEnding:THREE.ZeroCurvatureEnding:THREE.WrapAroundEnding)},_scheduleFading:function(a,b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions; -f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]=c;return this}}; -Object.assign(THREE.AnimationMixer.prototype,{_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings,g=a._interpolants,h=c.uuid,k=this._bindingsByRootAndName,m=k[h];void 0===m&&(m={},k[h]=m);for(k=0;k!==e;++k){var n=d[k],p=n.name,l=m[p];if(void 0===l){l=f[k];if(void 0!==l){null===l._cacheIndex&&(++l.referenceCount,this._addInactiveBinding(l,h,p));continue}l=new THREE.PropertyMixer(THREE.PropertyBinding.create(c,p,b&&b._propertyBindings[k].binding.parsedPath), -n.ValueTypeName,n.getValueSize());++l.referenceCount;this._addInactiveBinding(l,h,p)}f[k]=l;g[k].resultBuffer=l.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.name,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}}, +f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]=c;return this}};THREE.AnimationClip=function(a,b,c){this.name=a;this.tracks=c;this.duration=void 0!==b?b:-1;this.uuid=THREE.Math.generateUUID();0>this.duration&&this.resetDuration();this.trim();this.optimize()}; +THREE.AnimationClip.prototype={constructor:THREE.AnimationClip,resetDuration:function(){for(var a=0,b=0,c=this.tracks.length;b!==c;++b)var d=this.tracks[b],a=Math.max(a,d.times[d.times.length-1]);this.duration=a},trim:function(){for(var a=0;a=c){var p=c++,l=b[p];d[l.uuid]= -n;b[n]=l;d[m]=p;b[p]=k;k=0;for(m=f;k!==m;++k){var l=e[k],q=l[n];l[n]=l[p];l[p]=q}}}this.nCachedObjects_=c},uncache:function(a){for(var b=this._objects,c=b.length,d=this.nCachedObjects_,e=this._indicesByUUID,f=this._bindings,g=f.length,h=0,k=arguments.length;h!==k;++h){var m=arguments[h].uuid,n=e[m];if(void 0!==n)if(delete e[m],n=c){var p=c++,m=b[p];d[m.uuid]= +n;b[n]=m;d[l]=p;b[p]=k;k=0;for(l=f;k!==l;++k){var m=e[k],q=m[n];m[n]=m[p];m[p]=q}}}this.nCachedObjects_=c},uncache:function(a){for(var b=this._objects,c=b.length,d=this.nCachedObjects_,e=this._indicesByUUID,f=this._bindings,g=f.length,h=0,k=arguments.length;h!==k;++h){var l=arguments[h].uuid,n=e[l];if(void 0!==n)if(delete e[l],nb;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),d=this.getValueSize(),this.times=THREE.AnimationUtils.arraySlice(c,e,f),this.values=THREE.AnimationUtils.arraySlice(this.values,e*d,f*d);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("invalid value size in track", this),a=!1);var c=this.times,b=this.values,d=c.length;0===d&&(console.error("track is empty",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("time is not a valid number",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("out of order keys",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&THREE.AnimationUtils.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("value is not a valid number",this,f,d);a=!1;break}return a},optimize:function(){for(var a= -this.times,b=this.values,c=this.getValueSize(),d=1,e=1,f=a.length-1;e<=f;++e){var g=!1,h=a[e];if(h!==a[e+1]&&(1!==e||h!==h[0]))for(var k=e*c,m=k-c,n=k+c,h=0;h!==c;++h){var p=b[k+h];if(p!==b[m+h]||p!==b[n+h]){g=!0;break}}if(g){if(e!==d)for(a[d]=a[e],g=e*c,k=d*c,h=0;h!==c;++h)b[k+h]=b[g+h];++d}}d!==a.length&&(this.times=THREE.AnimationUtils.arraySlice(a,0,d),this.values=THREE.AnimationUtils.arraySlice(b,0,d*c));return this}}; -Object.assign(THREE.KeyframeTrack,{parse:function(a){if(void 0===a.type)throw Error("track type undefined, can not parse");var b=THREE.KeyframeTrack._getTrackTypeForValueTypeName(a.type);if(void 0===a.times){console.warn("legacy JSON format detected, converting");var c=[],d=[];THREE.AnimationUtils.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)},toJSON:function(a){var b=a.constructor;if(void 0!==b.toJSON)b=b.toJSON(a); -else{var b={name:a.name,times:THREE.AnimationUtils.convertArray(a.times,Array),values:THREE.AnimationUtils.convertArray(a.values,Array)},c=a.getInterpolation();c!==a.DefaultInterpolation&&(b.interpolation=c)}b.type=a.ValueTypeName;return b},_getTrackTypeForValueTypeName:function(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return THREE.NumberKeyframeTrack;case "vector":case "vector2":case "vector3":case "vector4":return THREE.VectorKeyframeTrack; -case "color":return THREE.ColorKeyframeTrack;case "quaternion":return THREE.QuaternionKeyframeTrack;case "bool":case "boolean":return THREE.BooleanKeyframeTrack;case "string":return THREE.StringKeyframeTrack}throw Error("Unsupported typeName: "+a);}});THREE.PropertyBinding=function(a,b,c){this.path=b;this.parsedPath=c||THREE.PropertyBinding.parseTrackName(b);this.node=THREE.PropertyBinding.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}; +this.times,b=this.values,c=this.getValueSize(),d=1,e=1,f=a.length-1;e<=f;++e){var g=!1,h=a[e];if(h!==a[e+1]&&(1!==e||h!==h[0]))for(var k=e*c,l=k-c,n=k+c,h=0;h!==c;++h){var p=b[k+h];if(p!==b[l+h]||p!==b[n+h]){g=!0;break}}if(g){if(e!==d)for(a[d]=a[e],g=e*c,k=d*c,h=0;h!==c;++h)b[k+h]=b[g+h];++d}}d!==a.length&&(this.times=THREE.AnimationUtils.arraySlice(a,0,d),this.values=THREE.AnimationUtils.arraySlice(b,0,d*c));return this}}; +Object.assign(THREE.KeyframeTrack,{parse:function(a){if(void 0===a.type)throw Error("track type undefined, can not parse");var b=THREE.KeyframeTrack._getTrackTypeForValueTypeName(a.type);if(void 0===a.times){var c=[],d=[];THREE.AnimationUtils.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)},toJSON:function(a){var b=a.constructor;if(void 0!==b.toJSON)b=b.toJSON(a);else{var b={name:a.name,times:THREE.AnimationUtils.convertArray(a.times, +Array),values:THREE.AnimationUtils.convertArray(a.values,Array)},c=a.getInterpolation();c!==a.DefaultInterpolation&&(b.interpolation=c)}b.type=a.ValueTypeName;return b},_getTrackTypeForValueTypeName:function(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return THREE.NumberKeyframeTrack;case "vector":case "vector2":case "vector3":case "vector4":return THREE.VectorKeyframeTrack;case "color":return THREE.ColorKeyframeTrack;case "quaternion":return THREE.QuaternionKeyframeTrack; +case "bool":case "boolean":return THREE.BooleanKeyframeTrack;case "string":return THREE.StringKeyframeTrack}throw Error("Unsupported typeName: "+a);}});THREE.PropertyBinding=function(a,b,c){this.path=b;this.parsedPath=c||THREE.PropertyBinding.parseTrackName(b);this.node=THREE.PropertyBinding.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}; THREE.PropertyBinding.prototype={constructor:THREE.PropertyBinding,getValue:function(a,b){this.bind();this.getValue(a,b)},setValue:function(a,b){this.bind();this.setValue(a,b)},bind:function(){var a=this.node,b=this.parsedPath,c=b.objectName,d=b.propertyName,e=b.propertyIndex;a||(this.node=a=THREE.PropertyBinding.findNode(this.rootNode,b.nodeName)||this.rootNode);this.getValue=this._getValue_unavailable;this.setValue=this._setValue_unavailable;if(a){if(c){var f=b.objectIndex;switch(c){case "materials":if(!a.material){console.error(" can not bind to material as node does not have a material", this);return}if(!a.material.materials){console.error(" can not bind to material.materials as node.material does not have a materials array",this);return}a=a.material.materials;break;case "bones":if(!a.skeleton){console.error(" can not bind to bones as node does not have a skeleton",this);return}a=a.skeleton.bones;for(c=0;cd&&this._mixBufferRegion(c,a,3*b,1-d,b);for(var d=b,f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a); break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d,e){THREE.Quaternion.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}}; -THREE.BooleanKeyframeTrack=function(a,b,c){THREE.KeyframeTrack.call(this,a,b,c)};THREE.BooleanKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.BooleanKeyframeTrack,ValueTypeName:"bool",ValueBufferType:Array,DefaultInterpolation:THREE.IntepolateDiscrete,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});THREE.NumberKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)}; -THREE.NumberKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.NumberKeyframeTrack,ValueTypeName:"number"});THREE.QuaternionKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)}; +THREE.BooleanKeyframeTrack=function(a,b,c){THREE.KeyframeTrack.call(this,a,b,c)};THREE.BooleanKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.BooleanKeyframeTrack,ValueTypeName:"bool",ValueBufferType:Array,DefaultInterpolation:THREE.InterpolateDiscrete,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});THREE.ColorKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)}; +THREE.ColorKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.ColorKeyframeTrack,ValueTypeName:"color"});THREE.NumberKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)};THREE.NumberKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.NumberKeyframeTrack,ValueTypeName:"number"});THREE.QuaternionKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)}; THREE.QuaternionKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.QuaternionKeyframeTrack,ValueTypeName:"quaternion",DefaultInterpolation:THREE.InterpolateLinear,InterpolantFactoryMethodLinear:function(a){return new THREE.QuaternionLinearInterpolant(this.times,this.values,this.getValueSize(),a)},InterpolantFactoryMethodSmooth:void 0});THREE.StringKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)}; -THREE.StringKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.StringKeyframeTrack,ValueTypeName:"string",ValueBufferType:Array,DefaultInterpolation:THREE.IntepolateDiscrete,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});THREE.VectorKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)}; +THREE.StringKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.StringKeyframeTrack,ValueTypeName:"string",ValueBufferType:Array,DefaultInterpolation:THREE.InterpolateDiscrete,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});THREE.VectorKeyframeTrack=function(a,b,c,d){THREE.KeyframeTrack.call(this,a,b,c,d)}; THREE.VectorKeyframeTrack.prototype=Object.assign(Object.create(THREE.KeyframeTrack.prototype),{constructor:THREE.VectorKeyframeTrack,ValueTypeName:"vector"}); -THREE.Audio=function(a){THREE.Object3D.call(this);this.type="Audio";this.context=a.context;this.source=this.context.createBufferSource();this.source.onended=this.onEnded.bind(this);this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filter=null};THREE.Audio.prototype=Object.create(THREE.Object3D.prototype);THREE.Audio.prototype.constructor=THREE.Audio; -THREE.Audio.prototype.getOutput=function(){return this.gain};THREE.Audio.prototype.load=function(a){var b=new THREE.AudioBuffer(this.context);b.load(a);this.setBuffer(b);return this};THREE.Audio.prototype.setNodeSource=function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this};THREE.Audio.prototype.setBuffer=function(a){var b=this;a.onReady(function(a){b.source.buffer=a;b.sourceType="buffer";b.autoplay&&b.play()});return this}; -THREE.Audio.prototype.play=function(){if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else{var a=this.context.createBufferSource();a.buffer=this.source.buffer;a.loop=this.source.loop;a.onended=this.source.onended;a.start(0,this.startTime);a.playbackRate.value=this.playbackRate;this.isPlaying=!0;this.source=a;this.connect()}}; -THREE.Audio.prototype.pause=function(){!1===this.hasPlaybackControl?console.warn("THREE.Audio: this Audio has no playback control."):(this.source.stop(),this.startTime=this.context.currentTime)};THREE.Audio.prototype.stop=function(){!1===this.hasPlaybackControl?console.warn("THREE.Audio: this Audio has no playback control."):(this.source.stop(),this.startTime=0)};THREE.Audio.prototype.connect=function(){null!==this.filter?(this.source.connect(this.filter),this.filter.connect(this.getOutput())):this.source.connect(this.getOutput())}; -THREE.Audio.prototype.disconnect=function(){null!==this.filter?(this.source.disconnect(this.filter),this.filter.disconnect(this.getOutput())):this.source.disconnect(this.getOutput())};THREE.Audio.prototype.getFilter=function(){return this.filter};THREE.Audio.prototype.setFilter=function(a){void 0===a&&(a=null);!0===this.isPlaying?(this.disconnect(),this.filter=a,this.connect()):this.filter=a}; -THREE.Audio.prototype.setPlaybackRate=function(a){!1===this.hasPlaybackControl?console.warn("THREE.Audio: this Audio has no playback control."):(this.playbackRate=a,!0===this.isPlaying&&(this.source.playbackRate.value=this.playbackRate))};THREE.Audio.prototype.getPlaybackRate=function(){return this.playbackRate};THREE.Audio.prototype.onEnded=function(){this.isPlaying=!1}; -THREE.Audio.prototype.setLoop=function(a){!1===this.hasPlaybackControl?console.warn("THREE.Audio: this Audio has no playback control."):this.source.loop=a};THREE.Audio.prototype.getLoop=function(){return!1===this.hasPlaybackControl?(console.warn("THREE.Audio: this Audio has no playback control."),!1):this.source.loop};THREE.Audio.prototype.setVolume=function(a){this.gain.gain.value=a};THREE.Audio.prototype.getVolume=function(){return this.gain.gain.value}; -THREE.AudioAnalyser=function(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)};THREE.AudioAnalyser.prototype={constructor:THREE.AudioAnalyser,getData:function(){this.analyser.getByteFrequencyData(this.data);return this.data}};THREE.AudioBuffer=function(a){this.context=a;this.ready=!1;this.readyCallbacks=[]}; -THREE.AudioBuffer.prototype.load=function(a){var b=this,c=new XMLHttpRequest;c.open("GET",a,!0);c.responseType="arraybuffer";c.onload=function(a){b.context.decodeAudioData(this.response,function(a){b.buffer=a;b.ready=!0;for(a=0;ak.opacity&&(k.transparent=!0);c.setTextures(h);return c.parse(k)}}()}; +g(n,d.mapAlphaRepeat,d.mapAlphaOffset,d.mapAlphaWrap,d.mapAlphaAnisotropy);break;case "mapAlphaRepeat":case "mapAlphaOffset":case "mapAlphaWrap":case "mapAlphaAnisotropy":break;case "flipSided":k.side=THREE.BackSide;break;case "doubleSided":k.side=THREE.DoubleSide;break;case "transparency":console.warn("THREE.Loader.createMaterial: transparency has been renamed to opacity");k.opacity=n;break;case "depthTest":case "depthWrite":case "colorWrite":case "opacity":case "reflectivity":case "transparent":case "visible":case "wireframe":k[l]= +n;break;case "vertexColors":!0===n&&(k.vertexColors=THREE.VertexColors);"face"===n&&(k.vertexColors=THREE.FaceColors);break;default:console.error("THREE.Loader.createMaterial: Unsupported",l,n)}}"MeshBasicMaterial"===k.type&&delete k.emissive;"MeshPhongMaterial"!==k.type&&delete k.specular;1>k.opacity&&(k.transparent=!0);c.setTextures(h);return c.parse(k)}}()}; THREE.Loader.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=this.handlers,c=0,d=b.length;cg;g++)l=v[k++],w=s[2*l],l=s[2*l+1],w=new THREE.Vector2(w,l),2!==g&&c.faceVertexUvs[d][h].push(w),0!==g&&c.faceVertexUvs[d][h+1].push(w);p&&(p=3*v[k++],q.normal.set(C[p++],C[p++],C[p]),u.normal.copy(q.normal));if(t)for(d=0;4>d;d++)p=3*v[k++],t=new THREE.Vector3(C[p++],C[p++],C[p]),2!==d&&q.vertexNormals.push(t),0!==d&&u.vertexNormals.push(t); -n&&(n=v[k++],n=x[n],q.color.setHex(n),u.color.setHex(n));if(b)for(d=0;4>d;d++)n=v[k++],n=x[n],2!==d&&q.vertexColors.push(new THREE.Color(n)),0!==d&&u.vertexColors.push(new THREE.Color(n));c.faces.push(q);c.faces.push(u)}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;dg;g++)l=v[k++],w=s[2*l],l=s[2*l+1],w=new THREE.Vector2(w,l),c.faceVertexUvs[d][h].push(w);p&&(p=3*v[k++],q.normal.set(C[p++], -C[p++],C[p]));if(t)for(d=0;3>d;d++)p=3*v[k++],t=new THREE.Vector3(C[p++],C[p++],C[p]),q.vertexNormals.push(t);n&&(n=v[k++],q.color.setHex(x[n]));if(b)for(d=0;3>d;d++)n=v[k++],q.vertexColors.push(new THREE.Color(x[n]));c.faces.push(q)}})(d);(function(){var b=void 0!==a.influencesPerVertex?a.influencesPerVertex:2;if(a.skinWeights)for(var d=0,g=a.skinWeights.length;dg;g++)m=v[k++],x=u[2*m],m=u[2*m+1],x=new THREE.Vector2(x,m),2!==g&&c.faceVertexUvs[d][h].push(x),0!==g&&c.faceVertexUvs[d][h+1].push(x);p&&(p=3*v[k++],q.normal.set(C[p++],C[p++],C[p]),s.normal.copy(q.normal));if(r)for(d=0;4>d;d++)p=3*v[k++],r=new THREE.Vector3(C[p++],C[p++],C[p]),2!==d&&q.vertexNormals.push(r),0!==d&&s.vertexNormals.push(r); +n&&(n=v[k++],n=w[n],q.color.setHex(n),s.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&&s.vertexColors.push(new THREE.Color(n));c.faces.push(q);c.faces.push(s)}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;dg;g++)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(C[p++], +C[p++],C[p]));if(r)for(d=0;3>d;d++)p=3*v[k++],r=new THREE.Vector3(C[p++],C[p++],C[p]),q.vertexNormals.push(r);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,g=a.skinWeights.length;dthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);0this.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);0a.x||1a.x?0:1;break;case THREE.MirroredRepeatWrapping:1===Math.abs(Math.floor(a.x)%2)?a.x=Math.ceil(a.x)-a.x:a.x-=Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case THREE.MirroredRepeatWrapping:1===Math.abs(Math.floor(a.y)% -2)?a.y=Math.ceil(a.y)-a.y:a.y-=Math.floor(a.y)}this.flipY&&(a.y=1-a.y)}}};THREE.EventDispatcher.prototype.apply(THREE.Texture.prototype);THREE.TextureIdCount=0;THREE.CanvasTexture=function(a,b,c,d,e,f,g,h,k){THREE.Texture.call(this,a,b,c,d,e,f,g,h,k);this.needsUpdate=!0};THREE.CanvasTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CanvasTexture.prototype.constructor=THREE.CanvasTexture; -THREE.CubeTexture=function(a,b,c,d,e,f,g,h,k){b=void 0!==b?b:THREE.CubeReflectionMapping;THREE.Texture.call(this,a,b,c,d,e,f,g,h,k);this.images=a;this.flipY=!1};THREE.CubeTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CubeTexture.prototype.constructor=THREE.CubeTexture;THREE.CubeTexture.prototype.copy=function(a){THREE.Texture.prototype.copy.call(this,a);this.images=a.images;return this}; -THREE.CompressedTexture=function(a,b,c,d,e,f,g,h,k,m,n){THREE.Texture.call(this,null,f,g,h,k,m,d,e,n);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1};THREE.CompressedTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CompressedTexture.prototype.constructor=THREE.CompressedTexture; -THREE.DataTexture=function(a,b,c,d,e,f,g,h,k,m,n){THREE.Texture.call(this,null,f,g,h,k,m,d,e,n);this.image={data:a,width:b,height:c};this.magFilter=void 0!==k?k:THREE.NearestFilter;this.minFilter=void 0!==m?m:THREE.NearestFilter;this.generateMipmaps=this.flipY=!1};THREE.DataTexture.prototype=Object.create(THREE.Texture.prototype);THREE.DataTexture.prototype.constructor=THREE.DataTexture; -THREE.VideoTexture=function(a,b,c,d,e,f,g,h,k){function m(){requestAnimationFrame(m);a.readyState===a.HAVE_ENOUGH_DATA&&(n.needsUpdate=!0)}THREE.Texture.call(this,a,b,c,d,e,f,g,h,k);this.generateMipmaps=!1;var n=this;m()};THREE.VideoTexture.prototype=Object.create(THREE.Texture.prototype);THREE.VideoTexture.prototype.constructor=THREE.VideoTexture;THREE.Group=function(){THREE.Object3D.call(this);this.type="Group"};THREE.Group.prototype=Object.create(THREE.Object3D.prototype); -THREE.Group.prototype.constructor=THREE.Group;THREE.Points=function(a,b){THREE.Object3D.call(this);this.type="Points";this.geometry=void 0!==a?a:new THREE.Geometry;this.material=void 0!==b?b:new THREE.PointsMaterial({color:16777215*Math.random()})};THREE.Points.prototype=Object.create(THREE.Object3D.prototype);THREE.Points.prototype.constructor=THREE.Points; -THREE.Points.prototype.raycast=function(){var a=new THREE.Matrix4,b=new THREE.Ray,c=new THREE.Sphere;return function(d,e){function f(a,c){var f=b.distanceSqToPoint(a);if(fd.far||e.push({distance:l,distanceToRay:Math.sqrt(f),point:h.clone(),index:c,face:null,object:g})}}var g=this,h=this.geometry,k=this.matrixWorld,m=d.params.Points.threshold;null===h.boundingSphere&&h.computeBoundingSphere();c.copy(h.boundingSphere); -c.applyMatrix4(k);if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);var m=m/((this.scale.x+this.scale.y+this.scale.z)/3),n=m*m,m=new THREE.Vector3;if(h instanceof THREE.BufferGeometry){var p=h.index,h=h.attributes.position.array;if(null!==p)for(var l=p.array,p=0,q=l.length;pf||(n.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(n),ud.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else for(g=0,t=q.length/3-1;gf||(n.applyMatrix4(this.matrixWorld), -u=d.ray.origin.distanceTo(n),ud.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(k=g.vertices,m=k.length,g=0;gf||(n.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(n),ud.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(); -THREE.Line.prototype.clone=function(){return(new this.constructor(this.geometry,this.material)).copy(this)};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.drawMode=THREE.TrianglesDrawMode;this.updateMorphTargets()};THREE.Mesh.prototype=Object.create(THREE.Object3D.prototype);THREE.Mesh.prototype.constructor=THREE.Mesh;THREE.Mesh.prototype.setDrawMode=function(a){this.drawMode=a}; -THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0b.far?null:{distance:c,point:w.clone(), -object:a}}function c(c,d,e,f,m,n,p,w){g.fromArray(f,3*n);h.fromArray(f,3*p);k.fromArray(f,3*w);if(c=b(c,d,e,g,h,k,s))m&&(l.fromArray(m,2*n),q.fromArray(m,2*p),t.fromArray(m,2*w),c.uv=a(s,g,h,k,l,q,t)),c.face=new THREE.Face3(n,p,w,THREE.Triangle.normal(g,h,k)),c.faceIndex=n;return c}var d=new THREE.Matrix4,e=new THREE.Ray,f=new THREE.Sphere,g=new THREE.Vector3,h=new THREE.Vector3,k=new THREE.Vector3,m=new THREE.Vector3,n=new THREE.Vector3,p=new THREE.Vector3,l=new THREE.Vector2,q=new THREE.Vector2, -t=new THREE.Vector2,u=new THREE.Vector3,s=new THREE.Vector3,w=new THREE.Vector3;return function(w,u){var x=this.geometry,D=this.material,A=this.matrixWorld;if(void 0!==D&&(null===x.boundingSphere&&x.computeBoundingSphere(),f.copy(x.boundingSphere),f.applyMatrix4(A),!1!==w.ray.intersectsSphere(f)&&(d.getInverse(A),e.copy(w.ray).applyMatrix4(d),null===x.boundingBox||!1!==e.intersectsBox(x.boundingBox)))){var B,y;if(x instanceof THREE.BufferGeometry){var I,F,D=x.index,A=x.attributes,x=A.position.array; -void 0!==A.uv&&(B=A.uv.array);if(null!==D)for(var A=D.array,z=0,J=A.length;za.x||1a.x?0:1;break;case THREE.MirroredRepeatWrapping:1===Math.abs(Math.floor(a.x)%2)?a.x=Math.ceil(a.x)-a.x:a.x-=Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case THREE.MirroredRepeatWrapping:1=== +Math.abs(Math.floor(a.y)%2)?a.y=Math.ceil(a.y)-a.y:a.y-=Math.floor(a.y)}this.flipY&&(a.y=1-a.y)}}};Object.assign(THREE.Texture.prototype,THREE.EventDispatcher.prototype);THREE.TextureIdCount=0; +THREE.DepthTexture=function(a,b,c,d,e,f,g,h,k){THREE.Texture.call(this,null,d,e,f,g,h,THREE.DepthFormat,c,k);this.image={width:a,height:b};this.type=void 0!==c?c:THREE.UnsignedShortType;this.magFilter=void 0!==g?g:THREE.NearestFilter;this.minFilter=void 0!==h?h:THREE.NearestFilter;this.generateMipmaps=this.flipY=!1};THREE.DepthTexture.prototype=Object.create(THREE.Texture.prototype);THREE.DepthTexture.prototype.constructor=THREE.DepthTexture; +THREE.CanvasTexture=function(a,b,c,d,e,f,g,h,k){THREE.Texture.call(this,a,b,c,d,e,f,g,h,k);this.needsUpdate=!0};THREE.CanvasTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CanvasTexture.prototype.constructor=THREE.CanvasTexture;THREE.CubeTexture=function(a,b,c,d,e,f,g,h,k,l){a=void 0!==a?a:[];b=void 0!==b?b:THREE.CubeReflectionMapping;THREE.Texture.call(this,a,b,c,d,e,f,g,h,k,l);this.flipY=!1};THREE.CubeTexture.prototype=Object.create(THREE.Texture.prototype); +THREE.CubeTexture.prototype.constructor=THREE.CubeTexture;Object.defineProperty(THREE.CubeTexture.prototype,"images",{get:function(){return this.image},set:function(a){this.image=a}});THREE.CompressedTexture=function(a,b,c,d,e,f,g,h,k,l,n,p){THREE.Texture.call(this,null,f,g,h,k,l,d,e,n,p);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1};THREE.CompressedTexture.prototype=Object.create(THREE.Texture.prototype);THREE.CompressedTexture.prototype.constructor=THREE.CompressedTexture; +THREE.DataTexture=function(a,b,c,d,e,f,g,h,k,l,n,p){THREE.Texture.call(this,null,f,g,h,k,l,d,e,n,p);this.image={data:a,width:b,height:c};this.magFilter=void 0!==k?k:THREE.NearestFilter;this.minFilter=void 0!==l?l:THREE.NearestFilter;this.generateMipmaps=this.flipY=!1};THREE.DataTexture.prototype=Object.create(THREE.Texture.prototype);THREE.DataTexture.prototype.constructor=THREE.DataTexture; +THREE.VideoTexture=function(a,b,c,d,e,f,g,h,k){function l(){requestAnimationFrame(l);a.readyState>=a.HAVE_CURRENT_DATA&&(n.needsUpdate=!0)}THREE.Texture.call(this,a,b,c,d,e,f,g,h,k);this.generateMipmaps=!1;var n=this;l()};THREE.VideoTexture.prototype=Object.create(THREE.Texture.prototype);THREE.VideoTexture.prototype.constructor=THREE.VideoTexture;THREE.Group=function(){THREE.Object3D.call(this);this.type="Group"};THREE.Group.prototype=Object.assign(Object.create(THREE.Object3D.prototype),{constructor:THREE.Group}); +THREE.Points=function(a,b){THREE.Object3D.call(this);this.type="Points";this.geometry=void 0!==a?a:new THREE.BufferGeometry;this.material=void 0!==b?b:new THREE.PointsMaterial({color:16777215*Math.random()})}; +THREE.Points.prototype=Object.assign(Object.create(THREE.Object3D.prototype),{constructor:THREE.Points,raycast:function(){var a=new THREE.Matrix4,b=new THREE.Ray,c=new THREE.Sphere;return function(d,e){function f(a,c){var f=b.distanceSqToPoint(a);if(fd.far||e.push({distance:m,distanceToRay:Math.sqrt(f),point:h.clone(),index:c,face:null,object:g})}}var g=this,h=this.geometry,k=this.matrixWorld,l=d.params.Points.threshold; +null===h.boundingSphere&&h.computeBoundingSphere();c.copy(h.boundingSphere);c.applyMatrix4(k);if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);var l=l/((this.scale.x+this.scale.y+this.scale.z)/3),n=l*l,l=new THREE.Vector3;if(h instanceof THREE.BufferGeometry){var p=h.index,h=h.attributes.position.array;if(null!==p)for(var m=p.array,p=0,q=m.length;pf||(n.applyMatrix4(this.matrixWorld),s=d.ray.origin.distanceTo(n),sd.far||e.push({distance:s,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else for(g=0,r= +q.length/3-1;gf||(n.applyMatrix4(this.matrixWorld),s=d.ray.origin.distanceTo(n),sd.far||e.push({distance:s,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g instanceof THREE.Geometry)for(k=g.vertices,l=k.length,g=0;gf||(n.applyMatrix4(this.matrixWorld),s=d.ray.origin.distanceTo(n),sd.far|| +e.push({distance:s,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});THREE.LineSegments=function(a,b){THREE.Line.call(this,a,b);this.type="LineSegments"};THREE.LineSegments.prototype=Object.assign(Object.create(THREE.Line.prototype),{constructor:THREE.LineSegments}); +THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new THREE.BufferGeometry;this.material=void 0!==b?b:new THREE.MeshBasicMaterial({color:16777215*Math.random()});this.drawMode=THREE.TrianglesDrawMode;this.updateMorphTargets()}; +THREE.Mesh.prototype=Object.assign(Object.create(THREE.Object3D.prototype),{constructor:THREE.Mesh,setDrawMode:function(a){this.drawMode=a},updateMorphTargets:function(){if(void 0!==this.geometry.morphTargets&&0b.far?null:{distance:c,point:x.clone(),object:a}}function c(c,d,e,f,l,p,n,s){g.fromArray(f,3*p);h.fromArray(f,3*n);k.fromArray(f,3*s);if(c=b(c,d,e,g,h,k,u))l&&(m.fromArray(l,2*p),q.fromArray(l,2*n),r.fromArray(l,2*s),c.uv=a(u,g,h,k,m,q,r)),c.face=new THREE.Face3(p,n,s,THREE.Triangle.normal(g,h,k)),c.faceIndex=p;return c}var d=new THREE.Matrix4,e=new THREE.Ray,f=new THREE.Sphere, +g=new THREE.Vector3,h=new THREE.Vector3,k=new THREE.Vector3,l=new THREE.Vector3,n=new THREE.Vector3,p=new THREE.Vector3,m=new THREE.Vector2,q=new THREE.Vector2,r=new THREE.Vector2,s=new THREE.Vector3,u=new THREE.Vector3,x=new THREE.Vector3;return function(s,x){var w=this.geometry,D=this.material,A=this.matrixWorld;if(void 0!==D&&(null===w.boundingSphere&&w.computeBoundingSphere(),f.copy(w.boundingSphere),f.applyMatrix4(A),!1!==s.ray.intersectsSphere(f)&&(d.getInverse(A),e.copy(s.ray).applyMatrix4(d), +null===w.boundingBox||!1!==e.intersectsBox(w.boundingBox)))){var y,B;if(w instanceof THREE.BufferGeometry){var G,z,D=w.index,A=w.attributes,w=A.position.array;void 0!==A.uv&&(y=A.uv.array);if(null!==D)for(var A=D.array,H=0,M=A.length;H=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;ethis.scale.x*this.scale.y||c.push({distance:Math.sqrt(d),point:this.position,face:null,object:this})}}();THREE.Sprite.prototype.clone=function(){return(new this.constructor(this.material)).copy(this)};THREE.Particle=THREE.Sprite; -THREE.LensFlare=function(a,b,c,d,e){THREE.Object3D.call(this);this.lensFlares=[];this.positionScreen=new THREE.Vector3;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)};THREE.LensFlare.prototype=Object.create(THREE.Object3D.prototype);THREE.LensFlare.prototype.constructor=THREE.LensFlare; -THREE.LensFlare.prototype.add=function(a,b,c,d,e,f){void 0===b&&(b=-1);void 0===c&&(c=0);void 0===f&&(f=1);void 0===e&&(e=new THREE.Color(16777215));void 0===d&&(d=THREE.NormalBlending);c=Math.min(c,Math.max(0,c));this.lensFlares.push({texture:a,size:b,distance:c,x:0,y:0,z:0,scale:1,rotation:0,opacity:f,color:e,blending:d})}; -THREE.LensFlare.prototype.updateLensFlares=function(){var a,b=this.lensFlares.length,c,d=2*-this.positionScreen.x,e=2*-this.positionScreen.y;for(a=0;a= +d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;ethis.scale.x*this.scale.y/4||c.push({distance:Math.sqrt(d),point:this.position,face:null,object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)}}); +THREE.LensFlare=function(a,b,c,d,e){THREE.Object3D.call(this);this.lensFlares=[];this.positionScreen=new THREE.Vector3;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)}; +THREE.LensFlare.prototype=Object.assign(Object.create(THREE.Object3D.prototype),{constructor:THREE.LensFlare,copy:function(a){THREE.Object3D.prototype.copy.call(this,a);this.positionScreen.copy(a.positionScreen);this.customUpdateCallback=a.customUpdateCallback;for(var b=0,c=a.lensFlares.length;b dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );", -THREE.ShaderChunk.logdepthbuf_fragment,THREE.ShaderChunk.color_fragment,"\toutgoingLight = diffuseColor.rgb;",THREE.ShaderChunk.fog_fragment,"\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n}"].join("\n")},depth:{uniforms:{mNear:{type:"f",value:1},mFar:{type:"f",value:2E3},opacity:{type:"f",value:1}},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex, -THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float mNear;\nuniform float mFar;\nuniform float opacity;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tfloat depth = gl_FragDepthEXT / gl_FragCoord.w;\n\t#else\n\t\tfloat depth = gl_FragCoord.z / gl_FragCoord.w;\n\t#endif\n\tfloat color = 1.0 - smoothstep( mNear, mFar, depth );\n\tgl_FragColor = vec4( vec3( color ), opacity );\n}"].join("\n")}, -normal:{uniforms:{opacity:{type:"f",value:1}},vertexShader:["varying vec3 vNormal;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvNormal = normalize( normalMatrix * normal );",THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform float opacity;\nvarying vec3 vNormal;",THREE.ShaderChunk.common, -THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", -THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );",THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"f",value:-1}},vertexShader:["varying vec3 vWorldPosition;", -THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:["uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.logdepthbuf_pars_fragment,"void main() {\nvec3 direction = normalize( vWorldPosition );\nvec2 sampleUV;\nsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\nsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\ngl_FragColor = texture2D( tEquirect, sampleUV );", -THREE.ShaderChunk.logdepthbuf_fragment,"}"].join("\n")},depthRGBA:{uniforms:{},vertexShader:[THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,THREE.ShaderChunk.logdepthbuf_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.logdepthbuf_vertex,"}"].join("\n"),fragmentShader:[THREE.ShaderChunk.common, -THREE.ShaderChunk.logdepthbuf_pars_fragment,"vec4 pack_depth( const in float depth ) {\n\tconst vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bit_shift * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bit_mask;\n\treturn res;\n}\nvoid main() {",THREE.ShaderChunk.logdepthbuf_fragment,"\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragDepthEXT );\n\t#else\n\t\tgl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );\n\t#endif\n}"].join("\n")}, -distanceRGBA:{uniforms:{lightPos:{type:"v3",value:new THREE.Vector3(0,0,0)}},vertexShader:["varying vec4 vWorldPosition;",THREE.ShaderChunk.common,THREE.ShaderChunk.morphtarget_pars_vertex,THREE.ShaderChunk.skinning_pars_vertex,"void main() {",THREE.ShaderChunk.skinbase_vertex,THREE.ShaderChunk.begin_vertex,THREE.ShaderChunk.morphtarget_vertex,THREE.ShaderChunk.skinning_vertex,THREE.ShaderChunk.project_vertex,THREE.ShaderChunk.worldpos_vertex,"vWorldPosition = worldPosition;\n}"].join("\n"),fragmentShader:["uniform vec3 lightPos;\nvarying vec4 vWorldPosition;", -THREE.ShaderChunk.common,"vec4 pack1K ( float depth ) {\n\tdepth /= 1000.0;\n\tconst vec4 bitSh = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );\n\tconst vec4 bitMsk = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );\n\tvec4 res = mod( depth * bitSh * vec4( 255 ), vec4( 256 ) ) / vec4( 255 );\n\tres -= res.xxyz * bitMsk;\n\treturn res; \n}\nfloat unpack1K ( vec4 color ) {\n\tconst vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\n\treturn dot( color, bitSh ) * 1000.0;\n}\nvoid main () {\n\tgl_FragColor = pack1K( length( vWorldPosition.xyz - lightPos.xyz ) );\n}"].join("\n")}}; -THREE.WebGLRenderer=function(a){function b(a,b,c,d){!0===Q&&(a*=d,b*=d,c*=d);H.clearColor(a,b,c,d)}function c(){H.init();H.scissor(pa.copy(xa).multiplyScalar($));H.viewport(ja.copy(ka).multiplyScalar($));b(aa.r,aa.g,aa.b,fa)}function d(){la=ga=null;ma="";qa=-1;H.reset()}function e(a){a.preventDefault();d();c();T.clear()}function f(a){a=a.target;a.removeEventListener("dispose",f);a:{var b=T.get(a);if(a.image&&b.__image__webglTextureCube)r.deleteTexture(b.__image__webglTextureCube);else{if(void 0=== -b.__webglInit)break a;r.deleteTexture(b.__webglTexture)}T.delete(a)}ha.textures--}function g(a){a=a.target;a.removeEventListener("dispose",g);var b=T.get(a),c=T.get(a.texture);if(a&&void 0!==c.__webglTexture){r.deleteTexture(c.__webglTexture);if(a instanceof THREE.WebGLRenderTargetCube)for(c=0;6>c;c++)r.deleteFramebuffer(b.__webglFramebuffer[c]),r.deleteRenderbuffer(b.__webglDepthbuffer[c]);else r.deleteFramebuffer(b.__webglFramebuffer),r.deleteRenderbuffer(b.__webglDepthbuffer);T.delete(a.texture); -T.delete(a)}ha.textures--}function h(a){a=a.target;a.removeEventListener("dispose",h);k(a);T.delete(a)}function k(a){var b=T.get(a).program;a.program=void 0;void 0!==b&&na.releaseProgram(b)}function m(a,b){return Math.abs(b[0])-Math.abs(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 l(a,b,c,d,e){var f;c.transparent?(d=V,f=++W):(d=M,f=++E);f=d[f];void 0!==f?(f.id=a.id,f.object=a,f.geometry=b,f.material=c,f.z=X.z,f.group=e):(f={id:a.id,object:a,geometry:b,material:c,z:X.z,group:e},d.push(f))}function q(a,b){if(!1!==a.visible){if(a.layers.test(b.layers))if(a instanceof THREE.Light)R.push(a);else if(a instanceof THREE.Sprite)!1!==a.frustumCulled&&!0!==ya.intersectsObject(a)||ia.push(a);else if(a instanceof -THREE.LensFlare)da.push(a);else if(a instanceof THREE.ImmediateRenderObject)!0===Y.sortObjects&&(X.setFromMatrixPosition(a.matrixWorld),X.applyProjection(ra)),l(a,null,a.material,X.z,null);else if(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===ya.intersectsObject(a)){var c=a.material;if(!0===c.visible){!0===Y.sortObjects&&(X.setFromMatrixPosition(a.matrixWorld),X.applyProjection(ra));var d= -oa.update(a);if(c instanceof THREE.MultiMaterial)for(var e=d.groups,f=c.materials,c=0,g=e.length;c=ca.maxTextures&&console.warn("WebGLRenderer: trying to use "+ -a+" texture units while this GPU supports only "+ca.maxTextures);sa+=1;return a}function v(a){for(var b,c,d=0,e=a.length;db||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 D(a){return THREE.Math.isPowerOfTwo(a.width)&& -THREE.Math.isPowerOfTwo(a.height)}function A(a,b){var c=T.get(a);if(6===a.image.length)if(0h;h++)g[h]=!Y.autoScaleCubemaps|| -d||e?e?a.image[h].image:a.image[h]:x(a.image[h],ca.maxCubemapSize);var k=D(g[0]),l=z(a.format),m=z(a.type);C(r.TEXTURE_CUBE_MAP,a,k);for(h=0;6>h;h++)if(d)for(var n,q=g[h].mipmaps,p=0,t=q.length;pf;f++)b.__webglFramebuffer[f]=r.createFramebuffer()}else b.__webglFramebuffer=r.createFramebuffer(); -if(d){H.bindTexture(r.TEXTURE_CUBE_MAP,c.__webglTexture);C(r.TEXTURE_CUBE_MAP,a.texture,e);for(f=0;6>f;f++)y(b.__webglFramebuffer[f],a,r.COLOR_ATTACHMENT0,r.TEXTURE_CUBE_MAP_POSITIVE_X+f);a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_CUBE_MAP);H.bindTexture(r.TEXTURE_CUBE_MAP,null)}else H.bindTexture(r.TEXTURE_2D,c.__webglTexture),C(r.TEXTURE_2D,a.texture,e),y(b.__webglFramebuffer,a,r.COLOR_ATTACHMENT0,r.TEXTURE_2D),a.texture.generateMipmaps&&e&&r.generateMipmap(r.TEXTURE_2D),H.bindTexture(r.TEXTURE_2D, -null);if(a.depthBuffer){b=T.get(a);if(a instanceof THREE.WebGLRenderTargetCube)for(b.__webglDepthbuffer=[],c=0;6>c;c++)r.bindFramebuffer(r.FRAMEBUFFER,b.__webglFramebuffer[c]),b.__webglDepthbuffer[c]=r.createRenderbuffer(),I(b.__webglDepthbuffer[c],a);else r.bindFramebuffer(r.FRAMEBUFFER,b.__webglFramebuffer),b.__webglDepthbuffer=r.createRenderbuffer(),I(b.__webglDepthbuffer,a);r.bindFramebuffer(r.FRAMEBUFFER,null)}}b=a instanceof THREE.WebGLRenderTargetCube;a?(c=T.get(a),c=b?c.__webglFramebuffer[a.activeCubeFace]: -c.__webglFramebuffer,pa.copy(a.scissor),za=a.scissorTest,ja.copy(a.viewport)):(c=null,pa.copy(xa).multiplyScalar($),za=Aa,ja.copy(ka).multiplyScalar($));ta!==c&&(r.bindFramebuffer(r.FRAMEBUFFER,c),ta=c);H.scissor(pa);H.setScissorTest(za);H.viewport(ja);b&&(b=T.get(a.texture),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,b.__webglTexture,0))};this.readRenderTargetPixels=function(a,b,c,d,e,g){if(!1===a instanceof THREE.WebGLRenderTarget)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget."); -else{var f=T.get(a).__webglFramebuffer;if(f){var h=!1;f!==ta&&(r.bindFramebuffer(r.FRAMEBUFFER,f),h=!0);try{var k=a.texture;k.format!==THREE.RGBAFormat&&z(k.format)!==r.getParameter(r.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):k.type===THREE.UnsignedByteType||z(k.type)===r.getParameter(r.IMPLEMENTATION_COLOR_READ_TYPE)||k.type===THREE.FloatType&&U.get("WEBGL_color_buffer_float")||k.type=== -THREE.HalfFloatType&&U.get("EXT_color_buffer_half_float")?r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE?r.readPixels(b,c,d,e,z(k.format),z(k.type),g):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&&r.bindFramebuffer(r.FRAMEBUFFER,ta)}}}}}; -THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;this.scissor=new THREE.Vector4(0,0,a,b);this.scissorTest=!1;this.viewport=new THREE.Vector4(0,0,a,b);c=c||{};void 0===c.minFilter&&(c.minFilter=THREE.LinearFilter);this.texture=new THREE.Texture(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0}; -THREE.WebGLRenderTarget.prototype={constructor:THREE.WebGLRenderTarget,setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;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; +THREE.UniformsLib={common:{diffuse:{type:"c",value:new THREE.Color(15658734)},opacity:{type:"1f",value:1},map:{type:"t",value:null},offsetRepeat:{type:"v4",value:new THREE.Vector4(0,0,1,1)},specularMap:{type:"t",value:null},alphaMap:{type:"t",value:null},envMap:{type:"t",value:null},flipEnvMap:{type:"1f",value:-1},reflectivity:{type:"1f",value:1},refractionRatio:{type:"1f",value:.98}},aomap:{aoMap:{type:"t",value:null},aoMapIntensity:{type:"1f",value:1}},lightmap:{lightMap:{type:"t",value:null},lightMapIntensity:{type:"1f", +value:1}},emissivemap:{emissiveMap:{type:"t",value:null}},bumpmap:{bumpMap:{type:"t",value:null},bumpScale:{type:"1f",value:1}},normalmap:{normalMap:{type:"t",value:null},normalScale:{type:"v2",value:new THREE.Vector2(1,1)}},displacementmap:{displacementMap:{type:"t",value:null},displacementScale:{type:"1f",value:1},displacementBias:{type:"1f",value:0}},roughnessmap:{roughnessMap:{type:"t",value:null}},metalnessmap:{metalnessMap:{type:"t",value:null}},fog:{fogDensity:{type:"1f",value:2.5E-4},fogNear:{type:"1f", +value:1},fogFar:{type:"1f",value:2E3},fogColor:{type:"c",value:new THREE.Color(16777215)}},lights:{ambientLightColor:{type:"3fv",value:[]},directionalLights:{type:"sa",value:[],properties:{direction:{type:"v3"},color:{type:"c"},shadow:{type:"1i"},shadowBias:{type:"1f"},shadowRadius:{type:"1f"},shadowMapSize:{type:"v2"}}},directionalShadowMap:{type:"tv",value:[]},directionalShadowMatrix:{type:"m4v",value:[]},spotLights:{type:"sa",value:[],properties:{color:{type:"c"},position:{type:"v3"},direction:{type:"v3"}, +distance:{type:"1f"},coneCos:{type:"1f"},penumbraCos:{type:"1f"},decay:{type:"1f"},shadow:{type:"1i"},shadowBias:{type:"1f"},shadowRadius:{type:"1f"},shadowMapSize:{type:"v2"}}},spotShadowMap:{type:"tv",value:[]},spotShadowMatrix:{type:"m4v",value:[]},pointLights:{type:"sa",value:[],properties:{color:{type:"c"},position:{type:"v3"},decay:{type:"1f"},distance:{type:"1f"},shadow:{type:"1i"},shadowBias:{type:"1f"},shadowRadius:{type:"1f"},shadowMapSize:{type:"v2"}}},pointShadowMap:{type:"tv",value:[]}, +pointShadowMatrix:{type:"m4v",value:[]},hemisphereLights:{type:"sa",value:[],properties:{direction:{type:"v3"},skyColor:{type:"c"},groundColor:{type:"c"}}}},points:{diffuse:{type:"c",value:new THREE.Color(15658734)},opacity:{type:"1f",value:1},size:{type:"1f",value:1},scale:{type:"1f",value:1},map:{type:"t",value:null},offsetRepeat:{type:"v4",value:new THREE.Vector4(0,0,1,1)}}};THREE.ShaderChunk.cube_frag="uniform samplerCube tCube;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n\t#include \n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\t#include \n}\n"; +THREE.ShaderChunk.cube_vert="varying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n";THREE.ShaderChunk.depth_frag="#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n"; +THREE.ShaderChunk.depth_vert="#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.distanceRGBA_frag="uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include \n#include \n#include \nvoid main () {\n\t#include \n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n";THREE.ShaderChunk.distanceRGBA_vert="varying vec4 vWorldPosition;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition;\n}\n"; +THREE.ShaderChunk.equirect_frag="uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include \n}\n"; +THREE.ShaderChunk.equirect_vert="varying vec3 vWorldPosition;\n#include \n#include \n#include \nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n";THREE.ShaderChunk.linedashed_frag="uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.linedashed_vert="uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshbasic_frag="uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight;\n\treflectedLight.directDiffuse = vec3( 0.0 );\n\treflectedLight.directSpecular = vec3( 0.0 );\n\treflectedLight.indirectDiffuse = diffuseColor.rgb;\n\treflectedLight.indirectSpecular = vec3( 0.0 );\n\t#include \n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshbasic_vert="#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_ENVMAP\n\t#include \n\t#include \n\t#include \n\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshlambert_frag="uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include \n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshlambert_vert="#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshphong_frag="#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshphong_vert="#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshphysical_frag="#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\nuniform float envMapIntensity;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.meshphysical_vert="#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.normal_frag="uniform float opacity;\nvarying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( vNormal ), opacity );\n\t#include \n}\n";THREE.ShaderChunk.normal_vert="varying vec3 vNormal;\n#include \n#include \n#include \n#include \nvoid main() {\n\tvNormal = normalize( normalMatrix * normal );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.points_frag="uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.points_vert="uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderChunk.shadow_frag="uniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n";THREE.ShaderChunk.shadow_vert="#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n}\n"; +THREE.ShaderLib={basic:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.aomap,THREE.UniformsLib.fog]),vertexShader:THREE.ShaderChunk.meshbasic_vert,fragmentShader:THREE.ShaderChunk.meshbasic_frag},lambert:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.aomap,THREE.UniformsLib.lightmap,THREE.UniformsLib.emissivemap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,{emissive:{type:"c",value:new THREE.Color(0)}}]),vertexShader:THREE.ShaderChunk.meshlambert_vert, +fragmentShader:THREE.ShaderChunk.meshlambert_frag},phong:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.aomap,THREE.UniformsLib.lightmap,THREE.UniformsLib.emissivemap,THREE.UniformsLib.bumpmap,THREE.UniformsLib.normalmap,THREE.UniformsLib.displacementmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,{emissive:{type:"c",value:new THREE.Color(0)},specular:{type:"c",value:new THREE.Color(1118481)},shininess:{type:"1f",value:30}}]),vertexShader:THREE.ShaderChunk.meshphong_vert, +fragmentShader:THREE.ShaderChunk.meshphong_frag},standard:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.aomap,THREE.UniformsLib.lightmap,THREE.UniformsLib.emissivemap,THREE.UniformsLib.bumpmap,THREE.UniformsLib.normalmap,THREE.UniformsLib.displacementmap,THREE.UniformsLib.roughnessmap,THREE.UniformsLib.metalnessmap,THREE.UniformsLib.fog,THREE.UniformsLib.lights,{emissive:{type:"c",value:new THREE.Color(0)},roughness:{type:"1f",value:.5},metalness:{type:"1f",value:0}, +envMapIntensity:{type:"1f",value:1}}]),vertexShader:THREE.ShaderChunk.meshphysical_vert,fragmentShader:THREE.ShaderChunk.meshphysical_frag},points:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.points,THREE.UniformsLib.fog]),vertexShader:THREE.ShaderChunk.points_vert,fragmentShader:THREE.ShaderChunk.points_frag},dashed:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.fog,{scale:{type:"1f",value:1},dashSize:{type:"1f",value:1},totalSize:{type:"1f",value:2}}]), +vertexShader:THREE.ShaderChunk.linedashed_vert,fragmentShader:THREE.ShaderChunk.linedashed_frag},depth:{uniforms:THREE.UniformsUtils.merge([THREE.UniformsLib.common,THREE.UniformsLib.displacementmap]),vertexShader:THREE.ShaderChunk.depth_vert,fragmentShader:THREE.ShaderChunk.depth_frag},normal:{uniforms:{opacity:{type:"1f",value:1}},vertexShader:THREE.ShaderChunk.normal_vert,fragmentShader:THREE.ShaderChunk.normal_frag},cube:{uniforms:{tCube:{type:"t",value:null},tFlip:{type:"1f",value:-1}},vertexShader:THREE.ShaderChunk.cube_vert, +fragmentShader:THREE.ShaderChunk.cube_frag},equirect:{uniforms:{tEquirect:{type:"t",value:null},tFlip:{type:"1f",value:-1}},vertexShader:THREE.ShaderChunk.equirect_vert,fragmentShader:THREE.ShaderChunk.equirect_frag},distanceRGBA:{uniforms:{lightPos:{type:"v3",value:new THREE.Vector3}},vertexShader:THREE.ShaderChunk.distanceRGBA_vert,fragmentShader:THREE.ShaderChunk.distanceRGBA_frag}}; +THREE.ShaderLib.physical={uniforms:THREE.UniformsUtils.merge([THREE.ShaderLib.standard.uniforms,{}]),vertexShader:THREE.ShaderChunk.meshphysical_vert,fragmentShader:THREE.ShaderChunk.meshphysical_frag}; +THREE.WebGLRenderer=function(a){function b(a,b,c,d){!0===K&&(a*=d,b*=d,c*=d);J.clearColor(a,b,c,d)}function c(){J.init();J.scissor(ra.copy(ya).multiplyScalar($));J.viewport(ma.copy(na).multiplyScalar($));b(aa.r,aa.g,aa.b,ia)}function d(){ea=fa=null;oa="";Z=-1;J.reset()}function e(a){a.preventDefault();d();c();T.clear()}function f(a){a=a.target;a.removeEventListener("dispose",f);a:{var b=T.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)}T.delete(a)}ja.textures--}function g(a){a=a.target;a.removeEventListener("dispose",g);var b=T.get(a),c=T.get(a.texture);if(a){void 0!==c.__webglTexture&&t.deleteTexture(c.__webglTexture);a.depthTexture&&a.depthTexture.dispose();if(a instanceof THREE.WebGLRenderTargetCube)for(c=0;6>c;c++)t.deleteFramebuffer(b.__webglFramebuffer[c]),b.__webglDepthbuffer&&t.deleteRenderbuffer(b.__webglDepthbuffer[c]);else t.deleteFramebuffer(b.__webglFramebuffer), +b.__webglDepthbuffer&&t.deleteRenderbuffer(b.__webglDepthbuffer);T.delete(a.texture);T.delete(a)}ja.textures--}function h(a){a=a.target;a.removeEventListener("dispose",h);k(a);T.delete(a)}function k(a){var b=T.get(a).program;a.program=void 0;void 0!==b&&pa.releaseProgram(b)}function l(a,b){return Math.abs(b[0])-Math.abs(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 g;c.transparent?(d=R,g=++F):(d=P,g=++Q);g=d[g];void 0!==g?(g.id=a.id,g.object=a,g.geometry=b,g.material=c,g.z=X.z,g.group=e):(g={id:a.id,object:a,geometry:b,material:c,z:X.z,group:e},d.push(g))}function q(a){if(!Ba.intersectsSphere(a))return!1;var b=ba.numPlanes;if(0===b)return!0;var c=W.clippingPlanes,d=a.center;a= +-a.radius;var e=0;do if(c[e].distanceToPoint(d)b||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 D(a){return THREE.Math.isPowerOfTwo(a.width)&&THREE.Math.isPowerOfTwo(a.height)}function A(a,b,c,d){var e=G(b.texture.format),f=G(b.texture.type);J.texImage2D(d,0,e,b.width,b.height,0,e,f,null);t.bindFramebuffer(t.FRAMEBUFFER,a);t.framebufferTexture2D(t.FRAMEBUFFER,c,d,T.get(b.texture).__webglTexture,0);t.bindFramebuffer(t.FRAMEBUFFER,null)}function y(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);t.bindRenderbuffer(t.RENDERBUFFER,null)}function B(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter? +t.NEAREST:t.LINEAR}function G(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=V.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.DepthFormat)return t.DEPTH_COMPONENT;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=V.get("WEBGL_compressed_texture_s3tc");if(null!==b){if(a===THREE.RGB_S3TC_DXT1_Format)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT1_Format)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(a===THREE.RGBA_S3TC_DXT3_Format)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(a===THREE.RGBA_S3TC_DXT5_Format)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}b=V.get("WEBGL_compressed_texture_pvrtc"); +if(null!==b){if(a===THREE.RGB_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(a===THREE.RGB_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(a===THREE.RGBA_PVRTC_4BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(a===THREE.RGBA_PVRTC_2BPPV1_Format)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}b=V.get("WEBGL_compressed_texture_etc1");if(null!==b&&a===THREE.RGB_ETC1_Format)return b.COMPRESSED_RGB_ETC1_WEBGL;b=V.get("EXT_blend_minmax");if(null!==b){if(a===THREE.MinEquation)return b.MIN_EXT; +if(a===THREE.MaxEquation)return b.MAX_EXT}return 0}console.log("THREE.WebGLRenderer",THREE.REVISION);a=a||{};var z=void 0!==a.canvas?a.canvas:document.createElement("canvas"),H=void 0!==a.context?a.context:null,M=void 0!==a.alpha?a.alpha:!1,O=void 0!==a.depth?a.depth:!0,N=void 0!==a.stencil?a.stencil:!0,E=void 0!==a.antialias?a.antialias:!1,K=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,I=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,L=[],P=[],Q=-1,R=[],F=-1,da=new Float32Array(8), +U=[],Y=[];this.domElement=z;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.clippingPlanes=[];this.localClippingEnabled=!1;this.gammaFactor=2;this.physicallyCorrectLights=this.gammaOutput=this.gammaInput=!1;this.toneMapping=THREE.LinearToneMapping;this.toneMappingWhitePoint=this.toneMappingExposure=1;this.maxMorphTargets=8;this.maxMorphNormals=4;this.autoScaleCubemaps=!0;var W=this,fa=null,la=null,ga=null,Z=-1,oa="",ea=null,ra= +new THREE.Vector4,Aa=null,ma=new THREE.Vector4,ta=0,aa=new THREE.Color(0),ia=0,va=z.width,wa=z.height,$=1,ya=new THREE.Vector4(0,0,va,wa),Ca=!1,na=new THREE.Vector4(0,0,va,wa),Ba=new THREE.Frustum,ba=new THREE.WebGLClipping,ua=!1,za=!1,ka=new THREE.Sphere,sa=new THREE.Matrix4,X=new THREE.Vector3,S={hash:"",ambient:[0,0,0],directional:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotShadowMap:[],spotShadowMatrix:[],point:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],shadows:[]}, +ja={geometries:0,textures:0},ha={calls:0,vertices:0,faces:0,points:0};this.info={render:ha,memory:ja,programs:null};var t;try{M={alpha:M,depth:O,stencil:N,antialias:E,premultipliedAlpha:K,preserveDrawingBuffer:I};t=H||z.getContext("webgl",M)||z.getContext("experimental-webgl",M);if(null===t){if(null!==z.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";throw"Error creating WebGL context.";}void 0===t.getShaderPrecisionFormat&&(t.getShaderPrecisionFormat=function(){return{rangeMin:1, +rangeMax:1,precision:1}});z.addEventListener("webglcontextlost",e,!1)}catch(Fa){console.error("THREE.WebGLRenderer: "+Fa)}var Da="undefined"!==typeof WebGL2RenderingContext&&t instanceof WebGL2RenderingContext,V=new THREE.WebGLExtensions(t);V.get("WEBGL_depth_texture");V.get("OES_texture_float");V.get("OES_texture_float_linear");V.get("OES_texture_half_float");V.get("OES_texture_half_float_linear");V.get("OES_standard_derivatives");V.get("ANGLE_instanced_arrays");V.get("OES_element_index_uint")&& +(THREE.BufferGeometry.MaxIndex=4294967296);var ca=new THREE.WebGLCapabilities(t,V,a),J=new THREE.WebGLState(t,V,G),T=new THREE.WebGLProperties,qa=new THREE.WebGLObjects(t,T,this.info),pa=new THREE.WebGLPrograms(this,ca),xa=new THREE.WebGLLights;this.info.programs=pa.programs;var Ga=new THREE.WebGLBufferRenderer(t,V,ha),Ha=new THREE.WebGLIndexedBufferRenderer(t,V,ha);c();this.context=t;this.capabilities=ca;this.extensions=V;this.properties=T;this.state=J;var Ea=new THREE.WebGLShadowMap(this,S,qa); +this.shadowMap=Ea;var Ia=new THREE.SpritePlugin(this,U),Ja=new THREE.LensFlarePlugin(this,Y);this.getContext=function(){return t};this.getContextAttributes=function(){return t.getContextAttributes()};this.forceContextLoss=function(){V.get("WEBGL_lose_context").loseContext()};this.getMaxAnisotropy=function(){var a;return function(){if(void 0!==a)return a;var b=V.get("EXT_texture_filter_anisotropic");return a=null!==b?t.getParameter(b.MAX_TEXTURE_MAX_ANISOTROPY_EXT):0}}();this.getPrecision=function(){return ca.precision}; +this.getPixelRatio=function(){return $};this.setPixelRatio=function(a){void 0!==a&&($=a,this.setSize(na.z,na.w,!1))};this.getSize=function(){return{width:va,height:wa}};this.setSize=function(a,b,c){va=a;wa=b;z.width=a*$;z.height=b*$;!1!==c&&(z.style.width=a+"px",z.style.height=b+"px");this.setViewport(0,0,a,b)};this.setViewport=function(a,b,c,d){J.viewport(na.set(a,b,c,d))};this.setScissor=function(a,b,c,d){J.scissor(ya.set(a,b,c,d))};this.setScissorTest=function(a){J.setScissorTest(Ca=a)};this.getClearColor= +function(){return aa};this.setClearColor=function(a,c){aa.set(a);ia=void 0!==c?c:1;b(aa.r,aa.g,aa.b,ia)};this.getClearAlpha=function(){return ia};this.setClearAlpha=function(a){ia=a;b(aa.r,aa.g,aa.b,ia)};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(){this.clear(!0,!1,!1)};this.clearDepth=function(){this.clear(!1,!0,!1)};this.clearStencil=function(){this.clear(!1, +!1,!0)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=d;this.dispose=function(){z.removeEventListener("webglcontextlost",e,!1)};this.renderBufferImmediate=function(a,b,c){J.initAttributes();var d=T.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),J.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&&"MeshStandardMaterial"!==c.type&&"MeshPhysicalMaterial"!==c.type&&c.shading===THREE.FlatShading)for(var e=0,f=3*a.count;e=ca.maxTextures&&console.warn("WebGLRenderer: trying to use "+ +a+" texture units while this GPU supports only "+ca.maxTextures);ta+=1;return a};this.setTexture2D=function(){var a=!1;return function(b,c){b instanceof THREE.WebGLRenderTarget&&(a||(console.warn("THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);var d=b,e=T.get(d);if(0m;m++)k[m]=!W.autoScaleCubemaps||g||h?h?d.image[m].image:d.image[m]:w(d.image[m],ca.maxCubemapSize);var l=D(k[0]),n=G(d.format),p=G(d.type);C(t.TEXTURE_CUBE_MAP,d,l);for(m=0;6>m;m++)if(g)for(var q,r=k[m].mipmaps, +s=0,x=r.length;sf;f++)b.__webglFramebuffer[f]=t.createFramebuffer()}else b.__webglFramebuffer=t.createFramebuffer();if(d){J.bindTexture(t.TEXTURE_CUBE_MAP,c.__webglTexture);C(t.TEXTURE_CUBE_MAP,a.texture,e);for(f=0;6>f;f++)A(b.__webglFramebuffer[f], +a,t.COLOR_ATTACHMENT0,t.TEXTURE_CUBE_MAP_POSITIVE_X+f);a.texture.generateMipmaps&&e&&t.generateMipmap(t.TEXTURE_CUBE_MAP);J.bindTexture(t.TEXTURE_CUBE_MAP,null)}else J.bindTexture(t.TEXTURE_2D,c.__webglTexture),C(t.TEXTURE_2D,a.texture,e),A(b.__webglFramebuffer,a,t.COLOR_ATTACHMENT0,t.TEXTURE_2D),a.texture.generateMipmaps&&e&&t.generateMipmap(t.TEXTURE_2D),J.bindTexture(t.TEXTURE_2D,null);if(a.depthBuffer){b=T.get(a);c=a instanceof THREE.WebGLRenderTargetCube;if(a.depthTexture){if(c)throw Error("target.depthTexture not supported in Cube render targets"); +if(a instanceof THREE.WebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported!");t.bindFramebuffer(t.FRAMEBUFFER,b.__webglFramebuffer);if(!(a.depthTexture instanceof THREE.DepthTexture))throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");T.get(a.depthTexture).__webglTexture&&a.depthTexture.image.width===a.width&&a.depthTexture.image.height===a.height||(a.depthTexture.image.width=a.width,a.depthTexture.image.height=a.height,a.depthTexture.needsUpdate= +!0);W.setTexture2D(a.depthTexture,0);b=T.get(a.depthTexture).__webglTexture;t.framebufferTexture2D(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.TEXTURE_2D,b,0)}else if(c)for(b.__webglDepthbuffer=[],c=0;6>c;c++)t.bindFramebuffer(t.FRAMEBUFFER,b.__webglFramebuffer[c]),b.__webglDepthbuffer[c]=t.createRenderbuffer(),y(b.__webglDepthbuffer[c],a);else t.bindFramebuffer(t.FRAMEBUFFER,b.__webglFramebuffer),b.__webglDepthbuffer=t.createRenderbuffer(),y(b.__webglDepthbuffer,a);t.bindFramebuffer(t.FRAMEBUFFER,null)}}b= +a instanceof THREE.WebGLRenderTargetCube;a?(c=T.get(a),c=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,ra.copy(a.scissor),Aa=a.scissorTest,ma.copy(a.viewport)):(c=null,ra.copy(ya).multiplyScalar($),Aa=Ca,ma.copy(na).multiplyScalar($));ga!==c&&(t.bindFramebuffer(t.FRAMEBUFFER,c),ga=c);J.scissor(ra);J.setScissorTest(Aa);J.viewport(ma);b&&(b=T.get(a.texture),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,b.__webglTexture,a.activeMipMapLevel))}; +this.readRenderTargetPixels=function(a,b,c,d,e,f){if(!1===a instanceof THREE.WebGLRenderTarget)console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");else{var g=T.get(a).__webglFramebuffer;if(g){var h=!1;g!==ga&&(t.bindFramebuffer(t.FRAMEBUFFER,g),h=!0);try{var k=a.texture;k.format!==THREE.RGBAFormat&&G(k.format)!==t.getParameter(t.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."): +k.type===THREE.UnsignedByteType||G(k.type)===t.getParameter(t.IMPLEMENTATION_COLOR_READ_TYPE)||k.type===THREE.FloatType&&V.get("WEBGL_color_buffer_float")||k.type===THREE.HalfFloatType&&V.get("EXT_color_buffer_half_float")?t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE?0<=b&&b<=a.width-d&&0<=c&&c<=a.height-e&&t.readPixels(b,c,d,e,G(k.format),G(k.type),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&& +t.bindFramebuffer(t.FRAMEBUFFER,ga)}}}}}; +THREE.WebGLRenderTarget=function(a,b,c){this.uuid=THREE.Math.generateUUID();this.width=a;this.height=b;this.scissor=new THREE.Vector4(0,0,a,b);this.scissorTest=!1;this.viewport=new THREE.Vector4(0,0,a,b);c=c||{};void 0===c.minFilter&&(c.minFilter=THREE.LinearFilter);this.texture=new THREE.Texture(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy,c.encoding);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer: +!0;this.depthTexture=null}; +Object.assign(THREE.WebGLRenderTarget.prototype,THREE.EventDispatcher.prototype,{setSize:function(a,b){if(this.width!==a||this.height!==b)this.width=a,this.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture; +return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});THREE.WebGLRenderTargetCube=function(a,b,c){THREE.WebGLRenderTarget.call(this,a,b,c);this.activeMipMapLevel=this.activeCubeFace=0};THREE.WebGLRenderTargetCube.prototype=Object.create(THREE.WebGLRenderTarget.prototype);THREE.WebGLRenderTargetCube.prototype.constructor=THREE.WebGLRenderTargetCube; THREE.WebGLBufferRenderer=function(a,b,c){var d;this.setMode=function(a){d=a};this.render=function(b,f){a.drawArrays(d,b,f);c.calls++;c.vertices+=f;d===a.TRIANGLES&&(c.faces+=f/3)};this.renderInstances=function(e){var f=b.get("ANGLE_instanced_arrays");if(null===f)console.error("THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");else{var g=e.attributes.position,h=0,h=g instanceof THREE.InterleavedBufferAttribute?g.data.count: g.count;f.drawArraysInstancedANGLE(d,0,h,e.maxInstancedCount);c.calls++;c.vertices+=h*e.maxInstancedCount;d===a.TRIANGLES&&(c.faces+=e.maxInstancedCount*h/3)}}}; -THREE.WebGLIndexedBufferRenderer=function(a,b,c){var d,e,f;this.setMode=function(a){d=a};this.setIndex=function(c){c.array instanceof Uint32Array&&b.get("OES_element_index_uint")?(e=a.UNSIGNED_INT,f=4):(e=a.UNSIGNED_SHORT,f=2)};this.render=function(b,h){a.drawElements(d,h,e,b*f);c.calls++;c.vertices+=h;d===a.TRIANGLES&&(c.faces+=h/3)};this.renderInstances=function(g,h,k){var m=b.get("ANGLE_instanced_arrays");null===m?console.error("THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays."): -(m.drawElementsInstancedANGLE(d,k,e,h*f,g.maxInstancedCount),c.calls++,c.vertices+=k*g.maxInstancedCount,d===a.TRIANGLES&&(c.faces+=g.maxInstancedCount*k/3))}}; -THREE.WebGLExtensions=function(a){var b={};this.get=function(c){if(void 0!==b[c])return b[c];var d;switch(c){case "EXT_texture_filter_anisotropic":d=a.getExtension("EXT_texture_filter_anisotropic")||a.getExtension("MOZ_EXT_texture_filter_anisotropic")||a.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case "WEBGL_compressed_texture_s3tc":d=a.getExtension("WEBGL_compressed_texture_s3tc")||a.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc"); -break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;case "WEBGL_compressed_texture_etc1":d=a.getExtension("WEBGL_compressed_texture_etc1");break;default:d=a.getExtension(c)}null===d&&console.warn("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}; +THREE.WebGLClipping=function(){function a(){l.value!==d&&(l.value=d,l.needsUpdate=0c){var d=b;b=c;c=d}d=a[b];return void 0===d?(a[b]=[c],!0):-1===d.indexOf(c)?(d.push(c),!0):!1}var f=new THREE.WebGLGeometries(a,b,c);this.getAttributeBuffer=function(a){return a instanceof THREE.InterleavedBufferAttribute?b.get(a.data).__webglBuffer:b.get(a).__webglBuffer};this.getWireframeAttribute= -function(c){var f=b.get(c);if(void 0!==f.wireframe)return f.wireframe;var k=[],m=c.index,n=c.attributes;c=n.position;if(null!==m)for(var n={},m=m.array,p=0,l=m.length;p/g,function(a,b){var c=THREE.ShaderChunk[b];if(void 0===c)throw Error("Can not resolve #include <"+ +b+">");return k(c)})}function l(a){return a.replace(/for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,b,c,d){a="";for(b=parseInt(b);b 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n")); -x.compileShader(G);x.compileShader(L);x.attachShader(K,G);x.attachShader(K,L);x.linkProgram(K);y=K;w=x.getAttribLocation(y,"position");v=x.getAttribLocation(y,"uv");c=x.getUniformLocation(y,"uvOffset");d=x.getUniformLocation(y,"uvScale");e=x.getUniformLocation(y,"rotation");f=x.getUniformLocation(y,"scale");g=x.getUniformLocation(y,"color");h=x.getUniformLocation(y,"map");k=x.getUniformLocation(y,"opacity");m=x.getUniformLocation(y,"modelViewMatrix");n=x.getUniformLocation(y,"projectionMatrix");p= -x.getUniformLocation(y,"fogType");l=x.getUniformLocation(y,"fogDensity");q=x.getUniformLocation(y,"fogNear");t=x.getUniformLocation(y,"fogFar");u=x.getUniformLocation(y,"fogColor");s=x.getUniformLocation(y,"alphaTest");K=document.createElement("canvas");K.width=8;K.height=8;G=K.getContext("2d");G.fillStyle="white";G.fillRect(0,0,8,8);I=new THREE.Texture(K);I.needsUpdate=!0}x.useProgram(y);D.initAttributes();D.enableAttribute(w);D.enableAttribute(v);D.disableUnusedAttributes();D.disable(x.CULL_FACE); -D.enable(x.BLEND);x.bindBuffer(x.ARRAY_BUFFER,A);x.vertexAttribPointer(w,2,x.FLOAT,!1,16,0);x.vertexAttribPointer(v,2,x.FLOAT,!1,16,8);x.bindBuffer(x.ELEMENT_ARRAY_BUFFER,B);x.uniformMatrix4fv(n,!1,N.projectionMatrix.elements);D.activeTexture(x.TEXTURE0);x.uniform1i(h,0);G=K=0;(L=P.fog)?(x.uniform3f(u,L.color.r,L.color.g,L.color.b),L instanceof THREE.Fog?(x.uniform1f(q,L.near),x.uniform1f(t,L.far),x.uniform1i(p,1),G=K=1):L instanceof THREE.FogExp2&&(x.uniform1f(l,L.density),x.uniform1i(p,2),G=K=2)): -(x.uniform1i(p,0),G=K=0);for(var L=0,Q=b.length;L=e||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(K);w.compileShader(I);w.attachShader(E,K);w.attachShader(E,I);w.linkProgram(E);B=E;x=w.getAttribLocation(B,"position");v=w.getAttribLocation(B,"uv");c=w.getUniformLocation(B,"uvOffset");d=w.getUniformLocation(B,"uvScale");e=w.getUniformLocation(B,"rotation");f=w.getUniformLocation(B,"scale");g=w.getUniformLocation(B,"color");h=w.getUniformLocation(B,"map");k=w.getUniformLocation(B,"opacity");l=w.getUniformLocation(B,"modelViewMatrix");n=w.getUniformLocation(B,"projectionMatrix");p= +w.getUniformLocation(B,"fogType");m=w.getUniformLocation(B,"fogDensity");q=w.getUniformLocation(B,"fogNear");r=w.getUniformLocation(B,"fogFar");s=w.getUniformLocation(B,"fogColor");u=w.getUniformLocation(B,"alphaTest");E=document.createElement("canvas");E.width=8;E.height=8;K=E.getContext("2d");K.fillStyle="white";K.fillRect(0,0,8,8);G=new THREE.Texture(E);G.needsUpdate=!0}w.useProgram(B);D.initAttributes();D.enableAttribute(x);D.enableAttribute(v);D.disableUnusedAttributes();D.disable(w.CULL_FACE); +D.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER,A);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(v,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,y);w.uniformMatrix4fv(n,!1,N.projectionMatrix.elements);D.activeTexture(w.TEXTURE0);w.uniform1i(h,0);K=E=0;(I=O.fog)?(w.uniform3f(s,I.color.r,I.color.g,I.color.b),I instanceof THREE.Fog?(w.uniform1f(q,I.near),w.uniform1f(r,I.far),w.uniform1i(p,1),K=E=1):I instanceof THREE.FogExp2&&(w.uniform1f(m,I.density),w.uniform1i(p,2),K=E=2)): +(w.uniform1i(p,0),K=E=0);for(var I=0,L=b.length;Ic)return null;var d=[],e=[],f=[],g,h,k;if(0=m--){console.warn("THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()");break}g=h;c<=g&&(g=0);h=g+1;c<=h&&(h=0);k=h+1;c<=k&&(k=0);var n;a:{var p= -n=void 0,l=void 0,q=void 0,t=void 0,u=void 0,s=void 0,w=void 0,v=void 0,p=a[e[g]].x,l=a[e[g]].y,q=a[e[h]].x,t=a[e[h]].y,u=a[e[k]].x,s=a[e[k]].y;if(Number.EPSILON>(q-p)*(s-l)-(t-l)*(u-p))n=!1;else{var C=void 0,x=void 0,D=void 0,A=void 0,B=void 0,y=void 0,I=void 0,F=void 0,z=void 0,J=void 0,z=F=I=v=w=void 0,C=u-q,x=s-t,D=p-u,A=l-s,B=q-p,y=t-l;for(n=0;n=-Number.EPSILON&& -F>=-Number.EPSILON&&I>=-Number.EPSILON)){n=!1;break a}n=!0}}if(n){d.push([a[e[g]],a[e[h]],a[e[k]]]);f.push([e[g],e[h],e[k]]);g=h;for(k=h+1;kNumber.EPSILON){if(0y||y> -B)return[];k=m*n-k*p;if(0>k||k>B)return[]}else{if(0d?[]:k===d?f?[]:[g]:a<=d?[g,h]:[g,m]}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 Math.abs(a)>Number.EPSILON?(b=g*c-d*b,0f&&(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;cN){console.log("Infinite Loop! Holes left:"+m.length+", Probably Hole outside Shape!");break}for(p=F;ph;h++)m=k[h].x+":"+k[h].y,m=n[m],void 0!==m&&(k[h]=m);return p.concat()},isClockWise:function(a){return 0>THREE.ShapeUtils.area(a)},b2:function(){return function(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}}(),b3:function(){return function(a,b,c,d,e){var f= +THREE.ShapeUtils={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;ec)return null;var d=[],e=[],f=[],g,h,k;if(0=l--){console.warn("THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()");break}g=h;c<=g&&(g=0);h=g+1;c<=h&&(h=0);k=h+1;c<=k&&(k=0);var n;a:{var p= +n=void 0,m=void 0,q=void 0,r=void 0,s=void 0,u=void 0,x=void 0,v=void 0,p=a[e[g]].x,m=a[e[g]].y,q=a[e[h]].x,r=a[e[h]].y,s=a[e[k]].x,u=a[e[k]].y;if(Number.EPSILON>(q-p)*(u-m)-(r-m)*(s-p))n=!1;else{var C=void 0,w=void 0,D=void 0,A=void 0,y=void 0,B=void 0,G=void 0,z=void 0,H=void 0,M=void 0,H=z=G=v=x=void 0,C=s-q,w=u-r,D=p-s,A=m-u,y=q-p,B=r-m;for(n=0;n=-Number.EPSILON&& +z>=-Number.EPSILON&&G>=-Number.EPSILON)){n=!1;break a}n=!0}}if(n){d.push([a[e[g]],a[e[h]],a[e[k]]]);f.push([e[g],e[h],e[k]]);g=h;for(k=h+1;kNumber.EPSILON){if(0B||B> +y)return[];k=l*n-k*p;if(0>k||k>y)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 Math.abs(a)>Number.EPSILON?(b=g*c-d*b,0f&&(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;cN){console.log("Infinite Loop! Holes left:"+l.length+", Probably Hole outside Shape!");break}for(p=z;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.ShapeUtils.area(a)},b2:function(){return function(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}}(),b3:function(){return function(a,b,c,d,e){var f= 1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}}()};THREE.Curve=function(){}; THREE.Curve.prototype={constructor:THREE.Curve,getPoint:function(a){console.warn("THREE.Curve: Warning, getPoint() not implemented!");return null},getPointAt:function(a){a=this.getUtoTmapping(a);return this.getPoint(a)},getPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPoint(b/a));return c},getSpacedPoints:function(a){a||(a=5);var b,c=[];for(b=0;b<=a;b++)c.push(this.getPointAt(b/a));return c},getLength:function(){var a=this.getLengths();return a[a.length-1]},getLengths:function(a){a|| (a=this.__arcLengthDivisions?this.__arcLengthDivisions:200);if(this.cacheArcLengths&&this.cacheArcLengths.length===a+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;var b=[],c,d=this.getPoint(0),e,f=0;b.push(0);for(e=1;e<=a;e++)c=this.getPoint(e/a),f+=c.distanceTo(d),b.push(f),d=c;return this.cacheArcLengths=b},updateArcLengths:function(){this.needsUpdate=!0;this.getLengths()},getUtoTmapping:function(a,b){var c=this.getLengths(),d=0,e=c.length,f;f=b?b:a*c[e-1];for(var g=0,h=e- 1,k;g<=h;)if(d=Math.floor(g+(h-g)/2),k=c[d]-f,0>k)g=d+1;else if(0b&&(b=0);1=b)return a=this.curves[d],b=1-(c[d]-b)/a.getLength(),a.getPointAt(b);d++}return null};THREE.CurvePath.prototype.getLength=function(){var a=this.getCurveLengths();return a[a.length-1]}; -THREE.CurvePath.prototype.getCurveLengths=function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;cNumber.EPSILON){if(0>l&&(g=b[f],k=-k,h=b[e],l=-l),!(a.yh.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=l*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x|| -g.x<=a.x&&a.x<=h.x))return!0}return d}var e=THREE.ShapeUtils.isClockWise,f=function(a){for(var b=[],c=new THREE.Path,d=0,e=a.length;db.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=THREE.CurveUtils.interpolate;return new THREE.Vector2(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a))};THREE.EllipseCurve=function(a,b,c,d,e,f,g,h){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g;this.aRotation=h||0};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype); -THREE.EllipseCurve.prototype.constructor=THREE.EllipseCurve; +THREE.Curve.create=function(a,b){a.prototype=Object.create(THREE.Curve.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};THREE.CurvePath=function(){this.curves=[];this.autoClose=!1}; +THREE.CurvePath.prototype=Object.assign(Object.create(THREE.Curve.prototype),{constructor:THREE.CurvePath,add:function(a){this.curves.push(a)},closePath:function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);a.equals(b)||this.curves.push(new THREE.LineCurve(b,a))},getPoint:function(a){for(var b=a*this.getLength(),c=this.getCurveLengths(),d=0;d=b)return a=this.curves[d],b=1-(c[d]-b)/a.getLength(),a.getPointAt(b);d++}return null},getLength:function(){var a= +this.getCurveLengths();return a[a.length-1]},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;for(var a=[],b=0,c=0,d=this.curves.length;cNumber.EPSILON){if(0>l&&(g=b[f],k=-k,h=b[e],l=-l),!(a.yh.y))if(a.y===g.y){if(a.x=== +g.x)return!0}else{e=l*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d}var e=THREE.ShapeUtils.isClockWise,f=function(a){for(var b=[],c=new THREE.Path,d=0,e=a.length;db.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=THREE.CurveUtils.interpolate;return new THREE.Vector2(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a))}; +THREE.EllipseCurve=function(a,b,c,d,e,f,g,h){this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=f;this.aClockwise=g;this.aRotation=h||0};THREE.EllipseCurve.prototype=Object.create(THREE.Curve.prototype);THREE.EllipseCurve.prototype.constructor=THREE.EllipseCurve; THREE.EllipseCurve.prototype.getPoint=function(a){var b=this.aEndAngle-this.aStartAngle;0>b&&(b+=2*Math.PI);b>2*Math.PI&&(b-=2*Math.PI);b=!0===this.aClockwise?this.aEndAngle+(1-a)*(2*Math.PI-b):this.aStartAngle+a*b;a=this.aX+this.xRadius*Math.cos(b);var c=this.aY+this.yRadius*Math.sin(b);if(0!==this.aRotation){var b=Math.cos(this.aRotation),d=Math.sin(this.aRotation),e=a;a=(e-this.aX)*b-(c-this.aY)*d+this.aX;c=(e-this.aX)*d+(c-this.aY)*b+this.aY}return new THREE.Vector2(a,c)}; THREE.ArcCurve=function(a,b,c,d,e,f){THREE.EllipseCurve.call(this,a,b,c,c,d,e,f)};THREE.ArcCurve.prototype=Object.create(THREE.EllipseCurve.prototype);THREE.ArcCurve.prototype.constructor=THREE.ArcCurve;THREE.LineCurve3=THREE.Curve.create(function(a,b){this.v1=a;this.v2=b},function(a){var b=new THREE.Vector3;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b}); THREE.QuadraticBezierCurve3=THREE.Curve.create(function(a,b,c){this.v0=a;this.v1=b;this.v2=c},function(a){var b=THREE.ShapeUtils.b2;return new THREE.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x),b(a,this.v0.y,this.v1.y,this.v2.y),b(a,this.v0.z,this.v1.z,this.v2.z))}); THREE.CubicBezierCurve3=THREE.Curve.create(function(a,b,c,d){this.v0=a;this.v1=b;this.v2=c;this.v3=d},function(a){var b=THREE.ShapeUtils.b3;return new THREE.Vector3(b(a,this.v0.x,this.v1.x,this.v2.x,this.v3.x),b(a,this.v0.y,this.v1.y,this.v2.y,this.v3.y),b(a,this.v0.z,this.v1.z,this.v2.z,this.v3.z))}); THREE.SplineCurve3=THREE.Curve.create(function(a){console.warn("THREE.SplineCurve3 will be deprecated. Please use THREE.CatmullRomCurve3");this.points=void 0==a?[]:a},function(a){var b=this.points;a*=b.length-1;var c=Math.floor(a);a-=c;var d=b[0==c?c:c-1],e=b[c],f=b[c>b.length-2?b.length-1:c+1],b=b[c>b.length-3?b.length-1:c+2],c=THREE.CurveUtils.interpolate;return new THREE.Vector3(c(d.x,e.x,f.x,b.x,a),c(d.y,e.y,f.y,b.y,a),c(d.z,e.z,f.z,b.z,a))}); THREE.CatmullRomCurve3=function(){function a(){}var b=new THREE.Vector3,c=new a,d=new a,e=new a;a.prototype.init=function(a,b,c,d){this.c0=a;this.c1=c;this.c2=-3*a+3*b-2*c-d;this.c3=2*a-2*b+c+d};a.prototype.initNonuniformCatmullRom=function(a,b,c,d,e,n,p){a=((b-a)/e-(c-a)/(e+n)+(c-b)/n)*n;d=((c-b)/n-(d-b)/(n+p)+(d-c)/p)*n;this.init(b,c,a,d)};a.prototype.initCatmullRom=function(a,b,c,d,e){this.init(b,c,e*(c-a),e*(d-b))};a.prototype.calc=function(a){var b=a*a;return this.c0+this.c1*a+this.c2*b+this.c3* -b*a};return THREE.Curve.create(function(a){this.points=a||[];this.closed=!1},function(a){var g=this.points,h,k;k=g.length;2>k&&console.log("duh, you need at least 2 points");a*=k-(this.closed?0:1);h=Math.floor(a);a-=h;this.closed?h+=0h&&(h=1);1E-4>k&&(k=h);1E-4>l&&(l=h);c.initNonuniformCatmullRom(m.x,n.x,p.x,g.x,k,h,l);d.initNonuniformCatmullRom(m.y,n.y,p.y,g.y,k,h,l);e.initNonuniformCatmullRom(m.z,n.z,p.z,g.z,k,h,l)}else"catmullrom"===this.type&&(k=void 0!==this.tension?this.tension:.5,c.initCatmullRom(m.x,n.x,p.x,g.x, -k),d.initCatmullRom(m.y,n.y,p.y,g.y,k),e.initCatmullRom(m.z,n.z,p.z,g.z,k));return new THREE.Vector3(c.calc(a),d.calc(a),e.calc(a))})}();THREE.ClosedSplineCurve3=function(a){console.warn("THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.");THREE.CatmullRomCurve3.call(this,a);this.type="catmullrom";this.closed=!0};THREE.ClosedSplineCurve3.prototype=Object.create(THREE.CatmullRomCurve3.prototype); -THREE.BoxGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,u){var s,w=h.widthSegments,v=h.heightSegments,C=e/2,x=f/2,D=h.vertices.length;if("x"===a&&"y"===b||"y"===a&&"x"===b)s="z";else if("x"===a&&"z"===b||"z"===a&&"x"===b)s="y",v=h.depthSegments;else if("z"===a&&"y"===b||"y"===a&&"z"===b)s="x",w=h.depthSegments;var A=w+1,B=v+1,y=e/w,I=f/v,F=new THREE.Vector3;F[s]=0k&&console.log("duh, you need at least 2 points");a*=k-(this.closed?0:1);h=Math.floor(a);a-=h;this.closed?h+=0h&&(h=1);1E-4>k&&(k=h);1E-4>m&&(m=h);c.initNonuniformCatmullRom(l.x,n.x,p.x,g.x,k,h,m);d.initNonuniformCatmullRom(l.y,n.y,p.y,g.y,k,h,m);e.initNonuniformCatmullRom(l.z,n.z,p.z,g.z,k,h,m)}else"catmullrom"===this.type&&(k=void 0!==this.tension?this.tension:.5,c.initCatmullRom(l.x,n.x,p.x,g.x, +k),d.initCatmullRom(l.y,n.y,p.y,g.y,k),e.initCatmullRom(l.z,n.z,p.z,g.z,k));return new THREE.Vector3(c.calc(a),d.calc(a),e.calc(a))})}();THREE.ClosedSplineCurve3=function(a){console.warn("THREE.ClosedSplineCurve3 has been deprecated. Please use THREE.CatmullRomCurve3.");THREE.CatmullRomCurve3.call(this,a);this.type="catmullrom";this.closed=!0};THREE.ClosedSplineCurve3.prototype=Object.create(THREE.CatmullRomCurve3.prototype); +THREE.BoxGeometry=function(a,b,c,d,e,f){THREE.Geometry.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new THREE.BoxBufferGeometry(a,b,c,d,e,f));this.mergeVertices()};THREE.BoxGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.BoxGeometry.prototype.constructor=THREE.BoxGeometry;THREE.CubeGeometry=THREE.BoxGeometry; +THREE.BoxBufferGeometry=function(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,k,l,M,O){var N=f/l,E=g/M,K=f/2,I=g/2,L=k/2;g=l+1;for(var P=M+1,Q=f=0,R=new THREE.Vector3,F=0;Fl;l++){e[0]=p[g[l]];e[1]=p[g[(l+1)%3]];e.sort(c);var q=e.toString();void 0===f[q]?f[q]={vert1:e[0],vert2:e[1],face1:m, -face2:void 0}:f[q].face2=m}e=[];for(q in f)if(g=f[q],void 0===g.face2||h[g.face1].normal.dot(h[g.face2].normal)<=d)m=k[g.vert1],e.push(m.x),e.push(m.y),e.push(m.z),m=k[g.vert2],e.push(m.x),e.push(m.y),e.push(m.z);this.addAttribute("position",new THREE.BufferAttribute(new Float32Array(e),3))};THREE.EdgesGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.EdgesGeometry.prototype.constructor=THREE.EdgesGeometry; +THREE.CylinderBufferGeometry=function(a,b,c,d,e,f,g,h){function k(c){var e,f,k,m=new THREE.Vector2,n=new THREE.Vector3,p=0,C=!0===c?a:b,N=!0===c?1:-1;f=x;for(e=1;e<=d;e++)r.setXYZ(x,0,w*N,0),s.setXYZ(x,0,N,0),m.x=.5,m.y=.5,u.setXY(x,m.x,m.y),x++;k=x;for(e=0;e<=d;e++){var E=e/d*h+g,K=Math.cos(E),E=Math.sin(E);n.x=C*E;n.y=w*N;n.z=C*K;r.setXYZ(x,n.x,n.y,n.z);s.setXYZ(x,0,N,0);m.x=.5*K+.5;m.y=.5*E*N+.5;u.setXY(x,m.x,m.y);x++}for(e=0;em;m++){e[0]=p[g[m]];e[1]=p[g[(m+1)%3]];e.sort(c);var q=e.toString();void 0===f[q]?f[q]={vert1:e[0],vert2:e[1],face1:l, +face2:void 0}:f[q].face2=l}e=[];for(q in f)if(g=f[q],void 0===g.face2||h[g.face1].normal.dot(h[g.face2].normal)<=d)l=k[g.vert1],e.push(l.x),e.push(l.y),e.push(l.z),l=k[g.vert2],e.push(l.x),e.push(l.y),e.push(l.z);this.addAttribute("position",new THREE.BufferAttribute(new Float32Array(e),3))};THREE.EdgesGeometry.prototype=Object.create(THREE.BufferGeometry.prototype);THREE.EdgesGeometry.prototype.constructor=THREE.EdgesGeometry; THREE.ExtrudeGeometry=function(a,b){"undefined"!==typeof a&&(THREE.Geometry.call(this),this.type="ExtrudeGeometry",a=Array.isArray(a)?a:[a],this.addShapeList(a,b),this.computeFaceNormals())};THREE.ExtrudeGeometry.prototype=Object.create(THREE.Geometry.prototype);THREE.ExtrudeGeometry.prototype.constructor=THREE.ExtrudeGeometry;THREE.ExtrudeGeometry.prototype.addShapeList=function(a,b){for(var c=a.length,d=0;dNumber.EPSILON){var k=Math.sqrt(h),l=Math.sqrt(f*f+g*g),h=b.x-e/k;b=b.y+d/k;f=((c.x-g/l-h)*g-(c.y+f/l-b)*f)/(d*g-e*f);c=h+d*f-a.x;a=b+e*f-a.y;d=c*c+a*a;if(2>=d)return new THREE.Vector2(c,a);d=Math.sqrt(d/2)}else a=!1,d>Number.EPSILON? -f>Number.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(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;eNumber.EPSILON&&(a=!0):d<-Number.EPSILON?f<-Number.EPSILON&&(a=!0):Math.sign(e)===Math.sign(g)&&(a=!0),a?(c=-e,a=d,d=Math.sqrt(h)):(c=d,a=e,d=Math.sqrt(h/2));return new THREE.Vector2(c/d,a/d)}function e(a,b){var c,d;for(F=a.length;0<=--F;){c=F;d=F-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;cNumber.EPSILON&&(h.normalize(),d=Math.acos(THREE.Math.clamp(e[m-1].dot(e[m]),-1,1)),f[m].applyMatrix4(k.makeRotationAxis(h,d))),g[m].crossVectors(e[m],f[m]);if(c)for(d=Math.acos(THREE.Math.clamp(f[0].dot(f[b-1]),-1,1)),d/=b-1,0c&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/ -2/Math.PI+.5,a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,m=0,n=a.length;mq&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>p&&(b[2].x+=1));m=0;for(n=this.vertices.length;mNumber.EPSILON&&(h.normalize(),d=Math.acos(THREE.Math.clamp(e[l-1].dot(e[l]),-1,1)),f[l].applyMatrix4(k.makeRotationAxis(h,d))),g[l].crossVectors(e[l],f[l]);if(c)for(d=Math.acos(THREE.Math.clamp(f[0].dot(f[b-1]),-1,1)),d/=b-1,0c&&1===a.x&&(a=new THREE.Vector2(a.x-1,a.y));0===b.x&&0===b.z&&(a=new THREE.Vector2(c/ +2/Math.PI+.5,a.y));return a.clone()}THREE.Geometry.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;for(var k=this,l=0,n=a.length;lq&&(.2>d&&(b[0].x+=1),.2>a&&(b[1].x+=1),.2>p&&(b[2].x+=1));l=0;for(n=this.vertices.length;lp;p++){c[0]=n[e[p]];c[1]=n[e[(p+1)%3]];c.sort(b);var l=c.toString();void 0===d[l]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[l]=!0,h++)}c=new Float32Array(6*h);a=0;for(m=h;ap;p++)d=f[k[2*a+p]],h=6*a+3*p,c[h+0]=d.x,c[h+1]=d.y, -c[h+2]=d.z;this.addAttribute("position",new THREE.BufferAttribute(c,3))}else if(a instanceof THREE.BufferGeometry){if(null!==a.index){m=a.index.array;f=a.attributes.position;e=a.groups;h=0;0===e.length&&a.addGroup(0,m.length);k=new Uint32Array(2*m.length);g=0;for(n=e.length;gp;p++)c[0]=m[a+p],c[1]=m[a+(p+1)%3],c.sort(b),l=c.toString(),void 0===d[l]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[l]=!0,h++)}c=new Float32Array(6*h);a=0;for(m=h;a< -m;a++)for(p=0;2>p;p++)h=6*a+3*p,d=k[2*a+p],c[h+0]=f.getX(d),c[h+1]=f.getY(d),c[h+2]=f.getZ(d)}else for(f=a.attributes.position.array,h=f.length/3,k=h/3,c=new Float32Array(6*h),a=0,m=k;ap;p++)h=18*a+6*p,k=9*a+3*p,c[h+0]=f[k],c[h+1]=f[k+1],c[h+2]=f[k+2],d=9*a+(p+1)%3*3,c[h+3]=f[d],c[h+4]=f[d+1],c[h+5]=f[d+2];this.addAttribute("position",new THREE.BufferAttribute(c,3))}};THREE.WireframeGeometry.prototype=Object.create(THREE.BufferGeometry.prototype); +THREE.ParametricGeometry=function(a,b,c){THREE.Geometry.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};var d=this.vertices,e=this.faces,f=this.faceVertexUvs[0],g,h,k,l,n=b+1;for(g=0;g<=c;g++)for(l=g/c,h=0;h<=b;h++)k=h/b,k=a(k,l),d.push(k);var p,m,q,r;for(g=0;gp;p++){c[0]=n[e[p]];c[1]=n[e[(p+1)%3]];c.sort(b);var m=c.toString();void 0===d[m]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[m]=!0,h++)}c=new Float32Array(6*h);a=0;for(l=h;ap;p++)d=f[k[2*a+p]],h=6*a+3*p,c[h+0]=d.x,c[h+1]=d.y, +c[h+2]=d.z;this.addAttribute("position",new THREE.BufferAttribute(c,3))}else if(a instanceof THREE.BufferGeometry){if(null!==a.index){l=a.index.array;f=a.attributes.position;e=a.groups;h=0;0===e.length&&a.addGroup(0,l.length);k=new Uint32Array(2*l.length);g=0;for(n=e.length;gp;p++)c[0]=l[a+p],c[1]=l[a+(p+1)%3],c.sort(b),m=c.toString(),void 0===d[m]&&(k[2*h]=c[0],k[2*h+1]=c[1],d[m]=!0,h++)}c=new Float32Array(6*h);a=0;for(l=h;a< +l;a++)for(p=0;2>p;p++)h=6*a+3*p,d=k[2*a+p],c[h+0]=f.getX(d),c[h+1]=f.getY(d),c[h+2]=f.getZ(d)}else for(f=a.attributes.position.array,h=f.length/3,k=h/3,c=new Float32Array(6*h),a=0,l=k;ap;p++)h=18*a+6*p,k=9*a+3*p,c[h+0]=f[k],c[h+1]=f[k+1],c[h+2]=f[k+2],d=9*a+(p+1)%3*3,c[h+3]=f[d],c[h+4]=f[d+1],c[h+5]=f[d+2];this.addAttribute("position",new THREE.BufferAttribute(c,3))}};THREE.WireframeGeometry.prototype=Object.create(THREE.BufferGeometry.prototype); THREE.WireframeGeometry.prototype.constructor=THREE.WireframeGeometry;THREE.AxisHelper=function(a){a=a||1;var b=new Float32Array([0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a]),c=new Float32Array([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1]);a=new THREE.BufferGeometry;a.addAttribute("position",new THREE.BufferAttribute(b,3));a.addAttribute("color",new THREE.BufferAttribute(c,3));b=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors});THREE.LineSegments.call(this,a,b)};THREE.AxisHelper.prototype=Object.create(THREE.LineSegments.prototype); THREE.AxisHelper.prototype.constructor=THREE.AxisHelper; -THREE.ArrowHelper=function(){var a=new THREE.Geometry;a.vertices.push(new THREE.Vector3(0,0,0),new THREE.Vector3(0,1,0));var b=new THREE.CylinderGeometry(0,.5,1,5,1);b.translate(0,-.5,0);return function(c,d,e,f,g,h){THREE.Object3D.call(this);void 0===f&&(f=16776960);void 0===e&&(e=1);void 0===g&&(g=.2*e);void 0===h&&(h=.2*g);this.position.copy(d);this.line=new THREE.Line(a,new THREE.LineBasicMaterial({color:f}));this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new THREE.Mesh(b,new THREE.MeshBasicMaterial({color:f})); -this.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(c);this.setLength(e,g,h)}}();THREE.ArrowHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.ArrowHelper.prototype.constructor=THREE.ArrowHelper;THREE.ArrowHelper.prototype.setDirection=function(){var a=new THREE.Vector3,b;return function(c){.99999c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}(); -THREE.ArrowHelper.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};THREE.ArrowHelper.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)}; -THREE.BoxHelper=function(a){var b=new Uint16Array([0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7]),c=new Float32Array(24),d=new THREE.BufferGeometry;d.setIndex(new THREE.BufferAttribute(b,1));d.addAttribute("position",new THREE.BufferAttribute(c,3));THREE.LineSegments.call(this,d,new THREE.LineBasicMaterial({color:16776960}));void 0!==a&&this.update(a)};THREE.BoxHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.BoxHelper.prototype.constructor=THREE.BoxHelper; -THREE.BoxHelper.prototype.update=function(){var a=new THREE.Box3;return function(b){a.setFromObject(b);if(!a.isEmpty()){b=a.min;var c=a.max,d=this.geometry.attributes.position,e=d.array;e[0]=c.x;e[1]=c.y;e[2]=c.z;e[3]=b.x;e[4]=c.y;e[5]=c.z;e[6]=b.x;e[7]=b.y;e[8]=c.z;e[9]=c.x;e[10]=b.y;e[11]=c.z;e[12]=c.x;e[13]=c.y;e[14]=b.z;e[15]=b.x;e[16]=c.y;e[17]=b.z;e[18]=b.x;e[19]=b.y;e[20]=b.z;e[21]=c.x;e[22]=b.y;e[23]=b.z;d.needsUpdate=!0;this.geometry.computeBoundingSphere()}}}(); +THREE.ArrowHelper=function(){var a=new THREE.BufferGeometry;a.addAttribute("position",new THREE.Float32Attribute([0,0,0,0,1,0],3));var b=new THREE.CylinderBufferGeometry(0,.5,1,5,1);b.translate(0,-.5,0);return function(c,d,e,f,g,h){THREE.Object3D.call(this);void 0===f&&(f=16776960);void 0===e&&(e=1);void 0===g&&(g=.2*e);void 0===h&&(h=.2*g);this.position.copy(d);this.line=new THREE.Line(a,new THREE.LineBasicMaterial({color:f}));this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new THREE.Mesh(b, +new THREE.MeshBasicMaterial({color:f}));this.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(c);this.setLength(e,g,h)}}();THREE.ArrowHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.ArrowHelper.prototype.constructor=THREE.ArrowHelper; +THREE.ArrowHelper.prototype.setDirection=function(){var a=new THREE.Vector3,b;return function(c){.99999c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,b))}}();THREE.ArrowHelper.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()}; +THREE.ArrowHelper.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};THREE.BoxHelper=function(a){var b=new Uint16Array([0,1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7]),c=new Float32Array(24),d=new THREE.BufferGeometry;d.setIndex(new THREE.BufferAttribute(b,1));d.addAttribute("position",new THREE.BufferAttribute(c,3));THREE.LineSegments.call(this,d,new THREE.LineBasicMaterial({color:16776960}));void 0!==a&&this.update(a)};THREE.BoxHelper.prototype=Object.create(THREE.LineSegments.prototype); +THREE.BoxHelper.prototype.constructor=THREE.BoxHelper; +THREE.BoxHelper.prototype.update=function(){var a=new THREE.Box3;return function(b){b instanceof THREE.Box3?a.copy(b):a.setFromObject(b);if(!a.isEmpty()){b=a.min;var c=a.max,d=this.geometry.attributes.position,e=d.array;e[0]=c.x;e[1]=c.y;e[2]=c.z;e[3]=b.x;e[4]=c.y;e[5]=c.z;e[6]=b.x;e[7]=b.y;e[8]=c.z;e[9]=c.x;e[10]=b.y;e[11]=c.z;e[12]=c.x;e[13]=c.y;e[14]=b.z;e[15]=b.x;e[16]=c.y;e[17]=b.z;e[18]=b.x;e[19]=b.y;e[20]=b.z;e[21]=c.x;e[22]=b.y;e[23]=b.z;d.needsUpdate=!0;this.geometry.computeBoundingSphere()}}}(); THREE.BoundingBoxHelper=function(a,b){var c=void 0!==b?b:8947848;this.object=a;this.box=new THREE.Box3;THREE.Mesh.call(this,new THREE.BoxGeometry(1,1,1),new THREE.MeshBasicMaterial({color:c,wireframe:!0}))};THREE.BoundingBoxHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.BoundingBoxHelper.prototype.constructor=THREE.BoundingBoxHelper;THREE.BoundingBoxHelper.prototype.update=function(){this.box.setFromObject(this.object);this.box.size(this.scale);this.box.center(this.position)}; THREE.CameraHelper=function(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){d.vertices.push(new THREE.Vector3);d.colors.push(new THREE.Color(b));void 0===f[a]&&(f[a]=[]);f[a].push(d.vertices.length-1)}var d=new THREE.Geometry,e=new THREE.LineBasicMaterial({color:16777215,vertexColors:THREE.FaceColors}),f={};b("n1","n2",16755200);b("n2","n4",16755200);b("n4","n3",16755200);b("n3","n1",16755200);b("f1","f2",16755200);b("f2","f4",16755200);b("f4","f3",16755200);b("f3","f1",16755200);b("n1","f1",16755200); b("n2","f2",16755200);b("n3","f3",16755200);b("n4","f4",16755200);b("p","n1",16711680);b("p","n2",16711680);b("p","n3",16711680);b("p","n4",16711680);b("u1","u2",43775);b("u2","u3",43775);b("u3","u1",43775);b("c","t",16777215);b("p","c",3355443);b("cn1","cn2",3355443);b("cn3","cn4",3355443);b("cf1","cf2",3355443);b("cf3","cf4",3355443);THREE.LineSegments.call(this,d,e);this.camera=a;this.camera.updateProjectionMatrix();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=f;this.update()}; THREE.CameraHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.CameraHelper.prototype.constructor=THREE.CameraHelper; THREE.CameraHelper.prototype.update=function(){function a(a,g,h,k){d.set(g,h,k).unproject(e);a=c[a];if(void 0!==a)for(g=0,h=a.length;gd;d++)c.faces[d].color=this.colors[4>d?0:1];d=new THREE.MeshBasicMaterial({vertexColors:THREE.FaceColors,wireframe:!0});this.lightSphere=new THREE.Mesh(c,d);this.add(this.lightSphere);this.update()}; THREE.HemisphereLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.HemisphereLightHelper.prototype.constructor=THREE.HemisphereLightHelper;THREE.HemisphereLightHelper.prototype.dispose=function(){this.lightSphere.geometry.dispose();this.lightSphere.material.dispose()}; THREE.HemisphereLightHelper.prototype.update=function(){var a=new THREE.Vector3;return function(){this.colors[0].copy(this.light.color).multiplyScalar(this.light.intensity);this.colors[1].copy(this.light.groundColor).multiplyScalar(this.light.intensity);this.lightSphere.lookAt(a.setFromMatrixPosition(this.light.matrixWorld).negate());this.lightSphere.geometry.colorsNeedUpdate=!0}}(); -THREE.PointLightHelper=function(a,b){this.light=a;this.light.updateMatrixWorld();var c=new THREE.SphereGeometry(b,4,2),d=new THREE.MeshBasicMaterial({wireframe:!0,fog:!1});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);THREE.Mesh.call(this,c,d);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1};THREE.PointLightHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.PointLightHelper.prototype.constructor=THREE.PointLightHelper; +THREE.PointLightHelper=function(a,b){this.light=a;this.light.updateMatrixWorld();var c=new THREE.SphereBufferGeometry(b,4,2),d=new THREE.MeshBasicMaterial({wireframe:!0,fog:!1});d.color.copy(this.light.color).multiplyScalar(this.light.intensity);THREE.Mesh.call(this,c,d);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1};THREE.PointLightHelper.prototype=Object.create(THREE.Mesh.prototype);THREE.PointLightHelper.prototype.constructor=THREE.PointLightHelper; THREE.PointLightHelper.prototype.dispose=function(){this.geometry.dispose();this.material.dispose()};THREE.PointLightHelper.prototype.update=function(){this.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)}; THREE.SkeletonHelper=function(a){this.bones=this.getBoneList(a);for(var b=new THREE.Geometry,c=0;cc;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new THREE.Float32Attribute(b,3));b=new THREE.LineBasicMaterial({fog:!1});this.cone=new THREE.LineSegments(a, +b);this.add(this.cone);this.update()};THREE.SpotLightHelper.prototype=Object.create(THREE.Object3D.prototype);THREE.SpotLightHelper.prototype.constructor=THREE.SpotLightHelper;THREE.SpotLightHelper.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()}; +THREE.SpotLightHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3;return function(){var c=this.light.distance?this.light.distance:1E3,d=c*Math.tan(this.light.angle);this.cone.scale.set(d,d,c);a.setFromMatrixPosition(this.light.matrixWorld);b.setFromMatrixPosition(this.light.target.matrixWorld);this.cone.lookAt(b.sub(a));this.cone.material.color.copy(this.light.color).multiplyScalar(this.light.intensity)}}(); THREE.VertexNormalsHelper=function(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16711680;d=void 0!==d?d:1;b=0;c=this.object.geometry;c instanceof THREE.Geometry?b=3*c.faces.length:c instanceof THREE.BufferGeometry&&(b=c.attributes.normal.count);c=new THREE.BufferGeometry;b=new THREE.Float32Attribute(6*b,3);c.addAttribute("position",b);THREE.LineSegments.call(this,c,new THREE.LineBasicMaterial({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}; THREE.VertexNormalsHelper.prototype=Object.create(THREE.LineSegments.prototype);THREE.VertexNormalsHelper.prototype.constructor=THREE.VertexNormalsHelper; -THREE.VertexNormalsHelper.prototype.update=function(){var a=new THREE.Vector3,b=new THREE.Vector3,c=new THREE.Matrix3;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,f=this.geometry.attributes.position,g=this.object.geometry;if(g instanceof THREE.Geometry)for(var h=g.vertices,k=g.faces,m=g=0,n=k.length;m