From 613df95ae7138d5db379a435255777bc1fbf2ead Mon Sep 17 00:00:00 2001 From: Dmitrii Tikhomirov Date: Sat, 11 Jul 2020 18:45:48 +0200 Subject: [PATCH 1/3] updated to r106 core components and extensions --- README.md | 4 +- .../treblereel/gwt/three4g/math/Vector4.java | 9 + .../treblereel/gwt/three4g/objects/LOD.java | 5 + .../gwt/three4g/resources/js/three.js | 14169 ++++++++-------- .../gwt/three4g/resources/js/three.min.js | 1694 +- .../local/examples/camera/WebGlCamera.java | 56 +- .../examples/lights/WebglLightsPhysical.java | 139 +- .../examples/loaders/WebglLoaderVrml.java | 4 + .../loaders/HDRCubeTextureLoader.java | 5 + .../extensions/loaders/VRMLLoader.java | 3 +- .../resources/js/libs/chevrotain.min.js | 2 + .../resources/js/loaders/AWDLoader.js | 121 +- .../resources/js/loaders/AssimpLoader.js | 18 +- .../resources/js/loaders/DRACOLoader.js | 1128 +- .../resources/js/loaders/GLTFLoader.js | 166 +- .../js/loaders/HDRCubeTextureLoader.js | 190 +- .../resources/js/loaders/LDrawLoader.js | 669 +- .../resources/js/loaders/PRWMLoader.js | 20 +- .../resources/js/loaders/RGBELoader.js | 188 +- .../resources/js/loaders/TDSLoader.js | 374 +- .../resources/js/loaders/VRMLLoader.js | 2786 ++- .../resources/js/loaders/VRMLoader.js | 6 +- .../resources/js/utils/BufferGeometryUtils.js | 1 + .../resources/js/utils/MathUtils.js | 62 +- .../resources/js/utils/SkeletonUtils.js | 2 +- .../resources/js/utils/TypedArrayUtils.js | 74 +- .../extensions/resources/js/vr/WebVR.js | 22 +- .../resources/js/vr/vive/ViveController.js | 2 +- .../gwt/three4g/Three4GProcessor.java | 12 +- 29 files changed, 11814 insertions(+), 10117 deletions(-) create mode 100644 extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/libs/chevrotain.min.js diff --git a/README.md b/README.md index f2d2ac63..795ad994 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ ## A Three.js wrapper for GWT # Maven -Current Version 0.105, implements 0.105 version of three.js +Current Version 0.106, implements 0.106 version of three.js ```xml org.treblereel.gwt three4g - 0.105 + 0.106 ``` # Setup diff --git a/core/src/main/java/org/treblereel/gwt/three4g/math/Vector4.java b/core/src/main/java/org/treblereel/gwt/three4g/math/Vector4.java index 72a308b8..5816da9b 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/math/Vector4.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/math/Vector4.java @@ -28,6 +28,15 @@ public class Vector4 implements Vector { */ public float x, y, z, w; + /** + * Alias for z. + */ + public float width; + + /** + * Alias for w. + */ + public float height; @JsConstructor public Vector4() { diff --git a/core/src/main/java/org/treblereel/gwt/three4g/objects/LOD.java b/core/src/main/java/org/treblereel/gwt/three4g/objects/LOD.java index ce050587..e9f62be6 100644 --- a/core/src/main/java/org/treblereel/gwt/three4g/objects/LOD.java +++ b/core/src/main/java/org/treblereel/gwt/three4g/objects/LOD.java @@ -26,6 +26,11 @@ public class LOD extends Object3D { */ public LODLevel[] levels; + /** + * Whether the LOD object is updated automatically by the renderer per frame or not. If set to false, you have to call LOD.update() in the render loop by yourself. Default is true. + */ + public boolean autoUpdate; + @JsConstructor public LOD() { diff --git a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js index 0119ed6d..42143bce 100644 --- a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js +++ b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.js @@ -185,7 +185,7 @@ } ); - var REVISION = '105'; + var REVISION = '106'; var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; var CullFaceNone = 0; var CullFaceBack = 1; @@ -1072,7 +1072,7 @@ set: function ( value ) { this._x = value; - this.onChangeCallback(); + this._onChangeCallback(); } @@ -1089,7 +1089,7 @@ set: function ( value ) { this._y = value; - this.onChangeCallback(); + this._onChangeCallback(); } @@ -1106,7 +1106,7 @@ set: function ( value ) { this._z = value; - this.onChangeCallback(); + this._onChangeCallback(); } @@ -1123,7 +1123,7 @@ set: function ( value ) { this._w = value; - this.onChangeCallback(); + this._onChangeCallback(); } @@ -1142,7 +1142,7 @@ this._z = z; this._w = w; - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1161,7 +1161,7 @@ this._z = quaternion.z; this._w = quaternion.w; - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1236,7 +1236,7 @@ } - if ( update !== false ) this.onChangeCallback(); + if ( update !== false ) this._onChangeCallback(); return this; @@ -1255,7 +1255,7 @@ this._z = axis.z * s; this._w = Math.cos( halfAngle ); - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1314,7 +1314,7 @@ } - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1397,7 +1397,7 @@ this._y *= - 1; this._z *= - 1; - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1443,7 +1443,7 @@ } - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1480,7 +1480,7 @@ this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1533,7 +1533,10 @@ this._y = s * y + t * this._y; this._z = s * z + t * this._z; - return this.normalize(); + this.normalize(); + this._onChangeCallback(); + + return this; } @@ -1547,7 +1550,7 @@ this._y = ( y * ratioA + this._y * ratioB ); this._z = ( z * ratioA + this._z * ratioB ); - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1568,7 +1571,7 @@ this._z = array[ offset + 2 ]; this._w = array[ offset + 3 ]; - this.onChangeCallback(); + this._onChangeCallback(); return this; @@ -1588,15 +1591,15 @@ }, - onChange: function ( callback ) { + _onChange: function ( callback ) { - this.onChangeCallback = callback; + this._onChangeCallback = callback; return this; }, - onChangeCallback: function () {} + _onChangeCallback: function () {} } ); @@ -3089,6 +3092,42 @@ } + Object.defineProperties( Vector4.prototype, { + + "width": { + + get: function () { + + return this.z; + + }, + + set: function ( value ) { + + this.z = value; + + } + + }, + + "height": { + + get: function () { + + return this.w; + + }, + + set: function ( value ) { + + this.w = value; + + } + + } + + } ); + Object.assign( Vector4.prototype, { isVector4: true, @@ -3724,6 +3763,10 @@ this.texture = new Texture( undefined, undefined, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding ); + this.texture.image = {}; + this.texture.image.width = width; + this.texture.image.height = height; + this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false; this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter; @@ -3746,6 +3789,9 @@ this.width = width; this.height = height; + this.texture.image.width = width; + this.texture.image.height = height; + this.dispose(); } @@ -3818,159 +3864,158 @@ } ); /** - * @author alteredq / http://alteredqualia.com + * @author mrdoob / http://mrdoob.com/ + * @author supereggbert / http://www.paulbrunt.co.uk/ + * @author philogb / http://blog.thejit.org/ + * @author jordi_ros / http://plattsoft.com + * @author D1plo1d / http://github.com/D1plo1d + * @author alteredq / http://alteredqualia.com/ + * @author mikael emtinger / http://gomo.se/ + * @author timknip / http://www.floorplanner.com/ + * @author bhouston / http://clara.io + * @author WestLangley / http://github.com/WestLangley */ - function WebGLRenderTargetCube( width, height, options ) { + function Matrix4() { - WebGLRenderTarget.call( this, width, height, options ); + this.elements = [ - } + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype ); - WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube; + ]; - WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true; + if ( arguments.length > 0 ) { - /** - * @author alteredq / http://alteredqualia.com/ - */ + console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); - function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { + } - Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ); + } - this.image = { data: data, width: width, height: height }; + Object.assign( Matrix4.prototype, { - this.magFilter = magFilter !== undefined ? magFilter : NearestFilter; - this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; + isMatrix4: true, - this.generateMipmaps = false; - this.flipY = false; - this.unpackAlignment = 1; + set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { - } + var te = this.elements; - DataTexture.prototype = Object.create( Texture.prototype ); - DataTexture.prototype.constructor = DataTexture; + te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; + te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; + te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; + te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; - DataTexture.prototype.isDataTexture = true; + return this; - /** - * @author bhouston / http://clara.io - * @author WestLangley / http://github.com/WestLangley - */ + }, - function Box3( min, max ) { + identity: function () { - this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity ); - this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity ); + this.set( - } + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - Object.assign( Box3.prototype, { + ); - isBox3: true, + return this; - set: function ( min, max ) { + }, - this.min.copy( min ); - this.max.copy( max ); + clone: function () { - return this; + return new Matrix4().fromArray( this.elements ); }, - setFromArray: function ( array ) { - - var minX = + Infinity; - var minY = + Infinity; - var minZ = + Infinity; + copy: function ( m ) { - var maxX = - Infinity; - var maxY = - Infinity; - var maxZ = - Infinity; + var te = this.elements; + var me = m.elements; - for ( var i = 0, l = array.length; i < l; i += 3 ) { + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; + te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; + te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; + te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; - var x = array[ i ]; - var y = array[ i + 1 ]; - var z = array[ i + 2 ]; + return this; - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( z < minZ ) minZ = z; + }, - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; - if ( z > maxZ ) maxZ = z; + copyPosition: function ( m ) { - } + var te = this.elements, me = m.elements; - this.min.set( minX, minY, minZ ); - this.max.set( maxX, maxY, maxZ ); + te[ 12 ] = me[ 12 ]; + te[ 13 ] = me[ 13 ]; + te[ 14 ] = me[ 14 ]; return this; }, - setFromBufferAttribute: function ( attribute ) { - - var minX = + Infinity; - var minY = + Infinity; - var minZ = + Infinity; - - var maxX = - Infinity; - var maxY = - Infinity; - var maxZ = - Infinity; - - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + extractBasis: function ( xAxis, yAxis, zAxis ) { - var x = attribute.getX( i ); - var y = attribute.getY( i ); - var z = attribute.getZ( i ); + xAxis.setFromMatrixColumn( this, 0 ); + yAxis.setFromMatrixColumn( this, 1 ); + zAxis.setFromMatrixColumn( this, 2 ); - if ( x < minX ) minX = x; - if ( y < minY ) minY = y; - if ( z < minZ ) minZ = z; + return this; - if ( x > maxX ) maxX = x; - if ( y > maxY ) maxY = y; - if ( z > maxZ ) maxZ = z; + }, - } + makeBasis: function ( xAxis, yAxis, zAxis ) { - this.min.set( minX, minY, minZ ); - this.max.set( maxX, maxY, maxZ ); + this.set( + xAxis.x, yAxis.x, zAxis.x, 0, + xAxis.y, yAxis.y, zAxis.y, 0, + xAxis.z, yAxis.z, zAxis.z, 0, + 0, 0, 0, 1 + ); return this; }, - setFromPoints: function ( points ) { - - this.makeEmpty(); - - for ( var i = 0, il = points.length; i < il; i ++ ) { + extractRotation: function () { - this.expandByPoint( points[ i ] ); + var v1 = new Vector3(); - } + return function extractRotation( m ) { - return this; + // this method does not support reflection matrices - }, + var te = this.elements; + var me = m.elements; - setFromCenterAndSize: function () { + var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length(); + var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length(); + var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length(); - var v1 = new Vector3(); + te[ 0 ] = me[ 0 ] * scaleX; + te[ 1 ] = me[ 1 ] * scaleX; + te[ 2 ] = me[ 2 ] * scaleX; + te[ 3 ] = 0; - return function setFromCenterAndSize( center, size ) { + te[ 4 ] = me[ 4 ] * scaleY; + te[ 5 ] = me[ 5 ] * scaleY; + te[ 6 ] = me[ 6 ] * scaleY; + te[ 7 ] = 0; - var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); + te[ 8 ] = me[ 8 ] * scaleZ; + te[ 9 ] = me[ 9 ] * scaleZ; + te[ 10 ] = me[ 10 ] * scaleZ; + te[ 11 ] = 0; - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; return this; @@ -3978,156 +4023,195 @@ }(), - setFromObject: function ( object ) { - - this.makeEmpty(); - - return this.expandByObject( object ); + makeRotationFromEuler: function ( euler ) { - }, + if ( ! ( euler && euler.isEuler ) ) { - clone: function () { + console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); - return new this.constructor().copy( this ); + } - }, + var te = this.elements; - copy: function ( box ) { + var x = euler.x, y = euler.y, z = euler.z; + var a = Math.cos( x ), b = Math.sin( x ); + var c = Math.cos( y ), d = Math.sin( y ); + var e = Math.cos( z ), f = Math.sin( z ); - this.min.copy( box.min ); - this.max.copy( box.max ); + if ( euler.order === 'XYZ' ) { - return this; + var ae = a * e, af = a * f, be = b * e, bf = b * f; - }, + te[ 0 ] = c * e; + te[ 4 ] = - c * f; + te[ 8 ] = d; - makeEmpty: function () { + te[ 1 ] = af + be * d; + te[ 5 ] = ae - bf * d; + te[ 9 ] = - b * c; - this.min.x = this.min.y = this.min.z = + Infinity; - this.max.x = this.max.y = this.max.z = - Infinity; + te[ 2 ] = bf - ae * d; + te[ 6 ] = be + af * d; + te[ 10 ] = a * c; - return this; + } else if ( euler.order === 'YXZ' ) { - }, + var ce = c * e, cf = c * f, de = d * e, df = d * f; - isEmpty: function () { + te[ 0 ] = ce + df * b; + te[ 4 ] = de * b - cf; + te[ 8 ] = a * d; - // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + te[ 1 ] = a * f; + te[ 5 ] = a * e; + te[ 9 ] = - b; - return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); + te[ 2 ] = cf * b - de; + te[ 6 ] = df + ce * b; + te[ 10 ] = a * c; - }, + } else if ( euler.order === 'ZXY' ) { - getCenter: function ( target ) { + var ce = c * e, cf = c * f, de = d * e, df = d * f; - if ( target === undefined ) { + te[ 0 ] = ce - df * b; + te[ 4 ] = - a * f; + te[ 8 ] = de + cf * b; - console.warn( 'THREE.Box3: .getCenter() target is now required' ); - target = new Vector3(); + te[ 1 ] = cf + de * b; + te[ 5 ] = a * e; + te[ 9 ] = df - ce * b; - } + te[ 2 ] = - a * d; + te[ 6 ] = b; + te[ 10 ] = a * c; - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); + } else if ( euler.order === 'ZYX' ) { - }, + var ae = a * e, af = a * f, be = b * e, bf = b * f; - getSize: function ( target ) { + te[ 0 ] = c * e; + te[ 4 ] = be * d - af; + te[ 8 ] = ae * d + bf; - if ( target === undefined ) { + te[ 1 ] = c * f; + te[ 5 ] = bf * d + ae; + te[ 9 ] = af * d - be; - console.warn( 'THREE.Box3: .getSize() target is now required' ); - target = new Vector3(); + te[ 2 ] = - d; + te[ 6 ] = b * c; + te[ 10 ] = a * c; - } + } else if ( euler.order === 'YZX' ) { - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); + var ac = a * c, ad = a * d, bc = b * c, bd = b * d; - }, + te[ 0 ] = c * e; + te[ 4 ] = bd - ac * f; + te[ 8 ] = bc * f + ad; - expandByPoint: function ( point ) { + te[ 1 ] = f; + te[ 5 ] = a * e; + te[ 9 ] = - b * e; - this.min.min( point ); - this.max.max( point ); + te[ 2 ] = - d * e; + te[ 6 ] = ad * f + bc; + te[ 10 ] = ac - bd * f; - return this; + } else if ( euler.order === 'XZY' ) { - }, + var ac = a * c, ad = a * d, bc = b * c, bd = b * d; - expandByVector: function ( vector ) { + te[ 0 ] = c * e; + te[ 4 ] = - f; + te[ 8 ] = d * e; - this.min.sub( vector ); - this.max.add( vector ); + te[ 1 ] = ac * f + bd; + te[ 5 ] = a * e; + te[ 9 ] = ad * f - bc; - return this; + te[ 2 ] = bc * f - ad; + te[ 6 ] = b * e; + te[ 10 ] = bd * f + ac; - }, + } - expandByScalar: function ( scalar ) { + // bottom row + te[ 3 ] = 0; + te[ 7 ] = 0; + te[ 11 ] = 0; - this.min.addScalar( - scalar ); - this.max.addScalar( scalar ); + // last column + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; return this; }, - expandByObject: function () { - - // Computes the world-axis-aligned bounding box of an object (including its children), - // accounting for both the object's, and children's, world transforms + makeRotationFromQuaternion: function () { - var scope, i, l; + var zero = new Vector3( 0, 0, 0 ); + var one = new Vector3( 1, 1, 1 ); - var v1 = new Vector3(); + return function makeRotationFromQuaternion( q ) { - function traverse( node ) { + return this.compose( zero, q, one ); - var geometry = node.geometry; + }; - if ( geometry !== undefined ) { + }(), - if ( geometry.isGeometry ) { + lookAt: function () { - var vertices = geometry.vertices; + var x = new Vector3(); + var y = new Vector3(); + var z = new Vector3(); - for ( i = 0, l = vertices.length; i < l; i ++ ) { + return function lookAt( eye, target, up ) { - v1.copy( vertices[ i ] ); - v1.applyMatrix4( node.matrixWorld ); + var te = this.elements; - scope.expandByPoint( v1 ); + z.subVectors( eye, target ); - } + if ( z.lengthSq() === 0 ) { - } else if ( geometry.isBufferGeometry ) { + // eye and target are in the same position - var attribute = geometry.attributes.position; + z.z = 1; - if ( attribute !== undefined ) { + } - for ( i = 0, l = attribute.count; i < l; i ++ ) { + z.normalize(); + x.crossVectors( up, z ); - v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld ); + if ( x.lengthSq() === 0 ) { - scope.expandByPoint( v1 ); + // up and z are parallel - } + if ( Math.abs( up.z ) === 1 ) { - } + z.x += 0.0001; - } + } else { - } + z.z += 0.0001; - } + } - return function expandByObject( object ) { + z.normalize(); + x.crossVectors( up, z ); - scope = this; + } - object.updateMatrixWorld( true ); + x.normalize(); + y.crossVectors( z, x ); - object.traverse( traverse ); + te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; + te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; + te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; return this; @@ -4135,388 +4219,479 @@ }(), - containsPoint: function ( point ) { + multiply: function ( m, n ) { - return point.x < this.min.x || point.x > this.max.x || - point.y < this.min.y || point.y > this.max.y || - point.z < this.min.z || point.z > this.max.z ? false : true; + if ( n !== undefined ) { + + console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); + return this.multiplyMatrices( m, n ); + + } + + return this.multiplyMatrices( this, m ); }, - containsBox: function ( box ) { + premultiply: function ( m ) { - return this.min.x <= box.min.x && box.max.x <= this.max.x && - this.min.y <= box.min.y && box.max.y <= this.max.y && - this.min.z <= box.min.z && box.max.z <= this.max.z; + return this.multiplyMatrices( m, this ); }, - getParameter: function ( point, target ) { + multiplyMatrices: function ( a, b ) { - // This can potentially have a divide by zero if the box - // has a size dimension of 0. + var ae = a.elements; + var be = b.elements; + var te = this.elements; - if ( target === undefined ) { + var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; + var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; + var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; + var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; - console.warn( 'THREE.Box3: .getParameter() target is now required' ); - target = new Vector3(); + var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; + var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; + var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; + var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; - } + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; + te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; + te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; + te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; - return target.set( - ( point.x - this.min.x ) / ( this.max.x - this.min.x ), - ( point.y - this.min.y ) / ( this.max.y - this.min.y ), - ( point.z - this.min.z ) / ( this.max.z - this.min.z ) - ); + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; + te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; + te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; + te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; - }, + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; + te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; + te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; + te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; - intersectsBox: function ( box ) { + te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; + te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; + te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; + te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; - // using 6 splitting planes to rule out intersections. - return box.max.x < this.min.x || box.min.x > this.max.x || - box.max.y < this.min.y || box.min.y > this.max.y || - box.max.z < this.min.z || box.min.z > this.max.z ? false : true; + return this; }, - intersectsSphere: ( function () { + multiplyScalar: function ( s ) { - var closestPoint = new Vector3(); + var te = this.elements; - return function intersectsSphere( sphere ) { + te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; + te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; + te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; + te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; - // Find the point on the AABB closest to the sphere center. - this.clampPoint( sphere.center, closestPoint ); + return this; - // If that point is inside the sphere, the AABB and sphere intersect. - return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); + }, - }; + applyToBufferAttribute: function () { - } )(), + var v1 = new Vector3(); - intersectsPlane: function ( plane ) { + return function applyToBufferAttribute( attribute ) { - // We compute the minimum and maximum dot product values. If those values - // are on the same side (back or front) of the plane, then there is no intersection. + for ( var i = 0, l = attribute.count; i < l; i ++ ) { - var min, max; + v1.x = attribute.getX( i ); + v1.y = attribute.getY( i ); + v1.z = attribute.getZ( i ); - if ( plane.normal.x > 0 ) { + v1.applyMatrix4( this ); - min = plane.normal.x * this.min.x; - max = plane.normal.x * this.max.x; + attribute.setXYZ( i, v1.x, v1.y, v1.z ); - } else { + } - min = plane.normal.x * this.max.x; - max = plane.normal.x * this.min.x; + return attribute; - } + }; - if ( plane.normal.y > 0 ) { + }(), - min += plane.normal.y * this.min.y; - max += plane.normal.y * this.max.y; + determinant: function () { - } else { + var te = this.elements; - min += plane.normal.y * this.max.y; - max += plane.normal.y * this.min.y; + var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; + var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; + var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; + var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - } + //TODO: make this more efficient + //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) - if ( plane.normal.z > 0 ) { + return ( + n41 * ( + + n14 * n23 * n32 + - n13 * n24 * n32 + - n14 * n22 * n33 + + n12 * n24 * n33 + + n13 * n22 * n34 + - n12 * n23 * n34 + ) + + n42 * ( + + n11 * n23 * n34 + - n11 * n24 * n33 + + n14 * n21 * n33 + - n13 * n21 * n34 + + n13 * n24 * n31 + - n14 * n23 * n31 + ) + + n43 * ( + + n11 * n24 * n32 + - n11 * n22 * n34 + - n14 * n21 * n32 + + n12 * n21 * n34 + + n14 * n22 * n31 + - n12 * n24 * n31 + ) + + n44 * ( + - n13 * n22 * n31 + - n11 * n23 * n32 + + n11 * n22 * n33 + + n13 * n21 * n32 + - n12 * n21 * n33 + + n12 * n23 * n31 + ) - min += plane.normal.z * this.min.z; - max += plane.normal.z * this.max.z; + ); - } else { + }, - min += plane.normal.z * this.max.z; - max += plane.normal.z * this.min.z; + transpose: function () { - } + var te = this.elements; + var tmp; - return ( min <= - plane.constant && max >= - plane.constant ); + tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; + tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; + tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; - }, + tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; + tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; + tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; - intersectsTriangle: ( function () { + return this; - // triangle centered vertices - var v0 = new Vector3(); - var v1 = new Vector3(); - var v2 = new Vector3(); + }, - // triangle edge vectors - var f0 = new Vector3(); - var f1 = new Vector3(); - var f2 = new Vector3(); + setPosition: function ( x, y, z ) { - var testAxis = new Vector3(); + var te = this.elements; - var center = new Vector3(); - var extents = new Vector3(); + if ( x.isVector3 ) { - var triangleNormal = new Vector3(); + te[ 12 ] = x.x; + te[ 13 ] = x.y; + te[ 14 ] = x.z; - function satForAxes( axes ) { + } else { - var i, j; + te[ 12 ] = x; + te[ 13 ] = y; + te[ 14 ] = z; - for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { + } - testAxis.fromArray( axes, i ); - // project the aabb onto the seperating axis - var r = extents.x * Math.abs( testAxis.x ) + extents.y * Math.abs( testAxis.y ) + extents.z * Math.abs( testAxis.z ); - // project all 3 vertices of the triangle onto the seperating axis - var p0 = v0.dot( testAxis ); - var p1 = v1.dot( testAxis ); - var p2 = v2.dot( testAxis ); - // actual test, basically see if either of the most extreme of the triangle points intersects r - if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { + return this; - // points of the projected triangle are outside the projected half-length of the aabb - // the axis is seperating and we can exit - return false; + }, - } + getInverse: function ( m, throwOnDegenerate ) { - } + // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm + var te = this.elements, + me = m.elements, - return true; + 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 ], - } + 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; - return function intersectsTriangle( triangle ) { + var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; - if ( this.isEmpty() ) { + if ( det === 0 ) { - return false; + var msg = "THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0"; - } + if ( throwOnDegenerate === true ) { - // compute box center and extents - this.getCenter( center ); - extents.subVectors( this.max, center ); + throw new Error( msg ); - // translate triangle to aabb origin - v0.subVectors( triangle.a, center ); - v1.subVectors( triangle.b, center ); - v2.subVectors( triangle.c, center ); + } else { - // compute edge vectors for triangle - f0.subVectors( v1, v0 ); - f1.subVectors( v2, v1 ); - f2.subVectors( v0, v2 ); + console.warn( msg ); - // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb - // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation - // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) - var axes = [ - 0, - f0.z, f0.y, 0, - f1.z, f1.y, 0, - f2.z, f2.y, - f0.z, 0, - f0.x, f1.z, 0, - f1.x, f2.z, 0, - f2.x, - - f0.y, f0.x, 0, - f1.y, f1.x, 0, - f2.y, f2.x, 0 - ]; - if ( ! satForAxes( axes ) ) { + } - return false; + return this.identity(); - } + } - // test 3 face normals from the aabb - axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; - if ( ! satForAxes( axes ) ) { + var detInv = 1 / det; - return false; + 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; - // finally testing the face normal of the triangle - // use already existing triangle edge vectors here - triangleNormal.crossVectors( f0, f1 ); - axes = [ triangleNormal.x, triangleNormal.y, triangleNormal.z ]; - return satForAxes( axes ); + 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; - clampPoint: function ( point, target ) { + }, - if ( target === undefined ) { + scale: function ( v ) { - console.warn( 'THREE.Box3: .clampPoint() target is now required' ); - target = new Vector3(); + var te = this.elements; + var x = v.x, y = v.y, z = v.z; - } + te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; + te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; + te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; + te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; - return target.copy( point ).clamp( this.min, this.max ); + return this; }, - distanceToPoint: function () { + getMaxScaleOnAxis: function () { - var v1 = new Vector3(); + var te = this.elements; - return function distanceToPoint( point ) { + var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; + var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; + var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; - var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); - return clampedPoint.sub( point ).length(); + return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); - }; + }, - }(), + makeTranslation: function ( x, y, z ) { - getBoundingSphere: function () { + this.set( - var v1 = new Vector3(); + 1, 0, 0, x, + 0, 1, 0, y, + 0, 0, 1, z, + 0, 0, 0, 1 - return function getBoundingSphere( target ) { + ); - if ( target === undefined ) { + return this; - console.error( 'THREE.Box3: .getBoundingSphere() target is now required' ); - //target = new Sphere(); // removed to avoid cyclic dependency + }, - } + makeRotationX: function ( theta ) { - this.getCenter( target.center ); + var c = Math.cos( theta ), s = Math.sin( theta ); - target.radius = this.getSize( v1 ).length() * 0.5; + this.set( - return target; + 1, 0, 0, 0, + 0, c, - s, 0, + 0, s, c, 0, + 0, 0, 0, 1 - }; + ); - }(), + return this; - intersect: function ( box ) { + }, - this.min.max( box.min ); - this.max.min( box.max ); + makeRotationY: function ( theta ) { - // 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(); + var c = Math.cos( theta ), s = Math.sin( theta ); + + this.set( + + c, 0, s, 0, + 0, 1, 0, 0, + - s, 0, c, 0, + 0, 0, 0, 1 + + ); return this; }, - union: function ( box ) { + makeRotationZ: function ( theta ) { - this.min.min( box.min ); - this.max.max( box.max ); + var c = Math.cos( theta ), s = Math.sin( theta ); + + this.set( + + c, - s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + + ); return this; }, - applyMatrix4: function () { + makeRotationAxis: function ( axis, angle ) { - var points = [ - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3(), - new Vector3() - ]; + // Based on http://www.gamedev.net/reference/articles/article1199.asp - return function applyMatrix4( matrix ) { + var c = Math.cos( angle ); + var s = Math.sin( angle ); + var t = 1 - c; + var x = axis.x, y = axis.y, z = axis.z; + var tx = t * x, ty = t * y; - // transform of empty box is an empty box. - if ( this.isEmpty() ) return this; + this.set( - // 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 - points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 - points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 - points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 - points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 - 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 + tx * x + c, tx * y - s * z, tx * z + s * y, 0, + tx * y + s * z, ty * y + c, ty * z - s * x, 0, + tx * z - s * y, ty * z + s * x, t * z * z + c, 0, + 0, 0, 0, 1 - this.setFromPoints( points ); + ); - return this; + return this; - }; + }, - }(), + makeScale: function ( x, y, z ) { - translate: function ( offset ) { + this.set( - this.min.add( offset ); - this.max.add( offset ); + x, 0, 0, 0, + 0, y, 0, 0, + 0, 0, z, 0, + 0, 0, 0, 1 + + ); return this; }, - equals: function ( box ) { + makeShear: function ( x, y, z ) { - return box.min.equals( this.min ) && box.max.equals( this.max ); + this.set( - } + 1, y, z, 0, + x, 1, z, 0, + x, y, 1, 0, + 0, 0, 0, 1 - } ); + ); - /** - * @author bhouston / http://clara.io - * @author mrdoob / http://mrdoob.com/ - */ + return this; - function Sphere( center, radius ) { + }, - this.center = ( center !== undefined ) ? center : new Vector3(); - this.radius = ( radius !== undefined ) ? radius : 0; + compose: function ( position, quaternion, scale ) { - } + var te = this.elements; - Object.assign( Sphere.prototype, { + var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; + var x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2; + var yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2; - set: function ( center, radius ) { + var sx = scale.x, sy = scale.y, sz = scale.z; - this.center.copy( center ); - this.radius = radius; + te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; + te[ 1 ] = ( xy + wz ) * sx; + te[ 2 ] = ( xz - wy ) * sx; + te[ 3 ] = 0; + + te[ 4 ] = ( xy - wz ) * sy; + te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; + te[ 6 ] = ( yz + wx ) * sy; + te[ 7 ] = 0; + + te[ 8 ] = ( xz + wy ) * sz; + te[ 9 ] = ( yz - wx ) * sz; + te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; + te[ 11 ] = 0; + + te[ 12 ] = position.x; + te[ 13 ] = position.y; + te[ 14 ] = position.z; + te[ 15 ] = 1; return this; }, - setFromPoints: function () { + decompose: function () { - var box = new Box3(); + var vector = new Vector3(); + var matrix = new Matrix4(); - return function setFromPoints( points, optionalCenter ) { + return function decompose( position, quaternion, scale ) { - var center = this.center; + var te = this.elements; - if ( optionalCenter !== undefined ) { + var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); + var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); + var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); - center.copy( optionalCenter ); + // if determine is negative, we need to invert one scale + var det = this.determinant(); + if ( det < 0 ) sx = - sx; - } else { + position.x = te[ 12 ]; + position.y = te[ 13 ]; + position.z = te[ 14 ]; - box.setFromPoints( points ).getCenter( center ); + // scale the rotation part + matrix.copy( this ); - } + var invSX = 1 / sx; + var invSY = 1 / sy; + var invSZ = 1 / sz; - var maxRadiusSq = 0; + matrix.elements[ 0 ] *= invSX; + matrix.elements[ 1 ] *= invSX; + matrix.elements[ 2 ] *= invSX; - for ( var i = 0, il = points.length; i < il; i ++ ) { + matrix.elements[ 4 ] *= invSY; + matrix.elements[ 5 ] *= invSY; + matrix.elements[ 6 ] *= invSY; - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); + matrix.elements[ 8 ] *= invSZ; + matrix.elements[ 9 ] *= invSZ; + matrix.elements[ 10 ] *= invSZ; - } + quaternion.setFromRotationMatrix( matrix ); - this.radius = Math.sqrt( maxRadiusSq ); + scale.x = sx; + scale.y = sy; + scale.z = sz; return this; @@ -4524,848 +4699,798 @@ }(), - clone: function () { + makePerspective: function ( left, right, top, bottom, near, far ) { - return new this.constructor().copy( this ); + if ( far === undefined ) { - }, + console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); - copy: function ( sphere ) { + } - this.center.copy( sphere.center ); - this.radius = sphere.radius; + var te = this.elements; + var x = 2 * near / ( right - left ); + var y = 2 * near / ( top - bottom ); + + var a = ( right + left ) / ( right - left ); + var b = ( top + bottom ) / ( top - bottom ); + var c = - ( far + near ) / ( far - near ); + var d = - 2 * far * near / ( far - near ); + + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; return this; }, - empty: function () { + makeOrthographic: function ( left, right, top, bottom, near, far ) { - return ( this.radius <= 0 ); + var te = this.elements; + 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; - containsPoint: function ( point ) { + 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 ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); + return this; }, - distanceToPoint: function ( point ) { + equals: function ( matrix ) { - return ( point.distanceTo( this.center ) - this.radius ); + var te = this.elements; + var me = matrix.elements; - }, + for ( var i = 0; i < 16; i ++ ) { - intersectsSphere: function ( sphere ) { + if ( te[ i ] !== me[ i ] ) return false; - var radiusSum = this.radius + sphere.radius; + } - return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); + return true; }, - intersectsBox: function ( box ) { + fromArray: function ( array, offset ) { - return box.intersectsSphere( this ); + if ( offset === undefined ) offset = 0; - }, + for ( var i = 0; i < 16; i ++ ) { - intersectsPlane: function ( plane ) { + this.elements[ i ] = array[ i + offset ]; - return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; + } - }, + return this; - clampPoint: function ( point, target ) { + }, - var deltaLengthSq = this.center.distanceToSquared( point ); + toArray: function ( array, offset ) { - if ( target === undefined ) { + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - console.warn( 'THREE.Sphere: .clampPoint() target is now required' ); - target = new Vector3(); + var te = this.elements; - } + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + array[ offset + 3 ] = te[ 3 ]; - target.copy( point ); + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; - if ( deltaLengthSq > ( this.radius * this.radius ) ) { + array[ offset + 8 ] = te[ 8 ]; + array[ offset + 9 ] = te[ 9 ]; + array[ offset + 10 ] = te[ 10 ]; + array[ offset + 11 ] = te[ 11 ]; - target.sub( this.center ).normalize(); - target.multiplyScalar( this.radius ).add( this.center ); + array[ offset + 12 ] = te[ 12 ]; + array[ offset + 13 ] = te[ 13 ]; + array[ offset + 14 ] = te[ 14 ]; + array[ offset + 15 ] = te[ 15 ]; - } + return array; - return target; + } - }, + } ); - getBoundingBox: function ( target ) { + /** + * @author mrdoob / http://mrdoob.com/ + * @author WestLangley / http://github.com/WestLangley + * @author bhouston / http://clara.io + */ - if ( target === undefined ) { + function Euler( x, y, z, order ) { - console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' ); - target = new Box3(); + this._x = x || 0; + this._y = y || 0; + this._z = z || 0; + this._order = order || Euler.DefaultOrder; - } + } - target.set( this.center, this.center ); - target.expandByScalar( this.radius ); + Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; - return target; + Euler.DefaultOrder = 'XYZ'; - }, + Object.defineProperties( Euler.prototype, { - applyMatrix4: function ( matrix ) { + x: { - this.center.applyMatrix4( matrix ); - this.radius = this.radius * matrix.getMaxScaleOnAxis(); + get: function () { - return this; + return this._x; - }, + }, - translate: function ( offset ) { + set: function ( value ) { - this.center.add( offset ); + this._x = value; + this._onChangeCallback(); - return this; + } }, - equals: function ( sphere ) { - - return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); - - } + y: { - } ); + get: function () { - /** - * @author bhouston / http://clara.io - */ + return this._y; - function Plane( normal, constant ) { + }, - // normal is assumed to be normalized + set: function ( value ) { - this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); - this.constant = ( constant !== undefined ) ? constant : 0; + this._y = value; + this._onChangeCallback(); - } + } - Object.assign( Plane.prototype, { + }, - set: function ( normal, constant ) { + z: { - this.normal.copy( normal ); - this.constant = constant; + get: function () { - return this; + return this._z; - }, + }, - setComponents: function ( x, y, z, w ) { + set: function ( value ) { - this.normal.set( x, y, z ); - this.constant = w; + this._z = value; + this._onChangeCallback(); - return this; + } }, - setFromNormalAndCoplanarPoint: function ( normal, point ) { + order: { - this.normal.copy( normal ); - this.constant = - point.dot( this.normal ); + get: function () { - return this; + return this._order; - }, + }, - setFromCoplanarPoints: function () { + set: function ( value ) { - var v1 = new Vector3(); - var v2 = new Vector3(); + this._order = value; + this._onChangeCallback(); - return function setFromCoplanarPoints( a, b, c ) { + } - var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); + } - // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? + } ); - this.setFromNormalAndCoplanarPoint( normal, a ); + Object.assign( Euler.prototype, { - return this; + isEuler: true, - }; + set: function ( x, y, z, order ) { - }(), + this._x = x; + this._y = y; + this._z = z; + this._order = order || this._order; - clone: function () { + this._onChangeCallback(); - return new this.constructor().copy( this ); + return this; }, - copy: function ( plane ) { - - this.normal.copy( plane.normal ); - this.constant = plane.constant; + clone: function () { - return this; + return new this.constructor( this._x, this._y, this._z, this._order ); }, - normalize: function () { + copy: function ( euler ) { - // Note: will lead to a divide by zero if the plane is invalid. + this._x = euler._x; + this._y = euler._y; + this._z = euler._z; + this._order = euler._order; - var inverseNormalLength = 1.0 / this.normal.length(); - this.normal.multiplyScalar( inverseNormalLength ); - this.constant *= inverseNormalLength; + this._onChangeCallback(); return this; }, - negate: function () { - - this.constant *= - 1; - this.normal.negate(); + setFromRotationMatrix: function ( m, order, update ) { - return this; + var clamp = _Math.clamp; - }, + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - distanceToPoint: function ( point ) { + var te = m.elements; + var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; + var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; + var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - return this.normal.dot( point ) + this.constant; + order = order || this._order; - }, + if ( order === 'XYZ' ) { - distanceToSphere: function ( sphere ) { + this._y = Math.asin( clamp( m13, - 1, 1 ) ); - return this.distanceToPoint( sphere.center ) - sphere.radius; + if ( Math.abs( m13 ) < 0.99999 ) { - }, + this._x = Math.atan2( - m23, m33 ); + this._z = Math.atan2( - m12, m11 ); - projectPoint: function ( point, target ) { + } else { - if ( target === undefined ) { + this._x = Math.atan2( m32, m22 ); + this._z = 0; - console.warn( 'THREE.Plane: .projectPoint() target is now required' ); - target = new Vector3(); + } - } + } else if ( order === 'YXZ' ) { - return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); + this._x = Math.asin( - clamp( m23, - 1, 1 ) ); - }, + if ( Math.abs( m23 ) < 0.99999 ) { - intersectLine: function () { + this._y = Math.atan2( m13, m33 ); + this._z = Math.atan2( m21, m22 ); - var v1 = new Vector3(); + } else { - return function intersectLine( line, target ) { + this._y = Math.atan2( - m31, m11 ); + this._z = 0; - if ( target === undefined ) { + } - console.warn( 'THREE.Plane: .intersectLine() target is now required' ); - target = new Vector3(); + } else if ( order === 'ZXY' ) { - } + this._x = Math.asin( clamp( m32, - 1, 1 ) ); - var direction = line.delta( v1 ); + if ( Math.abs( m32 ) < 0.99999 ) { - var denominator = this.normal.dot( direction ); + this._y = Math.atan2( - m31, m33 ); + this._z = Math.atan2( - m12, m22 ); - if ( denominator === 0 ) { + } else { - // line is coplanar, return origin - if ( this.distanceToPoint( line.start ) === 0 ) { + this._y = 0; + this._z = Math.atan2( m21, m11 ); - return target.copy( line.start ); + } - } + } else if ( order === 'ZYX' ) { - // Unsure if this is the correct method to handle this case. - return undefined; + this._y = Math.asin( - clamp( m31, - 1, 1 ) ); - } + if ( Math.abs( m31 ) < 0.99999 ) { - var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; + this._x = Math.atan2( m32, m33 ); + this._z = Math.atan2( m21, m11 ); - if ( t < 0 || t > 1 ) { + } else { - return undefined; + this._x = 0; + this._z = Math.atan2( - m12, m22 ); } - return target.copy( direction ).multiplyScalar( t ).add( line.start ); - - }; + } else if ( order === 'YZX' ) { - }(), + this._z = Math.asin( clamp( m21, - 1, 1 ) ); - intersectsLine: function ( line ) { + if ( Math.abs( m21 ) < 0.99999 ) { - // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. + this._x = Math.atan2( - m23, m22 ); + this._y = Math.atan2( - m31, m11 ); - var startSign = this.distanceToPoint( line.start ); - var endSign = this.distanceToPoint( line.end ); + } else { - return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); + this._x = 0; + this._y = Math.atan2( m13, m33 ); - }, + } - intersectsBox: function ( box ) { + } else if ( order === 'XZY' ) { - return box.intersectsPlane( this ); + this._z = Math.asin( - clamp( m12, - 1, 1 ) ); - }, + if ( Math.abs( m12 ) < 0.99999 ) { - intersectsSphere: function ( sphere ) { + this._x = Math.atan2( m32, m22 ); + this._y = Math.atan2( m13, m11 ); - return sphere.intersectsPlane( this ); + } else { - }, + this._x = Math.atan2( - m23, m33 ); + this._y = 0; - coplanarPoint: function ( target ) { + } - if ( target === undefined ) { + } else { - console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ); } - return target.copy( this.normal ).multiplyScalar( - this.constant ); - - }, + this._order = order; - applyMatrix4: function () { + if ( update !== false ) this._onChangeCallback(); - var v1 = new Vector3(); - var m1 = new Matrix3(); + return this; - return function applyMatrix4( matrix, optionalNormalMatrix ) { + }, - var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); + setFromQuaternion: function () { - var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix ); + var matrix = new Matrix4(); - var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); + return function setFromQuaternion( q, order, update ) { - this.constant = - referencePoint.dot( normal ); + matrix.makeRotationFromQuaternion( q ); - return this; + return this.setFromRotationMatrix( matrix, order, update ); }; }(), - translate: function ( offset ) { - - this.constant -= offset.dot( this.normal ); + setFromVector3: function ( v, order ) { - return this; + return this.set( v.x, v.y, v.z, order || this._order ); }, - equals: function ( plane ) { + reorder: function () { - return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); + // WARNING: this discards revolution information -bhouston - } + var q = new Quaternion(); - } ); + return function reorder( newOrder ) { - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * @author bhouston / http://clara.io - */ + q.setFromEuler( this ); - function Frustum( p0, p1, p2, p3, p4, p5 ) { + return this.setFromQuaternion( q, newOrder ); - this.planes = [ + }; - ( p0 !== undefined ) ? p0 : new Plane(), - ( p1 !== undefined ) ? p1 : new Plane(), - ( p2 !== undefined ) ? p2 : new Plane(), - ( p3 !== undefined ) ? p3 : new Plane(), - ( p4 !== undefined ) ? p4 : new Plane(), - ( p5 !== undefined ) ? p5 : new Plane() + }(), - ]; + equals: function ( euler ) { - } + return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); - Object.assign( Frustum.prototype, { + }, - set: function ( p0, p1, p2, p3, p4, p5 ) { + fromArray: function ( array ) { - var planes = this.planes; + this._x = array[ 0 ]; + this._y = array[ 1 ]; + this._z = array[ 2 ]; + if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; - planes[ 0 ].copy( p0 ); - planes[ 1 ].copy( p1 ); - planes[ 2 ].copy( p2 ); - planes[ 3 ].copy( p3 ); - planes[ 4 ].copy( p4 ); - planes[ 5 ].copy( p5 ); + this._onChangeCallback(); return this; }, - clone: function () { + toArray: function ( array, offset ) { - return new this.constructor().copy( this ); + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; + + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; + + return array; }, - copy: function ( frustum ) { + toVector3: function ( optionalResult ) { - var planes = this.planes; + if ( optionalResult ) { - for ( var i = 0; i < 6; i ++ ) { + return optionalResult.set( this._x, this._y, this._z ); - planes[ i ].copy( frustum.planes[ i ] ); + } else { - } + return new Vector3( this._x, this._y, this._z ); - return this; + } }, - setFromMatrix: function ( m ) { - - var planes = this.planes; - var me = m.elements; - var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; - var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; - var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; - var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; + _onChange: function ( callback ) { - planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); - planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); - planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); - planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); - planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); - planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); + this._onChangeCallback = callback; return this; }, - intersectsObject: function () { - - var sphere = new Sphere(); - - return function intersectsObject( object ) { - - var geometry = object.geometry; - - if ( geometry.boundingSphere === null ) - geometry.computeBoundingSphere(); - - sphere.copy( geometry.boundingSphere ) - .applyMatrix4( object.matrixWorld ); - - return this.intersectsSphere( sphere ); - - }; + _onChangeCallback: function () {} - }(), + } ); - intersectsSprite: function () { + /** + * @author mrdoob / http://mrdoob.com/ + */ - var sphere = new Sphere(); + function Layers() { - return function intersectsSprite( sprite ) { + this.mask = 1 | 0; - sphere.center.set( 0, 0, 0 ); - sphere.radius = 0.7071067811865476; - sphere.applyMatrix4( sprite.matrixWorld ); + } - return this.intersectsSphere( sphere ); + Object.assign( Layers.prototype, { - }; + set: function ( channel ) { - }(), + this.mask = 1 << channel | 0; - intersectsSphere: function ( sphere ) { + }, - var planes = this.planes; - var center = sphere.center; - var negRadius = - sphere.radius; + enable: function ( channel ) { - for ( var i = 0; i < 6; i ++ ) { + this.mask |= 1 << channel | 0; - var distance = planes[ i ].distanceToPoint( center ); + }, - if ( distance < negRadius ) { + toggle: function ( channel ) { - return false; + this.mask ^= 1 << channel | 0; - } + }, - } + disable: function ( channel ) { - return true; + this.mask &= ~ ( 1 << channel | 0 ); }, - intersectsBox: function () { + test: function ( layers ) { - var p = new Vector3(); + return ( this.mask & layers.mask ) !== 0; - return function intersectsBox( box ) { + } - var planes = this.planes; + } ); - for ( var i = 0; i < 6; i ++ ) { + /** + * @author mrdoob / http://mrdoob.com/ + * @author mikael emtinger / http://gomo.se/ + * @author alteredq / http://alteredqualia.com/ + * @author WestLangley / http://github.com/WestLangley + * @author elephantatwork / www.elephantatwork.ch + */ - var plane = planes[ i ]; + var object3DId = 0; - // corner at max distance + function Object3D() { - p.x = plane.normal.x > 0 ? box.max.x : box.min.x; - p.y = plane.normal.y > 0 ? box.max.y : box.min.y; - p.z = plane.normal.z > 0 ? box.max.z : box.min.z; + Object.defineProperty( this, 'id', { value: object3DId ++ } ); - if ( plane.distanceToPoint( p ) < 0 ) { + this.uuid = _Math.generateUUID(); - return false; + this.name = ''; + this.type = 'Object3D'; - } + this.parent = null; + this.children = []; - } + this.up = Object3D.DefaultUp.clone(); - return true; + var position = new Vector3(); + var rotation = new Euler(); + var quaternion = new Quaternion(); + var scale = new Vector3( 1, 1, 1 ); - }; + function onRotationChange() { - }(), + quaternion.setFromEuler( rotation, false ); - containsPoint: function ( point ) { + } - var planes = this.planes; + function onQuaternionChange() { - for ( var i = 0; i < 6; i ++ ) { + rotation.setFromQuaternion( quaternion, undefined, false ); - if ( planes[ i ].distanceToPoint( point ) < 0 ) { + } - return false; - - } + rotation._onChange( onRotationChange ); + quaternion._onChange( onQuaternionChange ); + Object.defineProperties( this, { + position: { + configurable: true, + enumerable: true, + value: position + }, + rotation: { + configurable: true, + enumerable: true, + value: rotation + }, + quaternion: { + configurable: true, + enumerable: true, + value: quaternion + }, + scale: { + configurable: true, + enumerable: true, + value: scale + }, + modelViewMatrix: { + value: new Matrix4() + }, + normalMatrix: { + value: new Matrix3() } + } ); - return true; + this.matrix = new Matrix4(); + this.matrixWorld = new Matrix4(); - } + this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; + this.matrixWorldNeedsUpdate = false; - } ); + this.layers = new Layers(); + this.visible = true; - /** - * @author mrdoob / http://mrdoob.com/ - * @author supereggbert / http://www.paulbrunt.co.uk/ - * @author philogb / http://blog.thejit.org/ - * @author jordi_ros / http://plattsoft.com - * @author D1plo1d / http://github.com/D1plo1d - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author timknip / http://www.floorplanner.com/ - * @author bhouston / http://clara.io - * @author WestLangley / http://github.com/WestLangley - */ + this.castShadow = false; + this.receiveShadow = false; - function Matrix4() { + this.frustumCulled = true; + this.renderOrder = 0; - this.elements = [ + this.userData = {}; - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + } - ]; + Object3D.DefaultUp = new Vector3( 0, 1, 0 ); + Object3D.DefaultMatrixAutoUpdate = true; - if ( arguments.length > 0 ) { + Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); + constructor: Object3D, - } + isObject3D: true, - } + onBeforeRender: function () {}, + onAfterRender: function () {}, - Object.assign( Matrix4.prototype, { + applyMatrix: function ( matrix ) { - isMatrix4: true, + if ( this.matrixAutoUpdate ) this.updateMatrix(); - set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + this.matrix.premultiply( matrix ); - var te = this.elements; + this.matrix.decompose( this.position, this.quaternion, this.scale ); - te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; - te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; - te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; - te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; + }, - return this; + applyQuaternion: function ( q ) { - }, + this.quaternion.premultiply( q ); - identity: function () { + return this; - this.set( + }, - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + setRotationFromAxisAngle: function ( axis, angle ) { - ); + // assumes axis is normalized - return this; + this.quaternion.setFromAxisAngle( axis, angle ); }, - clone: function () { + setRotationFromEuler: function ( euler ) { - return new Matrix4().fromArray( this.elements ); + this.quaternion.setFromEuler( euler, true ); }, - copy: function ( m ) { - - var te = this.elements; - var me = m.elements; + setRotationFromMatrix: function ( m ) { - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; - te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; - te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; - te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - return this; + this.quaternion.setFromRotationMatrix( m ); }, - copyPosition: function ( m ) { - - var te = this.elements, me = m.elements; + setRotationFromQuaternion: function ( q ) { - te[ 12 ] = me[ 12 ]; - te[ 13 ] = me[ 13 ]; - te[ 14 ] = me[ 14 ]; + // assumes q is normalized - return this; + this.quaternion.copy( q ); }, - extractBasis: function ( xAxis, yAxis, zAxis ) { + rotateOnAxis: function () { - xAxis.setFromMatrixColumn( this, 0 ); - yAxis.setFromMatrixColumn( this, 1 ); - zAxis.setFromMatrixColumn( this, 2 ); + // rotate object on axis in object space + // axis is assumed to be normalized - return this; + var q1 = new Quaternion(); - }, + return function rotateOnAxis( axis, angle ) { - makeBasis: function ( xAxis, yAxis, zAxis ) { + q1.setFromAxisAngle( axis, angle ); - this.set( - xAxis.x, yAxis.x, zAxis.x, 0, - xAxis.y, yAxis.y, zAxis.y, 0, - xAxis.z, yAxis.z, zAxis.z, 0, - 0, 0, 0, 1 - ); + this.quaternion.multiply( q1 ); - return this; + return this; - }, + }; - extractRotation: function () { + }(), - var v1 = new Vector3(); + rotateOnWorldAxis: function () { - return function extractRotation( m ) { + // rotate object on axis in world space + // axis is assumed to be normalized + // method assumes no rotated parent - // this method does not support reflection matrices + var q1 = new Quaternion(); - var te = this.elements; - var me = m.elements; + return function rotateOnWorldAxis( axis, angle ) { - var scaleX = 1 / v1.setFromMatrixColumn( m, 0 ).length(); - var scaleY = 1 / v1.setFromMatrixColumn( m, 1 ).length(); - var scaleZ = 1 / v1.setFromMatrixColumn( m, 2 ).length(); + q1.setFromAxisAngle( axis, angle ); - te[ 0 ] = me[ 0 ] * scaleX; - te[ 1 ] = me[ 1 ] * scaleX; - te[ 2 ] = me[ 2 ] * scaleX; - te[ 3 ] = 0; + this.quaternion.premultiply( q1 ); - te[ 4 ] = me[ 4 ] * scaleY; - te[ 5 ] = me[ 5 ] * scaleY; - te[ 6 ] = me[ 6 ] * scaleY; - te[ 7 ] = 0; + return this; - te[ 8 ] = me[ 8 ] * scaleZ; - te[ 9 ] = me[ 9 ] * scaleZ; - te[ 10 ] = me[ 10 ] * scaleZ; - te[ 11 ] = 0; + }; - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + }(), - return this; + rotateX: function () { + + var v1 = new Vector3( 1, 0, 0 ); + + return function rotateX( angle ) { + + return this.rotateOnAxis( v1, angle ); }; }(), - makeRotationFromEuler: function ( euler ) { + rotateY: function () { - if ( ! ( euler && euler.isEuler ) ) { + var v1 = new Vector3( 0, 1, 0 ); - console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); + return function rotateY( angle ) { - } + return this.rotateOnAxis( v1, angle ); - var te = this.elements; + }; - var x = euler.x, y = euler.y, z = euler.z; - var a = Math.cos( x ), b = Math.sin( x ); - var c = Math.cos( y ), d = Math.sin( y ); - var e = Math.cos( z ), f = Math.sin( z ); + }(), - if ( euler.order === 'XYZ' ) { + rotateZ: function () { - var ae = a * e, af = a * f, be = b * e, bf = b * f; + var v1 = new Vector3( 0, 0, 1 ); - te[ 0 ] = c * e; - te[ 4 ] = - c * f; - te[ 8 ] = d; + return function rotateZ( angle ) { - te[ 1 ] = af + be * d; - te[ 5 ] = ae - bf * d; - te[ 9 ] = - b * c; + return this.rotateOnAxis( v1, angle ); - te[ 2 ] = bf - ae * d; - te[ 6 ] = be + af * d; - te[ 10 ] = a * c; + }; - } else if ( euler.order === 'YXZ' ) { + }(), - var ce = c * e, cf = c * f, de = d * e, df = d * f; + translateOnAxis: function () { - te[ 0 ] = ce + df * b; - te[ 4 ] = de * b - cf; - te[ 8 ] = a * d; + // translate object by distance along axis in object space + // axis is assumed to be normalized - te[ 1 ] = a * f; - te[ 5 ] = a * e; - te[ 9 ] = - b; + var v1 = new Vector3(); - te[ 2 ] = cf * b - de; - te[ 6 ] = df + ce * b; - te[ 10 ] = a * c; + return function translateOnAxis( axis, distance ) { - } else if ( euler.order === 'ZXY' ) { + v1.copy( axis ).applyQuaternion( this.quaternion ); - var ce = c * e, cf = c * f, de = d * e, df = d * f; + this.position.add( v1.multiplyScalar( distance ) ); - te[ 0 ] = ce - df * b; - te[ 4 ] = - a * f; - te[ 8 ] = de + cf * b; + return this; - te[ 1 ] = cf + de * b; - te[ 5 ] = a * e; - te[ 9 ] = df - ce * b; + }; - te[ 2 ] = - a * d; - te[ 6 ] = b; - te[ 10 ] = a * c; + }(), - } else if ( euler.order === 'ZYX' ) { + translateX: function () { - var ae = a * e, af = a * f, be = b * e, bf = b * f; + var v1 = new Vector3( 1, 0, 0 ); - te[ 0 ] = c * e; - te[ 4 ] = be * d - af; - te[ 8 ] = ae * d + bf; + return function translateX( distance ) { - te[ 1 ] = c * f; - te[ 5 ] = bf * d + ae; - te[ 9 ] = af * d - be; + return this.translateOnAxis( v1, distance ); - te[ 2 ] = - d; - te[ 6 ] = b * c; - te[ 10 ] = a * c; + }; - } else if ( euler.order === 'YZX' ) { + }(), - var ac = a * c, ad = a * d, bc = b * c, bd = b * d; + translateY: function () { - te[ 0 ] = c * e; - te[ 4 ] = bd - ac * f; - te[ 8 ] = bc * f + ad; + var v1 = new Vector3( 0, 1, 0 ); - te[ 1 ] = f; - te[ 5 ] = a * e; - te[ 9 ] = - b * e; + return function translateY( distance ) { - te[ 2 ] = - d * e; - te[ 6 ] = ad * f + bc; - te[ 10 ] = ac - bd * f; + return this.translateOnAxis( v1, distance ); - } else if ( euler.order === 'XZY' ) { + }; - var ac = a * c, ad = a * d, bc = b * c, bd = b * d; + }(), - te[ 0 ] = c * e; - te[ 4 ] = - f; - te[ 8 ] = d * e; + translateZ: function () { - te[ 1 ] = ac * f + bd; - te[ 5 ] = a * e; - te[ 9 ] = ad * f - bc; + var v1 = new Vector3( 0, 0, 1 ); - te[ 2 ] = bc * f - ad; - te[ 6 ] = b * e; - te[ 10 ] = bd * f + ac; + return function translateZ( distance ) { - } + return this.translateOnAxis( v1, distance ); - // bottom row - te[ 3 ] = 0; - te[ 7 ] = 0; - te[ 11 ] = 0; + }; - // last column - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + }(), - return this; + localToWorld: function ( vector ) { + + return vector.applyMatrix4( this.matrixWorld ); }, - makeRotationFromQuaternion: function () { + worldToLocal: function () { - var zero = new Vector3( 0, 0, 0 ); - var one = new Vector3( 1, 1, 1 ); + var m1 = new Matrix4(); - return function makeRotationFromQuaternion( q ) { + return function worldToLocal( vector ) { - return this.compose( zero, q, one ); + return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) ); }; @@ -5373,1415 +5498,1274 @@ lookAt: function () { - var x = new Vector3(); - var y = new Vector3(); - var z = new Vector3(); + // This method does not support objects having non-uniformly-scaled parent(s) - return function lookAt( eye, target, up ) { + var q1 = new Quaternion(); + var m1 = new Matrix4(); + var target = new Vector3(); + var position = new Vector3(); - var te = this.elements; + return function lookAt( x, y, z ) { - z.subVectors( eye, target ); + if ( x.isVector3 ) { - if ( z.lengthSq() === 0 ) { + target.copy( x ); - // eye and target are in the same position + } else { - z.z = 1; + target.set( x, y, z ); } - z.normalize(); - x.crossVectors( up, z ); - - if ( x.lengthSq() === 0 ) { - - // up and z are parallel + var parent = this.parent; - if ( Math.abs( up.z ) === 1 ) { + this.updateWorldMatrix( true, false ); - z.x += 0.0001; + position.setFromMatrixPosition( this.matrixWorld ); - } else { + if ( this.isCamera || this.isLight ) { - z.z += 0.0001; + m1.lookAt( position, target, this.up ); - } + } else { - z.normalize(); - x.crossVectors( up, z ); + m1.lookAt( target, position, this.up ); } - x.normalize(); - y.crossVectors( z, x ); + this.quaternion.setFromRotationMatrix( m1 ); - te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; - te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; - te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; + if ( parent ) { - return this; + m1.extractRotation( parent.matrixWorld ); + q1.setFromRotationMatrix( m1 ); + this.quaternion.premultiply( q1.inverse() ); + + } }; }(), - multiply: function ( m, n ) { + add: function ( object ) { - if ( n !== undefined ) { + if ( arguments.length > 1 ) { - console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); - return this.multiplyMatrices( m, n ); + for ( var i = 0; i < arguments.length; i ++ ) { - } + this.add( arguments[ i ] ); - return this.multiplyMatrices( this, m ); + } - }, + return this; - premultiply: function ( m ) { + } - return this.multiplyMatrices( m, this ); + if ( object === this ) { - }, + console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); + return this; - multiplyMatrices: function ( a, b ) { + } - var ae = a.elements; - var be = b.elements; - var te = this.elements; + if ( ( object && object.isObject3D ) ) { - var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; - var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; - var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; - var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; + if ( object.parent !== null ) { - var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; - var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; - var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; - var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + object.parent.remove( object ); - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; - te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; - te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; - te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + } - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; - te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; - te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; - te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + object.parent = this; + this.children.push( object ); - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; - te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; - te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; - te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + object.dispatchEvent( { type: 'added' } ); - te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; - te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; - te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; - te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; + } else { + + console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); + + } return this; }, - multiplyScalar: function ( s ) { + remove: function ( object ) { - var te = this.elements; + if ( arguments.length > 1 ) { - te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; - te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; - te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; - te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; + for ( var i = 0; i < arguments.length; i ++ ) { + + this.remove( arguments[ i ] ); + + } + + return this; + + } + + var index = this.children.indexOf( object ); + + if ( index !== - 1 ) { + + object.parent = null; + this.children.splice( index, 1 ); + + object.dispatchEvent( { type: 'removed' } ); + + } return this; }, - applyToBufferAttribute: function () { + attach: function () { - var v1 = new Vector3(); + // adds object as a child of this, while maintaining the object's world transform - return function applyToBufferAttribute( attribute ) { + var m = new Matrix4(); - for ( var i = 0, l = attribute.count; i < l; i ++ ) { + return function attach( object ) { - v1.x = attribute.getX( i ); - v1.y = attribute.getY( i ); - v1.z = attribute.getZ( i ); + this.updateWorldMatrix( true, false ); - v1.applyMatrix4( this ); + m.getInverse( this.matrixWorld ); - attribute.setXYZ( i, v1.x, v1.y, v1.z ); + if ( object.parent !== null ) { + + object.parent.updateWorldMatrix( true, false ); + + m.multiply( object.parent.matrixWorld ); } - return attribute; + object.applyMatrix( m ); + + object.updateWorldMatrix( false, false ); + + this.add( object ); + + return this; }; }(), - determinant: function () { + getObjectById: function ( id ) { - var te = this.elements; + return this.getObjectByProperty( 'id', id ); - var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; - var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; - var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; - var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - - //TODO: make this more efficient - //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) + }, - return ( - n41 * ( - + n14 * n23 * n32 - - n13 * n24 * n32 - - n14 * n22 * n33 - + n12 * n24 * n33 - + n13 * n22 * n34 - - n12 * n23 * n34 - ) + - n42 * ( - + n11 * n23 * n34 - - n11 * n24 * n33 - + n14 * n21 * n33 - - n13 * n21 * n34 - + n13 * n24 * n31 - - n14 * n23 * n31 - ) + - n43 * ( - + n11 * n24 * n32 - - n11 * n22 * n34 - - n14 * n21 * n32 - + n12 * n21 * n34 - + n14 * n22 * n31 - - n12 * n24 * n31 - ) + - n44 * ( - - n13 * n22 * n31 - - n11 * n23 * n32 - + n11 * n22 * n33 - + n13 * n21 * n32 - - n12 * n21 * n33 - + n12 * n23 * n31 - ) + getObjectByName: function ( name ) { - ); + return this.getObjectByProperty( 'name', name ); }, - transpose: function () { + getObjectByProperty: function ( name, value ) { - var te = this.elements; - var tmp; + if ( this[ name ] === value ) return this; - tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; - tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; - tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; + for ( var i = 0, l = this.children.length; i < l; i ++ ) { - tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; - tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; - tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; + var child = this.children[ i ]; + var object = child.getObjectByProperty( name, value ); - return this; + if ( object !== undefined ) { - }, + return object; - setPosition: function ( x, y, z ) { + } - var te = this.elements; + } - if ( x.isVector3 ) { + return undefined; - te[ 12 ] = x.x; - te[ 13 ] = x.y; - te[ 14 ] = x.z; + }, - } else { + getWorldPosition: function ( target ) { - te[ 12 ] = x; - te[ 13 ] = y; - te[ 14 ] = z; + if ( target === undefined ) { + + console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' ); + target = new Vector3(); } - return this; + this.updateMatrixWorld( true ); - }, + return target.setFromMatrixPosition( this.matrixWorld ); - getInverse: function ( m, throwOnDegenerate ) { + }, - // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - var te = this.elements, - me = m.elements, + getWorldQuaternion: function () { - 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 ], + var position = new Vector3(); + var scale = new Vector3(); - 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; + return function getWorldQuaternion( target ) { - var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; + if ( target === undefined ) { - if ( det === 0 ) { + console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); + target = new Quaternion(); - var msg = "THREE.Matrix4: .getInverse() can't invert matrix, determinant is 0"; + } - if ( throwOnDegenerate === true ) { + this.updateMatrixWorld( true ); - throw new Error( msg ); + this.matrixWorld.decompose( position, target, scale ); - } else { + return target; - console.warn( msg ); + }; - } + }(), - return this.identity(); + getWorldScale: function () { - } + var position = new Vector3(); + var quaternion = new Quaternion(); - var detInv = 1 / det; + return function getWorldScale( target ) { - 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; + if ( target === undefined ) { - 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; + console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); + target = new Vector3(); - 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; + this.updateMatrixWorld( true ); - return this; + this.matrixWorld.decompose( position, quaternion, target ); - }, + return target; - scale: function ( v ) { + }; - var te = this.elements; - var x = v.x, y = v.y, z = v.z; + }(), - te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; - te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; - te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; - te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; + getWorldDirection: function ( target ) { - return this; + if ( target === undefined ) { - }, + console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' ); + target = new Vector3(); - getMaxScaleOnAxis: function () { + } - var te = this.elements; + this.updateMatrixWorld( true ); - var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; - var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; - var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; + var e = this.matrixWorld.elements; - return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); + return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); }, - makeTranslation: function ( x, y, z ) { + raycast: function () {}, - this.set( + traverse: function ( callback ) { - 1, 0, 0, x, - 0, 1, 0, y, - 0, 0, 1, z, - 0, 0, 0, 1 + callback( this ); - ); + var children = this.children; - return this; + for ( var i = 0, l = children.length; i < l; i ++ ) { + + children[ i ].traverse( callback ); + + } }, - makeRotationX: function ( theta ) { + traverseVisible: function ( callback ) { - var c = Math.cos( theta ), s = Math.sin( theta ); + if ( this.visible === false ) return; - this.set( + callback( this ); - 1, 0, 0, 0, - 0, c, - s, 0, - 0, s, c, 0, - 0, 0, 0, 1 + var children = this.children; - ); + for ( var i = 0, l = children.length; i < l; i ++ ) { - return this; + children[ i ].traverseVisible( callback ); + + } }, - makeRotationY: function ( theta ) { + traverseAncestors: function ( callback ) { - var c = Math.cos( theta ), s = Math.sin( theta ); + var parent = this.parent; - this.set( + if ( parent !== null ) { - c, 0, s, 0, - 0, 1, 0, 0, - - s, 0, c, 0, - 0, 0, 0, 1 + callback( parent ); - ); + parent.traverseAncestors( callback ); - return this; + } }, - makeRotationZ: function ( theta ) { + updateMatrix: function () { - var c = Math.cos( theta ), s = Math.sin( theta ); + this.matrix.compose( this.position, this.quaternion, this.scale ); - this.set( + this.matrixWorldNeedsUpdate = true; - c, - s, 0, 0, - s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + }, - ); + updateMatrixWorld: function ( force ) { - return this; + if ( this.matrixAutoUpdate ) this.updateMatrix(); - }, + if ( this.matrixWorldNeedsUpdate || force ) { - makeRotationAxis: function ( axis, angle ) { + if ( this.parent === null ) { - // Based on http://www.gamedev.net/reference/articles/article1199.asp + this.matrixWorld.copy( this.matrix ); - var c = Math.cos( angle ); - var s = Math.sin( angle ); - var t = 1 - c; - var x = axis.x, y = axis.y, z = axis.z; - var tx = t * x, ty = t * y; + } else { - this.set( + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - tx * x + c, tx * y - s * z, tx * z + s * y, 0, - tx * y + s * z, ty * y + c, ty * z - s * x, 0, - tx * z - s * y, ty * z + s * x, t * z * z + c, 0, - 0, 0, 0, 1 + } - ); + this.matrixWorldNeedsUpdate = false; - return this; + force = true; - }, + } - makeScale: function ( x, y, z ) { + // update children - this.set( + var children = this.children; - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 + for ( var i = 0, l = children.length; i < l; i ++ ) { - ); + children[ i ].updateMatrixWorld( force ); - return this; + } }, - makeShear: function ( x, y, z ) { + updateWorldMatrix: function ( updateParents, updateChildren ) { - this.set( + var parent = this.parent; - 1, y, z, 0, - x, 1, z, 0, - x, y, 1, 0, - 0, 0, 0, 1 + if ( updateParents === true && parent !== null ) { - ); + parent.updateWorldMatrix( true, false ); - return this; + } - }, + if ( this.matrixAutoUpdate ) this.updateMatrix(); - compose: function ( position, quaternion, scale ) { + if ( this.parent === null ) { - var te = this.elements; + this.matrixWorld.copy( this.matrix ); - var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; - var x2 = x + x, y2 = y + y, z2 = z + z; - var xx = x * x2, xy = x * y2, xz = x * z2; - var yy = y * y2, yz = y * z2, zz = z * z2; - var wx = w * x2, wy = w * y2, wz = w * z2; + } else { - var sx = scale.x, sy = scale.y, sz = scale.z; + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; - te[ 1 ] = ( xy + wz ) * sx; - te[ 2 ] = ( xz - wy ) * sx; - te[ 3 ] = 0; + } - te[ 4 ] = ( xy - wz ) * sy; - te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; - te[ 6 ] = ( yz + wx ) * sy; - te[ 7 ] = 0; + // update children - te[ 8 ] = ( xz + wy ) * sz; - te[ 9 ] = ( yz - wx ) * sz; - te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; - te[ 11 ] = 0; + if ( updateChildren === true ) { - te[ 12 ] = position.x; - te[ 13 ] = position.y; - te[ 14 ] = position.z; - te[ 15 ] = 1; + var children = this.children; - return this; + for ( var i = 0, l = children.length; i < l; i ++ ) { + + children[ i ].updateWorldMatrix( false, true ); + + } + + } }, - decompose: function () { + toJSON: function ( meta ) { - var vector = new Vector3(); - var matrix = new Matrix4(); + // meta is a string when called from JSON.stringify + var isRootObject = ( meta === undefined || typeof meta === 'string' ); - return function decompose( position, quaternion, scale ) { + var output = {}; - var te = this.elements; + // meta is a hash used to collect geometries, materials. + // not providing it implies that this is the root object + // being serialized. + if ( isRootObject ) { - var sx = vector.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); - var sy = vector.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); - var sz = vector.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); + // initialize meta obj + meta = { + geometries: {}, + materials: {}, + textures: {}, + images: {}, + shapes: {} + }; - // if determine is negative, we need to invert one scale - var det = this.determinant(); - if ( det < 0 ) sx = - sx; + output.metadata = { + version: 4.5, + type: 'Object', + generator: 'Object3D.toJSON' + }; - position.x = te[ 12 ]; - position.y = te[ 13 ]; - position.z = te[ 14 ]; + } - // scale the rotation part - matrix.copy( this ); + // standard Object3D serialization - var invSX = 1 / sx; - var invSY = 1 / sy; - var invSZ = 1 / sz; + var object = {}; - matrix.elements[ 0 ] *= invSX; - matrix.elements[ 1 ] *= invSX; - matrix.elements[ 2 ] *= invSX; + object.uuid = this.uuid; + object.type = this.type; - matrix.elements[ 4 ] *= invSY; - matrix.elements[ 5 ] *= invSY; - matrix.elements[ 6 ] *= invSY; + if ( this.name !== '' ) object.name = this.name; + if ( this.castShadow === true ) object.castShadow = true; + if ( this.receiveShadow === true ) object.receiveShadow = true; + if ( this.visible === false ) object.visible = false; + if ( this.frustumCulled === false ) object.frustumCulled = false; + if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; + if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; - matrix.elements[ 8 ] *= invSZ; - matrix.elements[ 9 ] *= invSZ; - matrix.elements[ 10 ] *= invSZ; + object.layers = this.layers.mask; + object.matrix = this.matrix.toArray(); - quaternion.setFromRotationMatrix( matrix ); + if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; - scale.x = sx; - scale.y = sy; - scale.z = sz; + // object specific properties - return this; + if ( this.isMesh && this.drawMode !== TrianglesDrawMode ) object.drawMode = this.drawMode; - }; + // - }(), + function serialize( library, element ) { - makePerspective: function ( left, right, top, bottom, near, far ) { + if ( library[ element.uuid ] === undefined ) { - if ( far === undefined ) { + library[ element.uuid ] = element.toJSON( meta ); - console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); + } - } + return element.uuid; - var te = this.elements; - var x = 2 * near / ( right - left ); - var y = 2 * near / ( top - bottom ); + } - var a = ( right + left ) / ( right - left ); - var b = ( top + bottom ) / ( top - bottom ); - var c = - ( far + near ) / ( far - near ); - var d = - 2 * far * near / ( far - near ); + if ( this.isMesh || this.isLine || this.isPoints ) { - te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; - te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; + object.geometry = serialize( meta.geometries, this.geometry ); - return this; + var parameters = this.geometry.parameters; - }, + if ( parameters !== undefined && parameters.shapes !== undefined ) { - makeOrthographic: function ( left, right, top, bottom, near, far ) { + var shapes = parameters.shapes; - var te = this.elements; - var w = 1.0 / ( right - left ); - var h = 1.0 / ( top - bottom ); - var p = 1.0 / ( far - near ); + if ( Array.isArray( shapes ) ) { - var x = ( right + left ) * w; - var y = ( top + bottom ) * h; - var z = ( far + near ) * p; + for ( var i = 0, l = shapes.length; i < l; i ++ ) { - 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; + var shape = shapes[ i ]; - return this; + serialize( meta.shapes, shape ); - }, + } - equals: function ( matrix ) { + } else { - var te = this.elements; - var me = matrix.elements; + serialize( meta.shapes, shapes ); - for ( var i = 0; i < 16; i ++ ) { + } - if ( te[ i ] !== me[ i ] ) return false; + } } - return true; + if ( this.material !== undefined ) { - }, + if ( Array.isArray( this.material ) ) { - fromArray: function ( array, offset ) { + var uuids = []; - if ( offset === undefined ) offset = 0; + for ( var i = 0, l = this.material.length; i < l; i ++ ) { - for ( var i = 0; i < 16; i ++ ) { + uuids.push( serialize( meta.materials, this.material[ i ] ) ); - this.elements[ i ] = array[ i + offset ]; + } - } + object.material = uuids; - return this; + } else { - }, + object.material = serialize( meta.materials, this.material ); - toArray: function ( array, offset ) { + } - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + } - var te = this.elements; + // - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - array[ offset + 3 ] = te[ 3 ]; + if ( this.children.length > 0 ) { - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; + object.children = []; - array[ offset + 8 ] = te[ 8 ]; - array[ offset + 9 ] = te[ 9 ]; - array[ offset + 10 ] = te[ 10 ]; - array[ offset + 11 ] = te[ 11 ]; + for ( var i = 0; i < this.children.length; i ++ ) { - array[ offset + 12 ] = te[ 12 ]; - array[ offset + 13 ] = te[ 13 ]; - array[ offset + 14 ] = te[ 14 ]; - array[ offset + 15 ] = te[ 15 ]; + object.children.push( this.children[ i ].toJSON( meta ).object ); - return array; + } - } + } - } ); + if ( isRootObject ) { - var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; + var geometries = extractFromCache( meta.geometries ); + var materials = extractFromCache( meta.materials ); + var textures = extractFromCache( meta.textures ); + var images = extractFromCache( meta.images ); + var shapes = extractFromCache( meta.shapes ); - var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; + if ( geometries.length > 0 ) output.geometries = geometries; + if ( materials.length > 0 ) output.materials = materials; + if ( textures.length > 0 ) output.textures = textures; + if ( images.length > 0 ) output.images = images; + if ( shapes.length > 0 ) output.shapes = shapes; - var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; + } - var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; + output.object = object; - var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; + return output; - var begin_vertex = "vec3 transformed = vec3( position );"; + // extract data from the cache hash + // remove metadata on each item + // and return as array + function extractFromCache( cache ) { - var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; + var values = []; + for ( var key in cache ) { - var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn 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\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn 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\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}"; + var data = cache[ key ]; + delete data.metadata; + values.push( data ); - var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; + } + return values; - var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; + } - var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; + }, - var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif"; + clone: function ( recursive ) { - var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; + return new this.constructor().copy( this, recursive ); - var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; + }, - var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; + copy: function ( source, recursive ) { - var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; + if ( recursive === undefined ) recursive = true; - var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; + this.name = source.name; - var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\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\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}"; + this.up.copy( source.up ); - var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn 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\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn 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\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif"; + this.position.copy( source.position ); + this.quaternion.copy( source.quaternion ); + this.scale.copy( source.scale ); - var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; + this.matrix.copy( source.matrix ); + this.matrixWorld.copy( source.matrixWorld ); - var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; + this.matrixAutoUpdate = source.matrixAutoUpdate; + this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif"; + this.layers.mask = source.layers.mask; + this.visible = source.visible; - var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; + this.castShadow = source.castShadow; + this.receiveShadow = source.receiveShadow; - var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; + this.frustumCulled = source.frustumCulled; + this.renderOrder = source.renderOrder; - var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn 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.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn 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.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn 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\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn 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\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; + if ( recursive === true ) { - var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; + for ( var i = 0; i < source.children.length; i ++ ) { - var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; + var child = source.children[ i ]; + this.add( child.clone() ); - var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; + } - var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; + } - var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; + return this; - var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; + } - var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; + } ); - var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; + /** + * @author mrdoob / http://mrdoob.com/ + */ - var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif"; + function Scene() { - var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif"; + Object3D.call( this ); - var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; + this.type = 'Scene'; - var 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 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif"; + this.background = null; + this.fog = null; + this.overrideMaterial = null; - var lights_pars_begin = "uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; + this.autoUpdate = true; // checked by the renderer - var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { - var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef - var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.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\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; + } - var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif"; + } - var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#endif\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\tfloat clearCoatInv = 1.0 - clearCoatDHR;\n\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec3 singleScattering = vec3( 0.0 );\n\t\tvec3 multiScattering = vec3( 0.0 );\n\t\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\t\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;\n\t\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\t\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n\t#else\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#endif\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; + Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { - var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif"; + constructor: Scene, - var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif"; + isScene: true, - var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, irradiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif"; + copy: function ( source, recursive ) { - var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; + Object3D.prototype.copy.call( this, source, recursive ); - var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif"; + if ( source.background !== null ) this.background = source.background.clone(); + if ( source.fog !== null ) this.fog = source.fog.clone(); + if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); - var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; + this.autoUpdate = source.autoUpdate; + this.matrixAutoUpdate = source.matrixAutoUpdate; - var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif"; + return this; - var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; + }, - var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; + toJSON: function ( meta ) { - var map_particle_fragment = "#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif"; + var data = Object3D.prototype.toJSON.call( this, meta ); - var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif"; + if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); + if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); - var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; + return data; - var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; + }, - var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif"; + dispose: function () { - var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; + this.dispatchEvent( { type: 'dispose' } ); - var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; + } - var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif"; + } ); - var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy = normalScale * mapN.xy;\n\t\t\tnormal = normalize( vTBN * mapN );\n\t\t#else\n\t\t\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\t\t#endif\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; + /** + * @author bhouston / http://clara.io + * @author WestLangley / http://github.com/WestLangley + */ - var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif"; + function Box3( min, max ) { - var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\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\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; + this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity ); + this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity ); - var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; + } - var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;"; + Object.assign( Box3.prototype, { - var dithering_fragment = "#if defined( DITHERING )\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; + isBox3: true, - var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; + set: function ( min, max ) { - var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; + this.min.copy( min ); + this.max.copy( max ); - var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; + return this; - var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; + }, - var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif"; + setFromArray: function ( array ) { - var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif"; + var minX = + Infinity; + var minY = + Infinity; + var minZ = + Infinity; - var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}"; + var maxX = - Infinity; + var maxY = - Infinity; + var maxZ = - Infinity; - var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; + for ( var i = 0, l = array.length; i < l; i += 3 ) { - var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; + var x = array[ i ]; + var y = array[ i + 1 ]; + var z = array[ i + 2 ]; - var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; - var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; - var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; + } - var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); - var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; + return this; - var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn 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\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; + }, - var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif"; + setFromBufferAttribute: function ( attribute ) { - var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif"; + var minX = + Infinity; + var minY = + Infinity; + var minZ = + Infinity; - var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; + var maxX = - Infinity; + var maxY = - Infinity; + var maxZ = - Infinity; - var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; + for ( var i = 0, l = attribute.count; i < l; i ++ ) { - var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif"; + var x = attribute.getX( i ); + var y = attribute.getY( i ); + var z = attribute.getZ( i ); - var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif"; + if ( x < minX ) minX = x; + if ( y < minY ) minY = y; + if ( z < minZ ) minZ = z; - var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif"; + if ( x > maxX ) maxX = x; + if ( y > maxY ) maxY = y; + if ( z > maxZ ) maxZ = z; - var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + } - var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; + this.min.set( minX, minY, minZ ); + this.max.set( maxX, maxY, maxZ ); - var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; + return this; - var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}"; + }, - var 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( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}"; + setFromPoints: function ( points ) { - var 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#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\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}"; + this.makeEmpty(); - var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\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#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; + for ( var i = 0, il = points.length; i < il; i ++ ) { - var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\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\tvWorldPosition = worldPosition.xyz;\n}"; + this.expandByPoint( points[ i ] ); - var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + } - var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; + return this; - var 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}"; + }, - var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \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\t#include \n}"; + setFromCenterAndSize: function () { - var 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 \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 = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\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}"; + var v1 = new Vector3(); - var meshbasic_vert = "#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#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\t#include \n}"; + return function setFromCenterAndSize( center, size ) { - var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\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 \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#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\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\t#include \n}"; + var halfSize = v1.copy( size ).multiplyScalar( 0.5 ); - var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\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 \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\t#include \n}"; + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\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 \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\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + return this; - var meshmatcap_vert = "#define MATCAP\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 \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\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\tvViewPosition = - mvPosition.xyz;\n}"; + }; - var 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 \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\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\t#include \n}"; + }(), - var 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 \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\t#include \n}"; + setFromObject: function ( object ) { - var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\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 \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\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\t#include \n}"; + this.makeEmpty(); - var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\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\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\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}"; + return this.expandByObject( object ); - var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; + }, - var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\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#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; + clone: function () { - var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\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}"; + return new this.constructor().copy( this ); - var points_vert = "uniform float size;\nuniform float scale;\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\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + }, - var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}"; + copy: function ( box ) { - var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + this.min.copy( box.min ); + this.max.copy( box.max ); - var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\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\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}"; + return this; - var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; + }, - var ShaderChunk = { - alphamap_fragment: alphamap_fragment, - alphamap_pars_fragment: alphamap_pars_fragment, - alphatest_fragment: alphatest_fragment, - aomap_fragment: aomap_fragment, - aomap_pars_fragment: aomap_pars_fragment, - begin_vertex: begin_vertex, - beginnormal_vertex: beginnormal_vertex, - bsdfs: bsdfs, - bumpmap_pars_fragment: bumpmap_pars_fragment, - clipping_planes_fragment: clipping_planes_fragment, - clipping_planes_pars_fragment: clipping_planes_pars_fragment, - clipping_planes_pars_vertex: clipping_planes_pars_vertex, - clipping_planes_vertex: clipping_planes_vertex, - color_fragment: color_fragment, - color_pars_fragment: color_pars_fragment, - color_pars_vertex: color_pars_vertex, - color_vertex: color_vertex, - common: common, - cube_uv_reflection_fragment: cube_uv_reflection_fragment, - defaultnormal_vertex: defaultnormal_vertex, - displacementmap_pars_vertex: displacementmap_pars_vertex, - displacementmap_vertex: displacementmap_vertex, - emissivemap_fragment: emissivemap_fragment, - emissivemap_pars_fragment: emissivemap_pars_fragment, - encodings_fragment: encodings_fragment, - encodings_pars_fragment: encodings_pars_fragment, - envmap_fragment: envmap_fragment, - envmap_pars_fragment: envmap_pars_fragment, - envmap_pars_vertex: envmap_pars_vertex, - envmap_physical_pars_fragment: envmap_physical_pars_fragment, - envmap_vertex: envmap_vertex, - fog_vertex: fog_vertex, - fog_pars_vertex: fog_pars_vertex, - fog_fragment: fog_fragment, - fog_pars_fragment: fog_pars_fragment, - gradientmap_pars_fragment: gradientmap_pars_fragment, - lightmap_fragment: lightmap_fragment, - lightmap_pars_fragment: lightmap_pars_fragment, - lights_lambert_vertex: lights_lambert_vertex, - lights_pars_begin: lights_pars_begin, - lights_phong_fragment: lights_phong_fragment, - lights_phong_pars_fragment: lights_phong_pars_fragment, - lights_physical_fragment: lights_physical_fragment, - lights_physical_pars_fragment: lights_physical_pars_fragment, - lights_fragment_begin: lights_fragment_begin, - lights_fragment_maps: lights_fragment_maps, - lights_fragment_end: lights_fragment_end, - logdepthbuf_fragment: logdepthbuf_fragment, - logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, - logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, - logdepthbuf_vertex: logdepthbuf_vertex, - map_fragment: map_fragment, - map_pars_fragment: map_pars_fragment, - map_particle_fragment: map_particle_fragment, - map_particle_pars_fragment: map_particle_pars_fragment, - metalnessmap_fragment: metalnessmap_fragment, - metalnessmap_pars_fragment: metalnessmap_pars_fragment, - morphnormal_vertex: morphnormal_vertex, - morphtarget_pars_vertex: morphtarget_pars_vertex, - morphtarget_vertex: morphtarget_vertex, - normal_fragment_begin: normal_fragment_begin, - normal_fragment_maps: normal_fragment_maps, - normalmap_pars_fragment: normalmap_pars_fragment, - packing: packing, - premultiplied_alpha_fragment: premultiplied_alpha_fragment, - project_vertex: project_vertex, - dithering_fragment: dithering_fragment, - dithering_pars_fragment: dithering_pars_fragment, - roughnessmap_fragment: roughnessmap_fragment, - roughnessmap_pars_fragment: roughnessmap_pars_fragment, - shadowmap_pars_fragment: shadowmap_pars_fragment, - shadowmap_pars_vertex: shadowmap_pars_vertex, - shadowmap_vertex: shadowmap_vertex, - shadowmask_pars_fragment: shadowmask_pars_fragment, - skinbase_vertex: skinbase_vertex, - skinning_pars_vertex: skinning_pars_vertex, - skinning_vertex: skinning_vertex, - skinnormal_vertex: skinnormal_vertex, - specularmap_fragment: specularmap_fragment, - specularmap_pars_fragment: specularmap_pars_fragment, - tonemapping_fragment: tonemapping_fragment, - tonemapping_pars_fragment: tonemapping_pars_fragment, - uv_pars_fragment: uv_pars_fragment, - uv_pars_vertex: uv_pars_vertex, - uv_vertex: uv_vertex, - uv2_pars_fragment: uv2_pars_fragment, - uv2_pars_vertex: uv2_pars_vertex, - uv2_vertex: uv2_vertex, - worldpos_vertex: worldpos_vertex, + makeEmpty: function () { - background_frag: background_frag, - background_vert: background_vert, - cube_frag: cube_frag, - cube_vert: cube_vert, - depth_frag: depth_frag, - depth_vert: depth_vert, - distanceRGBA_frag: distanceRGBA_frag, - distanceRGBA_vert: distanceRGBA_vert, - equirect_frag: equirect_frag, - equirect_vert: equirect_vert, - linedashed_frag: linedashed_frag, - linedashed_vert: linedashed_vert, - meshbasic_frag: meshbasic_frag, - meshbasic_vert: meshbasic_vert, - meshlambert_frag: meshlambert_frag, - meshlambert_vert: meshlambert_vert, - meshmatcap_frag: meshmatcap_frag, - meshmatcap_vert: meshmatcap_vert, - meshphong_frag: meshphong_frag, - meshphong_vert: meshphong_vert, - meshphysical_frag: meshphysical_frag, - meshphysical_vert: meshphysical_vert, - normal_frag: normal_frag, - normal_vert: normal_vert, - points_frag: points_frag, - points_vert: points_vert, - shadow_frag: shadow_frag, - shadow_vert: shadow_vert, - sprite_frag: sprite_frag, - sprite_vert: sprite_vert - }; + this.min.x = this.min.y = this.min.z = + Infinity; + this.max.x = this.max.y = this.max.z = - Infinity; - /** - * Uniform Utilities - */ + return this; - function cloneUniforms( src ) { + }, - var dst = {}; + isEmpty: function () { - for ( var u in src ) { + // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes - dst[ u ] = {}; + return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); - for ( var p in src[ u ] ) { + }, - var property = src[ u ][ p ]; + getCenter: function ( target ) { - if ( property && ( property.isColor || - property.isMatrix3 || property.isMatrix4 || - property.isVector2 || property.isVector3 || property.isVector4 || - property.isTexture ) ) { + if ( target === undefined ) { - dst[ u ][ p ] = property.clone(); + console.warn( 'THREE.Box3: .getCenter() target is now required' ); + target = new Vector3(); - } else if ( Array.isArray( property ) ) { + } - dst[ u ][ p ] = property.slice(); + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); - } else { + }, - dst[ u ][ p ] = property; + getSize: function ( target ) { - } + if ( target === undefined ) { + + console.warn( 'THREE.Box3: .getSize() target is now required' ); + target = new Vector3(); } - } + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); - return dst; + }, - } + expandByPoint: function ( point ) { - function mergeUniforms( uniforms ) { + this.min.min( point ); + this.max.max( point ); - var merged = {}; + return this; - for ( var u = 0; u < uniforms.length; u ++ ) { + }, - var tmp = cloneUniforms( uniforms[ u ] ); + expandByVector: function ( vector ) { - for ( var p in tmp ) { + this.min.sub( vector ); + this.max.add( vector ); - merged[ p ] = tmp[ p ]; + return this; - } + }, - } + expandByScalar: function ( scalar ) { - return merged; + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); - } + return this; - // Legacy + }, - var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; + expandByObject: function () { - /** - * @author mrdoob / http://mrdoob.com/ - */ + // 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 ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, - 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, - 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, - 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, - 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, - 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, - 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, - 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, - 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, - 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, - 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, - 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, - 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, - 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, - 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, - 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, - 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, - 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, - 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, - 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, - 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, - 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, - 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, - 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; + var scope, i, l; - function Color( r, g, b ) { + var v1 = new Vector3(); - if ( g === undefined && b === undefined ) { + function traverse( node ) { - // r is THREE.Color, hex or string - return this.set( r ); + var geometry = node.geometry; - } + if ( geometry !== undefined ) { - return this.setRGB( r, g, b ); + if ( geometry.isGeometry ) { - } + var vertices = geometry.vertices; - Object.assign( Color.prototype, { + for ( i = 0, l = vertices.length; i < l; i ++ ) { - isColor: true, + v1.copy( vertices[ i ] ); + v1.applyMatrix4( node.matrixWorld ); - r: 1, g: 1, b: 1, + scope.expandByPoint( v1 ); - set: function ( value ) { + } - if ( value && value.isColor ) { + } else if ( geometry.isBufferGeometry ) { - this.copy( value ); + var attribute = geometry.attributes.position; - } else if ( typeof value === 'number' ) { + if ( attribute !== undefined ) { - this.setHex( value ); + for ( i = 0, l = attribute.count; i < l; i ++ ) { - } else if ( typeof value === 'string' ) { + v1.fromBufferAttribute( attribute, i ).applyMatrix4( node.matrixWorld ); - this.setStyle( value ); + scope.expandByPoint( v1 ); - } + } - return this; + } - }, + } - setScalar: function ( scalar ) { + } - this.r = scalar; - this.g = scalar; - this.b = scalar; + } - return this; + return function expandByObject( object ) { - }, + scope = this; - setHex: function ( hex ) { + object.updateMatrixWorld( true ); - hex = Math.floor( hex ); + object.traverse( traverse ); - this.r = ( hex >> 16 & 255 ) / 255; - this.g = ( hex >> 8 & 255 ) / 255; - this.b = ( hex & 255 ) / 255; + return this; - return this; + }; - }, + }(), - setRGB: function ( r, g, b ) { + containsPoint: function ( point ) { - this.r = r; - this.g = g; - this.b = b; + return point.x < this.min.x || point.x > this.max.x || + point.y < this.min.y || point.y > this.max.y || + point.z < this.min.z || point.z > this.max.z ? false : true; - return this; + }, + + containsBox: function ( box ) { + + return this.min.x <= box.min.x && box.max.x <= this.max.x && + this.min.y <= box.min.y && box.max.y <= this.max.y && + this.min.z <= box.min.z && box.max.z <= this.max.z; }, - setHSL: function () { + getParameter: function ( point, target ) { + + // This can potentially have a divide by zero if the box + // has a size dimension of 0. - function hue2rgb( p, q, t ) { + if ( target === undefined ) { - if ( t < 0 ) t += 1; - if ( t > 1 ) t -= 1; - if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; - if ( t < 1 / 2 ) return q; - if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); - return p; + console.warn( 'THREE.Box3: .getParameter() target is now required' ); + target = new Vector3(); } - return function setHSL( h, s, l ) { + return target.set( + ( point.x - this.min.x ) / ( this.max.x - this.min.x ), + ( point.y - this.min.y ) / ( this.max.y - this.min.y ), + ( point.z - this.min.z ) / ( this.max.z - this.min.z ) + ); + + }, - // h,s,l ranges are in 0.0 - 1.0 - h = _Math.euclideanModulo( h, 1 ); - s = _Math.clamp( s, 0, 1 ); - l = _Math.clamp( l, 0, 1 ); + intersectsBox: function ( box ) { - if ( s === 0 ) { + // using 6 splitting planes to rule out intersections. + return box.max.x < this.min.x || box.min.x > this.max.x || + box.max.y < this.min.y || box.min.y > this.max.y || + box.max.z < this.min.z || box.min.z > this.max.z ? false : true; - this.r = this.g = this.b = l; + }, - } else { + intersectsSphere: ( function () { - var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); - var q = ( 2 * l ) - p; + var closestPoint = new Vector3(); - this.r = hue2rgb( q, p, h + 1 / 3 ); - this.g = hue2rgb( q, p, h ); - this.b = hue2rgb( q, p, h - 1 / 3 ); + return function intersectsSphere( sphere ) { - } + // Find the point on the AABB closest to the sphere center. + this.clampPoint( sphere.center, closestPoint ); - return this; + // If that point is inside the sphere, the AABB and sphere intersect. + return closestPoint.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); }; - }(), + } )(), - setStyle: function ( style ) { + intersectsPlane: function ( plane ) { - function handleAlpha( string ) { + // We compute the minimum and maximum dot product values. If those values + // are on the same side (back or front) of the plane, then there is no intersection. - if ( string === undefined ) return; + var min, max; - if ( parseFloat( string ) < 1 ) { + if ( plane.normal.x > 0 ) { - console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); + min = plane.normal.x * this.min.x; + max = plane.normal.x * this.max.x; - } + } else { - } + min = plane.normal.x * this.max.x; + max = plane.normal.x * this.min.x; + } - var m; + if ( plane.normal.y > 0 ) { - if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { + min += plane.normal.y * this.min.y; + max += plane.normal.y * this.max.y; - // rgb / hsl + } else { - var color; - var name = m[ 1 ]; - var components = m[ 2 ]; + min += plane.normal.y * this.max.y; + max += plane.normal.y * this.min.y; - switch ( name ) { + } - case 'rgb': - case 'rgba': + if ( plane.normal.z > 0 ) { - if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { + min += plane.normal.z * this.min.z; + max += plane.normal.z * this.max.z; - // rgb(255,0,0) rgba(255,0,0,0.5) - this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; - this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; - this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; + } else { - handleAlpha( color[ 5 ] ); + min += plane.normal.z * this.max.z; + max += plane.normal.z * this.min.z; - return this; + } - } + return ( min <= - plane.constant && max >= - plane.constant ); - if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { + }, - // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) - this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; - this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; - this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; + intersectsTriangle: ( function () { - handleAlpha( color[ 5 ] ); + // triangle centered vertices + var v0 = new Vector3(); + var v1 = new Vector3(); + var v2 = new Vector3(); - return this; + // triangle edge vectors + var f0 = new Vector3(); + var f1 = new Vector3(); + var f2 = new Vector3(); - } + var testAxis = new Vector3(); - break; + var center = new Vector3(); + var extents = new Vector3(); - case 'hsl': - case 'hsla': + var triangleNormal = new Vector3(); - if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { + function satForAxes( axes ) { - // hsl(120,50%,50%) hsla(120,50%,50%,0.5) - var h = parseFloat( color[ 1 ] ) / 360; - var s = parseInt( color[ 2 ], 10 ) / 100; - var l = parseInt( color[ 3 ], 10 ) / 100; + var i, j; - handleAlpha( color[ 5 ] ); + for ( i = 0, j = axes.length - 3; i <= j; i += 3 ) { - return this.setHSL( h, s, l ); + testAxis.fromArray( axes, i ); + // project the aabb onto the seperating axis + var r = extents.x * Math.abs( testAxis.x ) + extents.y * Math.abs( testAxis.y ) + extents.z * Math.abs( testAxis.z ); + // project all 3 vertices of the triangle onto the seperating axis + var p0 = v0.dot( testAxis ); + var p1 = v1.dot( testAxis ); + var p2 = v2.dot( testAxis ); + // actual test, basically see if either of the most extreme of the triangle points intersects r + if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { - } + // points of the projected triangle are outside the projected half-length of the aabb + // the axis is seperating and we can exit + return false; - break; + } } - } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { + return true; - // hex color + } - var hex = m[ 1 ]; - var size = hex.length; + return function intersectsTriangle( triangle ) { - if ( size === 3 ) { + if ( this.isEmpty() ) { - // #ff0 - this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; - this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; - this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; + return false; - return this; + } - } else if ( size === 6 ) { + // compute box center and extents + this.getCenter( center ); + extents.subVectors( this.max, center ); - // #ff0000 - this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; - this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; - this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; + // translate triangle to aabb origin + v0.subVectors( triangle.a, center ); + v1.subVectors( triangle.b, center ); + v2.subVectors( triangle.c, center ); - return this; + // compute edge vectors for triangle + f0.subVectors( v1, v0 ); + f1.subVectors( v2, v1 ); + f2.subVectors( v0, v2 ); + + // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation + // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) + var axes = [ + 0, - f0.z, f0.y, 0, - f1.z, f1.y, 0, - f2.z, f2.y, + f0.z, 0, - f0.x, f1.z, 0, - f1.x, f2.z, 0, - f2.x, + - f0.y, f0.x, 0, - f1.y, f1.x, 0, - f2.y, f2.x, 0 + ]; + if ( ! satForAxes( axes ) ) { + + return false; } - } + // test 3 face normals from the aabb + axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; + if ( ! satForAxes( axes ) ) { - if ( style && style.length > 0 ) { + return false; - // color keywords - var hex = ColorKeywords[ style ]; + } - if ( hex !== undefined ) { + // finally testing the face normal of the triangle + // use already existing triangle edge vectors here + triangleNormal.crossVectors( f0, f1 ); + axes = [ triangleNormal.x, triangleNormal.y, triangleNormal.z ]; + return satForAxes( axes ); - // red - this.setHex( hex ); + }; - } else { + } )(), - // unknown color - console.warn( 'THREE.Color: Unknown color ' + style ); + clampPoint: function ( point, target ) { - } + if ( target === undefined ) { + + console.warn( 'THREE.Box3: .clampPoint() target is now required' ); + target = new Vector3(); } - return this; + return target.copy( point ).clamp( this.min, this.max ); }, - clone: function () { + distanceToPoint: function () { - return new this.constructor( this.r, this.g, this.b ); + var v1 = new Vector3(); - }, + return function distanceToPoint( point ) { - copy: function ( color ) { + var clampedPoint = v1.copy( point ).clamp( this.min, this.max ); + return clampedPoint.sub( point ).length(); - this.r = color.r; - this.g = color.g; - this.b = color.b; + }; - return this; + }(), - }, + getBoundingSphere: function () { - copyGammaToLinear: function ( color, gammaFactor ) { + var v1 = new Vector3(); - if ( gammaFactor === undefined ) gammaFactor = 2.0; + return function getBoundingSphere( target ) { - this.r = Math.pow( color.r, gammaFactor ); - this.g = Math.pow( color.g, gammaFactor ); - this.b = Math.pow( color.b, gammaFactor ); + if ( target === undefined ) { - return this; + console.error( 'THREE.Box3: .getBoundingSphere() target is now required' ); + //target = new Sphere(); // removed to avoid cyclic dependency - }, + } - copyLinearToGamma: function ( color, gammaFactor ) { + this.getCenter( target.center ); - if ( gammaFactor === undefined ) gammaFactor = 2.0; + target.radius = this.getSize( v1 ).length() * 0.5; - var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; + return target; - this.r = Math.pow( color.r, safeInverse ); - this.g = Math.pow( color.g, safeInverse ); - this.b = Math.pow( color.b, safeInverse ); + }; - return this; + }(), - }, + intersect: function ( box ) { - convertGammaToLinear: function ( gammaFactor ) { + this.min.max( box.min ); + this.max.min( box.max ); - this.copyGammaToLinear( this, gammaFactor ); + // 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; }, - convertLinearToGamma: function ( gammaFactor ) { + union: function ( box ) { - this.copyLinearToGamma( this, gammaFactor ); + this.min.min( box.min ); + this.max.max( box.max ); return this; }, - copySRGBToLinear: function () { + applyMatrix4: function () { - function SRGBToLinear( c ) { + var points = [ + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3(), + new Vector3() + ]; - return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); + return function applyMatrix4( matrix ) { - } + // transform of empty box is an empty box. + if ( this.isEmpty() ) return this; - return function copySRGBToLinear( color ) { + // 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 + points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 + points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 + points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 + points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 + 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.r = SRGBToLinear( color.r ); - this.g = SRGBToLinear( color.g ); - this.b = SRGBToLinear( color.b ); + this.setFromPoints( points ); return this; @@ -6789,5665 +6773,6060 @@ }(), - copyLinearToSRGB: function () { + translate: function ( offset ) { - function LinearToSRGB( c ) { + this.min.add( offset ); + this.max.add( offset ); - return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; + return this; - } + }, - return function copyLinearToSRGB( color ) { + equals: function ( box ) { - this.r = LinearToSRGB( color.r ); - this.g = LinearToSRGB( color.g ); - this.b = LinearToSRGB( color.b ); + return box.min.equals( this.min ) && box.max.equals( this.max ); - return this; + } - }; + } ); - }(), + /** + * @author bhouston / http://clara.io + * @author mrdoob / http://mrdoob.com/ + */ - convertSRGBToLinear: function () { + function Sphere( center, radius ) { - this.copySRGBToLinear( this ); + this.center = ( center !== undefined ) ? center : new Vector3(); + this.radius = ( radius !== undefined ) ? radius : 0; - return this; + } - }, + Object.assign( Sphere.prototype, { - convertLinearToSRGB: function () { + set: function ( center, radius ) { - this.copyLinearToSRGB( this ); + this.center.copy( center ); + this.radius = radius; return this; }, - getHex: function () { + setFromPoints: function () { - return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; + var box = new Box3(); - }, + return function setFromPoints( points, optionalCenter ) { - getHexString: function () { + var center = this.center; - return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); + if ( optionalCenter !== undefined ) { - }, + center.copy( optionalCenter ); - getHSL: function ( target ) { + } else { - // h,s,l ranges are in 0.0 - 1.0 + box.setFromPoints( points ).getCenter( center ); - if ( target === undefined ) { + } - console.warn( 'THREE.Color: .getHSL() target is now required' ); - target = { h: 0, s: 0, l: 0 }; + var maxRadiusSq = 0; - } + for ( var i = 0, il = points.length; i < il; i ++ ) { - var r = this.r, g = this.g, b = this.b; + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); - var max = Math.max( r, g, b ); - var min = Math.min( r, g, b ); + } - var hue, saturation; - var lightness = ( min + max ) / 2.0; + this.radius = Math.sqrt( maxRadiusSq ); - if ( min === max ) { + return this; - hue = 0; - saturation = 0; + }; - } else { + }(), - var delta = max - min; + clone: function () { - saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); + return new this.constructor().copy( this ); - switch ( max ) { + }, - case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; - case g: hue = ( b - r ) / delta + 2; break; - case b: hue = ( r - g ) / delta + 4; break; + copy: function ( sphere ) { - } + this.center.copy( sphere.center ); + this.radius = sphere.radius; - hue /= 6; + return this; - } + }, - target.h = hue; - target.s = saturation; - target.l = lightness; + empty: function () { - return target; + return ( this.radius <= 0 ); }, - getStyle: function () { + containsPoint: function ( point ) { - return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; + return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); }, - offsetHSL: function () { + distanceToPoint: function ( point ) { - var hsl = {}; + return ( point.distanceTo( this.center ) - this.radius ); - return function ( h, s, l ) { + }, - this.getHSL( hsl ); + intersectsSphere: function ( sphere ) { - hsl.h += h; hsl.s += s; hsl.l += l; + var radiusSum = this.radius + sphere.radius; - this.setHSL( hsl.h, hsl.s, hsl.l ); + return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); - return this; + }, - }; + intersectsBox: function ( box ) { - }(), + return box.intersectsSphere( this ); - add: function ( color ) { + }, - this.r += color.r; - this.g += color.g; - this.b += color.b; + intersectsPlane: function ( plane ) { - return this; + return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; }, - addColors: function ( color1, color2 ) { - - this.r = color1.r + color2.r; - this.g = color1.g + color2.g; - this.b = color1.b + color2.b; + clampPoint: function ( point, target ) { - return this; + var deltaLengthSq = this.center.distanceToSquared( point ); - }, + if ( target === undefined ) { - addScalar: function ( s ) { + console.warn( 'THREE.Sphere: .clampPoint() target is now required' ); + target = new Vector3(); - this.r += s; - this.g += s; - this.b += s; + } - return this; + target.copy( point ); - }, + if ( deltaLengthSq > ( this.radius * this.radius ) ) { - sub: function ( color ) { + target.sub( this.center ).normalize(); + target.multiplyScalar( this.radius ).add( this.center ); - this.r = Math.max( 0, this.r - color.r ); - this.g = Math.max( 0, this.g - color.g ); - this.b = Math.max( 0, this.b - color.b ); + } - return this; + return target; }, - multiply: function ( color ) { + getBoundingBox: function ( target ) { - this.r *= color.r; - this.g *= color.g; - this.b *= color.b; + if ( target === undefined ) { - return this; + console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' ); + target = new Box3(); + + } + + target.set( this.center, this.center ); + target.expandByScalar( this.radius ); + + return target; }, - multiplyScalar: function ( s ) { + applyMatrix4: function ( matrix ) { - this.r *= s; - this.g *= s; - this.b *= s; + this.center.applyMatrix4( matrix ); + this.radius = this.radius * matrix.getMaxScaleOnAxis(); return this; }, - lerp: function ( color, alpha ) { + translate: function ( offset ) { - this.r += ( color.r - this.r ) * alpha; - this.g += ( color.g - this.g ) * alpha; - this.b += ( color.b - this.b ) * alpha; + this.center.add( offset ); return this; }, - lerpHSL: function () { + equals: function ( sphere ) { - var hslA = { h: 0, s: 0, l: 0 }; - var hslB = { h: 0, s: 0, l: 0 }; + return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); - return function lerpHSL( color, alpha ) { + } - this.getHSL( hslA ); - color.getHSL( hslB ); + } ); - var h = _Math.lerp( hslA.h, hslB.h, alpha ); - var s = _Math.lerp( hslA.s, hslB.s, alpha ); - var l = _Math.lerp( hslA.l, hslB.l, alpha ); + /** + * @author bhouston / http://clara.io + */ - this.setHSL( h, s, l ); + function Ray( origin, direction ) { - return this; + this.origin = ( origin !== undefined ) ? origin : new Vector3(); + this.direction = ( direction !== undefined ) ? direction : new Vector3(); - }; + } - }(), + Object.assign( Ray.prototype, { - equals: function ( c ) { + set: function ( origin, direction ) { - return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); + this.origin.copy( origin ); + this.direction.copy( direction ); + + return this; }, - fromArray: function ( array, offset ) { + clone: function () { - if ( offset === undefined ) offset = 0; + return new this.constructor().copy( this ); - this.r = array[ offset ]; - this.g = array[ offset + 1 ]; - this.b = array[ offset + 2 ]; + }, + + copy: function ( ray ) { + + this.origin.copy( ray.origin ); + this.direction.copy( ray.direction ); return this; }, - toArray: function ( array, offset ) { + at: function ( t, target ) { - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + if ( target === undefined ) { - array[ offset ] = this.r; - array[ offset + 1 ] = this.g; - array[ offset + 2 ] = this.b; + console.warn( 'THREE.Ray: .at() target is now required' ); + target = new Vector3(); - return array; + } - }, + return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); - toJSON: function () { + }, - return this.getHex(); + lookAt: function ( v ) { - } + this.direction.copy( v ).sub( this.origin ).normalize(); - } ); + return this; - /** - * Uniforms library for shared webgl shaders - */ + }, - var UniformsLib = { + recast: function () { - common: { + var v1 = new Vector3(); - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, + return function recast( t ) { - map: { value: null }, - uvTransform: { value: new Matrix3() }, + this.origin.copy( this.at( t, v1 ) ); - alphaMap: { value: null }, + return this; - }, + }; - specularmap: { + }(), - specularMap: { value: null }, + closestPointToPoint: function ( point, target ) { - }, + if ( target === undefined ) { - envmap: { + console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' ); + target = new Vector3(); - envMap: { value: null }, - flipEnvMap: { value: - 1 }, - reflectivity: { value: 1.0 }, - refractionRatio: { value: 0.98 }, - maxMipLevel: { value: 0 } + } - }, + target.subVectors( point, this.origin ); - aomap: { + var directionDistance = target.dot( this.direction ); - aoMap: { value: null }, - aoMapIntensity: { value: 1 } + if ( directionDistance < 0 ) { - }, + return target.copy( this.origin ); - lightmap: { + } - lightMap: { value: null }, - lightMapIntensity: { value: 1 } + return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); }, - emissivemap: { + distanceToPoint: function ( point ) { - emissiveMap: { value: null } + return Math.sqrt( this.distanceSqToPoint( point ) ); }, - bumpmap: { - - bumpMap: { value: null }, - bumpScale: { value: 1 } + distanceSqToPoint: function () { - }, + var v1 = new Vector3(); - normalmap: { + return function distanceSqToPoint( point ) { - normalMap: { value: null }, - normalScale: { value: new Vector2( 1, 1 ) } + var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction ); - }, + // point behind the ray - displacementmap: { + if ( directionDistance < 0 ) { - displacementMap: { value: null }, - displacementScale: { value: 1 }, - displacementBias: { value: 0 } + return this.origin.distanceToSquared( point ); - }, + } - roughnessmap: { + v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); - roughnessMap: { value: null } + return v1.distanceToSquared( point ); - }, + }; - metalnessmap: { + }(), - metalnessMap: { value: null } + distanceSqToSegment: function () { - }, + var segCenter = new Vector3(); + var segDir = new Vector3(); + var diff = new Vector3(); - gradientmap: { + return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - gradientMap: { value: null } + // 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 : + // - The closest point on the ray + // - The closest point on the segment - }, + segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); + segDir.copy( v1 ).sub( v0 ).normalize(); + diff.copy( this.origin ).sub( segCenter ); - fog: { + var segExtent = v0.distanceTo( v1 ) * 0.5; + var a01 = - this.direction.dot( segDir ); + var b0 = diff.dot( this.direction ); + var b1 = - diff.dot( segDir ); + var c = diff.lengthSq(); + var det = Math.abs( 1 - a01 * a01 ); + var s0, s1, sqrDist, extDet; - fogDensity: { value: 0.00025 }, - fogNear: { value: 1 }, - fogFar: { value: 2000 }, - fogColor: { value: new Color( 0xffffff ) } + if ( det > 0 ) { - }, + // The ray and segment are not parallel. - lights: { + s0 = a01 * b1 - b0; + s1 = a01 * b0 - b1; + extDet = segExtent * det; - ambientLightColor: { value: [] }, + if ( s0 >= 0 ) { - lightProbe: { value: [] }, + if ( s1 >= - extDet ) { - directionalLights: { value: [], properties: { - direction: {}, - color: {}, + if ( s1 <= extDet ) { - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, + // region 0 + // Minimum at interior points of ray and segment. - directionalShadowMap: { value: [] }, - directionalShadowMatrix: { value: [] }, + var invDet = 1 / det; + s0 *= invDet; + s1 *= invDet; + sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; - spotLights: { value: [], properties: { - color: {}, - position: {}, - direction: {}, - distance: {}, - coneCos: {}, - penumbraCos: {}, - decay: {}, + } else { - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {} - } }, + // region 1 - spotShadowMap: { value: [] }, - spotShadowMatrix: { value: [] }, + s1 = segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - pointLights: { value: [], properties: { - color: {}, - position: {}, - decay: {}, - distance: {}, + } - shadow: {}, - shadowBias: {}, - shadowRadius: {}, - shadowMapSize: {}, - shadowCameraNear: {}, - shadowCameraFar: {} - } }, + } else { - pointShadowMap: { value: [] }, - pointShadowMatrix: { value: [] }, + // region 5 - hemisphereLights: { value: [], properties: { - direction: {}, - skyColor: {}, - groundColor: {} - } }, + s1 = - segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src - rectAreaLights: { value: [], properties: { - color: {}, - position: {}, - width: {}, - height: {} - } } + } - }, + } else { - points: { + if ( s1 <= - extDet ) { - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - size: { value: 1.0 }, - scale: { value: 1.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } + // region 4 - }, + s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - sprite: { + } else if ( s1 <= extDet ) { - diffuse: { value: new Color( 0xeeeeee ) }, - opacity: { value: 1.0 }, - center: { value: new Vector2( 0.5, 0.5 ) }, - rotation: { value: 0.0 }, - map: { value: null }, - uvTransform: { value: new Matrix3() } + // region 3 - } + s0 = 0; + s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = s1 * ( s1 + 2 * b1 ) + c; - }; + } else { - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - */ + // region 2 - var ShaderLib = { + s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - basic: { + } - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.fog - ] ), + } - vertexShader: ShaderChunk.meshbasic_vert, - fragmentShader: ShaderChunk.meshbasic_frag + } else { - }, + // Ray and segment are parallel. - lambert: { + s1 = ( a01 > 0 ) ? - segExtent : segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) } } - ] ), - vertexShader: ShaderChunk.meshlambert_vert, - fragmentShader: ShaderChunk.meshlambert_frag + if ( optionalPointOnRay ) { - }, + optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); - phong: { + } + + if ( optionalPointOnSegment ) { + + optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter ); - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.specularmap, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.gradientmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - specular: { value: new Color( 0x111111 ) }, - shininess: { value: 30 } } - ] ), - vertexShader: ShaderChunk.meshphong_vert, - fragmentShader: ShaderChunk.meshphong_frag + return sqrDist; - }, + }; - standard: { + }(), - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.envmap, - UniformsLib.aomap, - UniformsLib.lightmap, - UniformsLib.emissivemap, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.roughnessmap, - UniformsLib.metalnessmap, - UniformsLib.fog, - UniformsLib.lights, - { - emissive: { value: new Color( 0x000000 ) }, - roughness: { value: 0.5 }, - metalness: { value: 0.5 }, - envMapIntensity: { value: 1 } // temporary - } - ] ), + intersectSphere: function () { - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag + var v1 = new Vector3(); - }, + return function intersectSphere( sphere, target ) { - matcap: { + v1.subVectors( sphere.center, this.origin ); + var tca = v1.dot( this.direction ); + var d2 = v1.dot( v1 ) - tca * tca; + var radius2 = sphere.radius * sphere.radius; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - UniformsLib.fog, - { - matcap: { value: null } - } - ] ), + if ( d2 > radius2 ) return null; - vertexShader: ShaderChunk.meshmatcap_vert, - fragmentShader: ShaderChunk.meshmatcap_frag + var thc = Math.sqrt( radius2 - d2 ); - }, + // t0 = first intersect point - entrance on front of sphere + var t0 = tca - thc; - points: { + // t1 = second intersect point - exit point on back of sphere + var t1 = tca + thc; - uniforms: mergeUniforms( [ - UniformsLib.points, - UniformsLib.fog - ] ), + // test to see if both t0 and t1 are behind the ray - if so, return null + if ( t0 < 0 && t1 < 0 ) return null; - vertexShader: ShaderChunk.points_vert, - fragmentShader: ShaderChunk.points_frag + // test to see if t0 is behind the ray: + // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, + // in order to always return an intersect point that is in front of the ray. + if ( t0 < 0 ) return this.at( t1, target ); - }, + // else t0 is in front of the ray, so return the first collision point scaled by t0 + return this.at( t0, target ); - dashed: { + }; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.fog, - { - scale: { value: 1 }, - dashSize: { value: 1 }, - totalSize: { value: 2 } - } - ] ), + }(), - vertexShader: ShaderChunk.linedashed_vert, - fragmentShader: ShaderChunk.linedashed_frag + intersectsSphere: function ( sphere ) { + + return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); }, - depth: { + distanceToPlane: function ( plane ) { - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.displacementmap - ] ), + var denominator = plane.normal.dot( this.direction ); - vertexShader: ShaderChunk.depth_vert, - fragmentShader: ShaderChunk.depth_frag + if ( denominator === 0 ) { - }, + // line is coplanar, return origin + if ( plane.distanceToPoint( this.origin ) === 0 ) { - normal: { + return 0; - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.bumpmap, - UniformsLib.normalmap, - UniformsLib.displacementmap, - { - opacity: { value: 1.0 } } - ] ), - vertexShader: ShaderChunk.normal_vert, - fragmentShader: ShaderChunk.normal_frag - - }, - - sprite: { - - uniforms: mergeUniforms( [ - UniformsLib.sprite, - UniformsLib.fog - ] ), + // Null is preferable to undefined since undefined means.... it is undefined - vertexShader: ShaderChunk.sprite_vert, - fragmentShader: ShaderChunk.sprite_frag + return null; - }, + } - background: { + var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; - uniforms: { - uvTransform: { value: new Matrix3() }, - t2D: { value: null }, - }, + // Return if the ray never intersects the plane - vertexShader: ShaderChunk.background_vert, - fragmentShader: ShaderChunk.background_frag + return t >= 0 ? t : null; }, - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ - - cube: { - uniforms: { - tCube: { value: null }, - tFlip: { value: - 1 }, - opacity: { value: 1.0 } - }, + intersectPlane: function ( plane, target ) { - vertexShader: ShaderChunk.cube_vert, - fragmentShader: ShaderChunk.cube_frag + var t = this.distanceToPlane( plane ); - }, + if ( t === null ) { - equirect: { + return null; - uniforms: { - tEquirect: { value: null }, - }, + } - vertexShader: ShaderChunk.equirect_vert, - fragmentShader: ShaderChunk.equirect_frag + return this.at( t, target ); }, - distanceRGBA: { - - uniforms: mergeUniforms( [ - UniformsLib.common, - UniformsLib.displacementmap, - { - referencePosition: { value: new Vector3() }, - nearDistance: { value: 1 }, - farDistance: { value: 1000 } - } - ] ), + intersectsPlane: function ( plane ) { - vertexShader: ShaderChunk.distanceRGBA_vert, - fragmentShader: ShaderChunk.distanceRGBA_frag + // check if the ray lies on the plane first - }, + var distToPoint = plane.distanceToPoint( this.origin ); - shadow: { + if ( distToPoint === 0 ) { - uniforms: mergeUniforms( [ - UniformsLib.lights, - UniformsLib.fog, - { - color: { value: new Color( 0x00000 ) }, - opacity: { value: 1.0 } - }, - ] ), + return true; - vertexShader: ShaderChunk.shadow_vert, - fragmentShader: ShaderChunk.shadow_frag + } - } + var denominator = plane.normal.dot( this.direction ); - }; + if ( denominator * distToPoint < 0 ) { - ShaderLib.physical = { + return true; - uniforms: mergeUniforms( [ - ShaderLib.standard.uniforms, - { - clearCoat: { value: 0 }, - clearCoatRoughness: { value: 0 } } - ] ), - vertexShader: ShaderChunk.meshphysical_vert, - fragmentShader: ShaderChunk.meshphysical_frag + // ray origin is behind the plane (and is pointing behind it) - }; + return false; - /** - * @author mrdoob / http://mrdoob.com/ - */ + }, - function WebGLAnimation() { + intersectBox: function ( box, target ) { - var context = null; - var isAnimating = false; - var animationLoop = null; + var tmin, tmax, tymin, tymax, tzmin, tzmax; - function onAnimationFrame( time, frame ) { + var invdirx = 1 / this.direction.x, + invdiry = 1 / this.direction.y, + invdirz = 1 / this.direction.z; - if ( isAnimating === false ) return; + var origin = this.origin; - animationLoop( time, frame ); + if ( invdirx >= 0 ) { - context.requestAnimationFrame( onAnimationFrame ); + tmin = ( box.min.x - origin.x ) * invdirx; + tmax = ( box.max.x - origin.x ) * invdirx; - } + } else { - return { + tmin = ( box.max.x - origin.x ) * invdirx; + tmax = ( box.min.x - origin.x ) * invdirx; - start: function () { + } - if ( isAnimating === true ) return; - if ( animationLoop === null ) return; + if ( invdiry >= 0 ) { - context.requestAnimationFrame( onAnimationFrame ); + tymin = ( box.min.y - origin.y ) * invdiry; + tymax = ( box.max.y - origin.y ) * invdiry; - isAnimating = true; + } else { - }, + tymin = ( box.max.y - origin.y ) * invdiry; + tymax = ( box.min.y - origin.y ) * invdiry; - stop: function () { + } - isAnimating = false; + if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; - }, + // These lines also handle the case where tmin or tmax is NaN + // (result of 0 * Infinity). x !== x returns true if x is NaN - setAnimationLoop: function ( callback ) { + if ( tymin > tmin || tmin !== tmin ) tmin = tymin; - animationLoop = callback; + if ( tymax < tmax || tmax !== tmax ) tmax = tymax; - }, + if ( invdirz >= 0 ) { - setContext: function ( value ) { + tzmin = ( box.min.z - origin.z ) * invdirz; + tzmax = ( box.max.z - origin.z ) * invdirz; - context = value; + } else { - } + tzmin = ( box.max.z - origin.z ) * invdirz; + tzmax = ( box.min.z - origin.z ) * invdirz; - }; + } - } + if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; - /** - * @author mrdoob / http://mrdoob.com/ - */ + if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; - function WebGLAttributes( gl ) { + if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; - var buffers = new WeakMap(); + //return point closest to the ray (positive side) - function createBuffer( attribute, bufferType ) { + if ( tmax < 0 ) return null; - var array = attribute.array; - var usage = attribute.dynamic ? 35048 : 35044; + return this.at( tmin >= 0 ? tmin : tmax, target ); - var buffer = gl.createBuffer(); + }, - gl.bindBuffer( bufferType, buffer ); - gl.bufferData( bufferType, array, usage ); + intersectsBox: ( function () { - attribute.onUploadCallback(); + var v = new Vector3(); - var type = 5126; + return function intersectsBox( box ) { - if ( array instanceof Float32Array ) { + return this.intersectBox( box, v ) !== null; - type = 5126; + }; - } else if ( array instanceof Float64Array ) { + } )(), - console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); + intersectTriangle: function () { - } else if ( array instanceof Uint16Array ) { + // Compute the offset origin, edges, and normal. + var diff = new Vector3(); + var edge1 = new Vector3(); + var edge2 = new Vector3(); + var normal = new Vector3(); - type = 5123; + return function intersectTriangle( a, b, c, backfaceCulling, target ) { - } else if ( array instanceof Int16Array ) { + // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h - type = 5122; + edge1.subVectors( b, a ); + edge2.subVectors( c, a ); + normal.crossVectors( edge1, edge2 ); - } else if ( array instanceof Uint32Array ) { + // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by + // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) + // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) + // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) + var DdN = this.direction.dot( normal ); + var sign; - type = 5125; + if ( DdN > 0 ) { - } else if ( array instanceof Int32Array ) { + if ( backfaceCulling ) return null; + sign = 1; - type = 5124; + } else if ( DdN < 0 ) { - } else if ( array instanceof Int8Array ) { + sign = - 1; + DdN = - DdN; - type = 5120; + } else { - } else if ( array instanceof Uint8Array ) { + return null; - type = 5121; + } - } + diff.subVectors( this.origin, a ); + var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) ); - return { - buffer: buffer, - type: type, - bytesPerElement: array.BYTES_PER_ELEMENT, - version: attribute.version - }; + // b1 < 0, no intersection + if ( DdQxE2 < 0 ) { - } + return null; - function updateBuffer( buffer, attribute, bufferType ) { + } - var array = attribute.array; - var updateRange = attribute.updateRange; + var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) ); - gl.bindBuffer( bufferType, buffer ); + // b2 < 0, no intersection + if ( DdE1xQ < 0 ) { - if ( attribute.dynamic === false ) { + return null; - gl.bufferData( bufferType, array, 35044 ); + } - } else if ( updateRange.count === - 1 ) { + // b1+b2 > 1, no intersection + if ( DdQxE2 + DdE1xQ > DdN ) { - // Not using update ranges + return null; - gl.bufferSubData( bufferType, 0, array ); + } - } else if ( updateRange.count === 0 ) { + // Line intersects triangle, check if ray does. + var QdN = - sign * diff.dot( normal ); - console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' ); + // t < 0, no intersection + if ( QdN < 0 ) { - } else { + return null; - gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, - array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); + } - updateRange.count = - 1; // reset range + // Ray intersects triangle. + return this.at( QdN / DdN, target ); - } + }; - } + }(), - // + applyMatrix4: function ( matrix4 ) { - function get( attribute ) { + this.origin.applyMatrix4( matrix4 ); + this.direction.transformDirection( matrix4 ); - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + return this; - return buffers.get( attribute ); + }, - } + equals: function ( ray ) { - function remove( attribute ) { + return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + } - var data = buffers.get( attribute ); + } ); - if ( data ) { + /** + * @author bhouston / http://clara.io + * @author mrdoob / http://mrdoob.com/ + */ - gl.deleteBuffer( data.buffer ); + function Triangle( a, b, c ) { - buffers.delete( attribute ); + this.a = ( a !== undefined ) ? a : new Vector3(); + this.b = ( b !== undefined ) ? b : new Vector3(); + this.c = ( c !== undefined ) ? c : new Vector3(); - } + } - } + Object.assign( Triangle, { - function update( attribute, bufferType ) { + getNormal: function () { - if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; + var v0 = new Vector3(); - var data = buffers.get( attribute ); + return function getNormal( a, b, c, target ) { - if ( data === undefined ) { + if ( target === undefined ) { - buffers.set( attribute, createBuffer( attribute, bufferType ) ); + console.warn( 'THREE.Triangle: .getNormal() target is now required' ); + target = new Vector3(); - } else if ( data.version < attribute.version ) { + } - updateBuffer( data.buffer, attribute, bufferType ); + target.subVectors( c, b ); + v0.subVectors( a, b ); + target.cross( v0 ); - data.version = attribute.version; + var targetLengthSq = target.lengthSq(); + if ( targetLengthSq > 0 ) { - } + return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); - } + } - return { + return target.set( 0, 0, 0 ); - get: get, - remove: remove, - update: update + }; - }; + }(), - } + // static/instance method to calculate barycentric coordinates + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html + getBarycoord: function () { - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ + var v0 = new Vector3(); + var v1 = new Vector3(); + var v2 = new Vector3(); - function Face3( a, b, c, normal, color, materialIndex ) { + return function getBarycoord( point, a, b, c, target ) { - this.a = a; - this.b = b; - this.c = c; + v0.subVectors( c, a ); + v1.subVectors( b, a ); + v2.subVectors( point, a ); - this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3(); - this.vertexNormals = Array.isArray( normal ) ? normal : []; + var dot00 = v0.dot( v0 ); + var dot01 = v0.dot( v1 ); + var dot02 = v0.dot( v2 ); + var dot11 = v1.dot( v1 ); + var dot12 = v1.dot( v2 ); - this.color = ( color && color.isColor ) ? color : new Color(); - this.vertexColors = Array.isArray( color ) ? color : []; + var denom = ( dot00 * dot11 - dot01 * dot01 ); - this.materialIndex = materialIndex !== undefined ? materialIndex : 0; + if ( target === undefined ) { - } + console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); + target = new Vector3(); - Object.assign( Face3.prototype, { + } - clone: function () { + // collinear or singular triangle + if ( denom === 0 ) { - return new this.constructor().copy( this ); + // arbitrary location outside of triangle? + // not sure if this is the best idea, maybe should be returning undefined + return target.set( - 2, - 1, - 1 ); - }, + } - copy: function ( source ) { + var invDenom = 1 / denom; + var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; + var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - this.a = source.a; - this.b = source.b; - this.c = source.c; + // barycentric coordinates must always sum to 1 + return target.set( 1 - u - v, v, u ); - this.normal.copy( source.normal ); - this.color.copy( source.color ); + }; - this.materialIndex = source.materialIndex; + }(), - for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) { + containsPoint: function () { - this.vertexNormals[ i ] = source.vertexNormals[ i ].clone(); + var v1 = new Vector3(); - } + return function containsPoint( point, a, b, c ) { - for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) { + Triangle.getBarycoord( point, a, b, c, v1 ); - this.vertexColors[ i ] = source.vertexColors[ i ].clone(); + return ( v1.x >= 0 ) && ( v1.y >= 0 ) && ( ( v1.x + v1.y ) <= 1 ); - } + }; - return this; + }(), - } + getUV: function () { - } ); + var barycoord = new Vector3(); - /** - * @author mrdoob / http://mrdoob.com/ - * @author WestLangley / http://github.com/WestLangley - * @author bhouston / http://clara.io - */ + return function getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) { - function Euler( x, y, z, order ) { + this.getBarycoord( point, p1, p2, p3, barycoord ); - this._x = x || 0; - this._y = y || 0; - this._z = z || 0; - this._order = order || Euler.DefaultOrder; + target.set( 0, 0 ); + target.addScaledVector( uv1, barycoord.x ); + target.addScaledVector( uv2, barycoord.y ); + target.addScaledVector( uv3, barycoord.z ); - } + return target; - Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; + }; - Euler.DefaultOrder = 'XYZ'; + }(), - Object.defineProperties( Euler.prototype, { + isFrontFacing: function () { - x: { + var v0 = new Vector3(); + var v1 = new Vector3(); - get: function () { + return function isFrontFacing( a, b, c, direction ) { - return this._x; + v0.subVectors( c, b ); + v1.subVectors( a, b ); - }, + // strictly front facing + return ( v0.cross( v1 ).dot( direction ) < 0 ) ? true : false; - set: function ( value ) { + }; - this._x = value; - this.onChangeCallback(); + }() - } + } ); - }, + Object.assign( Triangle.prototype, { - y: { + set: function ( a, b, c ) { - get: function () { + this.a.copy( a ); + this.b.copy( b ); + this.c.copy( c ); - return this._y; + return this; - }, + }, - set: function ( value ) { + setFromPointsAndIndices: function ( points, i0, i1, i2 ) { - this._y = value; - this.onChangeCallback(); + this.a.copy( points[ i0 ] ); + this.b.copy( points[ i1 ] ); + this.c.copy( points[ i2 ] ); - } + return this; }, - z: { - - get: function () { + clone: function () { - return this._z; + return new this.constructor().copy( this ); - }, + }, - set: function ( value ) { + copy: function ( triangle ) { - this._z = value; - this.onChangeCallback(); + this.a.copy( triangle.a ); + this.b.copy( triangle.b ); + this.c.copy( triangle.c ); - } + return this; }, - order: { + getArea: function () { - get: function () { + var v0 = new Vector3(); + var v1 = new Vector3(); - return this._order; + return function getArea() { - }, + v0.subVectors( this.c, this.b ); + v1.subVectors( this.a, this.b ); - set: function ( value ) { + return v0.cross( v1 ).length() * 0.5; - this._order = value; - this.onChangeCallback(); - - } - - } - - } ); + }; - Object.assign( Euler.prototype, { + }(), - isEuler: true, + getMidpoint: function ( target ) { - set: function ( x, y, z, order ) { + if ( target === undefined ) { - this._x = x; - this._y = y; - this._z = z; - this._order = order || this._order; + console.warn( 'THREE.Triangle: .getMidpoint() target is now required' ); + target = new Vector3(); - this.onChangeCallback(); + } - return this; + return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); }, - clone: function () { + getNormal: function ( target ) { - return new this.constructor( this._x, this._y, this._z, this._order ); + return Triangle.getNormal( this.a, this.b, this.c, target ); }, - copy: function ( euler ) { + getPlane: function ( target ) { - this._x = euler._x; - this._y = euler._y; - this._z = euler._z; - this._order = euler._order; + if ( target === undefined ) { + + console.warn( 'THREE.Triangle: .getPlane() target is now required' ); + target = new Vector3(); - this.onChangeCallback(); + } - return this; + return target.setFromCoplanarPoints( this.a, this.b, this.c ); }, - setFromRotationMatrix: function ( m, order, update ) { + getBarycoord: function ( point, target ) { - var clamp = _Math.clamp; + return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + }, - var te = m.elements; - var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; - var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; - var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + getUV: function ( point, uv1, uv2, uv3, target ) { - order = order || this._order; + return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target ); - if ( order === 'XYZ' ) { + }, - this._y = Math.asin( clamp( m13, - 1, 1 ) ); + containsPoint: function ( point ) { - if ( Math.abs( m13 ) < 0.99999 ) { + return Triangle.containsPoint( point, this.a, this.b, this.c ); - this._x = Math.atan2( - m23, m33 ); - this._z = Math.atan2( - m12, m11 ); + }, - } else { + isFrontFacing: function ( direction ) { - this._x = Math.atan2( m32, m22 ); - this._z = 0; + return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); - } + }, - } else if ( order === 'YXZ' ) { + intersectsBox: function ( box ) { - this._x = Math.asin( - clamp( m23, - 1, 1 ) ); + return box.intersectsTriangle( this ); - if ( Math.abs( m23 ) < 0.99999 ) { + }, - this._y = Math.atan2( m13, m33 ); - this._z = Math.atan2( m21, m22 ); + closestPointToPoint: function () { - } else { + var vab = new Vector3(); + var vac = new Vector3(); + var vbc = new Vector3(); + var vap = new Vector3(); + var vbp = new Vector3(); + var vcp = new Vector3(); - this._y = Math.atan2( - m31, m11 ); - this._z = 0; + return function closestPointToPoint( p, target ) { - } + if ( target === undefined ) { - } else if ( order === 'ZXY' ) { + console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); + target = new Vector3(); - this._x = Math.asin( clamp( m32, - 1, 1 ) ); + } - if ( Math.abs( m32 ) < 0.99999 ) { + var a = this.a, b = this.b, c = this.c; + var v, w; - this._y = Math.atan2( - m31, m33 ); - this._z = Math.atan2( - m12, m22 ); + // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., + // under the accompanying license; see chapter 5.1.5 for detailed explanation. + // basically, we're distinguishing which of the voronoi regions of the triangle + // the point lies in with the minimum amount of redundant computation. - } else { + vab.subVectors( b, a ); + vac.subVectors( c, a ); + vap.subVectors( p, a ); + var d1 = vab.dot( vap ); + var d2 = vac.dot( vap ); + if ( d1 <= 0 && d2 <= 0 ) { - this._y = 0; - this._z = Math.atan2( m21, m11 ); + // vertex region of A; barycentric coords (1, 0, 0) + return target.copy( a ); } - } else if ( order === 'ZYX' ) { - - this._y = Math.asin( - clamp( m31, - 1, 1 ) ); + vbp.subVectors( p, b ); + var d3 = vab.dot( vbp ); + var d4 = vac.dot( vbp ); + if ( d3 >= 0 && d4 <= d3 ) { - if ( Math.abs( m31 ) < 0.99999 ) { + // vertex region of B; barycentric coords (0, 1, 0) + return target.copy( b ); - this._x = Math.atan2( m32, m33 ); - this._z = Math.atan2( m21, m11 ); + } - } else { + var vc = d1 * d4 - d3 * d2; + if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { - this._x = 0; - this._z = Math.atan2( - m12, m22 ); + v = d1 / ( d1 - d3 ); + // edge region of AB; barycentric coords (1-v, v, 0) + return target.copy( a ).addScaledVector( vab, v ); } - } else if ( order === 'YZX' ) { - - this._z = Math.asin( clamp( m21, - 1, 1 ) ); + vcp.subVectors( p, c ); + var d5 = vab.dot( vcp ); + var d6 = vac.dot( vcp ); + if ( d6 >= 0 && d5 <= d6 ) { - if ( Math.abs( m21 ) < 0.99999 ) { + // vertex region of C; barycentric coords (0, 0, 1) + return target.copy( c ); - this._x = Math.atan2( - m23, m22 ); - this._y = Math.atan2( - m31, m11 ); + } - } else { + var vb = d5 * d2 - d1 * d6; + if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { - this._x = 0; - this._y = Math.atan2( m13, m33 ); + w = d2 / ( d2 - d6 ); + // edge region of AC; barycentric coords (1-w, 0, w) + return target.copy( a ).addScaledVector( vac, w ); } - } else if ( order === 'XZY' ) { + var va = d3 * d6 - d5 * d4; + if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { - this._z = Math.asin( - clamp( m12, - 1, 1 ) ); + vbc.subVectors( c, b ); + w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); + // edge region of BC; barycentric coords (0, 1-w, w) + return target.copy( b ).addScaledVector( vbc, w ); // edge region of BC - if ( Math.abs( m12 ) < 0.99999 ) { + } - this._x = Math.atan2( m32, m22 ); - this._y = Math.atan2( m13, m11 ); + // face region + var denom = 1 / ( va + vb + vc ); + // u = va * denom + v = vb * denom; + w = vc * denom; + return target.copy( a ).addScaledVector( vab, v ).addScaledVector( vac, w ); - } else { + }; - this._x = Math.atan2( - m23, m33 ); - this._y = 0; + }(), - } + equals: function ( triangle ) { - } else { + return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); - console.warn( 'THREE.Euler: .setFromRotationMatrix() given unsupported order: ' + order ); + } - } + } ); - this._order = order; + /** + * @author mrdoob / http://mrdoob.com/ + */ - if ( update !== false ) this.onChangeCallback(); + var ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, + 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, + 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, + 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, + 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, + 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, + 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, + 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, + 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, + 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, + 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, + 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, + 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, + 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, + 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, + 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, + 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, + 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, + 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, + 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, + 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, + 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, + 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, + 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; - return this; + function Color( r, g, b ) { - }, + if ( g === undefined && b === undefined ) { - setFromQuaternion: function () { + // r is THREE.Color, hex or string + return this.set( r ); - var matrix = new Matrix4(); + } - return function setFromQuaternion( q, order, update ) { + return this.setRGB( r, g, b ); - matrix.makeRotationFromQuaternion( q ); + } - return this.setFromRotationMatrix( matrix, order, update ); + function hue2rgb( p, q, t ) { - }; + if ( t < 0 ) t += 1; + if ( t > 1 ) t -= 1; + if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; + if ( t < 1 / 2 ) return q; + if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); + return p; - }(), + } - setFromVector3: function ( v, order ) { + function SRGBToLinear( c ) { - return this.set( v.x, v.y, v.z, order || this._order ); + return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); - }, + } - reorder: function () { + function LinearToSRGB( c ) { - // WARNING: this discards revolution information -bhouston + return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; - var q = new Quaternion(); + } - return function reorder( newOrder ) { + Object.assign( Color.prototype, { - q.setFromEuler( this ); + isColor: true, - return this.setFromQuaternion( q, newOrder ); + r: 1, g: 1, b: 1, - }; + set: function ( value ) { - }(), + if ( value && value.isColor ) { - equals: function ( euler ) { + this.copy( value ); - return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); + } else if ( typeof value === 'number' ) { - }, + this.setHex( value ); - fromArray: function ( array ) { + } else if ( typeof value === 'string' ) { - this._x = array[ 0 ]; - this._y = array[ 1 ]; - this._z = array[ 2 ]; - if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; + this.setStyle( value ); - this.onChangeCallback(); + } return this; }, - toArray: function ( array, offset ) { - - if ( array === undefined ) array = []; - if ( offset === undefined ) offset = 0; + setScalar: function ( scalar ) { - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._order; + this.r = scalar; + this.g = scalar; + this.b = scalar; - return array; + return this; }, - toVector3: function ( optionalResult ) { - - if ( optionalResult ) { - - return optionalResult.set( this._x, this._y, this._z ); + setHex: function ( hex ) { - } else { + hex = Math.floor( hex ); - return new Vector3( this._x, this._y, this._z ); + this.r = ( hex >> 16 & 255 ) / 255; + this.g = ( hex >> 8 & 255 ) / 255; + this.b = ( hex & 255 ) / 255; - } + return this; }, - onChange: function ( callback ) { + setRGB: function ( r, g, b ) { - this.onChangeCallback = callback; + this.r = r; + this.g = g; + this.b = b; return this; }, - onChangeCallback: function () {} + setHSL: function ( h, s, l ) { - } ); + // h,s,l ranges are in 0.0 - 1.0 + h = _Math.euclideanModulo( h, 1 ); + s = _Math.clamp( s, 0, 1 ); + l = _Math.clamp( l, 0, 1 ); - /** - * @author mrdoob / http://mrdoob.com/ - */ + if ( s === 0 ) { - function Layers() { + this.r = this.g = this.b = l; - this.mask = 1 | 0; + } else { - } + var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); + var q = ( 2 * l ) - p; - Object.assign( Layers.prototype, { + this.r = hue2rgb( q, p, h + 1 / 3 ); + this.g = hue2rgb( q, p, h ); + this.b = hue2rgb( q, p, h - 1 / 3 ); - set: function ( channel ) { + } - this.mask = 1 << channel | 0; + return this; }, - enable: function ( channel ) { - - this.mask |= 1 << channel | 0; + setStyle: function ( style ) { - }, + function handleAlpha( string ) { - toggle: function ( channel ) { + if ( string === undefined ) return; - this.mask ^= 1 << channel | 0; + if ( parseFloat( string ) < 1 ) { - }, + console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); - disable: function ( channel ) { + } - this.mask &= ~ ( 1 << channel | 0 ); + } - }, - test: function ( layers ) { + var m; - return ( this.mask & layers.mask ) !== 0; + if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { - } + // rgb / hsl - } ); + var color; + var name = m[ 1 ]; + var components = m[ 2 ]; - /** - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - * @author alteredq / http://alteredqualia.com/ - * @author WestLangley / http://github.com/WestLangley - * @author elephantatwork / www.elephantatwork.ch - */ + switch ( name ) { - var object3DId = 0; + case 'rgb': + case 'rgba': - function Object3D() { + if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { - Object.defineProperty( this, 'id', { value: object3DId ++ } ); + // rgb(255,0,0) rgba(255,0,0,0.5) + this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; + this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; + this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; - this.uuid = _Math.generateUUID(); + handleAlpha( color[ 5 ] ); - this.name = ''; - this.type = 'Object3D'; + return this; - this.parent = null; - this.children = []; + } - this.up = Object3D.DefaultUp.clone(); + if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { - var position = new Vector3(); - var rotation = new Euler(); - var quaternion = new Quaternion(); - var scale = new Vector3( 1, 1, 1 ); + // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) + this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; + this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; + this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; - function onRotationChange() { + handleAlpha( color[ 5 ] ); - quaternion.setFromEuler( rotation, false ); + return this; - } + } - function onQuaternionChange() { + break; - rotation.setFromQuaternion( quaternion, undefined, false ); + case 'hsl': + case 'hsla': - } + if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { - rotation.onChange( onRotationChange ); - quaternion.onChange( onQuaternionChange ); + // hsl(120,50%,50%) hsla(120,50%,50%,0.5) + var h = parseFloat( color[ 1 ] ) / 360; + var s = parseInt( color[ 2 ], 10 ) / 100; + var l = parseInt( color[ 3 ], 10 ) / 100; - Object.defineProperties( this, { - position: { - configurable: true, - enumerable: true, - value: position - }, - rotation: { - configurable: true, - enumerable: true, - value: rotation - }, - quaternion: { - configurable: true, - enumerable: true, - value: quaternion - }, - scale: { - configurable: true, - enumerable: true, - value: scale - }, - modelViewMatrix: { - value: new Matrix4() - }, - normalMatrix: { - value: new Matrix3() - } - } ); + handleAlpha( color[ 5 ] ); - this.matrix = new Matrix4(); - this.matrixWorld = new Matrix4(); + return this.setHSL( h, s, l ); - this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; - this.matrixWorldNeedsUpdate = false; + } - this.layers = new Layers(); - this.visible = true; + break; - this.castShadow = false; - this.receiveShadow = false; + } - this.frustumCulled = true; - this.renderOrder = 0; + } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { - this.userData = {}; + // hex color - } + var hex = m[ 1 ]; + var size = hex.length; - Object3D.DefaultUp = new Vector3( 0, 1, 0 ); - Object3D.DefaultMatrixAutoUpdate = true; + if ( size === 3 ) { - Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + // #ff0 + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; - constructor: Object3D, + return this; - isObject3D: true, + } else if ( size === 6 ) { - onBeforeRender: function () {}, - onAfterRender: function () {}, + // #ff0000 + this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; + this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; + this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; - applyMatrix: function ( matrix ) { + return this; - if ( this.matrixAutoUpdate ) this.updateMatrix(); + } - this.matrix.premultiply( matrix ); + } - this.matrix.decompose( this.position, this.quaternion, this.scale ); + if ( style && style.length > 0 ) { - }, + // color keywords + var hex = ColorKeywords[ style ]; - applyQuaternion: function ( q ) { + if ( hex !== undefined ) { - this.quaternion.premultiply( q ); + // red + this.setHex( hex ); - return this; + } else { - }, + // unknown color + console.warn( 'THREE.Color: Unknown color ' + style ); - setRotationFromAxisAngle: function ( axis, angle ) { + } - // assumes axis is normalized + } - this.quaternion.setFromAxisAngle( axis, angle ); + return this; }, - setRotationFromEuler: function ( euler ) { + clone: function () { - this.quaternion.setFromEuler( euler, true ); + return new this.constructor( this.r, this.g, this.b ); }, - setRotationFromMatrix: function ( m ) { + copy: function ( color ) { - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + this.r = color.r; + this.g = color.g; + this.b = color.b; - this.quaternion.setFromRotationMatrix( m ); + return this; }, - setRotationFromQuaternion: function ( q ) { + copyGammaToLinear: function ( color, gammaFactor ) { - // assumes q is normalized + if ( gammaFactor === undefined ) gammaFactor = 2.0; - this.quaternion.copy( q ); + this.r = Math.pow( color.r, gammaFactor ); + this.g = Math.pow( color.g, gammaFactor ); + this.b = Math.pow( color.b, gammaFactor ); + + return this; }, - rotateOnAxis: function () { + copyLinearToGamma: function ( color, gammaFactor ) { - // rotate object on axis in object space - // axis is assumed to be normalized - - var q1 = new Quaternion(); - - return function rotateOnAxis( axis, angle ) { - - q1.setFromAxisAngle( axis, angle ); + if ( gammaFactor === undefined ) gammaFactor = 2.0; - this.quaternion.multiply( q1 ); + var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; - return this; + this.r = Math.pow( color.r, safeInverse ); + this.g = Math.pow( color.g, safeInverse ); + this.b = Math.pow( color.b, safeInverse ); - }; + return this; - }(), + }, - rotateOnWorldAxis: function () { + convertGammaToLinear: function ( gammaFactor ) { - // rotate object on axis in world space - // axis is assumed to be normalized - // method assumes no rotated parent + this.copyGammaToLinear( this, gammaFactor ); - var q1 = new Quaternion(); + return this; - return function rotateOnWorldAxis( axis, angle ) { + }, - q1.setFromAxisAngle( axis, angle ); + convertLinearToGamma: function ( gammaFactor ) { - this.quaternion.premultiply( q1 ); + this.copyLinearToGamma( this, gammaFactor ); - return this; + return this; - }; + }, - }(), + copySRGBToLinear: function ( color ) { - rotateX: function () { + this.r = SRGBToLinear( color.r ); + this.g = SRGBToLinear( color.g ); + this.b = SRGBToLinear( color.b ); - var v1 = new Vector3( 1, 0, 0 ); + return this; - return function rotateX( angle ) { + }, - return this.rotateOnAxis( v1, angle ); + copyLinearToSRGB: function ( color ) { - }; + this.r = LinearToSRGB( color.r ); + this.g = LinearToSRGB( color.g ); + this.b = LinearToSRGB( color.b ); - }(), + return this; - rotateY: function () { + }, - var v1 = new Vector3( 0, 1, 0 ); + convertSRGBToLinear: function () { - return function rotateY( angle ) { + this.copySRGBToLinear( this ); - return this.rotateOnAxis( v1, angle ); + return this; - }; + }, - }(), + convertLinearToSRGB: function () { - rotateZ: function () { + this.copyLinearToSRGB( this ); - var v1 = new Vector3( 0, 0, 1 ); + return this; - return function rotateZ( angle ) { + }, - return this.rotateOnAxis( v1, angle ); + getHex: function () { - }; + return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; - }(), + }, - translateOnAxis: function () { + getHexString: function () { - // translate object by distance along axis in object space - // axis is assumed to be normalized + return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); - var v1 = new Vector3(); + }, - return function translateOnAxis( axis, distance ) { + getHSL: function ( target ) { - v1.copy( axis ).applyQuaternion( this.quaternion ); + // h,s,l ranges are in 0.0 - 1.0 - this.position.add( v1.multiplyScalar( distance ) ); + if ( target === undefined ) { - return this; + console.warn( 'THREE.Color: .getHSL() target is now required' ); + target = { h: 0, s: 0, l: 0 }; - }; + } - }(), + var r = this.r, g = this.g, b = this.b; - translateX: function () { + var max = Math.max( r, g, b ); + var min = Math.min( r, g, b ); - var v1 = new Vector3( 1, 0, 0 ); + var hue, saturation; + var lightness = ( min + max ) / 2.0; - return function translateX( distance ) { + if ( min === max ) { - return this.translateOnAxis( v1, distance ); + hue = 0; + saturation = 0; - }; + } else { - }(), + var delta = max - min; - translateY: function () { + saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); - var v1 = new Vector3( 0, 1, 0 ); + switch ( max ) { - return function translateY( distance ) { + case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; + case g: hue = ( b - r ) / delta + 2; break; + case b: hue = ( r - g ) / delta + 4; break; - return this.translateOnAxis( v1, distance ); + } - }; + hue /= 6; - }(), + } - translateZ: function () { + target.h = hue; + target.s = saturation; + target.l = lightness; - var v1 = new Vector3( 0, 0, 1 ); + return target; - return function translateZ( distance ) { + }, - return this.translateOnAxis( v1, distance ); + getStyle: function () { - }; + return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; - }(), + }, - localToWorld: function ( vector ) { + offsetHSL: function () { - return vector.applyMatrix4( this.matrixWorld ); + var hsl = {}; - }, + return function ( h, s, l ) { - worldToLocal: function () { + this.getHSL( hsl ); - var m1 = new Matrix4(); + hsl.h += h; hsl.s += s; hsl.l += l; - return function worldToLocal( vector ) { + this.setHSL( hsl.h, hsl.s, hsl.l ); - return vector.applyMatrix4( m1.getInverse( this.matrixWorld ) ); + return this; }; }(), - lookAt: function () { + add: function ( color ) { - // This method does not support objects having non-uniformly-scaled parent(s) + this.r += color.r; + this.g += color.g; + this.b += color.b; - var q1 = new Quaternion(); - var m1 = new Matrix4(); - var target = new Vector3(); - var position = new Vector3(); + return this; - return function lookAt( x, y, z ) { + }, - if ( x.isVector3 ) { + addColors: function ( color1, color2 ) { - target.copy( x ); + this.r = color1.r + color2.r; + this.g = color1.g + color2.g; + this.b = color1.b + color2.b; - } else { + return this; - target.set( x, y, z ); + }, - } + addScalar: function ( s ) { - var parent = this.parent; + this.r += s; + this.g += s; + this.b += s; - this.updateWorldMatrix( true, false ); + return this; - position.setFromMatrixPosition( this.matrixWorld ); + }, - if ( this.isCamera || this.isLight ) { + sub: function ( color ) { - m1.lookAt( position, target, this.up ); + this.r = Math.max( 0, this.r - color.r ); + this.g = Math.max( 0, this.g - color.g ); + this.b = Math.max( 0, this.b - color.b ); - } else { + return this; - m1.lookAt( target, position, this.up ); + }, - } + multiply: function ( color ) { - this.quaternion.setFromRotationMatrix( m1 ); + this.r *= color.r; + this.g *= color.g; + this.b *= color.b; - if ( parent ) { + return this; - m1.extractRotation( parent.matrixWorld ); - q1.setFromRotationMatrix( m1 ); - this.quaternion.premultiply( q1.inverse() ); + }, - } + multiplyScalar: function ( s ) { - }; + this.r *= s; + this.g *= s; + this.b *= s; - }(), + return this; - add: function ( object ) { + }, - if ( arguments.length > 1 ) { + lerp: function ( color, alpha ) { - for ( var i = 0; i < arguments.length; i ++ ) { + this.r += ( color.r - this.r ) * alpha; + this.g += ( color.g - this.g ) * alpha; + this.b += ( color.b - this.b ) * alpha; - this.add( arguments[ i ] ); + return this; - } + }, - return this; + lerpHSL: function () { - } + var hslA = { h: 0, s: 0, l: 0 }; + var hslB = { h: 0, s: 0, l: 0 }; - if ( object === this ) { + return function lerpHSL( color, alpha ) { - console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object ); - return this; + this.getHSL( hslA ); + color.getHSL( hslB ); - } + var h = _Math.lerp( hslA.h, hslB.h, alpha ); + var s = _Math.lerp( hslA.s, hslB.s, alpha ); + var l = _Math.lerp( hslA.l, hslB.l, alpha ); - if ( ( object && object.isObject3D ) ) { + this.setHSL( h, s, l ); - if ( object.parent !== null ) { + return this; - object.parent.remove( object ); + }; - } + }(), - object.parent = this; - object.dispatchEvent( { type: 'added' } ); + equals: function ( c ) { - this.children.push( object ); + return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); - } else { + }, - console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object ); + fromArray: function ( array, offset ) { - } + if ( offset === undefined ) offset = 0; + + this.r = array[ offset ]; + this.g = array[ offset + 1 ]; + this.b = array[ offset + 2 ]; return this; }, - remove: function ( object ) { - - if ( arguments.length > 1 ) { - - for ( var i = 0; i < arguments.length; i ++ ) { + toArray: function ( array, offset ) { - this.remove( arguments[ i ] ); + if ( array === undefined ) array = []; + if ( offset === undefined ) offset = 0; - } + array[ offset ] = this.r; + array[ offset + 1 ] = this.g; + array[ offset + 2 ] = this.b; - return this; + return array; - } + }, - var index = this.children.indexOf( object ); + toJSON: function () { - if ( index !== - 1 ) { + return this.getHex(); - object.parent = null; + } - object.dispatchEvent( { type: 'removed' } ); + } ); - this.children.splice( index, 1 ); + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - } + function Face3( a, b, c, normal, color, materialIndex ) { - return this; + this.a = a; + this.b = b; + this.c = c; - }, + this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3(); + this.vertexNormals = Array.isArray( normal ) ? normal : []; - attach: function () { + this.color = ( color && color.isColor ) ? color : new Color(); + this.vertexColors = Array.isArray( color ) ? color : []; - // adds object as a child of this, while maintaining the object's world transform + this.materialIndex = materialIndex !== undefined ? materialIndex : 0; - var m = new Matrix4(); + } - return function attach( object ) { + Object.assign( Face3.prototype, { - this.updateWorldMatrix( true, false ); + clone: function () { - m.getInverse( this.matrixWorld ); + return new this.constructor().copy( this ); - if ( object.parent !== null ) { + }, - object.parent.updateWorldMatrix( true, false ); + copy: function ( source ) { - m.multiply( object.parent.matrixWorld ); + this.a = source.a; + this.b = source.b; + this.c = source.c; - } + this.normal.copy( source.normal ); + this.color.copy( source.color ); - object.applyMatrix( m ); + this.materialIndex = source.materialIndex; - object.updateWorldMatrix( false, false ); + for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) { - this.add( object ); + this.vertexNormals[ i ] = source.vertexNormals[ i ].clone(); - return this; + } - }; + for ( var i = 0, il = source.vertexColors.length; i < il; i ++ ) { - }(), + this.vertexColors[ i ] = source.vertexColors[ i ].clone(); - getObjectById: function ( id ) { + } - return this.getObjectByProperty( 'id', id ); + return this; - }, + } - getObjectByName: function ( name ) { + } ); - return this.getObjectByProperty( 'name', name ); + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + */ - }, + var materialId = 0; - getObjectByProperty: function ( name, value ) { + function Material() { - if ( this[ name ] === value ) return this; + Object.defineProperty( this, 'id', { value: materialId ++ } ); - for ( var i = 0, l = this.children.length; i < l; i ++ ) { + this.uuid = _Math.generateUUID(); - var child = this.children[ i ]; - var object = child.getObjectByProperty( name, value ); + this.name = ''; + this.type = 'Material'; - if ( object !== undefined ) { + this.fog = true; + this.lights = true; - return object; + this.blending = NormalBlending; + this.side = FrontSide; + this.flatShading = false; + this.vertexTangents = false; + this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors - } + this.opacity = 1; + this.transparent = false; - } + this.blendSrc = SrcAlphaFactor; + this.blendDst = OneMinusSrcAlphaFactor; + this.blendEquation = AddEquation; + this.blendSrcAlpha = null; + this.blendDstAlpha = null; + this.blendEquationAlpha = null; - return undefined; + this.depthFunc = LessEqualDepth; + this.depthTest = true; + this.depthWrite = true; - }, + this.clippingPlanes = null; + this.clipIntersection = false; + this.clipShadows = false; - getWorldPosition: function ( target ) { + this.shadowSide = null; - if ( target === undefined ) { + this.colorWrite = true; - console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' ); - target = new Vector3(); + this.precision = null; // override the renderer's default precision for this material - } + this.polygonOffset = false; + this.polygonOffsetFactor = 0; + this.polygonOffsetUnits = 0; - this.updateMatrixWorld( true ); + this.dithering = false; - return target.setFromMatrixPosition( this.matrixWorld ); + this.alphaTest = 0; + this.premultipliedAlpha = false; - }, + this.visible = true; - getWorldQuaternion: function () { + this.userData = {}; - var position = new Vector3(); - var scale = new Vector3(); + this.needsUpdate = true; - return function getWorldQuaternion( target ) { + } - if ( target === undefined ) { + Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' ); - target = new Quaternion(); + constructor: Material, - } + isMaterial: true, - this.updateMatrixWorld( true ); + onBeforeCompile: function () {}, - this.matrixWorld.decompose( position, target, scale ); + setValues: function ( values ) { - return target; + if ( values === undefined ) return; - }; + for ( var key in values ) { - }(), + var newValue = values[ key ]; - getWorldScale: function () { + if ( newValue === undefined ) { - var position = new Vector3(); - var quaternion = new Quaternion(); + console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); + continue; - return function getWorldScale( target ) { + } - if ( target === undefined ) { + // for backward compatability if shading is set in the constructor + if ( key === 'shading' ) { - console.warn( 'THREE.Object3D: .getWorldScale() target is now required' ); - target = new Vector3(); + console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); + this.flatShading = ( newValue === FlatShading ) ? true : false; + continue; } - this.updateMatrixWorld( true ); + var currentValue = this[ key ]; - this.matrixWorld.decompose( position, quaternion, target ); + if ( currentValue === undefined ) { - return target; + console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." ); + continue; - }; + } - }(), + if ( currentValue && currentValue.isColor ) { - getWorldDirection: function ( target ) { + currentValue.set( newValue ); - if ( target === undefined ) { + } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { - console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' ); - target = new Vector3(); + currentValue.copy( newValue ); - } + } else { - this.updateMatrixWorld( true ); + this[ key ] = newValue; - var e = this.matrixWorld.elements; + } - return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); + } }, - raycast: function () {}, - - traverse: function ( callback ) { - - callback( this ); + toJSON: function ( meta ) { - var children = this.children; + var isRoot = ( meta === undefined || typeof meta === 'string' ); - for ( var i = 0, l = children.length; i < l; i ++ ) { + if ( isRoot ) { - children[ i ].traverse( callback ); + meta = { + textures: {}, + images: {} + }; } - }, + var data = { + metadata: { + version: 4.5, + type: 'Material', + generator: 'Material.toJSON' + } + }; - traverseVisible: function ( callback ) { + // standard Material serialization + data.uuid = this.uuid; + data.type = this.type; - if ( this.visible === false ) return; + if ( this.name !== '' ) data.name = this.name; - callback( this ); + if ( this.color && this.color.isColor ) data.color = this.color.getHex(); - var children = this.children; + if ( this.roughness !== undefined ) data.roughness = this.roughness; + if ( this.metalness !== undefined ) data.metalness = this.metalness; - for ( var i = 0, l = children.length; i < l; i ++ ) { + if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); + if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; - children[ i ].traverseVisible( callback ); + if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); + if ( this.shininess !== undefined ) data.shininess = this.shininess; + if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; + if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; - } - - }, + if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; + if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; + if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; + if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid; - traverseAncestors: function ( callback ) { + if ( this.aoMap && this.aoMap.isTexture ) { - var parent = this.parent; + data.aoMap = this.aoMap.toJSON( meta ).uuid; + data.aoMapIntensity = this.aoMapIntensity; - if ( parent !== null ) { + } - callback( parent ); + if ( this.bumpMap && this.bumpMap.isTexture ) { - parent.traverseAncestors( callback ); + data.bumpMap = this.bumpMap.toJSON( meta ).uuid; + data.bumpScale = this.bumpScale; } - }, - - updateMatrix: function () { + if ( this.normalMap && this.normalMap.isTexture ) { - this.matrix.compose( this.position, this.quaternion, this.scale ); + data.normalMap = this.normalMap.toJSON( meta ).uuid; + data.normalMapType = this.normalMapType; + data.normalScale = this.normalScale.toArray(); - this.matrixWorldNeedsUpdate = true; + } - }, + if ( this.displacementMap && this.displacementMap.isTexture ) { - updateMatrixWorld: function ( force ) { + data.displacementMap = this.displacementMap.toJSON( meta ).uuid; + data.displacementScale = this.displacementScale; + data.displacementBias = this.displacementBias; - if ( this.matrixAutoUpdate ) this.updateMatrix(); + } - if ( this.matrixWorldNeedsUpdate || force ) { + if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; + if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; - if ( this.parent === null ) { + if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; + if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; - this.matrixWorld.copy( this.matrix ); + if ( this.envMap && this.envMap.isTexture ) { - } else { + data.envMap = this.envMap.toJSON( meta ).uuid; + data.reflectivity = this.reflectivity; // Scale behind envMap + data.refractionRatio = this.refractionRatio; - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + if ( this.combine !== undefined ) data.combine = this.combine; + if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; - } + } - this.matrixWorldNeedsUpdate = false; + if ( this.gradientMap && this.gradientMap.isTexture ) { - force = true; + data.gradientMap = this.gradientMap.toJSON( meta ).uuid; } - // update children + if ( this.size !== undefined ) data.size = this.size; + if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; - var children = this.children; + if ( this.blending !== NormalBlending ) data.blending = this.blending; + if ( this.flatShading === true ) data.flatShading = this.flatShading; + if ( this.side !== FrontSide ) data.side = this.side; + if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors; - for ( var i = 0, l = children.length; i < l; i ++ ) { + if ( this.opacity < 1 ) data.opacity = this.opacity; + if ( this.transparent === true ) data.transparent = this.transparent; - children[ i ].updateMatrixWorld( force ); + data.depthFunc = this.depthFunc; + data.depthTest = this.depthTest; + data.depthWrite = this.depthWrite; - } + // rotation (SpriteMaterial) + if ( this.rotation && this.rotation !== 0 ) data.rotation = this.rotation; - }, + if ( this.polygonOffset === true ) data.polygonOffset = true; + if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; + if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; - updateWorldMatrix: function ( updateParents, updateChildren ) { + if ( this.linewidth && this.linewidth !== 1 ) data.linewidth = this.linewidth; + if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; + if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; + if ( this.scale !== undefined ) data.scale = this.scale; - var parent = this.parent; + if ( this.dithering === true ) data.dithering = true; - if ( updateParents === true && parent !== null ) { + if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; + if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha; - parent.updateWorldMatrix( true, false ); + if ( this.wireframe === true ) data.wireframe = this.wireframe; + if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; + if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; + if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; - } + if ( this.morphTargets === true ) data.morphTargets = true; + if ( this.morphNormals === true ) data.morphNormals = true; + if ( this.skinning === true ) data.skinning = true; - if ( this.matrixAutoUpdate ) this.updateMatrix(); + if ( this.visible === false ) data.visible = false; + if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; - if ( this.parent === null ) { + // TODO: Copied from Object3D.toJSON - this.matrixWorld.copy( this.matrix ); + function extractFromCache( cache ) { - } else { + var values = []; - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + for ( var key in cache ) { - } + var data = cache[ key ]; + delete data.metadata; + values.push( data ); - // update children + } - if ( updateChildren === true ) { + return values; - var children = this.children; + } - for ( var i = 0, l = children.length; i < l; i ++ ) { + if ( isRoot ) { - children[ i ].updateWorldMatrix( false, true ); + var textures = extractFromCache( meta.textures ); + var images = extractFromCache( meta.images ); - } + if ( textures.length > 0 ) data.textures = textures; + if ( images.length > 0 ) data.images = images; } + return data; + }, - toJSON: function ( meta ) { + clone: function () { - // meta is a string when called from JSON.stringify - var isRootObject = ( meta === undefined || typeof meta === 'string' ); + return new this.constructor().copy( this ); - var output = {}; + }, - // meta is a hash used to collect geometries, materials. - // not providing it implies that this is the root object - // being serialized. - if ( isRootObject ) { + copy: function ( source ) { - // initialize meta obj - meta = { - geometries: {}, - materials: {}, - textures: {}, - images: {}, - shapes: {} - }; + this.name = source.name; - output.metadata = { - version: 4.5, - type: 'Object', - generator: 'Object3D.toJSON' - }; + this.fog = source.fog; + this.lights = source.lights; - } + this.blending = source.blending; + this.side = source.side; + this.flatShading = source.flatShading; + this.vertexColors = source.vertexColors; - // standard Object3D serialization + this.opacity = source.opacity; + this.transparent = source.transparent; - var object = {}; + this.blendSrc = source.blendSrc; + this.blendDst = source.blendDst; + this.blendEquation = source.blendEquation; + this.blendSrcAlpha = source.blendSrcAlpha; + this.blendDstAlpha = source.blendDstAlpha; + this.blendEquationAlpha = source.blendEquationAlpha; - object.uuid = this.uuid; - object.type = this.type; + this.depthFunc = source.depthFunc; + this.depthTest = source.depthTest; + this.depthWrite = source.depthWrite; - if ( this.name !== '' ) object.name = this.name; - if ( this.castShadow === true ) object.castShadow = true; - if ( this.receiveShadow === true ) object.receiveShadow = true; - if ( this.visible === false ) object.visible = false; - if ( this.frustumCulled === false ) object.frustumCulled = false; - if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; - if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; + this.colorWrite = source.colorWrite; - object.layers = this.layers.mask; - object.matrix = this.matrix.toArray(); + this.precision = source.precision; - if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; + this.polygonOffset = source.polygonOffset; + this.polygonOffsetFactor = source.polygonOffsetFactor; + this.polygonOffsetUnits = source.polygonOffsetUnits; - // object specific properties + this.dithering = source.dithering; - if ( this.isMesh && this.drawMode !== TrianglesDrawMode ) object.drawMode = this.drawMode; + this.alphaTest = source.alphaTest; + this.premultipliedAlpha = source.premultipliedAlpha; - // + this.visible = source.visible; + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - function serialize( library, element ) { + this.clipShadows = source.clipShadows; + this.clipIntersection = source.clipIntersection; - if ( library[ element.uuid ] === undefined ) { + var srcPlanes = source.clippingPlanes, + dstPlanes = null; - library[ element.uuid ] = element.toJSON( meta ); + if ( srcPlanes !== null ) { - } + var n = srcPlanes.length; + dstPlanes = new Array( n ); - return element.uuid; + for ( var i = 0; i !== n; ++ i ) + dstPlanes[ i ] = srcPlanes[ i ].clone(); } - if ( this.isMesh || this.isLine || this.isPoints ) { - - object.geometry = serialize( meta.geometries, this.geometry ); - - var parameters = this.geometry.parameters; - - if ( parameters !== undefined && parameters.shapes !== undefined ) { + this.clippingPlanes = dstPlanes; - var shapes = parameters.shapes; + this.shadowSide = source.shadowSide; - if ( Array.isArray( shapes ) ) { + return this; - for ( var i = 0, l = shapes.length; i < l; i ++ ) { + }, - var shape = shapes[ i ]; + dispose: function () { - serialize( meta.shapes, shape ); + this.dispatchEvent( { type: 'dispose' } ); - } + } - } else { + } ); - serialize( meta.shapes, shapes ); + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * + * parameters = { + * color: , + * opacity: , + * map: new THREE.Texture( ), + * + * lightMap: new THREE.Texture( ), + * lightMapIntensity: + * + * aoMap: new THREE.Texture( ), + * aoMapIntensity: + * + * specularMap: new THREE.Texture( ), + * + * alphaMap: new THREE.Texture( ), + * + * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), + * combine: THREE.Multiply, + * reflectivity: , + * refractionRatio: , + * + * depthTest: , + * depthWrite: , + * + * wireframe: , + * wireframeLinewidth: , + * + * skinning: , + * morphTargets: + * } + */ - } + function MeshBasicMaterial( parameters ) { - } + Material.call( this ); - } + this.type = 'MeshBasicMaterial'; - if ( this.material !== undefined ) { + this.color = new Color( 0xffffff ); // emissive - if ( Array.isArray( this.material ) ) { + this.map = null; - var uuids = []; + this.lightMap = null; + this.lightMapIntensity = 1.0; - for ( var i = 0, l = this.material.length; i < l; i ++ ) { + this.aoMap = null; + this.aoMapIntensity = 1.0; - uuids.push( serialize( meta.materials, this.material[ i ] ) ); + this.specularMap = null; - } + this.alphaMap = null; - object.material = uuids; + this.envMap = null; + this.combine = MultiplyOperation; + this.reflectivity = 1; + this.refractionRatio = 0.98; - } else { + this.wireframe = false; + this.wireframeLinewidth = 1; + this.wireframeLinecap = 'round'; + this.wireframeLinejoin = 'round'; - object.material = serialize( meta.materials, this.material ); + this.skinning = false; + this.morphTargets = false; - } + this.lights = false; - } + this.setValues( parameters ); - // + } - if ( this.children.length > 0 ) { + MeshBasicMaterial.prototype = Object.create( Material.prototype ); + MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; - object.children = []; + MeshBasicMaterial.prototype.isMeshBasicMaterial = true; - for ( var i = 0; i < this.children.length; i ++ ) { + MeshBasicMaterial.prototype.copy = function ( source ) { - object.children.push( this.children[ i ].toJSON( meta ).object ); + Material.prototype.copy.call( this, source ); - } + this.color.copy( source.color ); - } + this.map = source.map; - if ( isRootObject ) { + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; - var geometries = extractFromCache( meta.geometries ); - var materials = extractFromCache( meta.materials ); - var textures = extractFromCache( meta.textures ); - var images = extractFromCache( meta.images ); - var shapes = extractFromCache( meta.shapes ); + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; - if ( geometries.length > 0 ) output.geometries = geometries; - if ( materials.length > 0 ) output.materials = materials; - if ( textures.length > 0 ) output.textures = textures; - if ( images.length > 0 ) output.images = images; - if ( shapes.length > 0 ) output.shapes = shapes; + this.specularMap = source.specularMap; - } + this.alphaMap = source.alphaMap; - output.object = object; + this.envMap = source.envMap; + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; - return output; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; - // extract data from the cache hash - // remove metadata on each item - // and return as array - function extractFromCache( cache ) { + this.skinning = source.skinning; + this.morphTargets = source.morphTargets; - var values = []; - for ( var key in cache ) { + return this; - var data = cache[ key ]; - delete data.metadata; - values.push( data ); + }; - } - return values; + /** + * @author mrdoob / http://mrdoob.com/ + */ - } + function BufferAttribute( array, itemSize, normalized ) { - }, + if ( Array.isArray( array ) ) { - clone: function ( recursive ) { + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - return new this.constructor().copy( this, recursive ); + } - }, + this.name = ''; - copy: function ( source, recursive ) { + this.array = array; + this.itemSize = itemSize; + this.count = array !== undefined ? array.length / itemSize : 0; + this.normalized = normalized === true; - if ( recursive === undefined ) recursive = true; + this.dynamic = false; + this.updateRange = { offset: 0, count: - 1 }; - this.name = source.name; + this.version = 0; - this.up.copy( source.up ); + } - this.position.copy( source.position ); - this.quaternion.copy( source.quaternion ); - this.scale.copy( source.scale ); + Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', { - this.matrix.copy( source.matrix ); - this.matrixWorld.copy( source.matrixWorld ); + set: function ( value ) { - this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; + if ( value === true ) this.version ++; - this.layers.mask = source.layers.mask; - this.visible = source.visible; + } - this.castShadow = source.castShadow; - this.receiveShadow = source.receiveShadow; + } ); - this.frustumCulled = source.frustumCulled; - this.renderOrder = source.renderOrder; + Object.assign( BufferAttribute.prototype, { - this.userData = JSON.parse( JSON.stringify( source.userData ) ); + isBufferAttribute: true, - if ( recursive === true ) { + onUploadCallback: function () {}, - for ( var i = 0; i < source.children.length; i ++ ) { + setArray: function ( array ) { - var child = source.children[ i ]; - this.add( child.clone() ); + if ( Array.isArray( array ) ) { - } + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); } - return this; + this.count = array !== undefined ? array.length / this.itemSize : 0; + this.array = array; - } + return this; - } ); + }, - /** - * @author mrdoob / http://mrdoob.com/ - * @author kile / http://kile.stravaganza.org/ - * @author alteredq / http://alteredqualia.com/ - * @author mikael emtinger / http://gomo.se/ - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author bhouston / http://clara.io - */ + setDynamic: function ( value ) { - var geometryId = 0; // Geometry uses even numbers as Id + this.dynamic = value; - function Geometry() { + return this; - Object.defineProperty( this, 'id', { value: geometryId += 2 } ); + }, - this.uuid = _Math.generateUUID(); + copy: function ( source ) { - this.name = ''; - this.type = 'Geometry'; + this.name = source.name; + this.array = new source.array.constructor( source.array ); + this.itemSize = source.itemSize; + this.count = source.count; + this.normalized = source.normalized; - this.vertices = []; - this.colors = []; - this.faces = []; - this.faceVertexUvs = [[]]; + this.dynamic = source.dynamic; - this.morphTargets = []; - this.morphNormals = []; + return this; - this.skinWeights = []; - this.skinIndices = []; + }, - this.lineDistances = []; + copyAt: function ( index1, attribute, index2 ) { - this.boundingBox = null; - this.boundingSphere = null; + index1 *= this.itemSize; + index2 *= attribute.itemSize; - // update flags + for ( var i = 0, l = this.itemSize; i < l; i ++ ) { - this.elementsNeedUpdate = false; - this.verticesNeedUpdate = false; - this.uvsNeedUpdate = false; - this.normalsNeedUpdate = false; - this.colorsNeedUpdate = false; - this.lineDistancesNeedUpdate = false; - this.groupsNeedUpdate = false; + this.array[ index1 + i ] = attribute.array[ index2 + i ]; - } + } - Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + return this; - constructor: Geometry, + }, - isGeometry: true, + copyArray: function ( array ) { - applyMatrix: function ( matrix ) { + this.array.set( array ); - var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + return this; - for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { + }, - var vertex = this.vertices[ i ]; - vertex.applyMatrix4( matrix ); + copyColorsArray: function ( colors ) { - } + var array = this.array, offset = 0; - for ( var i = 0, il = this.faces.length; i < il; i ++ ) { + for ( var i = 0, l = colors.length; i < l; i ++ ) { - var face = this.faces[ i ]; - face.normal.applyMatrix3( normalMatrix ).normalize(); + var color = colors[ i ]; - for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { + if ( color === undefined ) { - face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); + console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); + color = new Color(); } + array[ offset ++ ] = color.r; + array[ offset ++ ] = color.g; + array[ offset ++ ] = color.b; + } - if ( this.boundingBox !== null ) { + return this; - this.computeBoundingBox(); + }, - } + copyVector2sArray: function ( vectors ) { - if ( this.boundingSphere !== null ) { + var array = this.array, offset = 0; - this.computeBoundingSphere(); + for ( var i = 0, l = vectors.length; i < l; i ++ ) { - } + var vector = vectors[ i ]; - this.verticesNeedUpdate = true; - this.normalsNeedUpdate = true; + if ( vector === undefined ) { - return this; + console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); + vector = new Vector2(); - }, + } - rotateX: function () { + array[ offset ++ ] = vector.x; + array[ offset ++ ] = vector.y; - // rotate geometry around world x-axis + } - var m1 = new Matrix4(); + return this; - return function rotateX( angle ) { + }, - m1.makeRotationX( angle ); + copyVector3sArray: function ( vectors ) { - this.applyMatrix( m1 ); + var array = this.array, offset = 0; - return this; + for ( var i = 0, l = vectors.length; i < l; i ++ ) { - }; + var vector = vectors[ i ]; - }(), + if ( vector === undefined ) { - rotateY: function () { + console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i ); + vector = new Vector3(); - // rotate geometry around world y-axis + } - var m1 = new Matrix4(); + array[ offset ++ ] = vector.x; + array[ offset ++ ] = vector.y; + array[ offset ++ ] = vector.z; - return function rotateY( angle ) { + } - m1.makeRotationY( angle ); + return this; - this.applyMatrix( m1 ); + }, - return this; + copyVector4sArray: function ( vectors ) { - }; + var array = this.array, offset = 0; - }(), + for ( var i = 0, l = vectors.length; i < l; i ++ ) { - rotateZ: function () { + var vector = vectors[ i ]; - // rotate geometry around world z-axis + if ( vector === undefined ) { - var m1 = new Matrix4(); + console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); + vector = new Vector4(); - return function rotateZ( angle ) { + } - m1.makeRotationZ( angle ); + array[ offset ++ ] = vector.x; + array[ offset ++ ] = vector.y; + array[ offset ++ ] = vector.z; + array[ offset ++ ] = vector.w; - this.applyMatrix( m1 ); + } - return this; + return this; - }; + }, - }(), + set: function ( value, offset ) { - translate: function () { + if ( offset === undefined ) offset = 0; - // translate geometry + this.array.set( value, offset ); - var m1 = new Matrix4(); + return this; - return function translate( x, y, z ) { + }, - m1.makeTranslation( x, y, z ); + getX: function ( index ) { - this.applyMatrix( m1 ); + return this.array[ index * this.itemSize ]; - return this; + }, - }; + setX: function ( index, x ) { - }(), + this.array[ index * this.itemSize ] = x; - scale: function () { + return this; - // scale geometry + }, - var m1 = new Matrix4(); + getY: function ( index ) { - return function scale( x, y, z ) { + return this.array[ index * this.itemSize + 1 ]; - m1.makeScale( x, y, z ); + }, - this.applyMatrix( m1 ); + setY: function ( index, y ) { - return this; + this.array[ index * this.itemSize + 1 ] = y; - }; + return this; - }(), + }, - lookAt: function () { + getZ: function ( index ) { - var obj = new Object3D(); + return this.array[ index * this.itemSize + 2 ]; - return function lookAt( vector ) { + }, - obj.lookAt( vector ); + setZ: function ( index, z ) { - obj.updateMatrix(); + this.array[ index * this.itemSize + 2 ] = z; - this.applyMatrix( obj.matrix ); + return this; - }; + }, - }(), + getW: function ( index ) { - fromBufferGeometry: function ( geometry ) { + return this.array[ index * this.itemSize + 3 ]; - var scope = this; + }, - var indices = geometry.index !== null ? geometry.index.array : undefined; - var attributes = geometry.attributes; + setW: function ( index, w ) { - var positions = attributes.position.array; - var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; - var colors = attributes.color !== undefined ? attributes.color.array : undefined; - var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; - var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; + this.array[ index * this.itemSize + 3 ] = w; - if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = []; + return this; - for ( var i = 0; i < positions.length; i += 3 ) { + }, - scope.vertices.push( new Vector3().fromArray( positions, i ) ); + setXY: function ( index, x, y ) { - if ( colors !== undefined ) { + index *= this.itemSize; - scope.colors.push( new Color().fromArray( colors, i ) ); + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; - } + return this; - } + }, - function addFace( a, b, c, materialIndex ) { + setXYZ: function ( index, x, y, z ) { - var vertexColors = ( colors === undefined ) ? [] : [ - scope.colors[ a ].clone(), - scope.colors[ b ].clone(), - scope.colors[ c ].clone() ]; + index *= this.itemSize; - var vertexNormals = ( normals === undefined ) ? [] : [ - new Vector3().fromArray( normals, a * 3 ), - new Vector3().fromArray( normals, b * 3 ), - new Vector3().fromArray( normals, c * 3 ) - ]; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; - var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); + return this; - scope.faces.push( face ); + }, - if ( uvs !== undefined ) { + setXYZW: function ( index, x, y, z, w ) { - scope.faceVertexUvs[ 0 ].push( [ - new Vector2().fromArray( uvs, a * 2 ), - new Vector2().fromArray( uvs, b * 2 ), - new Vector2().fromArray( uvs, c * 2 ) - ] ); + index *= this.itemSize; - } + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; + this.array[ index + 3 ] = w; - if ( uvs2 !== undefined ) { + return this; - scope.faceVertexUvs[ 1 ].push( [ - new Vector2().fromArray( uvs2, a * 2 ), - new Vector2().fromArray( uvs2, b * 2 ), - new Vector2().fromArray( uvs2, c * 2 ) - ] ); + }, - } + onUpload: function ( callback ) { - } + this.onUploadCallback = callback; - var groups = geometry.groups; + return this; - if ( groups.length > 0 ) { + }, - for ( var i = 0; i < groups.length; i ++ ) { + clone: function () { - var group = groups[ i ]; + return new this.constructor( this.array, this.itemSize ).copy( this ); - var start = group.start; - var count = group.count; + }, - for ( var j = start, jl = start + count; j < jl; j += 3 ) { + toJSON: function () { - if ( indices !== undefined ) { + return { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: Array.prototype.slice.call( this.array ), + normalized: this.normalized + }; - addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); + } - } else { + } ); - addFace( j, j + 1, j + 2, group.materialIndex ); + // - } + function Int8BufferAttribute( array, itemSize, normalized ) { - } + BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized ); - } + } - } else { + Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; - if ( indices !== undefined ) { - for ( var i = 0; i < indices.length; i += 3 ) { + function Uint8BufferAttribute( array, itemSize, normalized ) { - addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); + BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized ); - } + } - } else { + Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; - for ( var i = 0; i < positions.length / 3; i += 3 ) { - addFace( i, i + 1, i + 2 ); + function Uint8ClampedBufferAttribute( array, itemSize, normalized ) { - } + BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized ); - } + } - } + Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; - this.computeFaceNormals(); - if ( geometry.boundingBox !== null ) { + function Int16BufferAttribute( array, itemSize, normalized ) { - this.boundingBox = geometry.boundingBox.clone(); + BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized ); - } + } - if ( geometry.boundingSphere !== null ) { + Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; - this.boundingSphere = geometry.boundingSphere.clone(); - } + function Uint16BufferAttribute( array, itemSize, normalized ) { - return this; + BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized ); - }, + } - center: function () { + Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; - var offset = new Vector3(); - return function center() { + function Int32BufferAttribute( array, itemSize, normalized ) { - this.computeBoundingBox(); + BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized ); - this.boundingBox.getCenter( offset ).negate(); + } - this.translate( offset.x, offset.y, offset.z ); + Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; - return this; - }; + function Uint32BufferAttribute( array, itemSize, normalized ) { - }(), + BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized ); - normalize: function () { + } - this.computeBoundingSphere(); + Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; - var center = this.boundingSphere.center; - var radius = this.boundingSphere.radius; - var s = radius === 0 ? 1 : 1.0 / radius; + function Float32BufferAttribute( array, itemSize, normalized ) { - var matrix = new Matrix4(); - matrix.set( - s, 0, 0, - s * center.x, - 0, s, 0, - s * center.y, - 0, 0, s, - s * center.z, - 0, 0, 0, 1 - ); + BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized ); - this.applyMatrix( matrix ); + } - return this; + Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; - }, - computeFaceNormals: function () { + function Float64BufferAttribute( array, itemSize, normalized ) { - var cb = new Vector3(), ab = new Vector3(); + BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized ); - for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { + } - var face = this.faces[ f ]; + Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); + Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; - var vA = this.vertices[ face.a ]; - var vB = this.vertices[ face.b ]; - var vC = this.vertices[ face.c ]; + /** + * @author mrdoob / http://mrdoob.com/ + */ - cb.subVectors( vC, vB ); - ab.subVectors( vA, vB ); - cb.cross( ab ); + function DirectGeometry() { - cb.normalize(); + this.vertices = []; + this.normals = []; + this.colors = []; + this.uvs = []; + this.uvs2 = []; - face.normal.copy( cb ); + this.groups = []; - } + this.morphTargets = {}; - }, + this.skinWeights = []; + this.skinIndices = []; - computeVertexNormals: function ( areaWeighted ) { + // this.lineDistances = []; - if ( areaWeighted === undefined ) areaWeighted = true; + this.boundingBox = null; + this.boundingSphere = null; - var v, vl, f, fl, face, vertices; + // update flags - vertices = new Array( this.vertices.length ); + this.verticesNeedUpdate = false; + this.normalsNeedUpdate = false; + this.colorsNeedUpdate = false; + this.uvsNeedUpdate = false; + this.groupsNeedUpdate = false; - for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { + } - vertices[ v ] = new Vector3(); + Object.assign( DirectGeometry.prototype, { - } + computeGroups: function ( geometry ) { - if ( areaWeighted ) { + var group; + var groups = []; + var materialIndex = undefined; - // vertex normals weighted by triangle areas - // http://www.iquilezles.org/www/articles/normals/normals.htm + var faces = geometry.faces; - var vA, vB, vC; - var cb = new Vector3(), ab = new Vector3(); + for ( var i = 0; i < faces.length; i ++ ) { - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + var face = faces[ i ]; - face = this.faces[ f ]; + // materials - vA = this.vertices[ face.a ]; - vB = this.vertices[ face.b ]; - vC = this.vertices[ face.c ]; + if ( face.materialIndex !== materialIndex ) { - cb.subVectors( vC, vB ); - ab.subVectors( vA, vB ); - cb.cross( ab ); + materialIndex = face.materialIndex; - vertices[ face.a ].add( cb ); - vertices[ face.b ].add( cb ); - vertices[ face.c ].add( cb ); + if ( group !== undefined ) { - } + group.count = ( i * 3 ) - group.start; + groups.push( group ); - } else { + } - this.computeFaceNormals(); + group = { + start: i * 3, + materialIndex: materialIndex + }; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + } - face = this.faces[ f ]; + } - vertices[ face.a ].add( face.normal ); - vertices[ face.b ].add( face.normal ); - vertices[ face.c ].add( face.normal ); + if ( group !== undefined ) { - } + group.count = ( i * 3 ) - group.start; + groups.push( group ); } - for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { + this.groups = groups; - vertices[ v ].normalize(); + }, - } + fromGeometry: function ( geometry ) { - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + var faces = geometry.faces; + var vertices = geometry.vertices; + var faceVertexUvs = geometry.faceVertexUvs; - face = this.faces[ f ]; + var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0; + var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0; - var vertexNormals = face.vertexNormals; + // morphs - if ( vertexNormals.length === 3 ) { + var morphTargets = geometry.morphTargets; + var morphTargetsLength = morphTargets.length; - vertexNormals[ 0 ].copy( vertices[ face.a ] ); - vertexNormals[ 1 ].copy( vertices[ face.b ] ); - vertexNormals[ 2 ].copy( vertices[ face.c ] ); + var morphTargetsPosition; - } else { + if ( morphTargetsLength > 0 ) { - vertexNormals[ 0 ] = vertices[ face.a ].clone(); - vertexNormals[ 1 ] = vertices[ face.b ].clone(); - vertexNormals[ 2 ] = vertices[ face.c ].clone(); + morphTargetsPosition = []; - } + for ( var i = 0; i < morphTargetsLength; i ++ ) { - } + morphTargetsPosition[ i ] = { + name: morphTargets[ i ].name, + data: [] + }; - if ( this.faces.length > 0 ) { + } - this.normalsNeedUpdate = true; + this.morphTargets.position = morphTargetsPosition; } - }, + var morphNormals = geometry.morphNormals; + var morphNormalsLength = morphNormals.length; - computeFlatVertexNormals: function () { + var morphTargetsNormal; - var f, fl, face; + if ( morphNormalsLength > 0 ) { - this.computeFaceNormals(); + morphTargetsNormal = []; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + for ( var i = 0; i < morphNormalsLength; i ++ ) { - face = this.faces[ f ]; + morphTargetsNormal[ i ] = { + name: morphNormals[ i ].name, + data: [] + }; - var vertexNormals = face.vertexNormals; + } - if ( vertexNormals.length === 3 ) { + this.morphTargets.normal = morphTargetsNormal; - vertexNormals[ 0 ].copy( face.normal ); - vertexNormals[ 1 ].copy( face.normal ); - vertexNormals[ 2 ].copy( face.normal ); + } - } else { + // skins - vertexNormals[ 0 ] = face.normal.clone(); - vertexNormals[ 1 ] = face.normal.clone(); - vertexNormals[ 2 ] = face.normal.clone(); + var skinIndices = geometry.skinIndices; + var skinWeights = geometry.skinWeights; - } + var hasSkinIndices = skinIndices.length === vertices.length; + var hasSkinWeights = skinWeights.length === vertices.length; - } + // - if ( this.faces.length > 0 ) { + if ( vertices.length > 0 && faces.length === 0 ) { - this.normalsNeedUpdate = true; + console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' ); } - }, - - computeMorphNormals: function () { - - var i, il, f, fl, face; + for ( var i = 0; i < faces.length; i ++ ) { - // save original normals - // - create temp variables on first access - // otherwise just copy (for faster repeated calls) + var face = faces[ i ]; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] ); - face = this.faces[ f ]; + var vertexNormals = face.vertexNormals; - if ( ! face.__originalFaceNormal ) { + if ( vertexNormals.length === 3 ) { - face.__originalFaceNormal = face.normal.clone(); + this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] ); } else { - face.__originalFaceNormal.copy( face.normal ); + var normal = face.normal; - } + this.normals.push( normal, normal, normal ); - if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; + } - for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { + var vertexColors = face.vertexColors; - if ( ! face.__originalVertexNormals[ i ] ) { + if ( vertexColors.length === 3 ) { - face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); + this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] ); - } else { + } else { - face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); + var color = face.color; - } + this.colors.push( color, color, color ); } - } + if ( hasFaceVertexUv === true ) { - // use temp geometry to compute face and vertex normals for each morph + var vertexUvs = faceVertexUvs[ 0 ][ i ]; - var tmpGeo = new Geometry(); - tmpGeo.faces = this.faces; + if ( vertexUvs !== undefined ) { - for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { + this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); - // create on first access + } else { - if ( ! this.morphNormals[ i ] ) { + console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i ); - this.morphNormals[ i ] = {}; - this.morphNormals[ i ].faceNormals = []; - this.morphNormals[ i ].vertexNormals = []; + this.uvs.push( new Vector2(), new Vector2(), new Vector2() ); - var dstNormalsFace = this.morphNormals[ i ].faceNormals; - var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; + } - var faceNormal, vertexNormals; + } - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + if ( hasFaceVertexUv2 === true ) { - faceNormal = new Vector3(); - vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() }; + var vertexUvs = faceVertexUvs[ 1 ][ i ]; - dstNormalsFace.push( faceNormal ); - dstNormalsVertex.push( vertexNormals ); + if ( vertexUvs !== undefined ) { - } + this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); - } + } else { - var morphNormals = this.morphNormals[ i ]; + console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i ); - // set vertices to morph target + this.uvs2.push( new Vector2(), new Vector2(), new Vector2() ); - tmpGeo.vertices = this.morphTargets[ i ].vertices; + } - // compute morph normals + } - tmpGeo.computeFaceNormals(); - tmpGeo.computeVertexNormals(); + // morphs - // store morph normals + for ( var j = 0; j < morphTargetsLength; j ++ ) { - var faceNormal, vertexNormals; + var morphTarget = morphTargets[ j ].vertices; - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] ); - face = this.faces[ f ]; + } - faceNormal = morphNormals.faceNormals[ f ]; - vertexNormals = morphNormals.vertexNormals[ f ]; + for ( var j = 0; j < morphNormalsLength; j ++ ) { - faceNormal.copy( face.normal ); + var morphNormal = morphNormals[ j ].vertexNormals[ i ]; - vertexNormals.a.copy( face.vertexNormals[ 0 ] ); - vertexNormals.b.copy( face.vertexNormals[ 1 ] ); - vertexNormals.c.copy( face.vertexNormals[ 2 ] ); + morphTargetsNormal[ j ].data.push( morphNormal.a, morphNormal.b, morphNormal.c ); } - } - - // restore original normals + // skins - for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { + if ( hasSkinIndices ) { - face = this.faces[ f ]; + this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] ); - face.normal = face.__originalFaceNormal; - face.vertexNormals = face.__originalVertexNormals; + } - } + if ( hasSkinWeights ) { - }, + this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] ); - computeBoundingBox: function () { + } - if ( this.boundingBox === null ) { + } - this.boundingBox = new Box3(); + this.computeGroups( geometry ); - } + this.verticesNeedUpdate = geometry.verticesNeedUpdate; + this.normalsNeedUpdate = geometry.normalsNeedUpdate; + this.colorsNeedUpdate = geometry.colorsNeedUpdate; + this.uvsNeedUpdate = geometry.uvsNeedUpdate; + this.groupsNeedUpdate = geometry.groupsNeedUpdate; - this.boundingBox.setFromPoints( this.vertices ); + if ( geometry.boundingSphere !== null ) { - }, + this.boundingSphere = geometry.boundingSphere.clone(); - computeBoundingSphere: function () { + } - if ( this.boundingSphere === null ) { + if ( geometry.boundingBox !== null ) { - this.boundingSphere = new Sphere(); + this.boundingBox = geometry.boundingBox.clone(); } - this.boundingSphere.setFromPoints( this.vertices ); + return this; - }, + } - merge: function ( geometry, matrix, materialIndexOffset ) { + } ); - if ( ! ( geometry && geometry.isGeometry ) ) { + /** + * @author mrdoob / http://mrdoob.com/ + */ - console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); - return; + function arrayMax( array ) { - } + if ( array.length === 0 ) return - Infinity; - var normalMatrix, - vertexOffset = this.vertices.length, - vertices1 = this.vertices, - vertices2 = geometry.vertices, - faces1 = this.faces, - faces2 = geometry.faces, - uvs1 = this.faceVertexUvs[ 0 ], - uvs2 = geometry.faceVertexUvs[ 0 ], - colors1 = this.colors, - colors2 = geometry.colors; + var max = array[ 0 ]; - if ( materialIndexOffset === undefined ) materialIndexOffset = 0; + for ( var i = 1, l = array.length; i < l; ++ i ) { - if ( matrix !== undefined ) { + if ( array[ i ] > max ) max = array[ i ]; - normalMatrix = new Matrix3().getNormalMatrix( matrix ); + } - } + return max; - // vertices + } - for ( var i = 0, il = vertices2.length; i < il; i ++ ) { + /** + * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ + */ - var vertex = vertices2[ i ]; + var bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id - var vertexCopy = vertex.clone(); + function BufferGeometry() { - if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); + Object.defineProperty( this, 'id', { value: bufferGeometryId += 2 } ); - vertices1.push( vertexCopy ); + this.uuid = _Math.generateUUID(); - } + this.name = ''; + this.type = 'BufferGeometry'; - // colors + this.index = null; + this.attributes = {}; - for ( var i = 0, il = colors2.length; i < il; i ++ ) { + this.morphAttributes = {}; - colors1.push( colors2[ i ].clone() ); + this.groups = []; - } + this.boundingBox = null; + this.boundingSphere = null; - // faces + this.drawRange = { start: 0, count: Infinity }; - for ( i = 0, il = faces2.length; i < il; i ++ ) { + this.userData = {}; - var face = faces2[ i ], faceCopy, normal, color, - faceVertexNormals = face.vertexNormals, - faceVertexColors = face.vertexColors; + } - faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); - faceCopy.normal.copy( face.normal ); + BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - if ( normalMatrix !== undefined ) { + constructor: BufferGeometry, - faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); + isBufferGeometry: true, - } + getIndex: function () { - for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { + return this.index; - normal = faceVertexNormals[ j ].clone(); + }, - if ( normalMatrix !== undefined ) { + setIndex: function ( index ) { - normal.applyMatrix3( normalMatrix ).normalize(); + if ( Array.isArray( index ) ) { - } + this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); - faceCopy.vertexNormals.push( normal ); + } else { - } + this.index = index; - faceCopy.color.copy( face.color ); + } - for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { + }, - color = faceVertexColors[ j ]; - faceCopy.vertexColors.push( color.clone() ); + addAttribute: function ( name, attribute ) { - } + if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { - faceCopy.materialIndex = face.materialIndex + materialIndexOffset; + console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); - faces1.push( faceCopy ); + return this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); } - // uvs + if ( name === 'index' ) { - for ( i = 0, il = uvs2.length; i < il; i ++ ) { + console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); + this.setIndex( attribute ); - var uv = uvs2[ i ], uvCopy = []; + return this; - if ( uv === undefined ) { + } - continue; + this.attributes[ name ] = attribute; - } + return this; - for ( var j = 0, jl = uv.length; j < jl; j ++ ) { + }, - uvCopy.push( uv[ j ].clone() ); + getAttribute: function ( name ) { - } + return this.attributes[ name ]; - uvs1.push( uvCopy ); + }, - } + removeAttribute: function ( name ) { - }, + delete this.attributes[ name ]; - mergeMesh: function ( mesh ) { + return this; - if ( ! ( mesh && mesh.isMesh ) ) { + }, - console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); - return; + addGroup: function ( start, count, materialIndex ) { - } + this.groups.push( { - if ( mesh.matrixAutoUpdate ) mesh.updateMatrix(); + start: start, + count: count, + materialIndex: materialIndex !== undefined ? materialIndex : 0 - this.merge( mesh.geometry, mesh.matrix ); + } ); }, - /* - * Checks for duplicate vertices with hashmap. - * Duplicated vertices are removed - * and faces' vertices are updated. - */ - - mergeVertices: function () { + clearGroups: function () { - var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) - var unique = [], changes = []; + this.groups = []; - var v, key; - var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 - var precision = Math.pow( 10, precisionPoints ); - var i, il, face; - var indices, j, jl; + }, - for ( i = 0, il = this.vertices.length; i < il; i ++ ) { + setDrawRange: function ( start, count ) { - v = this.vertices[ i ]; - key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); + this.drawRange.start = start; + this.drawRange.count = count; - if ( verticesMap[ key ] === undefined ) { + }, - verticesMap[ key ] = i; - unique.push( this.vertices[ i ] ); - changes[ i ] = unique.length - 1; + applyMatrix: function ( matrix ) { - } else { + var position = this.attributes.position; - //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); - changes[ i ] = changes[ verticesMap[ key ] ]; + if ( position !== undefined ) { - } + matrix.applyToBufferAttribute( position ); + position.needsUpdate = true; } + var normal = this.attributes.normal; - // if faces are completely degenerate after merging vertices, we - // have to remove them from the geometry. - var faceIndicesToRemove = []; + if ( normal !== undefined ) { - for ( i = 0, il = this.faces.length; i < il; i ++ ) { + var normalMatrix = new Matrix3().getNormalMatrix( matrix ); - face = this.faces[ i ]; + normalMatrix.applyToBufferAttribute( normal ); + normal.needsUpdate = true; - face.a = changes[ face.a ]; - face.b = changes[ face.b ]; - face.c = changes[ face.c ]; + } - indices = [ face.a, face.b, face.c ]; + var tangent = this.attributes.tangent; - // if any duplicate vertices are found in a Face3 - // we have to remove the face as nothing can be saved - for ( var n = 0; n < 3; n ++ ) { + if ( tangent !== undefined ) { - if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) { + var normalMatrix = new Matrix3().getNormalMatrix( matrix ); - faceIndicesToRemove.push( i ); - break; + // Tangent is vec4, but the '.w' component is a sign value (+1/-1). + normalMatrix.applyToBufferAttribute( tangent ); + tangent.needsUpdate = true; - } + } - } + if ( this.boundingBox !== null ) { + + this.computeBoundingBox(); } - for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { + if ( this.boundingSphere !== null ) { - var idx = faceIndicesToRemove[ i ]; + this.computeBoundingSphere(); - this.faces.splice( idx, 1 ); + } - for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { + return this; - this.faceVertexUvs[ j ].splice( idx, 1 ); + }, - } + rotateX: function () { - } + // rotate geometry around world x-axis - // Use unique set of vertices + var m1 = new Matrix4(); - var diff = this.vertices.length - unique.length; - this.vertices = unique; - return diff; + return function rotateX( angle ) { - }, + m1.makeRotationX( angle ); - setFromPoints: function ( points ) { + this.applyMatrix( m1 ); - this.vertices = []; + return this; - for ( var i = 0, l = points.length; i < l; i ++ ) { + }; - var point = points[ i ]; - this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); + }(), - } + rotateY: function () { - return this; + // rotate geometry around world y-axis - }, + var m1 = new Matrix4(); - sortFacesByMaterialIndex: function () { + return function rotateY( angle ) { - var faces = this.faces; - var length = faces.length; + m1.makeRotationY( angle ); - // tag faces + this.applyMatrix( m1 ); - for ( var i = 0; i < length; i ++ ) { + return this; - faces[ i ]._id = i; + }; - } + }(), - // sort faces + rotateZ: function () { - function materialIndexSort( a, b ) { + // rotate geometry around world z-axis - return a.materialIndex - b.materialIndex; + var m1 = new Matrix4(); - } + return function rotateZ( angle ) { - faces.sort( materialIndexSort ); + m1.makeRotationZ( angle ); - // sort uvs + this.applyMatrix( m1 ); - var uvs1 = this.faceVertexUvs[ 0 ]; - var uvs2 = this.faceVertexUvs[ 1 ]; + return this; - var newUvs1, newUvs2; + }; - if ( uvs1 && uvs1.length === length ) newUvs1 = []; - if ( uvs2 && uvs2.length === length ) newUvs2 = []; + }(), - for ( var i = 0; i < length; i ++ ) { + translate: function () { - var id = faces[ i ]._id; + // translate geometry - if ( newUvs1 ) newUvs1.push( uvs1[ id ] ); - if ( newUvs2 ) newUvs2.push( uvs2[ id ] ); + var m1 = new Matrix4(); - } + return function translate( x, y, z ) { - if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1; - if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2; + m1.makeTranslation( x, y, z ); - }, + this.applyMatrix( m1 ); - toJSON: function () { + return this; - var data = { - metadata: { - version: 4.5, - type: 'Geometry', - generator: 'Geometry.toJSON' - } }; - // standard Geometry serialization + }(), - data.uuid = this.uuid; - data.type = this.type; - if ( this.name !== '' ) data.name = this.name; + scale: function () { - if ( this.parameters !== undefined ) { + // scale geometry - var parameters = this.parameters; + var m1 = new Matrix4(); - for ( var key in parameters ) { + return function scale( x, y, z ) { - if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + m1.makeScale( x, y, z ); - } + this.applyMatrix( m1 ); - return data; + return this; - } + }; - var vertices = []; + }(), - for ( var i = 0; i < this.vertices.length; i ++ ) { + lookAt: function () { - var vertex = this.vertices[ i ]; - vertices.push( vertex.x, vertex.y, vertex.z ); + var obj = new Object3D(); - } + return function lookAt( vector ) { - var faces = []; - var normals = []; - var normalsHash = {}; - var colors = []; - var colorsHash = {}; - var uvs = []; - var uvsHash = {}; + obj.lookAt( vector ); - for ( var i = 0; i < this.faces.length; i ++ ) { + obj.updateMatrix(); - var face = this.faces[ i ]; + this.applyMatrix( obj.matrix ); - var hasMaterial = true; - var hasFaceUv = false; // deprecated - var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined; - var hasFaceNormal = face.normal.length() > 0; - var hasFaceVertexNormal = face.vertexNormals.length > 0; - var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; - var hasFaceVertexColor = face.vertexColors.length > 0; + }; - var faceType = 0; + }(), - faceType = setBit( faceType, 0, 0 ); // isQuad - faceType = setBit( faceType, 1, hasMaterial ); - faceType = setBit( faceType, 2, hasFaceUv ); - faceType = setBit( faceType, 3, hasFaceVertexUv ); - faceType = setBit( faceType, 4, hasFaceNormal ); - faceType = setBit( faceType, 5, hasFaceVertexNormal ); - faceType = setBit( faceType, 6, hasFaceColor ); - faceType = setBit( faceType, 7, hasFaceVertexColor ); + center: function () { - faces.push( faceType ); - faces.push( face.a, face.b, face.c ); - faces.push( face.materialIndex ); + var offset = new Vector3(); - if ( hasFaceVertexUv ) { + return function center() { - var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ]; + this.computeBoundingBox(); - faces.push( - getUvIndex( faceVertexUvs[ 0 ] ), - getUvIndex( faceVertexUvs[ 1 ] ), - getUvIndex( faceVertexUvs[ 2 ] ) - ); + this.boundingBox.getCenter( offset ).negate(); - } + this.translate( offset.x, offset.y, offset.z ); - if ( hasFaceNormal ) { + return this; - faces.push( getNormalIndex( face.normal ) ); + }; - } + }(), - if ( hasFaceVertexNormal ) { + setFromObject: function ( object ) { - var vertexNormals = face.vertexNormals; + // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); - faces.push( - getNormalIndex( vertexNormals[ 0 ] ), - getNormalIndex( vertexNormals[ 1 ] ), - getNormalIndex( vertexNormals[ 2 ] ) - ); - - } + var geometry = object.geometry; - if ( hasFaceColor ) { + if ( object.isPoints || object.isLine ) { - faces.push( getColorIndex( face.color ) ); + var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); + var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); - } + this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); + this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); - if ( hasFaceVertexColor ) { + if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { - var vertexColors = face.vertexColors; + var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); - faces.push( - getColorIndex( vertexColors[ 0 ] ), - getColorIndex( vertexColors[ 1 ] ), - getColorIndex( vertexColors[ 2 ] ) - ); + this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); } - } - - function setBit( value, position, enabled ) { - - return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) ); - - } - - function getNormalIndex( normal ) { - - var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); - - if ( normalsHash[ hash ] !== undefined ) { + if ( geometry.boundingSphere !== null ) { - return normalsHash[ hash ]; + this.boundingSphere = geometry.boundingSphere.clone(); } - normalsHash[ hash ] = normals.length / 3; - normals.push( normal.x, normal.y, normal.z ); - - return normalsHash[ hash ]; + if ( geometry.boundingBox !== null ) { - } + this.boundingBox = geometry.boundingBox.clone(); - function getColorIndex( color ) { + } - var hash = color.r.toString() + color.g.toString() + color.b.toString(); + } else if ( object.isMesh ) { - if ( colorsHash[ hash ] !== undefined ) { + if ( geometry && geometry.isGeometry ) { - return colorsHash[ hash ]; + this.fromGeometry( geometry ); } - colorsHash[ hash ] = colors.length; - colors.push( color.getHex() ); - - return colorsHash[ hash ]; - } - function getUvIndex( uv ) { - - var hash = uv.x.toString() + uv.y.toString(); + return this; - if ( uvsHash[ hash ] !== undefined ) { + }, - return uvsHash[ hash ]; + setFromPoints: function ( points ) { - } + var position = []; - uvsHash[ hash ] = uvs.length / 2; - uvs.push( uv.x, uv.y ); + for ( var i = 0, l = points.length; i < l; i ++ ) { - return uvsHash[ hash ]; + var point = points[ i ]; + position.push( point.x, point.y, point.z || 0 ); } - data.data = {}; - - data.data.vertices = vertices; - data.data.normals = normals; - if ( colors.length > 0 ) data.data.colors = colors; - if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility - data.data.faces = faces; + this.addAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); - return data; + return this; }, - clone: function () { + updateFromObject: function ( object ) { - /* - // Handle primitives + var geometry = object.geometry; - var parameters = this.parameters; + if ( object.isMesh ) { - if ( parameters !== undefined ) { + var direct = geometry.__directGeometry; - var values = []; + if ( geometry.elementsNeedUpdate === true ) { - for ( var key in parameters ) { + direct = undefined; + geometry.elementsNeedUpdate = false; - values.push( parameters[ key ] ); + } - } + if ( direct === undefined ) { - var geometry = Object.create( this.constructor.prototype ); - this.constructor.apply( geometry, values ); - return geometry; + return this.fromGeometry( geometry ); - } + } - return new this.constructor().copy( this ); - */ + direct.verticesNeedUpdate = geometry.verticesNeedUpdate; + direct.normalsNeedUpdate = geometry.normalsNeedUpdate; + direct.colorsNeedUpdate = geometry.colorsNeedUpdate; + direct.uvsNeedUpdate = geometry.uvsNeedUpdate; + direct.groupsNeedUpdate = geometry.groupsNeedUpdate; - return new Geometry().copy( this ); + geometry.verticesNeedUpdate = false; + geometry.normalsNeedUpdate = false; + geometry.colorsNeedUpdate = false; + geometry.uvsNeedUpdate = false; + geometry.groupsNeedUpdate = false; - }, + geometry = direct; - copy: function ( source ) { + } - var i, il, j, jl, k, kl; + var attribute; - // reset + if ( geometry.verticesNeedUpdate === true ) { - this.vertices = []; - this.colors = []; - this.faces = []; - this.faceVertexUvs = [[]]; - this.morphTargets = []; - this.morphNormals = []; - this.skinWeights = []; - this.skinIndices = []; - this.lineDistances = []; - this.boundingBox = null; - this.boundingSphere = null; + attribute = this.attributes.position; - // name + if ( attribute !== undefined ) { - this.name = source.name; + attribute.copyVector3sArray( geometry.vertices ); + attribute.needsUpdate = true; - // vertices + } - var vertices = source.vertices; + geometry.verticesNeedUpdate = false; - for ( i = 0, il = vertices.length; i < il; i ++ ) { + } - this.vertices.push( vertices[ i ].clone() ); + if ( geometry.normalsNeedUpdate === true ) { - } + attribute = this.attributes.normal; - // colors + if ( attribute !== undefined ) { - var colors = source.colors; + attribute.copyVector3sArray( geometry.normals ); + attribute.needsUpdate = true; - for ( i = 0, il = colors.length; i < il; i ++ ) { + } - this.colors.push( colors[ i ].clone() ); + geometry.normalsNeedUpdate = false; } - // faces + if ( geometry.colorsNeedUpdate === true ) { - var faces = source.faces; + attribute = this.attributes.color; - for ( i = 0, il = faces.length; i < il; i ++ ) { + if ( attribute !== undefined ) { - this.faces.push( faces[ i ].clone() ); + attribute.copyColorsArray( geometry.colors ); + attribute.needsUpdate = true; - } + } - // face vertex uvs + geometry.colorsNeedUpdate = false; - for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { + } - var faceVertexUvs = source.faceVertexUvs[ i ]; + if ( geometry.uvsNeedUpdate ) { - if ( this.faceVertexUvs[ i ] === undefined ) { + attribute = this.attributes.uv; - this.faceVertexUvs[ i ] = []; + if ( attribute !== undefined ) { - } + attribute.copyVector2sArray( geometry.uvs ); + attribute.needsUpdate = true; - for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { + } - var uvs = faceVertexUvs[ j ], uvsCopy = []; + geometry.uvsNeedUpdate = false; - for ( k = 0, kl = uvs.length; k < kl; k ++ ) { + } - var uv = uvs[ k ]; + if ( geometry.lineDistancesNeedUpdate ) { - uvsCopy.push( uv.clone() ); + attribute = this.attributes.lineDistance; - } + if ( attribute !== undefined ) { - this.faceVertexUvs[ i ].push( uvsCopy ); + attribute.copyArray( geometry.lineDistances ); + attribute.needsUpdate = true; } + geometry.lineDistancesNeedUpdate = false; + } - // morph targets + if ( geometry.groupsNeedUpdate ) { - var morphTargets = source.morphTargets; + geometry.computeGroups( object.geometry ); + this.groups = geometry.groups; - for ( i = 0, il = morphTargets.length; i < il; i ++ ) { + geometry.groupsNeedUpdate = false; - var morphTarget = {}; - morphTarget.name = morphTargets[ i ].name; + } - // vertices + return this; - if ( morphTargets[ i ].vertices !== undefined ) { + }, - morphTarget.vertices = []; + fromGeometry: function ( geometry ) { - for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) { + geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry ); - morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() ); + return this.fromDirectGeometry( geometry.__directGeometry ); - } + }, - } + fromDirectGeometry: function ( geometry ) { - // normals + var positions = new Float32Array( geometry.vertices.length * 3 ); + this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); - if ( morphTargets[ i ].normals !== undefined ) { + if ( geometry.normals.length > 0 ) { - morphTarget.normals = []; + var normals = new Float32Array( geometry.normals.length * 3 ); + this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); - for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) { + } - morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() ); + if ( geometry.colors.length > 0 ) { - } + var colors = new Float32Array( geometry.colors.length * 3 ); + this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); - } + } - this.morphTargets.push( morphTarget ); + if ( geometry.uvs.length > 0 ) { + + var uvs = new Float32Array( geometry.uvs.length * 2 ); + this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); } - // morph normals + if ( geometry.uvs2.length > 0 ) { - var morphNormals = source.morphNormals; + var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); + this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); - for ( i = 0, il = morphNormals.length; i < il; i ++ ) { + } - var morphNormal = {}; + // groups - // vertex normals + this.groups = geometry.groups; - if ( morphNormals[ i ].vertexNormals !== undefined ) { + // morphs - morphNormal.vertexNormals = []; + for ( var name in geometry.morphTargets ) { - for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) { + var array = []; + var morphTargets = geometry.morphTargets[ name ]; - var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ]; - var destVertexNormal = {}; + for ( var i = 0, l = morphTargets.length; i < l; i ++ ) { - destVertexNormal.a = srcVertexNormal.a.clone(); - destVertexNormal.b = srcVertexNormal.b.clone(); - destVertexNormal.c = srcVertexNormal.c.clone(); + var morphTarget = morphTargets[ i ]; - morphNormal.vertexNormals.push( destVertexNormal ); + var attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 ); + attribute.name = morphTarget.name; - } + array.push( attribute.copyVector3sArray( morphTarget.data ) ); } - // face normals + this.morphAttributes[ name ] = array; - if ( morphNormals[ i ].faceNormals !== undefined ) { + } - morphNormal.faceNormals = []; + // skinning - for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) { + if ( geometry.skinIndices.length > 0 ) { - morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() ); + var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); + this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); - } + } - } + if ( geometry.skinWeights.length > 0 ) { - this.morphNormals.push( morphNormal ); + var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); + this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); } - // skin weights - - var skinWeights = source.skinWeights; + // - for ( i = 0, il = skinWeights.length; i < il; i ++ ) { + if ( geometry.boundingSphere !== null ) { - this.skinWeights.push( skinWeights[ i ].clone() ); + this.boundingSphere = geometry.boundingSphere.clone(); } - // skin indices + if ( geometry.boundingBox !== null ) { - var skinIndices = source.skinIndices; + this.boundingBox = geometry.boundingBox.clone(); - for ( i = 0, il = skinIndices.length; i < il; i ++ ) { + } - this.skinIndices.push( skinIndices[ i ].clone() ); + return this; - } + }, - // line distances + computeBoundingBox: function () { - var lineDistances = source.lineDistances; + var box = new Box3(); - for ( i = 0, il = lineDistances.length; i < il; i ++ ) { + return function computeBoundingBox() { - this.lineDistances.push( lineDistances[ i ] ); + if ( this.boundingBox === null ) { - } + this.boundingBox = new Box3(); - // bounding box + } - var boundingBox = source.boundingBox; + var position = this.attributes.position; + var morphAttributesPosition = this.morphAttributes.position; - if ( boundingBox !== null ) { + if ( position !== undefined ) { - this.boundingBox = boundingBox.clone(); + this.boundingBox.setFromBufferAttribute( position ); - } + // process morph attributes if present - // bounding sphere + if ( morphAttributesPosition ) { - var boundingSphere = source.boundingSphere; + for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - if ( boundingSphere !== null ) { + var morphAttribute = morphAttributesPosition[ i ]; + box.setFromBufferAttribute( morphAttribute ); - this.boundingSphere = boundingSphere.clone(); + this.boundingBox.expandByPoint( box.min ); + this.boundingBox.expandByPoint( box.max ); - } + } - // update flags + } - this.elementsNeedUpdate = source.elementsNeedUpdate; - this.verticesNeedUpdate = source.verticesNeedUpdate; - this.uvsNeedUpdate = source.uvsNeedUpdate; - this.normalsNeedUpdate = source.normalsNeedUpdate; - this.colorsNeedUpdate = source.colorsNeedUpdate; - this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; - this.groupsNeedUpdate = source.groupsNeedUpdate; + } else { - return this; + this.boundingBox.makeEmpty(); - }, + } - dispose: function () { + if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { - this.dispatchEvent( { type: 'dispose' } ); + console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); - } + } - } ); + }; - /** - * @author mrdoob / http://mrdoob.com/ - */ + }(), - function BufferAttribute( array, itemSize, normalized ) { + computeBoundingSphere: function () { - if ( Array.isArray( array ) ) { + var box = new Box3(); + var boxMorphTargets = new Box3(); + var vector = new Vector3(); - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + return function computeBoundingSphere() { - } + if ( this.boundingSphere === null ) { - this.name = ''; + this.boundingSphere = new Sphere(); - this.array = array; - this.itemSize = itemSize; - this.count = array !== undefined ? array.length / itemSize : 0; - this.normalized = normalized === true; + } - this.dynamic = false; - this.updateRange = { offset: 0, count: - 1 }; + var position = this.attributes.position; + var morphAttributesPosition = this.morphAttributes.position; - this.version = 0; + if ( position ) { - } + // first, find the center of the bounding sphere - Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', { + var center = this.boundingSphere.center; - set: function ( value ) { + box.setFromBufferAttribute( position ); - if ( value === true ) this.version ++; + // process morph attributes if present - } + if ( morphAttributesPosition ) { - } ); + for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - Object.assign( BufferAttribute.prototype, { + var morphAttribute = morphAttributesPosition[ i ]; + boxMorphTargets.setFromBufferAttribute( morphAttribute ); - isBufferAttribute: true, + box.expandByPoint( boxMorphTargets.min ); + box.expandByPoint( boxMorphTargets.max ); - onUploadCallback: function () {}, + } - setArray: function ( array ) { + } - if ( Array.isArray( array ) ) { + box.getCenter( center ); - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + // second, try to find a boundingSphere with a radius smaller than the + // boundingSphere of the boundingBox: sqrt(3) smaller in the best case - } + var maxRadiusSq = 0; - this.count = array !== undefined ? array.length / this.itemSize : 0; - this.array = array; + for ( var i = 0, il = position.count; i < il; i ++ ) { - return this; + vector.fromBufferAttribute( position, i ); - }, + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); - setDynamic: function ( value ) { + } - this.dynamic = value; + // process morph attributes if present - return this; + if ( morphAttributesPosition ) { - }, + for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - copy: function ( source ) { + var morphAttribute = morphAttributesPosition[ i ]; - this.name = source.name; - this.array = new source.array.constructor( source.array ); - this.itemSize = source.itemSize; - this.count = source.count; - this.normalized = source.normalized; + for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { - this.dynamic = source.dynamic; + vector.fromBufferAttribute( morphAttribute, j ); - return this; + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); - }, + } - copyAt: function ( index1, attribute, index2 ) { + } - index1 *= this.itemSize; - index2 *= attribute.itemSize; + } - for ( var i = 0, l = this.itemSize; i < l; i ++ ) { + this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); - this.array[ index1 + i ] = attribute.array[ index2 + i ]; + if ( isNaN( this.boundingSphere.radius ) ) { - } + console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); - return this; + } - }, + } - copyArray: function ( array ) { + }; - this.array.set( array ); + }(), - return this; + computeFaceNormals: function () { + + // backwards compatibility }, - copyColorsArray: function ( colors ) { + computeVertexNormals: function () { - var array = this.array, offset = 0; + var index = this.index; + var attributes = this.attributes; - for ( var i = 0, l = colors.length; i < l; i ++ ) { + if ( attributes.position ) { - var color = colors[ i ]; + var positions = attributes.position.array; - if ( color === undefined ) { + if ( attributes.normal === undefined ) { - console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i ); - color = new Color(); + this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); - } + } else { - array[ offset ++ ] = color.r; - array[ offset ++ ] = color.g; - array[ offset ++ ] = color.b; + // reset existing normals to zero - } + var array = attributes.normal.array; - return this; + for ( var i = 0, il = array.length; i < il; i ++ ) { - }, + array[ i ] = 0; - copyVector2sArray: function ( vectors ) { - - var array = this.array, offset = 0; - - for ( var i = 0, l = vectors.length; i < l; i ++ ) { - - var vector = vectors[ i ]; - - if ( vector === undefined ) { - - console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i ); - vector = new Vector2(); + } } - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; + var normals = attributes.normal.array; - } + var vA, vB, vC; + var pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); + var cb = new Vector3(), ab = new Vector3(); - return this; + // indexed elements - }, + if ( index ) { - copyVector3sArray: function ( vectors ) { + var indices = index.array; - var array = this.array, offset = 0; + for ( var i = 0, il = index.count; i < il; i += 3 ) { - for ( var i = 0, l = vectors.length; i < l; i ++ ) { + vA = indices[ i + 0 ] * 3; + vB = indices[ i + 1 ] * 3; + vC = indices[ i + 2 ] * 3; - var vector = vectors[ i ]; + pA.fromArray( positions, vA ); + pB.fromArray( positions, vB ); + pC.fromArray( positions, vC ); - if ( vector === undefined ) { + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i ); - vector = new Vector3(); + normals[ vA ] += cb.x; + normals[ vA + 1 ] += cb.y; + normals[ vA + 2 ] += cb.z; - } + normals[ vB ] += cb.x; + normals[ vB + 1 ] += cb.y; + normals[ vB + 2 ] += cb.z; - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - array[ offset ++ ] = vector.z; + normals[ vC ] += cb.x; + normals[ vC + 1 ] += cb.y; + normals[ vC + 2 ] += cb.z; - } + } - return this; + } else { - }, + // non-indexed elements (unconnected triangle soup) - copyVector4sArray: function ( vectors ) { + for ( var i = 0, il = positions.length; i < il; i += 9 ) { - var array = this.array, offset = 0; + pA.fromArray( positions, i ); + pB.fromArray( positions, i + 3 ); + pC.fromArray( positions, i + 6 ); - for ( var i = 0, l = vectors.length; i < l; i ++ ) { + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - var vector = vectors[ i ]; + normals[ i ] = cb.x; + normals[ i + 1 ] = cb.y; + normals[ i + 2 ] = cb.z; - if ( vector === undefined ) { + normals[ i + 3 ] = cb.x; + normals[ i + 4 ] = cb.y; + normals[ i + 5 ] = cb.z; - console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i ); - vector = new Vector4(); + normals[ i + 6 ] = cb.x; + normals[ i + 7 ] = cb.y; + normals[ i + 8 ] = cb.z; + + } } - array[ offset ++ ] = vector.x; - array[ offset ++ ] = vector.y; - array[ offset ++ ] = vector.z; - array[ offset ++ ] = vector.w; + this.normalizeNormals(); - } + attributes.normal.needsUpdate = true; - return this; + } }, - set: function ( value, offset ) { + merge: function ( geometry, offset ) { - if ( offset === undefined ) offset = 0; + if ( ! ( geometry && geometry.isBufferGeometry ) ) { - this.array.set( value, offset ); + console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); + return; - return this; + } - }, + if ( offset === undefined ) { - getX: function ( index ) { + offset = 0; - return this.array[ index * this.itemSize ]; + console.warn( + 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' + ); - }, + } - setX: function ( index, x ) { + var attributes = this.attributes; - this.array[ index * this.itemSize ] = x; + for ( var key in attributes ) { - return this; + if ( geometry.attributes[ key ] === undefined ) continue; - }, + var attribute1 = attributes[ key ]; + var attributeArray1 = attribute1.array; - getY: function ( index ) { + var attribute2 = geometry.attributes[ key ]; + var attributeArray2 = attribute2.array; - return this.array[ index * this.itemSize + 1 ]; + var attributeOffset = attribute2.itemSize * offset; + var length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset ); - }, + for ( var i = 0, j = attributeOffset; i < length; i ++, j ++ ) { - setY: function ( index, y ) { + attributeArray1[ j ] = attributeArray2[ i ]; - this.array[ index * this.itemSize + 1 ] = y; + } + + } return this; }, - getZ: function ( index ) { + normalizeNormals: function () { - return this.array[ index * this.itemSize + 2 ]; + var vector = new Vector3(); - }, + return function normalizeNormals() { - setZ: function ( index, z ) { + var normals = this.attributes.normal; - this.array[ index * this.itemSize + 2 ] = z; + for ( var i = 0, il = normals.count; i < il; i ++ ) { - return this; + vector.x = normals.getX( i ); + vector.y = normals.getY( i ); + vector.z = normals.getZ( i ); - }, + vector.normalize(); - getW: function ( index ) { + normals.setXYZ( i, vector.x, vector.y, vector.z ); - return this.array[ index * this.itemSize + 3 ]; + } - }, + }; - setW: function ( index, w ) { + }(), - this.array[ index * this.itemSize + 3 ] = w; + toNonIndexed: function () { - return this; + function convertBufferAttribute( attribute, indices ) { - }, + var array = attribute.array; + var itemSize = attribute.itemSize; - setXY: function ( index, x, y ) { + var array2 = new array.constructor( indices.length * itemSize ); - index *= this.itemSize; + var index = 0, index2 = 0; - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; + for ( var i = 0, l = indices.length; i < l; i ++ ) { - return this; + index = indices[ i ] * itemSize; - }, + for ( var j = 0; j < itemSize; j ++ ) { - setXYZ: function ( index, x, y, z ) { + array2[ index2 ++ ] = array[ index ++ ]; - index *= this.itemSize; + } - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; + } - return this; + return new BufferAttribute( array2, itemSize ); - }, + } - setXYZW: function ( index, x, y, z, w ) { + // - index *= this.itemSize; + if ( this.index === null ) { - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; - this.array[ index + 3 ] = w; + console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' ); + return this; - return this; + } - }, + var geometry2 = new BufferGeometry(); - onUpload: function ( callback ) { + var indices = this.index.array; + var attributes = this.attributes; - this.onUploadCallback = callback; + // attributes - return this; + for ( var name in attributes ) { - }, + var attribute = attributes[ name ]; - clone: function () { + var newAttribute = convertBufferAttribute( attribute, indices ); - return new this.constructor( this.array, this.itemSize ).copy( this ); + geometry2.addAttribute( name, newAttribute ); - }, + } - toJSON: function () { + // morph attributes - return { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: Array.prototype.slice.call( this.array ), - normalized: this.normalized - }; + var morphAttributes = this.morphAttributes; - } + for ( name in morphAttributes ) { - } ); + var morphArray = []; + var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes - // + for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) { - function Int8BufferAttribute( array, itemSize, normalized ) { + var attribute = morphAttribute[ i ]; - BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized ); + var newAttribute = convertBufferAttribute( attribute, indices ); - } + morphArray.push( newAttribute ); - Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Int8BufferAttribute.prototype.constructor = Int8BufferAttribute; + } + geometry2.morphAttributes[ name ] = morphArray; - function Uint8BufferAttribute( array, itemSize, normalized ) { + } - BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized ); + // groups - } + var groups = this.groups; - Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute; + for ( var i = 0, l = groups.length; i < l; i ++ ) { + var group = groups[ i ]; + geometry2.addGroup( group.start, group.count, group.materialIndex ); - function Uint8ClampedBufferAttribute( array, itemSize, normalized ) { + } - BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized ); + return geometry2; - } + }, - Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute; + toJSON: function () { + var data = { + metadata: { + version: 4.5, + type: 'BufferGeometry', + generator: 'BufferGeometry.toJSON' + } + }; - function Int16BufferAttribute( array, itemSize, normalized ) { + // standard BufferGeometry serialization - BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized ); + data.uuid = this.uuid; + data.type = this.type; + if ( this.name !== '' ) data.name = this.name; + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; - } + if ( this.parameters !== undefined ) { - Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; + var parameters = this.parameters; + for ( var key in parameters ) { - function Uint16BufferAttribute( array, itemSize, normalized ) { + if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; - BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized ); + } - } + return data; - Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute; + } + data.data = { attributes: {} }; - function Int32BufferAttribute( array, itemSize, normalized ) { + var index = this.index; - BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized ); + if ( index !== null ) { - } + data.data.index = { + type: index.array.constructor.name, + array: Array.prototype.slice.call( index.array ) + }; - Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Int32BufferAttribute.prototype.constructor = Int32BufferAttribute; + } + var attributes = this.attributes; - function Uint32BufferAttribute( array, itemSize, normalized ) { + for ( var key in attributes ) { - BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized ); + var attribute = attributes[ key ]; - } + var attributeData = attribute.toJSON(); - Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute; + if ( attribute.name !== '' ) attributeData.name = attribute.name; + data.data.attributes[ key ] = attributeData; - function Float32BufferAttribute( array, itemSize, normalized ) { + } - BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized ); + var morphAttributes = {}; + var hasMorphAttributes = false; - } + for ( var key in this.morphAttributes ) { - Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Float32BufferAttribute.prototype.constructor = Float32BufferAttribute; + var attributeArray = this.morphAttributes[ key ]; + var array = []; - function Float64BufferAttribute( array, itemSize, normalized ) { + for ( var i = 0, il = attributeArray.length; i < il; i ++ ) { - BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized ); + var attribute = attributeArray[ i ]; - } + var attributeData = attribute.toJSON(); - Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); - Float64BufferAttribute.prototype.constructor = Float64BufferAttribute; + if ( attribute.name !== '' ) attributeData.name = attribute.name; - /** - * @author mrdoob / http://mrdoob.com/ - */ + array.push( attributeData ); - function DirectGeometry() { + } - this.vertices = []; - this.normals = []; - this.colors = []; - this.uvs = []; - this.uvs2 = []; + if ( array.length > 0 ) { - this.groups = []; + morphAttributes[ key ] = array; - this.morphTargets = {}; + hasMorphAttributes = true; - this.skinWeights = []; - this.skinIndices = []; + } - // this.lineDistances = []; + } - this.boundingBox = null; - this.boundingSphere = null; + if ( hasMorphAttributes ) data.data.morphAttributes = morphAttributes; - // update flags + var groups = this.groups; - this.verticesNeedUpdate = false; - this.normalsNeedUpdate = false; - this.colorsNeedUpdate = false; - this.uvsNeedUpdate = false; - this.groupsNeedUpdate = false; + if ( groups.length > 0 ) { - } + data.data.groups = JSON.parse( JSON.stringify( groups ) ); - Object.assign( DirectGeometry.prototype, { + } - computeGroups: function ( geometry ) { + var boundingSphere = this.boundingSphere; - var group; - var groups = []; - var materialIndex = undefined; + if ( boundingSphere !== null ) { - var faces = geometry.faces; + data.data.boundingSphere = { + center: boundingSphere.center.toArray(), + radius: boundingSphere.radius + }; - for ( var i = 0; i < faces.length; i ++ ) { + } - var face = faces[ i ]; + return data; - // materials + }, - if ( face.materialIndex !== materialIndex ) { + clone: function () { - materialIndex = face.materialIndex; + /* + // Handle primitives - if ( group !== undefined ) { + var parameters = this.parameters; - group.count = ( i * 3 ) - group.start; - groups.push( group ); + if ( parameters !== undefined ) { - } + var values = []; - group = { - start: i * 3, - materialIndex: materialIndex - }; + for ( var key in parameters ) { - } + values.push( parameters[ key ] ); - } + } - if ( group !== undefined ) { + var geometry = Object.create( this.constructor.prototype ); + this.constructor.apply( geometry, values ); + return geometry; - group.count = ( i * 3 ) - group.start; - groups.push( group ); + } - } + return new this.constructor().copy( this ); + */ - this.groups = groups; + return new BufferGeometry().copy( this ); }, - fromGeometry: function ( geometry ) { + copy: function ( source ) { - var faces = geometry.faces; - var vertices = geometry.vertices; - var faceVertexUvs = geometry.faceVertexUvs; + var name, i, l; - var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0; - var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0; + // reset - // morphs + this.index = null; + this.attributes = {}; + this.morphAttributes = {}; + this.groups = []; + this.boundingBox = null; + this.boundingSphere = null; - var morphTargets = geometry.morphTargets; - var morphTargetsLength = morphTargets.length; + // name - var morphTargetsPosition; + this.name = source.name; - if ( morphTargetsLength > 0 ) { + // index - morphTargetsPosition = []; + var index = source.index; - for ( var i = 0; i < morphTargetsLength; i ++ ) { + if ( index !== null ) { - morphTargetsPosition[ i ] = { - name: morphTargets[ i ].name, - data: [] - }; + this.setIndex( index.clone() ); - } + } - this.morphTargets.position = morphTargetsPosition; + // attributes + + var attributes = source.attributes; + + for ( name in attributes ) { + + var attribute = attributes[ name ]; + this.addAttribute( name, attribute.clone() ); } - var morphNormals = geometry.morphNormals; - var morphNormalsLength = morphNormals.length; + // morph attributes - var morphTargetsNormal; + var morphAttributes = source.morphAttributes; - if ( morphNormalsLength > 0 ) { + for ( name in morphAttributes ) { - morphTargetsNormal = []; + var array = []; + var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes - for ( var i = 0; i < morphNormalsLength; i ++ ) { + for ( i = 0, l = morphAttribute.length; i < l; i ++ ) { - morphTargetsNormal[ i ] = { - name: morphNormals[ i ].name, - data: [] - }; + array.push( morphAttribute[ i ].clone() ); } - this.morphTargets.normal = morphTargetsNormal; + this.morphAttributes[ name ] = array; } - // skins - - var skinIndices = geometry.skinIndices; - var skinWeights = geometry.skinWeights; - - var hasSkinIndices = skinIndices.length === vertices.length; - var hasSkinWeights = skinWeights.length === vertices.length; + // groups - // + var groups = source.groups; - if ( vertices.length > 0 && faces.length === 0 ) { + for ( i = 0, l = groups.length; i < l; i ++ ) { - console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' ); + var group = groups[ i ]; + this.addGroup( group.start, group.count, group.materialIndex ); } - for ( var i = 0; i < faces.length; i ++ ) { + // bounding box - var face = faces[ i ]; + var boundingBox = source.boundingBox; - this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] ); + if ( boundingBox !== null ) { - var vertexNormals = face.vertexNormals; + this.boundingBox = boundingBox.clone(); - if ( vertexNormals.length === 3 ) { + } - this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] ); + // bounding sphere - } else { + var boundingSphere = source.boundingSphere; - var normal = face.normal; + if ( boundingSphere !== null ) { - this.normals.push( normal, normal, normal ); + this.boundingSphere = boundingSphere.clone(); - } + } - var vertexColors = face.vertexColors; + // draw range - if ( vertexColors.length === 3 ) { + this.drawRange.start = source.drawRange.start; + this.drawRange.count = source.drawRange.count; - this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] ); + // user data - } else { + this.userData = source.userData; - var color = face.color; + return this; - this.colors.push( color, color, color ); + }, - } + dispose: function () { - if ( hasFaceVertexUv === true ) { + this.dispatchEvent( { type: 'dispose' } ); - var vertexUvs = faceVertexUvs[ 0 ][ i ]; + } - if ( vertexUvs !== undefined ) { + } ); - this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author mikael emtinger / http://gomo.se/ + * @author jonobr1 / http://jonobr1.com/ + */ - } else { + function Mesh( geometry, material ) { - console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i ); + Object3D.call( this ); - this.uvs.push( new Vector2(), new Vector2(), new Vector2() ); + this.type = 'Mesh'; - } + this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); + this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } ); - } + this.drawMode = TrianglesDrawMode; - if ( hasFaceVertexUv2 === true ) { + this.updateMorphTargets(); - var vertexUvs = faceVertexUvs[ 1 ][ i ]; + } - if ( vertexUvs !== undefined ) { + Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { - this.uvs2.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] ); + constructor: Mesh, - } else { + isMesh: true, - console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i ); + setDrawMode: function ( value ) { - this.uvs2.push( new Vector2(), new Vector2(), new Vector2() ); + this.drawMode = value; - } + }, - } + copy: function ( source ) { - // morphs + Object3D.prototype.copy.call( this, source ); - for ( var j = 0; j < morphTargetsLength; j ++ ) { + this.drawMode = source.drawMode; - var morphTarget = morphTargets[ j ].vertices; + if ( source.morphTargetInfluences !== undefined ) { - morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] ); + this.morphTargetInfluences = source.morphTargetInfluences.slice(); - } + } - for ( var j = 0; j < morphNormalsLength; j ++ ) { + if ( source.morphTargetDictionary !== undefined ) { - var morphNormal = morphNormals[ j ].vertexNormals[ i ]; + this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); - morphTargetsNormal[ j ].data.push( morphNormal.a, morphNormal.b, morphNormal.c ); + } - } + return this; - // skins + }, - if ( hasSkinIndices ) { + updateMorphTargets: function () { - this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] ); + var geometry = this.geometry; + var m, ml, name; - } + if ( geometry.isBufferGeometry ) { - if ( hasSkinWeights ) { + var morphAttributes = geometry.morphAttributes; + var keys = Object.keys( morphAttributes ); - this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] ); + if ( keys.length > 0 ) { - } + var morphAttribute = morphAttributes[ keys[ 0 ] ]; - } + if ( morphAttribute !== undefined ) { - this.computeGroups( geometry ); + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - this.verticesNeedUpdate = geometry.verticesNeedUpdate; - this.normalsNeedUpdate = geometry.normalsNeedUpdate; - this.colorsNeedUpdate = geometry.colorsNeedUpdate; - this.uvsNeedUpdate = geometry.uvsNeedUpdate; - this.groupsNeedUpdate = geometry.groupsNeedUpdate; + for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { - return this; + name = morphAttribute[ m ].name || String( m ); - } + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; - } ); + } - /** - * @author mrdoob / http://mrdoob.com/ - */ + } - function arrayMax( array ) { + } - if ( array.length === 0 ) return - Infinity; + } else { - var max = array[ 0 ]; + var morphTargets = geometry.morphTargets; - for ( var i = 1, l = array.length; i < l; ++ i ) { + if ( morphTargets !== undefined && morphTargets.length > 0 ) { - if ( array[ i ] > max ) max = array[ i ]; + console.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' ); - } + } - return max; + } - } + }, - /** - * @author alteredq / http://alteredqualia.com/ - * @author mrdoob / http://mrdoob.com/ - */ + raycast: ( function () { - var bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id + var inverseMatrix = new Matrix4(); + var ray = new Ray(); + var sphere = new Sphere(); - function BufferGeometry() { + var vA = new Vector3(); + var vB = new Vector3(); + var vC = new Vector3(); - Object.defineProperty( this, 'id', { value: bufferGeometryId += 2 } ); + var tempA = new Vector3(); + var tempB = new Vector3(); + var tempC = new Vector3(); - this.uuid = _Math.generateUUID(); + var morphA = new Vector3(); + var morphB = new Vector3(); + var morphC = new Vector3(); - this.name = ''; - this.type = 'BufferGeometry'; + var uvA = new Vector2(); + var uvB = new Vector2(); + var uvC = new Vector2(); - this.index = null; - this.attributes = {}; + var intersectionPoint = new Vector3(); + var intersectionPointWorld = new Vector3(); - this.morphAttributes = {}; + function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { - this.groups = []; + var intersect; - this.boundingBox = null; - this.boundingSphere = null; + if ( material.side === BackSide ) { - this.drawRange = { start: 0, count: Infinity }; + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); - this.userData = {}; + } else { - } + intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); - BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { + } - constructor: BufferGeometry, + if ( intersect === null ) return null; - isBufferGeometry: true, + intersectionPointWorld.copy( point ); + intersectionPointWorld.applyMatrix4( object.matrixWorld ); - getIndex: function () { + var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); - return this.index; + if ( distance < raycaster.near || distance > raycaster.far ) return null; - }, + return { + distance: distance, + point: intersectionPointWorld.clone(), + object: object + }; - setIndex: function ( index ) { + } - if ( Array.isArray( index ) ) { + function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, a, b, c ) { - this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); + vA.fromBufferAttribute( position, a ); + vB.fromBufferAttribute( position, b ); + vC.fromBufferAttribute( position, c ); - } else { + var morphInfluences = object.morphTargetInfluences; - this.index = index; + if ( material.morphTargets && morphPosition && morphInfluences ) { - } + morphA.set( 0, 0, 0 ); + morphB.set( 0, 0, 0 ); + morphC.set( 0, 0, 0 ); - }, + for ( var i = 0, il = morphPosition.length; i < il; i ++ ) { - addAttribute: function ( name, attribute ) { + var influence = morphInfluences[ i ]; + var morphAttribute = morphPosition[ i ]; - if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) { + if ( influence === 0 ) continue; - console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' ); + tempA.fromBufferAttribute( morphAttribute, a ); + tempB.fromBufferAttribute( morphAttribute, b ); + tempC.fromBufferAttribute( morphAttribute, c ); - return this.addAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) ); + morphA.addScaledVector( tempA.sub( vA ), influence ); + morphB.addScaledVector( tempB.sub( vB ), influence ); + morphC.addScaledVector( tempC.sub( vC ), influence ); - } + } - if ( name === 'index' ) { + vA.add( morphA ); + vB.add( morphB ); + vC.add( morphC ); - console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' ); - this.setIndex( attribute ); + } - return this; + var intersection = checkIntersection( object, material, raycaster, ray, vA, vB, vC, intersectionPoint ); - } + if ( intersection ) { - this.attributes[ name ] = attribute; + if ( uv ) { - return this; + uvA.fromBufferAttribute( uv, a ); + uvB.fromBufferAttribute( uv, b ); + uvC.fromBufferAttribute( uv, c ); - }, + intersection.uv = Triangle.getUV( intersectionPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() ); - getAttribute: function ( name ) { + } - return this.attributes[ name ]; + var face = new Face3( a, b, c ); + Triangle.getNormal( vA, vB, vC, face.normal ); - }, + intersection.face = face; - removeAttribute: function ( name ) { + } - delete this.attributes[ name ]; + return intersection; - return this; + } - }, + return function raycast( raycaster, intersects ) { - addGroup: function ( start, count, materialIndex ) { + var geometry = this.geometry; + var material = this.material; + var matrixWorld = this.matrixWorld; - this.groups.push( { + if ( material === undefined ) return; - start: start, - count: count, - materialIndex: materialIndex !== undefined ? materialIndex : 0 + // Checking boundingSphere distance to ray - } ); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); - }, + sphere.copy( geometry.boundingSphere ); + sphere.applyMatrix4( matrixWorld ); - clearGroups: function () { + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; - this.groups = []; + // - }, + inverseMatrix.getInverse( matrixWorld ); + ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); - setDrawRange: function ( start, count ) { + // Check boundingBox before continuing - this.drawRange.start = start; - this.drawRange.count = count; + if ( geometry.boundingBox !== null ) { - }, + if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; - applyMatrix: function ( matrix ) { + } - var position = this.attributes.position; + var intersection; - if ( position !== undefined ) { + if ( geometry.isBufferGeometry ) { - matrix.applyToBufferAttribute( position ); - position.needsUpdate = true; + var a, b, c; + var index = geometry.index; + var position = geometry.attributes.position; + var morphPosition = geometry.morphAttributes.position; + var uv = geometry.attributes.uv; + var groups = geometry.groups; + var drawRange = geometry.drawRange; + var i, j, il, jl; + var group, groupMaterial; + var start, end; - } + if ( index !== null ) { - var normal = this.attributes.normal; + // indexed buffer geometry - if ( normal !== undefined ) { + if ( Array.isArray( material ) ) { - var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + for ( i = 0, il = groups.length; i < il; i ++ ) { - normalMatrix.applyToBufferAttribute( normal ); - normal.needsUpdate = true; + group = groups[ i ]; + groupMaterial = material[ group.materialIndex ]; - } + start = Math.max( group.start, drawRange.start ); + end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); - var tangent = this.attributes.tangent; + for ( j = start, jl = end; j < jl; j += 3 ) { - if ( tangent !== undefined ) { + a = index.getX( j ); + b = index.getX( j + 1 ); + c = index.getX( j + 2 ); - var normalMatrix = new Matrix3().getNormalMatrix( matrix ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c ); - // Tangent is vec4, but the '.w' component is a sign value (+1/-1). - normalMatrix.applyToBufferAttribute( tangent ); - tangent.needsUpdate = true; + if ( intersection ) { - } + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - if ( this.boundingBox !== null ) { + } - this.computeBoundingBox(); + } - } + } - if ( this.boundingSphere !== null ) { + } else { - this.computeBoundingSphere(); + start = Math.max( 0, drawRange.start ); + end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); - } + for ( i = start, il = end; i < il; i += 3 ) { - return this; + a = index.getX( i ); + b = index.getX( i + 1 ); + c = index.getX( i + 2 ); - }, + intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c ); - rotateX: function () { + if ( intersection ) { - // rotate geometry around world x-axis + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - var m1 = new Matrix4(); + } - return function rotateX( angle ) { + } - m1.makeRotationX( angle ); + } - this.applyMatrix( m1 ); + } else if ( position !== undefined ) { - return this; + // non-indexed buffer geometry - }; + if ( Array.isArray( material ) ) { - }(), + for ( i = 0, il = groups.length; i < il; i ++ ) { - rotateY: function () { + group = groups[ i ]; + groupMaterial = material[ group.materialIndex ]; - // rotate geometry around world y-axis + start = Math.max( group.start, drawRange.start ); + end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); - var m1 = new Matrix4(); + for ( j = start, jl = end; j < jl; j += 3 ) { - return function rotateY( angle ) { + a = j; + b = j + 1; + c = j + 2; - m1.makeRotationY( angle ); + intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c ); - this.applyMatrix( m1 ); + if ( intersection ) { - return this; + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - }; + } - }(), + } - rotateZ: function () { + } - // rotate geometry around world z-axis + } else { - var m1 = new Matrix4(); + start = Math.max( 0, drawRange.start ); + end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); - return function rotateZ( angle ) { + for ( i = start, il = end; i < il; i += 3 ) { - m1.makeRotationZ( angle ); + a = i; + b = i + 1; + c = i + 2; - this.applyMatrix( m1 ); + intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c ); - return this; + if ( intersection ) { - }; + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); - }(), + } - translate: function () { + } - // translate geometry + } - var m1 = new Matrix4(); + } - return function translate( x, y, z ) { + } else if ( geometry.isGeometry ) { - m1.makeTranslation( x, y, z ); + var fvA, fvB, fvC; + var isMultiMaterial = Array.isArray( material ); - this.applyMatrix( m1 ); + var vertices = geometry.vertices; + var faces = geometry.faces; + var uvs; - return this; + 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 = isMultiMaterial ? material[ face.materialIndex ] : material; - scale: function () { + if ( faceMaterial === undefined ) continue; - // scale geometry + fvA = vertices[ face.a ]; + fvB = vertices[ face.b ]; + fvC = vertices[ face.c ]; - var m1 = new Matrix4(); + intersection = checkIntersection( this, faceMaterial, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); - return function scale( x, y, z ) { + if ( intersection ) { - m1.makeScale( x, y, z ); + if ( uvs && uvs[ f ] ) { - this.applyMatrix( m1 ); + var uvs_f = uvs[ f ]; + uvA.copy( uvs_f[ 0 ] ); + uvB.copy( uvs_f[ 1 ] ); + uvC.copy( uvs_f[ 2 ] ); - return this; + intersection.uv = Triangle.getUV( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC, new Vector2() ); - }; + } - }(), + intersection.face = face; + intersection.faceIndex = f; + intersects.push( intersection ); - lookAt: function () { + } - var obj = new Object3D(); + } - return function lookAt( vector ) { + } - obj.lookAt( vector ); + }; - obj.updateMatrix(); + }() ), - this.applyMatrix( obj.matrix ); + clone: function () { - }; + return new this.constructor( this.geometry, this.material ).copy( this ); - }(), + } - center: function () { + } ); - var offset = new Vector3(); + /** + * @author mrdoob / http://mrdoob.com/ + * @author kile / http://kile.stravaganza.org/ + * @author alteredq / http://alteredqualia.com/ + * @author mikael emtinger / http://gomo.se/ + * @author zz85 / http://www.lab4games.net/zz85/blog + * @author bhouston / http://clara.io + */ - return function center() { + var geometryId = 0; // Geometry uses even numbers as Id - this.computeBoundingBox(); + function Geometry() { - this.boundingBox.getCenter( offset ).negate(); + Object.defineProperty( this, 'id', { value: geometryId += 2 } ); - this.translate( offset.x, offset.y, offset.z ); + this.uuid = _Math.generateUUID(); - return this; + this.name = ''; + this.type = 'Geometry'; - }; - - }(), + this.vertices = []; + this.colors = []; + this.faces = []; + this.faceVertexUvs = [[]]; - setFromObject: function ( object ) { + this.morphTargets = []; + this.morphNormals = []; - // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this ); + this.skinWeights = []; + this.skinIndices = []; - var geometry = object.geometry; + this.lineDistances = []; - if ( object.isPoints || object.isLine ) { + this.boundingBox = null; + this.boundingSphere = null; - var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 ); - var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 ); + // update flags - this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) ); - this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) ); + this.elementsNeedUpdate = false; + this.verticesNeedUpdate = false; + this.uvsNeedUpdate = false; + this.normalsNeedUpdate = false; + this.colorsNeedUpdate = false; + this.lineDistancesNeedUpdate = false; + this.groupsNeedUpdate = false; - if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) { + } - var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 ); + Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) ); + constructor: Geometry, - } + isGeometry: true, - if ( geometry.boundingSphere !== null ) { + applyMatrix: function ( matrix ) { - this.boundingSphere = geometry.boundingSphere.clone(); + var normalMatrix = new Matrix3().getNormalMatrix( matrix ); - } + for ( var i = 0, il = this.vertices.length; i < il; i ++ ) { - if ( geometry.boundingBox !== null ) { + var vertex = this.vertices[ i ]; + vertex.applyMatrix4( matrix ); - this.boundingBox = geometry.boundingBox.clone(); + } - } + for ( var i = 0, il = this.faces.length; i < il; i ++ ) { - } else if ( object.isMesh ) { + var face = this.faces[ i ]; + face.normal.applyMatrix3( normalMatrix ).normalize(); - if ( geometry && geometry.isGeometry ) { + for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) { - this.fromGeometry( geometry ); + face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize(); } } - return this; - - }, + if ( this.boundingBox !== null ) { - setFromPoints: function ( points ) { + this.computeBoundingBox(); - var position = []; + } - for ( var i = 0, l = points.length; i < l; i ++ ) { + if ( this.boundingSphere !== null ) { - var point = points[ i ]; - position.push( point.x, point.y, point.z || 0 ); + this.computeBoundingSphere(); } - this.addAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); + this.verticesNeedUpdate = true; + this.normalsNeedUpdate = true; return this; }, - updateFromObject: function ( object ) { - - var geometry = object.geometry; + rotateX: function () { - if ( object.isMesh ) { + // rotate geometry around world x-axis - var direct = geometry.__directGeometry; + var m1 = new Matrix4(); - if ( geometry.elementsNeedUpdate === true ) { + return function rotateX( angle ) { - direct = undefined; - geometry.elementsNeedUpdate = false; + m1.makeRotationX( angle ); - } + this.applyMatrix( m1 ); - if ( direct === undefined ) { + return this; - return this.fromGeometry( geometry ); + }; - } + }(), - direct.verticesNeedUpdate = geometry.verticesNeedUpdate; - direct.normalsNeedUpdate = geometry.normalsNeedUpdate; - direct.colorsNeedUpdate = geometry.colorsNeedUpdate; - direct.uvsNeedUpdate = geometry.uvsNeedUpdate; - direct.groupsNeedUpdate = geometry.groupsNeedUpdate; + rotateY: function () { - geometry.verticesNeedUpdate = false; - geometry.normalsNeedUpdate = false; - geometry.colorsNeedUpdate = false; - geometry.uvsNeedUpdate = false; - geometry.groupsNeedUpdate = false; + // rotate geometry around world y-axis - geometry = direct; + var m1 = new Matrix4(); - } + return function rotateY( angle ) { - var attribute; + m1.makeRotationY( angle ); - if ( geometry.verticesNeedUpdate === true ) { + this.applyMatrix( m1 ); - attribute = this.attributes.position; + return this; - if ( attribute !== undefined ) { + }; - attribute.copyVector3sArray( geometry.vertices ); - attribute.needsUpdate = true; + }(), - } + rotateZ: function () { - geometry.verticesNeedUpdate = false; + // rotate geometry around world z-axis - } + var m1 = new Matrix4(); - if ( geometry.normalsNeedUpdate === true ) { + return function rotateZ( angle ) { - attribute = this.attributes.normal; + m1.makeRotationZ( angle ); - if ( attribute !== undefined ) { + this.applyMatrix( m1 ); - attribute.copyVector3sArray( geometry.normals ); - attribute.needsUpdate = true; + return this; - } + }; - geometry.normalsNeedUpdate = false; + }(), - } + translate: function () { - if ( geometry.colorsNeedUpdate === true ) { + // translate geometry - attribute = this.attributes.color; + var m1 = new Matrix4(); - if ( attribute !== undefined ) { + return function translate( x, y, z ) { - attribute.copyColorsArray( geometry.colors ); - attribute.needsUpdate = true; + m1.makeTranslation( x, y, z ); - } + this.applyMatrix( m1 ); - geometry.colorsNeedUpdate = false; + return this; - } + }; - if ( geometry.uvsNeedUpdate ) { + }(), - attribute = this.attributes.uv; + scale: function () { - if ( attribute !== undefined ) { + // scale geometry - attribute.copyVector2sArray( geometry.uvs ); - attribute.needsUpdate = true; + var m1 = new Matrix4(); - } + return function scale( x, y, z ) { - geometry.uvsNeedUpdate = false; + m1.makeScale( x, y, z ); - } + this.applyMatrix( m1 ); - if ( geometry.lineDistancesNeedUpdate ) { + return this; - attribute = this.attributes.lineDistance; + }; - if ( attribute !== undefined ) { + }(), - attribute.copyArray( geometry.lineDistances ); - attribute.needsUpdate = true; + lookAt: function () { - } + var obj = new Object3D(); - geometry.lineDistancesNeedUpdate = false; + return function lookAt( vector ) { - } + obj.lookAt( vector ); - if ( geometry.groupsNeedUpdate ) { + obj.updateMatrix(); - geometry.computeGroups( object.geometry ); - this.groups = geometry.groups; + this.applyMatrix( obj.matrix ); - geometry.groupsNeedUpdate = false; + }; - } + }(), - return this; + fromBufferGeometry: function ( geometry ) { - }, + var scope = this; - fromGeometry: function ( geometry ) { + var indices = geometry.index !== null ? geometry.index.array : undefined; + var attributes = geometry.attributes; - geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry ); + var positions = attributes.position.array; + var normals = attributes.normal !== undefined ? attributes.normal.array : undefined; + var colors = attributes.color !== undefined ? attributes.color.array : undefined; + var uvs = attributes.uv !== undefined ? attributes.uv.array : undefined; + var uvs2 = attributes.uv2 !== undefined ? attributes.uv2.array : undefined; - return this.fromDirectGeometry( geometry.__directGeometry ); + if ( uvs2 !== undefined ) this.faceVertexUvs[ 1 ] = []; - }, + for ( var i = 0; i < positions.length; i += 3 ) { - fromDirectGeometry: function ( geometry ) { + scope.vertices.push( new Vector3().fromArray( positions, i ) ); - var positions = new Float32Array( geometry.vertices.length * 3 ); - this.addAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) ); + if ( colors !== undefined ) { - if ( geometry.normals.length > 0 ) { + scope.colors.push( new Color().fromArray( colors, i ) ); - var normals = new Float32Array( geometry.normals.length * 3 ); - this.addAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) ); + } } - if ( geometry.colors.length > 0 ) { + function addFace( a, b, c, materialIndex ) { - var colors = new Float32Array( geometry.colors.length * 3 ); - this.addAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) ); + var vertexColors = ( colors === undefined ) ? [] : [ + scope.colors[ a ].clone(), + scope.colors[ b ].clone(), + scope.colors[ c ].clone() ]; - } + var vertexNormals = ( normals === undefined ) ? [] : [ + new Vector3().fromArray( normals, a * 3 ), + new Vector3().fromArray( normals, b * 3 ), + new Vector3().fromArray( normals, c * 3 ) + ]; - if ( geometry.uvs.length > 0 ) { + var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex ); - var uvs = new Float32Array( geometry.uvs.length * 2 ); - this.addAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) ); + scope.faces.push( face ); - } + if ( uvs !== undefined ) { - if ( geometry.uvs2.length > 0 ) { + scope.faceVertexUvs[ 0 ].push( [ + new Vector2().fromArray( uvs, a * 2 ), + new Vector2().fromArray( uvs, b * 2 ), + new Vector2().fromArray( uvs, c * 2 ) + ] ); - var uvs2 = new Float32Array( geometry.uvs2.length * 2 ); - this.addAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) ); + } + + if ( uvs2 !== undefined ) { + + scope.faceVertexUvs[ 1 ].push( [ + new Vector2().fromArray( uvs2, a * 2 ), + new Vector2().fromArray( uvs2, b * 2 ), + new Vector2().fromArray( uvs2, c * 2 ) + ] ); + + } } - // groups + var groups = geometry.groups; - this.groups = geometry.groups; + if ( groups.length > 0 ) { - // morphs + for ( var i = 0; i < groups.length; i ++ ) { - for ( var name in geometry.morphTargets ) { + var group = groups[ i ]; - var array = []; - var morphTargets = geometry.morphTargets[ name ]; + var start = group.start; + var count = group.count; - for ( var i = 0, l = morphTargets.length; i < l; i ++ ) { + for ( var j = start, jl = start + count; j < jl; j += 3 ) { - var morphTarget = morphTargets[ i ]; + if ( indices !== undefined ) { - var attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 ); - attribute.name = morphTarget.name; + addFace( indices[ j ], indices[ j + 1 ], indices[ j + 2 ], group.materialIndex ); - array.push( attribute.copyVector3sArray( morphTarget.data ) ); + } else { - } + addFace( j, j + 1, j + 2, group.materialIndex ); - this.morphAttributes[ name ] = array; + } - } + } - // skinning + } - if ( geometry.skinIndices.length > 0 ) { + } else { - var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 ); - this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) ); + if ( indices !== undefined ) { - } + for ( var i = 0; i < indices.length; i += 3 ) { - if ( geometry.skinWeights.length > 0 ) { + addFace( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] ); - var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 ); - this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) ); + } - } + } else { - // + for ( var i = 0; i < positions.length / 3; i += 3 ) { - if ( geometry.boundingSphere !== null ) { + addFace( i, i + 1, i + 2 ); - this.boundingSphere = geometry.boundingSphere.clone(); + } + + } } + this.computeFaceNormals(); + if ( geometry.boundingBox !== null ) { this.boundingBox = geometry.boundingBox.clone(); } - return this; + if ( geometry.boundingSphere !== null ) { - }, + this.boundingSphere = geometry.boundingSphere.clone(); - computeBoundingBox: function () { + } - var box = new Box3(); + return this; - return function computeBoundingBox() { + }, - if ( this.boundingBox === null ) { + center: function () { - this.boundingBox = new Box3(); + var offset = new Vector3(); - } + return function center() { - var position = this.attributes.position; - var morphAttributesPosition = this.morphAttributes.position; + this.computeBoundingBox(); - if ( position !== undefined ) { + this.boundingBox.getCenter( offset ).negate(); - this.boundingBox.setFromBufferAttribute( position ); + this.translate( offset.x, offset.y, offset.z ); - // process morph attributes if present + return this; - if ( morphAttributesPosition ) { + }; - for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + }(), - var morphAttribute = morphAttributesPosition[ i ]; - box.setFromBufferAttribute( morphAttribute ); + normalize: function () { - this.boundingBox.expandByPoint( box.min ); - this.boundingBox.expandByPoint( box.max ); + this.computeBoundingSphere(); - } + var center = this.boundingSphere.center; + var radius = this.boundingSphere.radius; - } + var s = radius === 0 ? 1 : 1.0 / radius; - } else { + var matrix = new Matrix4(); + matrix.set( + s, 0, 0, - s * center.x, + 0, s, 0, - s * center.y, + 0, 0, s, - s * center.z, + 0, 0, 0, 1 + ); - this.boundingBox.makeEmpty(); + this.applyMatrix( matrix ); - } + return 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 ); + computeFaceNormals: function () { - } + var cb = new Vector3(), ab = new Vector3(); - }; + for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) { - }(), + var face = this.faces[ f ]; - computeBoundingSphere: function () { + var vA = this.vertices[ face.a ]; + var vB = this.vertices[ face.b ]; + var vC = this.vertices[ face.c ]; - var box = new Box3(); - var boxMorphTargets = new Box3(); - var vector = new Vector3(); + cb.subVectors( vC, vB ); + ab.subVectors( vA, vB ); + cb.cross( ab ); - return function computeBoundingSphere() { + cb.normalize(); - if ( this.boundingSphere === null ) { + face.normal.copy( cb ); - this.boundingSphere = new Sphere(); + } - } + }, - var position = this.attributes.position; - var morphAttributesPosition = this.morphAttributes.position; + computeVertexNormals: function ( areaWeighted ) { - if ( position ) { + if ( areaWeighted === undefined ) areaWeighted = true; - // first, find the center of the bounding sphere + var v, vl, f, fl, face, vertices; - var center = this.boundingSphere.center; + vertices = new Array( this.vertices.length ); - box.setFromBufferAttribute( position ); + for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { - // process morph attributes if present + vertices[ v ] = new Vector3(); - if ( morphAttributesPosition ) { + } - for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + if ( areaWeighted ) { - var morphAttribute = morphAttributesPosition[ i ]; - boxMorphTargets.setFromBufferAttribute( morphAttribute ); + // vertex normals weighted by triangle areas + // http://www.iquilezles.org/www/articles/normals/normals.htm - box.expandByPoint( boxMorphTargets.min ); - box.expandByPoint( boxMorphTargets.max ); + var vA, vB, vC; + var cb = new Vector3(), ab = new Vector3(); - } + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - } + face = this.faces[ f ]; - box.getCenter( center ); + vA = this.vertices[ face.a ]; + vB = this.vertices[ face.b ]; + vC = this.vertices[ face.c ]; - // second, try to find a boundingSphere with a radius smaller than the - // boundingSphere of the boundingBox: sqrt(3) smaller in the best case + cb.subVectors( vC, vB ); + ab.subVectors( vA, vB ); + cb.cross( ab ); - var maxRadiusSq = 0; + vertices[ face.a ].add( cb ); + vertices[ face.b ].add( cb ); + vertices[ face.c ].add( cb ); - for ( var i = 0, il = position.count; i < il; i ++ ) { + } - vector.fromBufferAttribute( position, i ); + } else { - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); + this.computeFaceNormals(); - } + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - // process morph attributes if present + face = this.faces[ f ]; - if ( morphAttributesPosition ) { + vertices[ face.a ].add( face.normal ); + vertices[ face.b ].add( face.normal ); + vertices[ face.c ].add( face.normal ); - for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + } - var morphAttribute = morphAttributesPosition[ i ]; + } - for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) { + for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) { - vector.fromBufferAttribute( morphAttribute, j ); + vertices[ v ].normalize(); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) ); + } - } + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - } + face = this.faces[ f ]; - } + var vertexNormals = face.vertexNormals; - this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); + if ( vertexNormals.length === 3 ) { - if ( isNaN( this.boundingSphere.radius ) ) { + vertexNormals[ 0 ].copy( vertices[ face.a ] ); + vertexNormals[ 1 ].copy( vertices[ face.b ] ); + vertexNormals[ 2 ].copy( vertices[ face.c ] ); - console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); + } else { - } + vertexNormals[ 0 ] = vertices[ face.a ].clone(); + vertexNormals[ 1 ] = vertices[ face.b ].clone(); + vertexNormals[ 2 ] = vertices[ face.c ].clone(); } - }; + } - }(), + if ( this.faces.length > 0 ) { - computeFaceNormals: function () { + this.normalsNeedUpdate = true; - // backwards compatibility + } }, - computeVertexNormals: function () { - - var index = this.index; - var attributes = this.attributes; + computeFlatVertexNormals: function () { - if ( attributes.position ) { + var f, fl, face; - var positions = attributes.position.array; + this.computeFaceNormals(); - if ( attributes.normal === undefined ) { + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - this.addAttribute( 'normal', new BufferAttribute( new Float32Array( positions.length ), 3 ) ); + face = this.faces[ f ]; - } else { + var vertexNormals = face.vertexNormals; - // reset existing normals to zero + if ( vertexNormals.length === 3 ) { - var array = attributes.normal.array; + vertexNormals[ 0 ].copy( face.normal ); + vertexNormals[ 1 ].copy( face.normal ); + vertexNormals[ 2 ].copy( face.normal ); - for ( var i = 0, il = array.length; i < il; i ++ ) { + } else { - array[ i ] = 0; - - } + vertexNormals[ 0 ] = face.normal.clone(); + vertexNormals[ 1 ] = face.normal.clone(); + vertexNormals[ 2 ] = face.normal.clone(); } - var normals = attributes.normal.array; - - var vA, vB, vC; - var pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); - var cb = new Vector3(), ab = new Vector3(); + } - // indexed elements + if ( this.faces.length > 0 ) { - if ( index ) { + this.normalsNeedUpdate = true; - var indices = index.array; + } - for ( var i = 0, il = index.count; i < il; i += 3 ) { + }, - vA = indices[ i + 0 ] * 3; - vB = indices[ i + 1 ] * 3; - vC = indices[ i + 2 ] * 3; + computeMorphNormals: function () { - pA.fromArray( positions, vA ); - pB.fromArray( positions, vB ); - pC.fromArray( positions, vC ); + var i, il, f, fl, face; - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + // save original normals + // - create temp variables on first access + // otherwise just copy (for faster repeated calls) - normals[ vA ] += cb.x; - normals[ vA + 1 ] += cb.y; - normals[ vA + 2 ] += cb.z; + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - normals[ vB ] += cb.x; - normals[ vB + 1 ] += cb.y; - normals[ vB + 2 ] += cb.z; + face = this.faces[ f ]; - normals[ vC ] += cb.x; - normals[ vC + 1 ] += cb.y; - normals[ vC + 2 ] += cb.z; + if ( ! face.__originalFaceNormal ) { - } + face.__originalFaceNormal = face.normal.clone(); } else { - // non-indexed elements (unconnected triangle soup) + face.__originalFaceNormal.copy( face.normal ); - for ( var i = 0, il = positions.length; i < il; i += 9 ) { + } - pA.fromArray( positions, i ); - pB.fromArray( positions, i + 3 ); - pC.fromArray( positions, i + 6 ); + if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = []; - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) { - normals[ i ] = cb.x; - normals[ i + 1 ] = cb.y; - normals[ i + 2 ] = cb.z; + if ( ! face.__originalVertexNormals[ i ] ) { - normals[ i + 3 ] = cb.x; - normals[ i + 4 ] = cb.y; - normals[ i + 5 ] = cb.z; + face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone(); - normals[ i + 6 ] = cb.x; - normals[ i + 7 ] = cb.y; - normals[ i + 8 ] = cb.z; + } else { + + face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] ); } } - this.normalizeNormals(); + } - attributes.normal.needsUpdate = true; + // use temp geometry to compute face and vertex normals for each morph - } + var tmpGeo = new Geometry(); + tmpGeo.faces = this.faces; - }, + for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) { - merge: function ( geometry, offset ) { + // create on first access - if ( ! ( geometry && geometry.isBufferGeometry ) ) { + if ( ! this.morphNormals[ i ] ) { - console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry ); - return; + this.morphNormals[ i ] = {}; + this.morphNormals[ i ].faceNormals = []; + this.morphNormals[ i ].vertexNormals = []; - } + var dstNormalsFace = this.morphNormals[ i ].faceNormals; + var dstNormalsVertex = this.morphNormals[ i ].vertexNormals; - if ( offset === undefined ) { + var faceNormal, vertexNormals; - offset = 0; + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - console.warn( - 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' - + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.' - ); + faceNormal = new Vector3(); + vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() }; - } + dstNormalsFace.push( faceNormal ); + dstNormalsVertex.push( vertexNormals ); - var attributes = this.attributes; + } - for ( var key in attributes ) { + } - if ( geometry.attributes[ key ] === undefined ) continue; + var morphNormals = this.morphNormals[ i ]; - var attribute1 = attributes[ key ]; - var attributeArray1 = attribute1.array; + // set vertices to morph target - var attribute2 = geometry.attributes[ key ]; - var attributeArray2 = attribute2.array; + tmpGeo.vertices = this.morphTargets[ i ].vertices; - var attributeOffset = attribute2.itemSize * offset; - var length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset ); + // compute morph normals - for ( var i = 0, j = attributeOffset; i < length; i ++, j ++ ) { + tmpGeo.computeFaceNormals(); + tmpGeo.computeVertexNormals(); - attributeArray1[ j ] = attributeArray2[ i ]; + // store morph normals - } + var faceNormal, vertexNormals; - } + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - return this; + face = this.faces[ f ]; - }, + faceNormal = morphNormals.faceNormals[ f ]; + vertexNormals = morphNormals.vertexNormals[ f ]; - normalizeNormals: function () { + faceNormal.copy( face.normal ); - var vector = new Vector3(); + vertexNormals.a.copy( face.vertexNormals[ 0 ] ); + vertexNormals.b.copy( face.vertexNormals[ 1 ] ); + vertexNormals.c.copy( face.vertexNormals[ 2 ] ); - return function normalizeNormals() { + } - var normals = this.attributes.normal; + } - for ( var i = 0, il = normals.count; i < il; i ++ ) { + // restore original normals - vector.x = normals.getX( i ); - vector.y = normals.getY( i ); - vector.z = normals.getZ( i ); + for ( f = 0, fl = this.faces.length; f < fl; f ++ ) { - vector.normalize(); + face = this.faces[ f ]; - normals.setXYZ( i, vector.x, vector.y, vector.z ); + face.normal = face.__originalFaceNormal; + face.vertexNormals = face.__originalVertexNormals; - } + } - }; + }, - }(), + computeBoundingBox: function () { - toNonIndexed: function () { + if ( this.boundingBox === null ) { - function convertBufferAttribute( attribute, indices ) { + this.boundingBox = new Box3(); - var array = attribute.array; - var itemSize = attribute.itemSize; + } - var array2 = new array.constructor( indices.length * itemSize ); + this.boundingBox.setFromPoints( this.vertices ); - var index = 0, index2 = 0; + }, - for ( var i = 0, l = indices.length; i < l; i ++ ) { + computeBoundingSphere: function () { - index = indices[ i ] * itemSize; + if ( this.boundingSphere === null ) { - for ( var j = 0; j < itemSize; j ++ ) { + this.boundingSphere = new Sphere(); - array2[ index2 ++ ] = array[ index ++ ]; + } - } + this.boundingSphere.setFromPoints( this.vertices ); - } + }, - return new BufferAttribute( array2, itemSize ); + merge: function ( geometry, matrix, materialIndexOffset ) { + + if ( ! ( geometry && geometry.isGeometry ) ) { + + console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry ); + return; } - // + var normalMatrix, + vertexOffset = this.vertices.length, + vertices1 = this.vertices, + vertices2 = geometry.vertices, + faces1 = this.faces, + faces2 = geometry.faces, + uvs1 = this.faceVertexUvs[ 0 ], + uvs2 = geometry.faceVertexUvs[ 0 ], + colors1 = this.colors, + colors2 = geometry.colors; - if ( this.index === null ) { + if ( materialIndexOffset === undefined ) materialIndexOffset = 0; - console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' ); - return this; + if ( matrix !== undefined ) { - } + normalMatrix = new Matrix3().getNormalMatrix( matrix ); - var geometry2 = new BufferGeometry(); + } - var indices = this.index.array; - var attributes = this.attributes; + // vertices - // attributes + for ( var i = 0, il = vertices2.length; i < il; i ++ ) { - for ( var name in attributes ) { + var vertex = vertices2[ i ]; - var attribute = attributes[ name ]; + var vertexCopy = vertex.clone(); - var newAttribute = convertBufferAttribute( attribute, indices ); + if ( matrix !== undefined ) vertexCopy.applyMatrix4( matrix ); - geometry2.addAttribute( name, newAttribute ); + vertices1.push( vertexCopy ); } - // morph attributes + // colors - var morphAttributes = this.morphAttributes; + for ( var i = 0, il = colors2.length; i < il; i ++ ) { - for ( name in morphAttributes ) { + colors1.push( colors2[ i ].clone() ); - var morphArray = []; - var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + } - for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) { + // faces - var attribute = morphAttribute[ i ]; + for ( i = 0, il = faces2.length; i < il; i ++ ) { - var newAttribute = convertBufferAttribute( attribute, indices ); + var face = faces2[ i ], faceCopy, normal, color, + faceVertexNormals = face.vertexNormals, + faceVertexColors = face.vertexColors; - morphArray.push( newAttribute ); + faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset ); + faceCopy.normal.copy( face.normal ); + + if ( normalMatrix !== undefined ) { + + faceCopy.normal.applyMatrix3( normalMatrix ).normalize(); } - geometry2.morphAttributes[ name ] = morphArray; + for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) { - } + normal = faceVertexNormals[ j ].clone(); - // groups + if ( normalMatrix !== undefined ) { - var groups = this.groups; + normal.applyMatrix3( normalMatrix ).normalize(); - for ( var i = 0, l = groups.length; i < l; i ++ ) { + } - var group = groups[ i ]; - geometry2.addGroup( group.start, group.count, group.materialIndex ); + faceCopy.vertexNormals.push( normal ); - } + } - return geometry2; + faceCopy.color.copy( face.color ); - }, + for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) { - toJSON: function () { + color = faceVertexColors[ j ]; + faceCopy.vertexColors.push( color.clone() ); - var data = { - metadata: { - version: 4.5, - type: 'BufferGeometry', - generator: 'BufferGeometry.toJSON' } - }; - // standard BufferGeometry serialization + faceCopy.materialIndex = face.materialIndex + materialIndexOffset; - data.uuid = this.uuid; - data.type = this.type; - if ( this.name !== '' ) data.name = this.name; - if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; + faces1.push( faceCopy ); - if ( this.parameters !== undefined ) { + } - var parameters = this.parameters; + // uvs - for ( var key in parameters ) { + for ( i = 0, il = uvs2.length; i < il; i ++ ) { - if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + var uv = uvs2[ i ], uvCopy = []; - } + if ( uv === undefined ) { - return data; + continue; - } + } - data.data = { attributes: {} }; + for ( var j = 0, jl = uv.length; j < jl; j ++ ) { - var index = this.index; + uvCopy.push( uv[ j ].clone() ); - if ( index !== null ) { + } - data.data.index = { - type: index.array.constructor.name, - array: Array.prototype.slice.call( index.array ) - }; + uvs1.push( uvCopy ); } - var attributes = this.attributes; - - for ( var key in attributes ) { - - var attribute = attributes[ key ]; + }, - var attributeData = attribute.toJSON(); + mergeMesh: function ( mesh ) { - if ( attribute.name !== '' ) attributeData.name = attribute.name; + if ( ! ( mesh && mesh.isMesh ) ) { - data.data.attributes[ key ] = attributeData; + console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh ); + return; } - var morphAttributes = {}; - var hasMorphAttributes = false; + if ( mesh.matrixAutoUpdate ) mesh.updateMatrix(); - for ( var key in this.morphAttributes ) { + this.merge( mesh.geometry, mesh.matrix ); - var attributeArray = this.morphAttributes[ key ]; + }, - var array = []; + /* + * Checks for duplicate vertices with hashmap. + * Duplicated vertices are removed + * and faces' vertices are updated. + */ - for ( var i = 0, il = attributeArray.length; i < il; i ++ ) { + mergeVertices: function () { - var attribute = attributeArray[ i ]; + var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique) + var unique = [], changes = []; - var attributeData = attribute.toJSON(); + var v, key; + var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001 + var precision = Math.pow( 10, precisionPoints ); + var i, il, face; + var indices, j, jl; - if ( attribute.name !== '' ) attributeData.name = attribute.name; + for ( i = 0, il = this.vertices.length; i < il; i ++ ) { - array.push( attributeData ); + v = this.vertices[ i ]; + key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision ); - } + if ( verticesMap[ key ] === undefined ) { - if ( array.length > 0 ) { + verticesMap[ key ] = i; + unique.push( this.vertices[ i ] ); + changes[ i ] = unique.length - 1; - morphAttributes[ key ] = array; + } else { - hasMorphAttributes = true; + //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]); + changes[ i ] = changes[ verticesMap[ key ] ]; } } - if ( hasMorphAttributes ) data.data.morphAttributes = morphAttributes; - var groups = this.groups; + // if faces are completely degenerate after merging vertices, we + // have to remove them from the geometry. + var faceIndicesToRemove = []; - if ( groups.length > 0 ) { + for ( i = 0, il = this.faces.length; i < il; i ++ ) { - data.data.groups = JSON.parse( JSON.stringify( groups ) ); + face = this.faces[ i ]; - } + face.a = changes[ face.a ]; + face.b = changes[ face.b ]; + face.c = changes[ face.c ]; - var boundingSphere = this.boundingSphere; + indices = [ face.a, face.b, face.c ]; - if ( boundingSphere !== null ) { + // if any duplicate vertices are found in a Face3 + // we have to remove the face as nothing can be saved + for ( var n = 0; n < 3; n ++ ) { - data.data.boundingSphere = { - center: boundingSphere.center.toArray(), - radius: boundingSphere.radius - }; + if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) { - } + faceIndicesToRemove.push( i ); + break; - return data; + } - }, + } - clone: function () { + } - /* - // Handle primitives + for ( i = faceIndicesToRemove.length - 1; i >= 0; i -- ) { - var parameters = this.parameters; + var idx = faceIndicesToRemove[ i ]; - if ( parameters !== undefined ) { + this.faces.splice( idx, 1 ); - var values = []; + for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) { - for ( var key in parameters ) { + this.faceVertexUvs[ j ].splice( idx, 1 ); - values.push( parameters[ key ] ); + } - } + } - var geometry = Object.create( this.constructor.prototype ); - this.constructor.apply( geometry, values ); - return geometry; + // Use unique set of vertices - } + var diff = this.vertices.length - unique.length; + this.vertices = unique; + return diff; - return new this.constructor().copy( this ); - */ + }, - return new BufferGeometry().copy( this ); + setFromPoints: function ( points ) { - }, + this.vertices = []; - copy: function ( source ) { + for ( var i = 0, l = points.length; i < l; i ++ ) { - var name, i, l; + var point = points[ i ]; + this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) ); - // reset + } - this.index = null; - this.attributes = {}; - this.morphAttributes = {}; - this.groups = []; - this.boundingBox = null; - this.boundingSphere = null; + return this; - // name + }, - this.name = source.name; + sortFacesByMaterialIndex: function () { - // index + var faces = this.faces; + var length = faces.length; - var index = source.index; + // tag faces - if ( index !== null ) { + for ( var i = 0; i < length; i ++ ) { - this.setIndex( index.clone() ); + faces[ i ]._id = i; } - // attributes - - var attributes = source.attributes; + // sort faces - for ( name in attributes ) { + function materialIndexSort( a, b ) { - var attribute = attributes[ name ]; - this.addAttribute( name, attribute.clone() ); + return a.materialIndex - b.materialIndex; } - // morph attributes + faces.sort( materialIndexSort ); - var morphAttributes = source.morphAttributes; + // sort uvs - for ( name in morphAttributes ) { + var uvs1 = this.faceVertexUvs[ 0 ]; + var uvs2 = this.faceVertexUvs[ 1 ]; - var array = []; - var morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + var newUvs1, newUvs2; - for ( i = 0, l = morphAttribute.length; i < l; i ++ ) { + if ( uvs1 && uvs1.length === length ) newUvs1 = []; + if ( uvs2 && uvs2.length === length ) newUvs2 = []; - array.push( morphAttribute[ i ].clone() ); + for ( var i = 0; i < length; i ++ ) { - } + var id = faces[ i ]._id; - this.morphAttributes[ name ] = array; + if ( newUvs1 ) newUvs1.push( uvs1[ id ] ); + if ( newUvs2 ) newUvs2.push( uvs2[ id ] ); } - // groups + if ( newUvs1 ) this.faceVertexUvs[ 0 ] = newUvs1; + if ( newUvs2 ) this.faceVertexUvs[ 1 ] = newUvs2; - var groups = source.groups; + }, - for ( i = 0, l = groups.length; i < l; i ++ ) { + toJSON: function () { - var group = groups[ i ]; - this.addGroup( group.start, group.count, group.materialIndex ); + var data = { + metadata: { + version: 4.5, + type: 'Geometry', + generator: 'Geometry.toJSON' + } + }; - } + // standard Geometry serialization - // bounding box + data.uuid = this.uuid; + data.type = this.type; + if ( this.name !== '' ) data.name = this.name; - var boundingBox = source.boundingBox; + if ( this.parameters !== undefined ) { - if ( boundingBox !== null ) { + var parameters = this.parameters; - this.boundingBox = boundingBox.clone(); + for ( var key in parameters ) { - } + if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + + } + + return data; + + } + + var vertices = []; + + for ( var i = 0; i < this.vertices.length; i ++ ) { + + var vertex = this.vertices[ i ]; + vertices.push( vertex.x, vertex.y, vertex.z ); + + } + + var faces = []; + var normals = []; + var normalsHash = {}; + var colors = []; + var colorsHash = {}; + var uvs = []; + var uvsHash = {}; + + for ( var i = 0; i < this.faces.length; i ++ ) { + + var face = this.faces[ i ]; + + var hasMaterial = true; + var hasFaceUv = false; // deprecated + var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i ] !== undefined; + var hasFaceNormal = face.normal.length() > 0; + var hasFaceVertexNormal = face.vertexNormals.length > 0; + var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1; + var hasFaceVertexColor = face.vertexColors.length > 0; + + var faceType = 0; + + faceType = setBit( faceType, 0, 0 ); // isQuad + faceType = setBit( faceType, 1, hasMaterial ); + faceType = setBit( faceType, 2, hasFaceUv ); + faceType = setBit( faceType, 3, hasFaceVertexUv ); + faceType = setBit( faceType, 4, hasFaceNormal ); + faceType = setBit( faceType, 5, hasFaceVertexNormal ); + faceType = setBit( faceType, 6, hasFaceColor ); + faceType = setBit( faceType, 7, hasFaceVertexColor ); + + faces.push( faceType ); + faces.push( face.a, face.b, face.c ); + faces.push( face.materialIndex ); + + if ( hasFaceVertexUv ) { + + var faceVertexUvs = this.faceVertexUvs[ 0 ][ i ]; + + faces.push( + getUvIndex( faceVertexUvs[ 0 ] ), + getUvIndex( faceVertexUvs[ 1 ] ), + getUvIndex( faceVertexUvs[ 2 ] ) + ); + + } + + if ( hasFaceNormal ) { + + faces.push( getNormalIndex( face.normal ) ); + + } + + if ( hasFaceVertexNormal ) { + + var vertexNormals = face.vertexNormals; + + faces.push( + getNormalIndex( vertexNormals[ 0 ] ), + getNormalIndex( vertexNormals[ 1 ] ), + getNormalIndex( vertexNormals[ 2 ] ) + ); + + } + + if ( hasFaceColor ) { + + faces.push( getColorIndex( face.color ) ); + + } + + if ( hasFaceVertexColor ) { + + var vertexColors = face.vertexColors; + + faces.push( + getColorIndex( vertexColors[ 0 ] ), + getColorIndex( vertexColors[ 1 ] ), + getColorIndex( vertexColors[ 2 ] ) + ); + + } + + } + + function setBit( value, position, enabled ) { + + return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) ); + + } + + function getNormalIndex( normal ) { + + var hash = normal.x.toString() + normal.y.toString() + normal.z.toString(); + + if ( normalsHash[ hash ] !== undefined ) { + + return normalsHash[ hash ]; + + } + + normalsHash[ hash ] = normals.length / 3; + normals.push( normal.x, normal.y, normal.z ); + + return normalsHash[ hash ]; + + } + + function getColorIndex( color ) { + + var hash = color.r.toString() + color.g.toString() + color.b.toString(); + + if ( colorsHash[ hash ] !== undefined ) { + + return colorsHash[ hash ]; + + } + + colorsHash[ hash ] = colors.length; + colors.push( color.getHex() ); + + return colorsHash[ hash ]; + + } + + function getUvIndex( uv ) { + + var hash = uv.x.toString() + uv.y.toString(); + + if ( uvsHash[ hash ] !== undefined ) { + + return uvsHash[ hash ]; + + } + + uvsHash[ hash ] = uvs.length / 2; + uvs.push( uv.x, uv.y ); + + return uvsHash[ hash ]; + + } + + data.data = {}; + + data.data.vertices = vertices; + data.data.normals = normals; + if ( colors.length > 0 ) data.data.colors = colors; + if ( uvs.length > 0 ) data.data.uvs = [ uvs ]; // temporal backward compatibility + data.data.faces = faces; + + return data; + + }, + + clone: function () { + + /* + // Handle primitives + + var parameters = this.parameters; + + if ( parameters !== undefined ) { + + var values = []; + + for ( var key in parameters ) { + + values.push( parameters[ key ] ); + + } + + var geometry = Object.create( this.constructor.prototype ); + this.constructor.apply( geometry, values ); + return geometry; + + } + + return new this.constructor().copy( this ); + */ + + return new Geometry().copy( this ); + + }, + + copy: function ( source ) { + + var i, il, j, jl, k, kl; + + // reset + + this.vertices = []; + this.colors = []; + this.faces = []; + this.faceVertexUvs = [[]]; + this.morphTargets = []; + this.morphNormals = []; + this.skinWeights = []; + this.skinIndices = []; + this.lineDistances = []; + this.boundingBox = null; + this.boundingSphere = null; + + // name + + this.name = source.name; + + // vertices + + var vertices = source.vertices; + + for ( i = 0, il = vertices.length; i < il; i ++ ) { + + this.vertices.push( vertices[ i ].clone() ); + + } + + // colors + + var colors = source.colors; + + for ( i = 0, il = colors.length; i < il; i ++ ) { + + this.colors.push( colors[ i ].clone() ); + + } + + // faces + + var faces = source.faces; + + for ( i = 0, il = faces.length; i < il; i ++ ) { + + this.faces.push( faces[ i ].clone() ); + + } + + // face vertex uvs + + for ( i = 0, il = source.faceVertexUvs.length; i < il; i ++ ) { + + var faceVertexUvs = source.faceVertexUvs[ i ]; + + if ( this.faceVertexUvs[ i ] === undefined ) { + + this.faceVertexUvs[ i ] = []; + + } + + for ( j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) { + + var uvs = faceVertexUvs[ j ], uvsCopy = []; + + for ( k = 0, kl = uvs.length; k < kl; k ++ ) { + + var uv = uvs[ k ]; + + uvsCopy.push( uv.clone() ); + + } + + this.faceVertexUvs[ i ].push( uvsCopy ); + + } + + } + + // morph targets + + var morphTargets = source.morphTargets; + + for ( i = 0, il = morphTargets.length; i < il; i ++ ) { + + var morphTarget = {}; + morphTarget.name = morphTargets[ i ].name; + + // vertices + + if ( morphTargets[ i ].vertices !== undefined ) { + + morphTarget.vertices = []; + + for ( j = 0, jl = morphTargets[ i ].vertices.length; j < jl; j ++ ) { + + morphTarget.vertices.push( morphTargets[ i ].vertices[ j ].clone() ); + + } + + } + + // normals + + if ( morphTargets[ i ].normals !== undefined ) { + + morphTarget.normals = []; + + for ( j = 0, jl = morphTargets[ i ].normals.length; j < jl; j ++ ) { + + morphTarget.normals.push( morphTargets[ i ].normals[ j ].clone() ); + + } + + } + + this.morphTargets.push( morphTarget ); + + } + + // morph normals + + var morphNormals = source.morphNormals; + + for ( i = 0, il = morphNormals.length; i < il; i ++ ) { + + var morphNormal = {}; + + // vertex normals + + if ( morphNormals[ i ].vertexNormals !== undefined ) { + + morphNormal.vertexNormals = []; + + for ( j = 0, jl = morphNormals[ i ].vertexNormals.length; j < jl; j ++ ) { + + var srcVertexNormal = morphNormals[ i ].vertexNormals[ j ]; + var destVertexNormal = {}; + + destVertexNormal.a = srcVertexNormal.a.clone(); + destVertexNormal.b = srcVertexNormal.b.clone(); + destVertexNormal.c = srcVertexNormal.c.clone(); + + morphNormal.vertexNormals.push( destVertexNormal ); + + } + + } + + // face normals + + if ( morphNormals[ i ].faceNormals !== undefined ) { + + morphNormal.faceNormals = []; + + for ( j = 0, jl = morphNormals[ i ].faceNormals.length; j < jl; j ++ ) { + + morphNormal.faceNormals.push( morphNormals[ i ].faceNormals[ j ].clone() ); + + } + + } + + this.morphNormals.push( morphNormal ); + + } + + // skin weights + + var skinWeights = source.skinWeights; + + for ( i = 0, il = skinWeights.length; i < il; i ++ ) { + + this.skinWeights.push( skinWeights[ i ].clone() ); + + } + + // skin indices + + var skinIndices = source.skinIndices; + + for ( i = 0, il = skinIndices.length; i < il; i ++ ) { + + this.skinIndices.push( skinIndices[ i ].clone() ); + + } + + // line distances + + var lineDistances = source.lineDistances; + + for ( i = 0, il = lineDistances.length; i < il; i ++ ) { + + this.lineDistances.push( lineDistances[ i ] ); + + } + + // bounding box + + var boundingBox = source.boundingBox; + + if ( boundingBox !== null ) { + + this.boundingBox = boundingBox.clone(); + + } // bounding sphere @@ -12459,14 +12838,15 @@ } - // draw range - - this.drawRange.start = source.drawRange.start; - this.drawRange.count = source.drawRange.count; - - // user data + // update flags - this.userData = source.userData; + this.elementsNeedUpdate = source.elementsNeedUpdate; + this.verticesNeedUpdate = source.verticesNeedUpdate; + this.uvsNeedUpdate = source.uvsNeedUpdate; + this.normalsNeedUpdate = source.normalsNeedUpdate; + this.colorsNeedUpdate = source.colorsNeedUpdate; + this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate; + this.groupsNeedUpdate = source.groupsNeedUpdate; return this; @@ -12677,503 +13057,71 @@ BoxBufferGeometry.prototype.constructor = BoxBufferGeometry; /** - * @author mrdoob / http://mrdoob.com/ - * @author Mugen87 / https://github.com/Mugen87 + * Uniform Utilities */ - // PlaneGeometry + function cloneUniforms( src ) { - function PlaneGeometry( width, height, widthSegments, heightSegments ) { + var dst = {}; - Geometry.call( this ); + for ( var u in src ) { - this.type = 'PlaneGeometry'; + dst[ u ] = {}; - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + for ( var p in src[ u ] ) { - this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); - this.mergeVertices(); + var property = src[ u ][ p ]; - } + if ( property && ( property.isColor || + property.isMatrix3 || property.isMatrix4 || + property.isVector2 || property.isVector3 || property.isVector4 || + property.isTexture ) ) { - PlaneGeometry.prototype = Object.create( Geometry.prototype ); - PlaneGeometry.prototype.constructor = PlaneGeometry; + dst[ u ][ p ] = property.clone(); - // PlaneBufferGeometry + } else if ( Array.isArray( property ) ) { - function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { + dst[ u ][ p ] = property.slice(); - BufferGeometry.call( this ); + } else { - this.type = 'PlaneBufferGeometry'; + dst[ u ][ p ] = property; - this.parameters = { - width: width, - height: height, - widthSegments: widthSegments, - heightSegments: heightSegments - }; + } - width = width || 1; - height = height || 1; + } - var width_half = width / 2; - var height_half = height / 2; + } - var gridX = Math.floor( widthSegments ) || 1; - var gridY = Math.floor( heightSegments ) || 1; + return dst; - var gridX1 = gridX + 1; - var gridY1 = gridY + 1; + } - var segment_width = width / gridX; - var segment_height = height / gridY; + function mergeUniforms( uniforms ) { - var ix, iy; + var merged = {}; - // buffers + for ( var u = 0; u < uniforms.length; u ++ ) { - var indices = []; - var vertices = []; - var normals = []; - var uvs = []; + var tmp = cloneUniforms( uniforms[ u ] ); - // generate vertices, normals and uvs + for ( var p in tmp ) { - for ( iy = 0; iy < gridY1; iy ++ ) { + merged[ p ] = tmp[ p ]; - var y = iy * segment_height - height_half; + } - for ( ix = 0; ix < gridX1; ix ++ ) { + } - var x = ix * segment_width - width_half; + return merged; - vertices.push( x, - y, 0 ); + } - normals.push( 0, 0, 1 ); + // Legacy - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; - } - - } - - // indices - - 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; - - // faces - - indices.push( a, b, d ); - indices.push( b, c, d ); - - } - - } - - // build geometry - - this.setIndex( indices ); - this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); - - } - - PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); - PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; - - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - */ - - var materialId = 0; - - function Material() { - - Object.defineProperty( this, 'id', { value: materialId ++ } ); - - this.uuid = _Math.generateUUID(); - - this.name = ''; - this.type = 'Material'; - - this.fog = true; - this.lights = true; - - this.blending = NormalBlending; - this.side = FrontSide; - this.flatShading = false; - this.vertexTangents = false; - this.vertexColors = NoColors; // THREE.NoColors, THREE.VertexColors, THREE.FaceColors - - this.opacity = 1; - this.transparent = false; - - this.blendSrc = SrcAlphaFactor; - this.blendDst = OneMinusSrcAlphaFactor; - this.blendEquation = AddEquation; - this.blendSrcAlpha = null; - this.blendDstAlpha = null; - this.blendEquationAlpha = null; - - this.depthFunc = LessEqualDepth; - this.depthTest = true; - this.depthWrite = true; - - this.clippingPlanes = null; - this.clipIntersection = false; - this.clipShadows = false; - - this.shadowSide = null; - - this.colorWrite = true; - - this.precision = null; // override the renderer's default precision for this material - - this.polygonOffset = false; - this.polygonOffsetFactor = 0; - this.polygonOffsetUnits = 0; - - this.dithering = false; - - this.alphaTest = 0; - this.premultipliedAlpha = false; - - this.visible = true; - - this.userData = {}; - - this.needsUpdate = true; - - } - - Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), { - - constructor: Material, - - isMaterial: true, - - onBeforeCompile: function () {}, - - setValues: function ( values ) { - - if ( values === undefined ) return; - - for ( var key in values ) { - - var newValue = values[ key ]; - - if ( newValue === undefined ) { - - console.warn( "THREE.Material: '" + key + "' parameter is undefined." ); - continue; - - } - - // for backward compatability if shading is set in the constructor - if ( key === 'shading' ) { - - console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' ); - this.flatShading = ( newValue === FlatShading ) ? true : false; - continue; - - } - - var currentValue = this[ key ]; - - if ( currentValue === undefined ) { - - console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." ); - continue; - - } - - if ( currentValue && currentValue.isColor ) { - - currentValue.set( newValue ); - - } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { - - currentValue.copy( newValue ); - - } else { - - this[ key ] = newValue; - - } - - } - - }, - - toJSON: function ( meta ) { - - var isRoot = ( meta === undefined || typeof meta === 'string' ); - - if ( isRoot ) { - - meta = { - textures: {}, - images: {} - }; - - } - - var data = { - metadata: { - version: 4.5, - type: 'Material', - generator: 'Material.toJSON' - } - }; - - // standard Material serialization - data.uuid = this.uuid; - data.type = this.type; - - if ( this.name !== '' ) data.name = this.name; - - if ( this.color && this.color.isColor ) data.color = this.color.getHex(); - - if ( this.roughness !== undefined ) data.roughness = this.roughness; - if ( this.metalness !== undefined ) data.metalness = this.metalness; - - if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); - if ( this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; - - if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); - if ( this.shininess !== undefined ) data.shininess = this.shininess; - if ( this.clearCoat !== undefined ) data.clearCoat = this.clearCoat; - if ( this.clearCoatRoughness !== undefined ) data.clearCoatRoughness = this.clearCoatRoughness; - - if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; - if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; - if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; - if ( this.lightMap && this.lightMap.isTexture ) data.lightMap = this.lightMap.toJSON( meta ).uuid; - - if ( this.aoMap && this.aoMap.isTexture ) { - - data.aoMap = this.aoMap.toJSON( meta ).uuid; - data.aoMapIntensity = this.aoMapIntensity; - - } - - if ( this.bumpMap && this.bumpMap.isTexture ) { - - data.bumpMap = this.bumpMap.toJSON( meta ).uuid; - data.bumpScale = this.bumpScale; - - } - - if ( this.normalMap && this.normalMap.isTexture ) { - - data.normalMap = this.normalMap.toJSON( meta ).uuid; - data.normalMapType = this.normalMapType; - data.normalScale = this.normalScale.toArray(); - - } - - if ( this.displacementMap && this.displacementMap.isTexture ) { - - data.displacementMap = this.displacementMap.toJSON( meta ).uuid; - data.displacementScale = this.displacementScale; - data.displacementBias = this.displacementBias; - - } - - if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; - if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; - - if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; - if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; - - if ( this.envMap && this.envMap.isTexture ) { - - data.envMap = this.envMap.toJSON( meta ).uuid; - data.reflectivity = this.reflectivity; // Scale behind envMap - - if ( this.combine !== undefined ) data.combine = this.combine; - if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; - - } - - if ( this.gradientMap && this.gradientMap.isTexture ) { - - data.gradientMap = this.gradientMap.toJSON( meta ).uuid; - - } - - if ( this.size !== undefined ) data.size = this.size; - if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; - - if ( this.blending !== NormalBlending ) data.blending = this.blending; - if ( this.flatShading === true ) data.flatShading = this.flatShading; - if ( this.side !== FrontSide ) data.side = this.side; - if ( this.vertexColors !== NoColors ) data.vertexColors = this.vertexColors; - - if ( this.opacity < 1 ) data.opacity = this.opacity; - if ( this.transparent === true ) data.transparent = this.transparent; - - data.depthFunc = this.depthFunc; - data.depthTest = this.depthTest; - data.depthWrite = this.depthWrite; - - // rotation (SpriteMaterial) - if ( this.rotation !== 0 ) data.rotation = this.rotation; - - if ( this.polygonOffset === true ) data.polygonOffset = true; - if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; - if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; - - if ( this.linewidth !== 1 ) data.linewidth = this.linewidth; - if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; - if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; - if ( this.scale !== undefined ) data.scale = this.scale; - - if ( this.dithering === true ) data.dithering = true; - - 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; - if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; - if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; - - if ( this.morphTargets === true ) data.morphTargets = true; - if ( this.skinning === true ) data.skinning = true; - - if ( this.visible === false ) data.visible = false; - if ( JSON.stringify( this.userData ) !== '{}' ) data.userData = this.userData; - - // TODO: Copied from Object3D.toJSON - - function extractFromCache( cache ) { - - var values = []; - - for ( var key in cache ) { - - var data = cache[ key ]; - delete data.metadata; - values.push( data ); - - } - - return values; - - } - - if ( isRoot ) { - - var textures = extractFromCache( meta.textures ); - var images = extractFromCache( meta.images ); - - if ( textures.length > 0 ) data.textures = textures; - if ( images.length > 0 ) data.images = images; - - } - - return data; - - }, - - clone: function () { - - return new this.constructor().copy( this ); - - }, - - copy: function ( source ) { - - this.name = source.name; - - this.fog = source.fog; - this.lights = source.lights; - - this.blending = source.blending; - this.side = source.side; - this.flatShading = source.flatShading; - this.vertexColors = source.vertexColors; - - this.opacity = source.opacity; - this.transparent = source.transparent; - - this.blendSrc = source.blendSrc; - this.blendDst = source.blendDst; - this.blendEquation = source.blendEquation; - this.blendSrcAlpha = source.blendSrcAlpha; - this.blendDstAlpha = source.blendDstAlpha; - this.blendEquationAlpha = source.blendEquationAlpha; - - this.depthFunc = source.depthFunc; - this.depthTest = source.depthTest; - this.depthWrite = source.depthWrite; - - this.colorWrite = source.colorWrite; - - this.precision = source.precision; - - this.polygonOffset = source.polygonOffset; - this.polygonOffsetFactor = source.polygonOffsetFactor; - this.polygonOffsetUnits = source.polygonOffsetUnits; - - this.dithering = source.dithering; - - this.alphaTest = source.alphaTest; - this.premultipliedAlpha = source.premultipliedAlpha; - - this.visible = source.visible; - this.userData = JSON.parse( JSON.stringify( source.userData ) ); - - this.clipShadows = source.clipShadows; - this.clipIntersection = source.clipIntersection; - - 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; - - this.shadowSide = source.shadowSide; - - return this; - - }, - - dispose: function () { - - this.dispatchEvent( { type: 'dispose' } ); - - } - - } ); - - var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; + var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; @@ -13380,1471 +13328,2147 @@ }; /** - * @author bhouston / http://clara.io - */ + * @author mrdoob / http://mrdoob.com/ + * @author mikael emtinger / http://gomo.se/ + * @author WestLangley / http://github.com/WestLangley + */ - function Ray( origin, direction ) { + function Camera() { - this.origin = ( origin !== undefined ) ? origin : new Vector3(); - this.direction = ( direction !== undefined ) ? direction : new Vector3(); + Object3D.call( this ); - } + this.type = 'Camera'; - Object.assign( Ray.prototype, { + this.matrixWorldInverse = new Matrix4(); - set: function ( origin, direction ) { + this.projectionMatrix = new Matrix4(); + this.projectionMatrixInverse = new Matrix4(); - this.origin.copy( origin ); - this.direction.copy( direction ); + } - return this; + Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { - }, + constructor: Camera, - clone: function () { + isCamera: true, - return new this.constructor().copy( this ); + copy: function ( source, recursive ) { - }, + Object3D.prototype.copy.call( this, source, recursive ); - copy: function ( ray ) { + this.matrixWorldInverse.copy( source.matrixWorldInverse ); - this.origin.copy( ray.origin ); - this.direction.copy( ray.direction ); + this.projectionMatrix.copy( source.projectionMatrix ); + this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); return this; }, - at: function ( t, target ) { + getWorldDirection: function ( target ) { if ( target === undefined ) { - console.warn( 'THREE.Ray: .at() target is now required' ); + console.warn( 'THREE.Camera: .getWorldDirection() target is now required' ); target = new Vector3(); } - return target.copy( this.direction ).multiplyScalar( t ).add( this.origin ); + this.updateMatrixWorld( true ); + + var e = this.matrixWorld.elements; + + return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize(); }, - lookAt: function ( v ) { + updateMatrixWorld: function ( force ) { - this.direction.copy( v ).sub( this.origin ).normalize(); + Object3D.prototype.updateMatrixWorld.call( this, force ); - return this; + this.matrixWorldInverse.getInverse( this.matrixWorld ); }, - recast: function () { + clone: function () { - var v1 = new Vector3(); + return new this.constructor().copy( this ); - return function recast( t ) { + } - this.origin.copy( this.at( t, v1 ) ); + } ); - return this; + /** + * @author mrdoob / http://mrdoob.com/ + * @author greggman / http://games.greggman.com/ + * @author zz85 / http://www.lab4games.net/zz85/blog + * @author tschw + */ - }; + function PerspectiveCamera( fov, aspect, near, far ) { - }(), + Camera.call( this ); - closestPointToPoint: function ( point, target ) { + this.type = 'PerspectiveCamera'; - if ( target === undefined ) { + this.fov = fov !== undefined ? fov : 50; + this.zoom = 1; - console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' ); - target = new Vector3(); + 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; - target.subVectors( point, this.origin ); + this.filmGauge = 35; // width of the film (default in millimeters) + this.filmOffset = 0; // horizontal film offset (same unit as gauge) - var directionDistance = target.dot( this.direction ); + this.updateProjectionMatrix(); - if ( directionDistance < 0 ) { + } - return target.copy( this.origin ); + PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), { - } + constructor: PerspectiveCamera, - return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + isPerspectiveCamera: true, - }, + copy: function ( source, recursive ) { - distanceToPoint: function ( point ) { + Camera.prototype.copy.call( this, source, recursive ); - return Math.sqrt( this.distanceSqToPoint( point ) ); + this.fov = source.fov; + this.zoom = source.zoom; - }, + this.near = source.near; + this.far = source.far; + this.focus = source.focus; - distanceSqToPoint: function () { + this.aspect = source.aspect; + this.view = source.view === null ? null : Object.assign( {}, source.view ); - var v1 = new Vector3(); + this.filmGauge = source.filmGauge; + this.filmOffset = source.filmOffset; - return function distanceSqToPoint( point ) { + return this; - var directionDistance = v1.subVectors( point, this.origin ).dot( this.direction ); + }, - // point behind the ray + /** + * 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 ) { - if ( directionDistance < 0 ) { + // see http://www.bobatkins.com/photography/technical/field_of_view.html + var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - return this.origin.distanceToSquared( point ); + this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.updateProjectionMatrix(); - } + }, - v1.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin ); + /** + * Calculates the focal length from the current .fov and .filmGauge. + */ + getFocalLength: function () { - return v1.distanceToSquared( point ); + var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov ); - }; + return 0.5 * this.getFilmHeight() / vExtentSlope; - }(), + }, - distanceSqToSegment: function () { + getEffectiveFOV: function () { - var segCenter = new Vector3(); - var segDir = new Vector3(); - var diff = new Vector3(); + return _Math.RAD2DEG * 2 * Math.atan( + Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom ); - return function distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { + }, - // 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 : - // - The closest point on the ray - // - The closest point on the segment + getFilmWidth: function () { - segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); - segDir.copy( v1 ).sub( v0 ).normalize(); - diff.copy( this.origin ).sub( segCenter ); + // film not completely covered in portrait format (aspect < 1) + return this.filmGauge * Math.min( this.aspect, 1 ); - var segExtent = v0.distanceTo( v1 ) * 0.5; - var a01 = - this.direction.dot( segDir ); - var b0 = diff.dot( this.direction ); - var b1 = - diff.dot( segDir ); - var c = diff.lengthSq(); - var det = Math.abs( 1 - a01 * a01 ); - var s0, s1, sqrDist, extDet; + }, - if ( det > 0 ) { + getFilmHeight: function () { - // The ray and segment are not parallel. + // film not completely covered in landscape format (aspect > 1) + return this.filmGauge / Math.max( this.aspect, 1 ); - s0 = a01 * b1 - b0; - s1 = a01 * b0 - b1; - extDet = segExtent * det; + }, - if ( s0 >= 0 ) { + /** + * 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.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * --B-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * --C-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * --D-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * --E-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * --F-- + * camera.setViewOffset( 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 ) { - if ( s1 >= - extDet ) { + this.aspect = fullWidth / fullHeight; - if ( s1 <= extDet ) { + if ( this.view === null ) { - // region 0 - // Minimum at interior points of ray and segment. + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; - var invDet = 1 / det; - s0 *= invDet; - s1 *= invDet; - sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; + } - } else { + this.view.enabled = true; + this.view.fullWidth = fullWidth; + this.view.fullHeight = fullHeight; + this.view.offsetX = x; + this.view.offsetY = y; + this.view.width = width; + this.view.height = height; - // region 1 + this.updateProjectionMatrix(); - s1 = segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + }, - } + clearViewOffset: function () { - } else { + if ( this.view !== null ) { - // region 5 + this.view.enabled = false; - s1 = - segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + } - } + this.updateProjectionMatrix(); - } else { + }, - if ( s1 <= - extDet ) { + updateProjectionMatrix: function () { - // region 4 + var near = this.near, + top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, + height = 2 * top, + width = this.aspect * height, + left = - 0.5 * width, + view = this.view; - s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + if ( this.view !== null && this.view.enabled ) { - } else if ( s1 <= extDet ) { + var fullWidth = view.fullWidth, + fullHeight = view.fullHeight; - // region 3 + left += view.offsetX * width / fullWidth; + top -= view.offsetY * height / fullHeight; + width *= view.width / fullWidth; + height *= view.height / fullHeight; - s0 = 0; - s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = s1 * ( s1 + 2 * b1 ) + c; + } - } else { + var skew = this.filmOffset; + if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); - // region 2 + this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far ); - s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + this.projectionMatrixInverse.getInverse( this.projectionMatrix ); - } + }, - } + toJSON: function ( meta ) { - } else { + var data = Object3D.prototype.toJSON.call( this, meta ); - // Ray and segment are parallel. + data.object.fov = this.fov; + data.object.zoom = this.zoom; - s1 = ( a01 > 0 ) ? - segExtent : segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + data.object.near = this.near; + data.object.far = this.far; + data.object.focus = this.focus; - } + data.object.aspect = this.aspect; - if ( optionalPointOnRay ) { + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin ); + data.object.filmGauge = this.filmGauge; + data.object.filmOffset = this.filmOffset; - } + return data; - if ( optionalPointOnSegment ) { + } - optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter ); + } ); - } + /** + * Camera for rendering cube maps + * - renders scene into axis-aligned cube + * + * @author alteredq / http://alteredqualia.com/ + */ - return sqrDist; + var fov = 90, aspect = 1; - }; + function CubeCamera( near, far, cubeResolution, options ) { - }(), + Object3D.call( this ); - intersectSphere: function () { + this.type = 'CubeCamera'; - var v1 = new Vector3(); + var cameraPX = new PerspectiveCamera( fov, aspect, near, far ); + cameraPX.up.set( 0, - 1, 0 ); + cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); + this.add( cameraPX ); - return function intersectSphere( sphere, target ) { + var cameraNX = new PerspectiveCamera( fov, aspect, near, far ); + cameraNX.up.set( 0, - 1, 0 ); + cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); + this.add( cameraNX ); - v1.subVectors( sphere.center, this.origin ); - var tca = v1.dot( this.direction ); - var d2 = v1.dot( v1 ) - tca * tca; - var radius2 = sphere.radius * sphere.radius; + var cameraPY = new PerspectiveCamera( fov, aspect, near, far ); + cameraPY.up.set( 0, 0, 1 ); + cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); + this.add( cameraPY ); - if ( d2 > radius2 ) return null; + var cameraNY = new PerspectiveCamera( fov, aspect, near, far ); + cameraNY.up.set( 0, 0, - 1 ); + cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); + this.add( cameraNY ); - var thc = Math.sqrt( radius2 - d2 ); + var cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraPZ.up.set( 0, - 1, 0 ); + cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); + this.add( cameraPZ ); - // t0 = first intersect point - entrance on front of sphere - var t0 = tca - thc; + var cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraNZ.up.set( 0, - 1, 0 ); + cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); + this.add( cameraNZ ); - // t1 = second intersect point - exit point on back of sphere - var t1 = tca + thc; + options = options || { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; - // test to see if both t0 and t1 are behind the ray - if so, return null - if ( t0 < 0 && t1 < 0 ) return null; + this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options ); + this.renderTarget.texture.name = "CubeCamera"; - // test to see if t0 is behind the ray: - // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, - // in order to always return an intersect point that is in front of the ray. - if ( t0 < 0 ) return this.at( t1, target ); + this.update = function ( renderer, scene ) { - // else t0 is in front of the ray, so return the first collision point scaled by t0 - return this.at( t0, target ); + if ( this.parent === null ) this.updateMatrixWorld(); - }; + var currentRenderTarget = renderer.getRenderTarget(); - }(), + var renderTarget = this.renderTarget; + var generateMipmaps = renderTarget.texture.generateMipmaps; - intersectsSphere: function ( sphere ) { + renderTarget.texture.generateMipmaps = false; - return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); + renderer.setRenderTarget( renderTarget, 0 ); + renderer.render( scene, cameraPX ); - }, + renderer.setRenderTarget( renderTarget, 1 ); + renderer.render( scene, cameraNX ); - distanceToPlane: function ( plane ) { + renderer.setRenderTarget( renderTarget, 2 ); + renderer.render( scene, cameraPY ); - var denominator = plane.normal.dot( this.direction ); + renderer.setRenderTarget( renderTarget, 3 ); + renderer.render( scene, cameraNY ); - if ( denominator === 0 ) { + renderer.setRenderTarget( renderTarget, 4 ); + renderer.render( scene, cameraPZ ); - // line is coplanar, return origin - if ( plane.distanceToPoint( this.origin ) === 0 ) { + renderTarget.texture.generateMipmaps = generateMipmaps; - return 0; + renderer.setRenderTarget( renderTarget, 5 ); + renderer.render( scene, cameraNZ ); - } + renderer.setRenderTarget( currentRenderTarget ); - // Null is preferable to undefined since undefined means.... it is undefined + }; - return null; + this.clear = function ( renderer, color, depth, stencil ) { - } + var currentRenderTarget = renderer.getRenderTarget(); - var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + var renderTarget = this.renderTarget; - // Return if the ray never intersects the plane + for ( var i = 0; i < 6; i ++ ) { - return t >= 0 ? t : null; + renderer.setRenderTarget( renderTarget, i ); - }, + renderer.clear( color, depth, stencil ); - intersectPlane: function ( plane, target ) { + } - var t = this.distanceToPlane( plane ); + renderer.setRenderTarget( currentRenderTarget ); - if ( t === null ) { + }; - return null; + } - } + CubeCamera.prototype = Object.create( Object3D.prototype ); + CubeCamera.prototype.constructor = CubeCamera; - return this.at( t, target ); + /** + * @author alteredq / http://alteredqualia.com + * @author WestLangley / http://github.com/WestLangley + */ - }, + function WebGLRenderTargetCube( width, height, options ) { - intersectsPlane: function ( plane ) { + WebGLRenderTarget.call( this, width, height, options ); - // check if the ray lies on the plane first + } - var distToPoint = plane.distanceToPoint( this.origin ); + WebGLRenderTargetCube.prototype = Object.create( WebGLRenderTarget.prototype ); + WebGLRenderTargetCube.prototype.constructor = WebGLRenderTargetCube; - if ( distToPoint === 0 ) { + WebGLRenderTargetCube.prototype.isWebGLRenderTargetCube = true; - return true; + WebGLRenderTargetCube.prototype.fromEquirectangularTexture = function ( renderer, texture ) { - } + this.texture.type = texture.type; + this.texture.format = texture.format; + this.texture.encoding = texture.encoding; - var denominator = plane.normal.dot( this.direction ); + var scene = new Scene(); - if ( denominator * distToPoint < 0 ) { + var shader = { - return true; + uniforms: { + tEquirect: { value: null }, + }, - } + vertexShader: [ - // ray origin is behind the plane (and is pointing behind it) + "varying vec3 vWorldDirection;", - return false; + "vec3 transformDirection( in vec3 dir, in mat4 matrix ) {", - }, + " return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );", - intersectBox: function ( box, target ) { + "}", - var tmin, tmax, tymin, tymax, tzmin, tzmax; + "void main() {", - var invdirx = 1 / this.direction.x, - invdiry = 1 / this.direction.y, - invdirz = 1 / this.direction.z; + " vWorldDirection = transformDirection( position, modelMatrix );", - var origin = this.origin; + " #include ", + " #include ", - if ( invdirx >= 0 ) { + "}" - tmin = ( box.min.x - origin.x ) * invdirx; - tmax = ( box.max.x - origin.x ) * invdirx; + ].join( '\n' ), - } else { + fragmentShader: [ - tmin = ( box.max.x - origin.x ) * invdirx; - tmax = ( box.min.x - origin.x ) * invdirx; + "uniform sampler2D tEquirect;", - } + "varying vec3 vWorldDirection;", - if ( invdiry >= 0 ) { + "#define RECIPROCAL_PI 0.31830988618", + "#define RECIPROCAL_PI2 0.15915494", - tymin = ( box.min.y - origin.y ) * invdiry; - tymax = ( box.max.y - origin.y ) * invdiry; + "void main() {", - } else { + " vec3 direction = normalize( vWorldDirection );", - tymin = ( box.max.y - origin.y ) * invdiry; - tymax = ( box.min.y - origin.y ) * invdiry; + " vec2 sampleUV;", - } + " sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;", - if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + " sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;", - // These lines also handle the case where tmin or tmax is NaN - // (result of 0 * Infinity). x !== x returns true if x is NaN + " gl_FragColor = texture2D( tEquirect, sampleUV );", - if ( tymin > tmin || tmin !== tmin ) tmin = tymin; + "}" - if ( tymax < tmax || tmax !== tmax ) tmax = tymax; + ].join( '\n' ), + }; - if ( invdirz >= 0 ) { + var material = new ShaderMaterial( { - tzmin = ( box.min.z - origin.z ) * invdirz; - tzmax = ( box.max.z - origin.z ) * invdirz; + type: 'CubemapFromEquirect', - } else { + uniforms: cloneUniforms( shader.uniforms ), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader, + side: BackSide, + blending: NoBlending - tzmin = ( box.max.z - origin.z ) * invdirz; - tzmax = ( box.min.z - origin.z ) * invdirz; + } ); - } + material.uniforms.tEquirect.value = texture; - if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; + var mesh = new Mesh( new BoxBufferGeometry( 5, 5, 5 ), material ); - if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; + scene.add( mesh ); - if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; + var camera = new CubeCamera( 1, 10, 1 ); - //return point closest to the ray (positive side) + camera.renderTarget = this; + camera.renderTarget.texture.name = 'CubeCameraTexture'; - if ( tmax < 0 ) return null; + camera.update( renderer, scene ); - return this.at( tmin >= 0 ? tmin : tmax, target ); + mesh.geometry.dispose(); + mesh.material.dispose(); - }, + return this; - intersectsBox: ( function () { + }; - var v = new Vector3(); + /** + * @author alteredq / http://alteredqualia.com/ + */ - return function intersectsBox( box ) { + function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) { - return this.intersectBox( box, v ) !== null; + 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 : NearestFilter; + this.minFilter = minFilter !== undefined ? minFilter : NearestFilter; - intersectTriangle: function () { + this.generateMipmaps = false; + this.flipY = false; + this.unpackAlignment = 1; - // Compute the offset origin, edges, and normal. - var diff = new Vector3(); - var edge1 = new Vector3(); - var edge2 = new Vector3(); - var normal = new Vector3(); + } - return function intersectTriangle( a, b, c, backfaceCulling, target ) { + DataTexture.prototype = Object.create( Texture.prototype ); + DataTexture.prototype.constructor = DataTexture; - // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h + DataTexture.prototype.isDataTexture = true; - edge1.subVectors( b, a ); - edge2.subVectors( c, a ); - normal.crossVectors( edge1, edge2 ); + /** + * @author bhouston / http://clara.io + */ - // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, - // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by - // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) - // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) - // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) - var DdN = this.direction.dot( normal ); - var sign; + function Plane( normal, constant ) { - if ( DdN > 0 ) { + // normal is assumed to be normalized - if ( backfaceCulling ) return null; - sign = 1; + this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); + this.constant = ( constant !== undefined ) ? constant : 0; - } else if ( DdN < 0 ) { + } - sign = - 1; - DdN = - DdN; + Object.assign( Plane.prototype, { - } else { + isPlane: true, - return null; + set: function ( normal, constant ) { - } + this.normal.copy( normal ); + this.constant = constant; - diff.subVectors( this.origin, a ); - var DdQxE2 = sign * this.direction.dot( edge2.crossVectors( diff, edge2 ) ); + return this; - // b1 < 0, no intersection - if ( DdQxE2 < 0 ) { + }, - return null; + setComponents: function ( x, y, z, w ) { - } + this.normal.set( x, y, z ); + this.constant = w; - var DdE1xQ = sign * this.direction.dot( edge1.cross( diff ) ); + return this; - // b2 < 0, no intersection - if ( DdE1xQ < 0 ) { + }, - return null; + setFromNormalAndCoplanarPoint: function ( normal, point ) { - } + this.normal.copy( normal ); + this.constant = - point.dot( this.normal ); - // b1+b2 > 1, no intersection - if ( DdQxE2 + DdE1xQ > DdN ) { + return this; - return null; + }, - } + setFromCoplanarPoints: function () { - // Line intersects triangle, check if ray does. - var QdN = - sign * diff.dot( normal ); + var v1 = new Vector3(); + var v2 = new Vector3(); - // t < 0, no intersection - if ( QdN < 0 ) { + return function setFromCoplanarPoints( a, b, c ) { - return null; + var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize(); - } + // Q: should an error be thrown if normal is zero (e.g. degenerate plane)? - // Ray intersects triangle. - return this.at( QdN / DdN, target ); + this.setFromNormalAndCoplanarPoint( normal, a ); + + return this; }; }(), - applyMatrix4: function ( matrix4 ) { - - this.origin.applyMatrix4( matrix4 ); - this.direction.transformDirection( matrix4 ); + clone: function () { - return this; + return new this.constructor().copy( this ); }, - equals: function ( ray ) { + copy: function ( plane ) { - return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); + this.normal.copy( plane.normal ); + this.constant = plane.constant; - } + return this; - } ); + }, - /** - * @author bhouston / http://clara.io - * @author mrdoob / http://mrdoob.com/ - */ + normalize: function () { - function Triangle( a, b, c ) { + // Note: will lead to a divide by zero if the plane is invalid. - this.a = ( a !== undefined ) ? a : new Vector3(); - this.b = ( b !== undefined ) ? b : new Vector3(); - this.c = ( c !== undefined ) ? c : new Vector3(); + var inverseNormalLength = 1.0 / this.normal.length(); + this.normal.multiplyScalar( inverseNormalLength ); + this.constant *= inverseNormalLength; - } + return this; - Object.assign( Triangle, { + }, - getNormal: function () { + negate: function () { - var v0 = new Vector3(); + this.constant *= - 1; + this.normal.negate(); - return function getNormal( a, b, c, target ) { + return this; - if ( target === undefined ) { + }, - console.warn( 'THREE.Triangle: .getNormal() target is now required' ); - target = new Vector3(); + distanceToPoint: function ( point ) { - } + return this.normal.dot( point ) + this.constant; - target.subVectors( c, b ); - v0.subVectors( a, b ); - target.cross( v0 ); + }, - var targetLengthSq = target.lengthSq(); - if ( targetLengthSq > 0 ) { + distanceToSphere: function ( sphere ) { - return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); + return this.distanceToPoint( sphere.center ) - sphere.radius; - } + }, - return target.set( 0, 0, 0 ); + projectPoint: function ( point, target ) { - }; + if ( target === undefined ) { - }(), + console.warn( 'THREE.Plane: .projectPoint() target is now required' ); + target = new Vector3(); - // static/instance method to calculate barycentric coordinates - // based on: http://www.blackpawn.com/texts/pointinpoly/default.html - getBarycoord: function () { + } - var v0 = new Vector3(); - var v1 = new Vector3(); - var v2 = new Vector3(); + return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point ); - return function getBarycoord( point, a, b, c, target ) { + }, - v0.subVectors( c, a ); - v1.subVectors( b, a ); - v2.subVectors( point, a ); + intersectLine: function () { - var dot00 = v0.dot( v0 ); - var dot01 = v0.dot( v1 ); - var dot02 = v0.dot( v2 ); - var dot11 = v1.dot( v1 ); - var dot12 = v1.dot( v2 ); + var v1 = new Vector3(); - var denom = ( dot00 * dot11 - dot01 * dot01 ); + return function intersectLine( line, target ) { if ( target === undefined ) { - console.warn( 'THREE.Triangle: .getBarycoord() target is now required' ); + console.warn( 'THREE.Plane: .intersectLine() target is now required' ); target = new Vector3(); } - // collinear or singular triangle - if ( denom === 0 ) { + var direction = line.delta( v1 ); - // arbitrary location outside of triangle? - // not sure if this is the best idea, maybe should be returning undefined - return target.set( - 2, - 1, - 1 ); + var denominator = this.normal.dot( direction ); - } + if ( denominator === 0 ) { - var invDenom = 1 / denom; - var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; - var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; + // line is coplanar, return origin + if ( this.distanceToPoint( line.start ) === 0 ) { - // barycentric coordinates must always sum to 1 - return target.set( 1 - u - v, v, u ); + return target.copy( line.start ); - }; + } - }(), + // Unsure if this is the correct method to handle this case. + return undefined; - containsPoint: function () { + } - var v1 = new Vector3(); + var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator; - return function containsPoint( point, a, b, c ) { + if ( t < 0 || t > 1 ) { - Triangle.getBarycoord( point, a, b, c, v1 ); + return undefined; - return ( v1.x >= 0 ) && ( v1.y >= 0 ) && ( ( v1.x + v1.y ) <= 1 ); + } + + return target.copy( direction ).multiplyScalar( t ).add( line.start ); }; }(), - getUV: function () { - - var barycoord = new Vector3(); + intersectsLine: function ( line ) { - return function getUV( point, p1, p2, p3, uv1, uv2, uv3, target ) { + // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it. - this.getBarycoord( point, p1, p2, p3, barycoord ); + var startSign = this.distanceToPoint( line.start ); + var endSign = this.distanceToPoint( line.end ); - target.set( 0, 0 ); - target.addScaledVector( uv1, barycoord.x ); - target.addScaledVector( uv2, barycoord.y ); - target.addScaledVector( uv3, barycoord.z ); + return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 ); - return target; + }, - }; + intersectsBox: function ( box ) { - }(), + return box.intersectsPlane( this ); - isFrontFacing: function () { + }, - var v0 = new Vector3(); - var v1 = new Vector3(); + intersectsSphere: function ( sphere ) { - return function isFrontFacing( a, b, c, direction ) { + return sphere.intersectsPlane( this ); - v0.subVectors( c, b ); - v1.subVectors( a, b ); + }, - // strictly front facing - return ( v0.cross( v1 ).dot( direction ) < 0 ) ? true : false; + coplanarPoint: function ( target ) { - }; + if ( target === undefined ) { - }() + console.warn( 'THREE.Plane: .coplanarPoint() target is now required' ); + target = new Vector3(); - } ); + } - Object.assign( Triangle.prototype, { + return target.copy( this.normal ).multiplyScalar( - this.constant ); - set: function ( a, b, c ) { + }, - this.a.copy( a ); - this.b.copy( b ); - this.c.copy( c ); + applyMatrix4: function () { - return this; + var v1 = new Vector3(); + var m1 = new Matrix3(); - }, + return function applyMatrix4( matrix, optionalNormalMatrix ) { - setFromPointsAndIndices: function ( points, i0, i1, i2 ) { + var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix ); - this.a.copy( points[ i0 ] ); - this.b.copy( points[ i1 ] ); - this.c.copy( points[ i2 ] ); + var referencePoint = this.coplanarPoint( v1 ).applyMatrix4( matrix ); - return this; + var normal = this.normal.applyMatrix3( normalMatrix ).normalize(); - }, + this.constant = - referencePoint.dot( normal ); - clone: function () { + return this; - return new this.constructor().copy( this ); + }; - }, + }(), - copy: function ( triangle ) { + translate: function ( offset ) { - this.a.copy( triangle.a ); - this.b.copy( triangle.b ); - this.c.copy( triangle.c ); + this.constant -= offset.dot( this.normal ); return this; }, - getArea: function () { + equals: function ( plane ) { - var v0 = new Vector3(); - var v1 = new Vector3(); + return plane.normal.equals( this.normal ) && ( plane.constant === this.constant ); - return function getArea() { + } - v0.subVectors( this.c, this.b ); - v1.subVectors( this.a, this.b ); + } ); - return v0.cross( v1 ).length() * 0.5; + /** + * @author mrdoob / http://mrdoob.com/ + * @author alteredq / http://alteredqualia.com/ + * @author bhouston / http://clara.io + */ - }; + function Frustum( p0, p1, p2, p3, p4, p5 ) { - }(), + this.planes = [ - getMidpoint: function ( target ) { + ( p0 !== undefined ) ? p0 : new Plane(), + ( p1 !== undefined ) ? p1 : new Plane(), + ( p2 !== undefined ) ? p2 : new Plane(), + ( p3 !== undefined ) ? p3 : new Plane(), + ( p4 !== undefined ) ? p4 : new Plane(), + ( p5 !== undefined ) ? p5 : new Plane() - if ( target === undefined ) { + ]; - console.warn( 'THREE.Triangle: .getMidpoint() target is now required' ); - target = new Vector3(); + } - } + Object.assign( Frustum.prototype, { - return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); + set: function ( p0, p1, p2, p3, p4, p5 ) { + + var planes = this.planes; + + planes[ 0 ].copy( p0 ); + planes[ 1 ].copy( p1 ); + planes[ 2 ].copy( p2 ); + planes[ 3 ].copy( p3 ); + planes[ 4 ].copy( p4 ); + planes[ 5 ].copy( p5 ); + + return this; }, - getNormal: function ( target ) { + clone: function () { - return Triangle.getNormal( this.a, this.b, this.c, target ); + return new this.constructor().copy( this ); }, - getPlane: function ( target ) { + copy: function ( frustum ) { - if ( target === undefined ) { + var planes = this.planes; - console.warn( 'THREE.Triangle: .getPlane() target is now required' ); - target = new Vector3(); + for ( var i = 0; i < 6; i ++ ) { + + planes[ i ].copy( frustum.planes[ i ] ); } - return target.setFromCoplanarPoints( this.a, this.b, this.c ); + return this; }, - getBarycoord: function ( point, target ) { + setFromMatrix: function ( m ) { - return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); + var planes = this.planes; + var me = m.elements; + var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ]; + var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ]; + var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ]; + var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ]; + + planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize(); + planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize(); + planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize(); + planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize(); + planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize(); + planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize(); + + return this; }, - getUV: function ( point, uv1, uv2, uv3, target ) { + intersectsObject: function () { - return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target ); + var sphere = new Sphere(); - }, + return function intersectsObject( object ) { - containsPoint: function ( point ) { + var geometry = object.geometry; - return Triangle.containsPoint( point, this.a, this.b, this.c ); + if ( geometry.boundingSphere === null ) + geometry.computeBoundingSphere(); - }, + sphere.copy( geometry.boundingSphere ) + .applyMatrix4( object.matrixWorld ); - isFrontFacing: function ( direction ) { + return this.intersectsSphere( sphere ); - return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); + }; - }, + }(), - intersectsBox: function ( box ) { + intersectsSprite: function () { - return box.intersectsTriangle( this ); + var sphere = new Sphere(); - }, + return function intersectsSprite( sprite ) { - closestPointToPoint: function () { + sphere.center.set( 0, 0, 0 ); + sphere.radius = 0.7071067811865476; + sphere.applyMatrix4( sprite.matrixWorld ); - var vab = new Vector3(); - var vac = new Vector3(); - var vbc = new Vector3(); - var vap = new Vector3(); - var vbp = new Vector3(); - var vcp = new Vector3(); + return this.intersectsSphere( sphere ); - return function closestPointToPoint( p, target ) { + }; - if ( target === undefined ) { + }(), - console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' ); - target = new Vector3(); + intersectsSphere: function ( sphere ) { - } + var planes = this.planes; + var center = sphere.center; + var negRadius = - sphere.radius; - var a = this.a, b = this.b, c = this.c; - var v, w; + for ( var i = 0; i < 6; i ++ ) { - // algorithm thanks to Real-Time Collision Detection by Christer Ericson, - // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., - // under the accompanying license; see chapter 5.1.5 for detailed explanation. - // basically, we're distinguishing which of the voronoi regions of the triangle - // the point lies in with the minimum amount of redundant computation. + var distance = planes[ i ].distanceToPoint( center ); - vab.subVectors( b, a ); - vac.subVectors( c, a ); - vap.subVectors( p, a ); - var d1 = vab.dot( vap ); - var d2 = vac.dot( vap ); - if ( d1 <= 0 && d2 <= 0 ) { + if ( distance < negRadius ) { - // vertex region of A; barycentric coords (1, 0, 0) - return target.copy( a ); + return false; } - vbp.subVectors( p, b ); - var d3 = vab.dot( vbp ); - var d4 = vac.dot( vbp ); - if ( d3 >= 0 && d4 <= d3 ) { + } - // vertex region of B; barycentric coords (0, 1, 0) - return target.copy( b ); + return true; - } + }, - var vc = d1 * d4 - d3 * d2; - if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { + intersectsBox: function () { - v = d1 / ( d1 - d3 ); - // edge region of AB; barycentric coords (1-v, v, 0) - return target.copy( a ).addScaledVector( vab, v ); + var p = new Vector3(); - } + return function intersectsBox( box ) { - vcp.subVectors( p, c ); - var d5 = vab.dot( vcp ); - var d6 = vac.dot( vcp ); - if ( d6 >= 0 && d5 <= d6 ) { + var planes = this.planes; - // vertex region of C; barycentric coords (0, 0, 1) - return target.copy( c ); + for ( var i = 0; i < 6; i ++ ) { - } + var plane = planes[ i ]; - var vb = d5 * d2 - d1 * d6; - if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { + // corner at max distance - w = d2 / ( d2 - d6 ); - // edge region of AC; barycentric coords (1-w, 0, w) - return target.copy( a ).addScaledVector( vac, w ); + p.x = plane.normal.x > 0 ? box.max.x : box.min.x; + p.y = plane.normal.y > 0 ? box.max.y : box.min.y; + p.z = plane.normal.z > 0 ? box.max.z : box.min.z; - } + if ( plane.distanceToPoint( p ) < 0 ) { - var va = d3 * d6 - d5 * d4; - if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { + return false; - vbc.subVectors( c, b ); - w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); - // edge region of BC; barycentric coords (0, 1-w, w) - return target.copy( b ).addScaledVector( vbc, w ); // edge region of BC + } } - // face region - var denom = 1 / ( va + vb + vc ); - // u = va * denom - v = vb * denom; - w = vc * denom; - return target.copy( a ).addScaledVector( vab, v ).addScaledVector( vac, w ); + return true; }; }(), - equals: function ( triangle ) { + containsPoint: function ( point ) { - return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); + var planes = this.planes; - } + for ( var i = 0; i < 6; i ++ ) { - } ); + if ( planes[ i ].distanceToPoint( point ) < 0 ) { - /** - * @author mrdoob / http://mrdoob.com/ - * @author alteredq / http://alteredqualia.com/ - * - * parameters = { - * color: , - * opacity: , - * map: new THREE.Texture( ), - * - * lightMap: new THREE.Texture( ), - * lightMapIntensity: - * - * aoMap: new THREE.Texture( ), - * aoMapIntensity: - * - * specularMap: new THREE.Texture( ), - * - * alphaMap: new THREE.Texture( ), - * - * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ), - * combine: THREE.Multiply, - * reflectivity: , - * refractionRatio: , - * - * depthTest: , - * depthWrite: , - * - * wireframe: , - * wireframeLinewidth: , - * - * skinning: , - * morphTargets: - * } - */ + return false; - function MeshBasicMaterial( parameters ) { + } - Material.call( this ); + } - this.type = 'MeshBasicMaterial'; + return true; - this.color = new Color( 0xffffff ); // emissive + } - this.map = null; + } ); - this.lightMap = null; - this.lightMapIntensity = 1.0; + var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif"; - this.aoMap = null; - this.aoMapIntensity = 1.0; + var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif"; - this.specularMap = null; + var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif"; - this.alphaMap = null; + var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif"; - this.envMap = null; - this.combine = MultiplyOperation; - this.reflectivity = 1; - this.refractionRatio = 0.98; + var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif"; - this.wireframe = false; - this.wireframeLinewidth = 1; - this.wireframeLinecap = 'round'; - this.wireframeLinejoin = 'round'; + var begin_vertex = "vec3 transformed = vec3( position );"; - this.skinning = false; - this.morphTargets = false; + var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif"; - this.lights = false; + var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn 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\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn 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\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}"; - this.setValues( parameters ); + var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif"; - } + var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif"; - MeshBasicMaterial.prototype = Object.create( Material.prototype ); - MeshBasicMaterial.prototype.constructor = MeshBasicMaterial; + var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif"; - MeshBasicMaterial.prototype.isMeshBasicMaterial = true; + var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif"; - MeshBasicMaterial.prototype.copy = function ( source ) { + var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif"; - Material.prototype.copy.call( this, source ); + var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif"; - this.color.copy( source.color ); + var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - this.map = source.map; + var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif"; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; + var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif"; - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + var common = "#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\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\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}"; - this.specularMap = source.specularMap; + var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn 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\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn 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\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale = bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV( sampler2D envMap, vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif"; - this.alphaMap = source.alphaMap; + var defaultnormal_vertex = "vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = normalMatrix * objectTangent;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif"; - this.envMap = source.envMap; - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; + var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif"; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; + var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif"; - this.skinning = source.skinning; - this.morphTargets = source.morphTargets; + var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif"; - return this; + var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif"; + + var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );"; + + var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn 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.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn 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.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = min( floor( D ) / 255.0, 1.0 );\n\treturn 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\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn 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\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}"; + + var envmap_fragment = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\treflectVec = normalize( reflectVec );\n\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif"; + + var envmap_pars_fragment = "#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif"; + + var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif"; + + var envmap_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif"; + + var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif"; + + var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif"; + + var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif"; + + var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif"; + + var gradientmap_pars_fragment = "#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif"; + + var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif"; + + var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif"; + + var 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 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif"; + + var lights_pars_begin = "uniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t\tfloat shadowCameraNear;\n\t\tfloat shadowCameraFar;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif"; + + var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent ));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif"; + + var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;"; + + var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.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\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)"; + + var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif"; + + var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#endif\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\tfloat clearCoatInv = 1.0 - clearCoatDHR;\n\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec3 singleScattering = vec3( 0.0 );\n\t\tvec3 multiScattering = vec3( 0.0 );\n\t\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\t\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * singleScattering;\n\t\treflectedLight.indirectDiffuse += multiScattering * cosineWeightedIrradiance;\n\t\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n\t#else\n\t\treflectedLight.indirectSpecular += clearCoatInv * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#endif\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material ) GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}"; + + var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearCoatRadiance = vec3( 0.0 );\n#endif"; + + var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), maxMipLevel );\n\t#ifndef STANDARD\n\t\tclearCoatRadiance += getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), maxMipLevel );\n\t#endif\n#endif"; + + var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, irradiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif"; + + var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif"; + + var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n#endif"; + + var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif"; + + var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\tgl_Position.z *= gl_Position.w;\n\t#endif\n#endif"; + + var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif"; + + var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif"; + + var map_particle_fragment = "#ifdef USE_MAP\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif"; + + var map_particle_pars_fragment = "#ifdef USE_MAP\n\tuniform mat3 uvTransform;\n\tuniform sampler2D map;\n#endif"; + + var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif"; + + var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif"; + + var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif"; + + var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif"; + + var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif"; + + var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t#endif\n#endif"; + + var normal_fragment_maps = "#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t#ifdef FLIP_SIDED\n\t\t\tnormal = - normal;\n\t\t#endif\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\tnormal = normalize( normalMatrix * normal );\n\t#else\n\t\t#ifdef USE_TANGENT\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy = normalScale * mapN.xy;\n\t\t\tnormal = normalize( vTBN * mapN );\n\t\t#else\n\t\t\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n\t\t#endif\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif"; + + var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif"; + + var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\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\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}"; + + var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif"; + + var project_vertex = "vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;"; + + var dithering_fragment = "#if defined( DITHERING )\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif"; + + var dithering_pars_fragment = "#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif"; + + var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif"; + + var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif"; + + var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif"; + + var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif"; + + var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif"; + + var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}"; + + var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif"; + + var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif"; + + var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif"; + + var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif"; + + var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif"; + + var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif"; + + var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif"; + + var tonemapping_pars_fragment = "#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn 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\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}"; + + var uv_pars_fragment = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif"; + + var uv_pars_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif"; + + var uv_vertex = "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif"; + + var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif"; + + var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif"; + + var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif"; + + var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif"; + + var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + + var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}"; + + var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}"; + + var cube_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}"; + + var 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( 1.0 - gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}"; + + var 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#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\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}"; + + var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\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#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}"; + + var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\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\tvWorldPosition = worldPosition.xyz;\n}"; + + var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include \n\t#include \n}"; + + var equirect_vert = "varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}"; + + var 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}"; + + var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \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\t#include \n}"; + + var 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 \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 = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\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}"; + + var meshbasic_vert = "#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#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\t#include \n}"; + + var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\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 \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#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\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\t#include \n}"; + + var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\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 \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\t#include \n}"; + + var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\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 \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\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + + var meshmatcap_vert = "#define MATCAP\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 \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\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\tvViewPosition = - mvPosition.xyz;\n}"; + + var 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 \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\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\t#include \n}"; + + var 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 \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\t#include \n}"; + + var meshphysical_frag = "#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\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 \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\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\t#include \n}"; + + var meshphysical_vert = "#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\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\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\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}"; + + var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\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\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}"; + + var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\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#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}"; + + var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\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}"; + + var points_vert = "uniform float size;\nuniform float scale;\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\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}"; + + var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}"; + + var shadow_vert = "#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}"; + + var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\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\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}"; + + var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"; + + var ShaderChunk = { + alphamap_fragment: alphamap_fragment, + alphamap_pars_fragment: alphamap_pars_fragment, + alphatest_fragment: alphatest_fragment, + aomap_fragment: aomap_fragment, + aomap_pars_fragment: aomap_pars_fragment, + begin_vertex: begin_vertex, + beginnormal_vertex: beginnormal_vertex, + bsdfs: bsdfs, + bumpmap_pars_fragment: bumpmap_pars_fragment, + clipping_planes_fragment: clipping_planes_fragment, + clipping_planes_pars_fragment: clipping_planes_pars_fragment, + clipping_planes_pars_vertex: clipping_planes_pars_vertex, + clipping_planes_vertex: clipping_planes_vertex, + color_fragment: color_fragment, + color_pars_fragment: color_pars_fragment, + color_pars_vertex: color_pars_vertex, + color_vertex: color_vertex, + common: common, + cube_uv_reflection_fragment: cube_uv_reflection_fragment, + defaultnormal_vertex: defaultnormal_vertex, + displacementmap_pars_vertex: displacementmap_pars_vertex, + displacementmap_vertex: displacementmap_vertex, + emissivemap_fragment: emissivemap_fragment, + emissivemap_pars_fragment: emissivemap_pars_fragment, + encodings_fragment: encodings_fragment, + encodings_pars_fragment: encodings_pars_fragment, + envmap_fragment: envmap_fragment, + envmap_pars_fragment: envmap_pars_fragment, + envmap_pars_vertex: envmap_pars_vertex, + envmap_physical_pars_fragment: envmap_physical_pars_fragment, + envmap_vertex: envmap_vertex, + fog_vertex: fog_vertex, + fog_pars_vertex: fog_pars_vertex, + fog_fragment: fog_fragment, + fog_pars_fragment: fog_pars_fragment, + gradientmap_pars_fragment: gradientmap_pars_fragment, + lightmap_fragment: lightmap_fragment, + lightmap_pars_fragment: lightmap_pars_fragment, + lights_lambert_vertex: lights_lambert_vertex, + lights_pars_begin: lights_pars_begin, + lights_phong_fragment: lights_phong_fragment, + lights_phong_pars_fragment: lights_phong_pars_fragment, + lights_physical_fragment: lights_physical_fragment, + lights_physical_pars_fragment: lights_physical_pars_fragment, + lights_fragment_begin: lights_fragment_begin, + lights_fragment_maps: lights_fragment_maps, + lights_fragment_end: lights_fragment_end, + logdepthbuf_fragment: logdepthbuf_fragment, + logdepthbuf_pars_fragment: logdepthbuf_pars_fragment, + logdepthbuf_pars_vertex: logdepthbuf_pars_vertex, + logdepthbuf_vertex: logdepthbuf_vertex, + map_fragment: map_fragment, + map_pars_fragment: map_pars_fragment, + map_particle_fragment: map_particle_fragment, + map_particle_pars_fragment: map_particle_pars_fragment, + metalnessmap_fragment: metalnessmap_fragment, + metalnessmap_pars_fragment: metalnessmap_pars_fragment, + morphnormal_vertex: morphnormal_vertex, + morphtarget_pars_vertex: morphtarget_pars_vertex, + morphtarget_vertex: morphtarget_vertex, + normal_fragment_begin: normal_fragment_begin, + normal_fragment_maps: normal_fragment_maps, + normalmap_pars_fragment: normalmap_pars_fragment, + packing: packing, + premultiplied_alpha_fragment: premultiplied_alpha_fragment, + project_vertex: project_vertex, + dithering_fragment: dithering_fragment, + dithering_pars_fragment: dithering_pars_fragment, + roughnessmap_fragment: roughnessmap_fragment, + roughnessmap_pars_fragment: roughnessmap_pars_fragment, + shadowmap_pars_fragment: shadowmap_pars_fragment, + shadowmap_pars_vertex: shadowmap_pars_vertex, + shadowmap_vertex: shadowmap_vertex, + shadowmask_pars_fragment: shadowmask_pars_fragment, + skinbase_vertex: skinbase_vertex, + skinning_pars_vertex: skinning_pars_vertex, + skinning_vertex: skinning_vertex, + skinnormal_vertex: skinnormal_vertex, + specularmap_fragment: specularmap_fragment, + specularmap_pars_fragment: specularmap_pars_fragment, + tonemapping_fragment: tonemapping_fragment, + tonemapping_pars_fragment: tonemapping_pars_fragment, + uv_pars_fragment: uv_pars_fragment, + uv_pars_vertex: uv_pars_vertex, + uv_vertex: uv_vertex, + uv2_pars_fragment: uv2_pars_fragment, + uv2_pars_vertex: uv2_pars_vertex, + uv2_vertex: uv2_vertex, + worldpos_vertex: worldpos_vertex, + + background_frag: background_frag, + background_vert: background_vert, + cube_frag: cube_frag, + cube_vert: cube_vert, + depth_frag: depth_frag, + depth_vert: depth_vert, + distanceRGBA_frag: distanceRGBA_frag, + distanceRGBA_vert: distanceRGBA_vert, + equirect_frag: equirect_frag, + equirect_vert: equirect_vert, + linedashed_frag: linedashed_frag, + linedashed_vert: linedashed_vert, + meshbasic_frag: meshbasic_frag, + meshbasic_vert: meshbasic_vert, + meshlambert_frag: meshlambert_frag, + meshlambert_vert: meshlambert_vert, + meshmatcap_frag: meshmatcap_frag, + meshmatcap_vert: meshmatcap_vert, + meshphong_frag: meshphong_frag, + meshphong_vert: meshphong_vert, + meshphysical_frag: meshphysical_frag, + meshphysical_vert: meshphysical_vert, + normal_frag: normal_frag, + normal_vert: normal_vert, + points_frag: points_frag, + points_vert: points_vert, + shadow_frag: shadow_frag, + shadow_vert: shadow_vert, + sprite_frag: sprite_frag, + sprite_vert: sprite_vert + }; + + /** + * Uniforms library for shared webgl shaders + */ + + var UniformsLib = { + + common: { + + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + + map: { value: null }, + uvTransform: { value: new Matrix3() }, + + alphaMap: { value: null }, + + }, + + specularmap: { + + specularMap: { value: null }, + + }, + + envmap: { + + envMap: { value: null }, + flipEnvMap: { value: - 1 }, + reflectivity: { value: 1.0 }, + refractionRatio: { value: 0.98 }, + maxMipLevel: { value: 0 } + + }, + + aomap: { + + aoMap: { value: null }, + aoMapIntensity: { value: 1 } + + }, + + lightmap: { + + lightMap: { value: null }, + lightMapIntensity: { value: 1 } + + }, + + emissivemap: { + + emissiveMap: { value: null } + + }, + + bumpmap: { + + bumpMap: { value: null }, + bumpScale: { value: 1 } + + }, + + normalmap: { + + normalMap: { value: null }, + normalScale: { value: new Vector2( 1, 1 ) } + + }, + + displacementmap: { + + displacementMap: { value: null }, + displacementScale: { value: 1 }, + displacementBias: { value: 0 } + + }, + + roughnessmap: { + + roughnessMap: { value: null } + + }, + + metalnessmap: { + + metalnessMap: { value: null } + + }, + + gradientmap: { + + gradientMap: { value: null } + + }, + + fog: { + + fogDensity: { value: 0.00025 }, + fogNear: { value: 1 }, + fogFar: { value: 2000 }, + fogColor: { value: new Color( 0xffffff ) } + + }, + + lights: { + + ambientLightColor: { value: [] }, + + lightProbe: { value: [] }, + + directionalLights: { value: [], properties: { + direction: {}, + color: {}, + + shadow: {}, + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, + + directionalShadowMap: { value: [] }, + directionalShadowMatrix: { value: [] }, + + spotLights: { value: [], properties: { + color: {}, + position: {}, + direction: {}, + distance: {}, + coneCos: {}, + penumbraCos: {}, + decay: {}, + + shadow: {}, + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {} + } }, + + spotShadowMap: { value: [] }, + spotShadowMatrix: { value: [] }, + + pointLights: { value: [], properties: { + color: {}, + position: {}, + decay: {}, + distance: {}, + + shadow: {}, + shadowBias: {}, + shadowRadius: {}, + shadowMapSize: {}, + shadowCameraNear: {}, + shadowCameraFar: {} + } }, + + pointShadowMap: { value: [] }, + pointShadowMatrix: { value: [] }, + + hemisphereLights: { value: [], properties: { + direction: {}, + skyColor: {}, + groundColor: {} + } }, + + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src + rectAreaLights: { value: [], properties: { + color: {}, + position: {}, + width: {}, + height: {} + } } + + }, + + points: { + + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + size: { value: 1.0 }, + scale: { value: 1.0 }, + map: { value: null }, + uvTransform: { value: new Matrix3() } + + }, + + sprite: { + + diffuse: { value: new Color( 0xeeeeee ) }, + opacity: { value: 1.0 }, + center: { value: new Vector2( 0.5, 0.5 ) }, + rotation: { value: 0.0 }, + map: { value: null }, + uvTransform: { value: new Matrix3() } + + } }; /** - * @author mrdoob / http://mrdoob.com/ * @author alteredq / http://alteredqualia.com/ + * @author mrdoob / http://mrdoob.com/ * @author mikael emtinger / http://gomo.se/ - * @author jonobr1 / http://jonobr1.com/ */ - function Mesh( geometry, material ) { + var ShaderLib = { - Object3D.call( this ); + basic: { - this.type = 'Mesh'; + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.fog + ] ), - this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); - this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } ); + vertexShader: ShaderChunk.meshbasic_vert, + fragmentShader: ShaderChunk.meshbasic_frag - this.drawMode = TrianglesDrawMode; + }, - this.updateMorphTargets(); + lambert: { - } + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) } + } + ] ), - Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), { + vertexShader: ShaderChunk.meshlambert_vert, + fragmentShader: ShaderChunk.meshlambert_frag - constructor: Mesh, + }, - isMesh: true, + phong: { - setDrawMode: function ( value ) { + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.specularmap, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.gradientmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + specular: { value: new Color( 0x111111 ) }, + shininess: { value: 30 } + } + ] ), - this.drawMode = value; + vertexShader: ShaderChunk.meshphong_vert, + fragmentShader: ShaderChunk.meshphong_frag }, - copy: function ( source ) { + standard: { - Object3D.prototype.copy.call( this, source ); + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.envmap, + UniformsLib.aomap, + UniformsLib.lightmap, + UniformsLib.emissivemap, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.roughnessmap, + UniformsLib.metalnessmap, + UniformsLib.fog, + UniformsLib.lights, + { + emissive: { value: new Color( 0x000000 ) }, + roughness: { value: 0.5 }, + metalness: { value: 0.5 }, + envMapIntensity: { value: 1 } // temporary + } + ] ), - this.drawMode = source.drawMode; + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag - if ( source.morphTargetInfluences !== undefined ) { + }, - this.morphTargetInfluences = source.morphTargetInfluences.slice(); + matcap: { - } + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + UniformsLib.fog, + { + matcap: { value: null } + } + ] ), - if ( source.morphTargetDictionary !== undefined ) { + vertexShader: ShaderChunk.meshmatcap_vert, + fragmentShader: ShaderChunk.meshmatcap_frag - this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); + }, - } + points: { - return this; + uniforms: mergeUniforms( [ + UniformsLib.points, + UniformsLib.fog + ] ), + + vertexShader: ShaderChunk.points_vert, + fragmentShader: ShaderChunk.points_frag }, - updateMorphTargets: function () { + dashed: { - var geometry = this.geometry; - var m, ml, name; + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.fog, + { + scale: { value: 1 }, + dashSize: { value: 1 }, + totalSize: { value: 2 } + } + ] ), - if ( geometry.isBufferGeometry ) { + vertexShader: ShaderChunk.linedashed_vert, + fragmentShader: ShaderChunk.linedashed_frag - var morphAttributes = geometry.morphAttributes; - var keys = Object.keys( morphAttributes ); + }, - if ( keys.length > 0 ) { + depth: { - var morphAttribute = morphAttributes[ keys[ 0 ] ]; + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap + ] ), - if ( morphAttribute !== undefined ) { + vertexShader: ShaderChunk.depth_vert, + fragmentShader: ShaderChunk.depth_frag + + }, + + normal: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.bumpmap, + UniformsLib.normalmap, + UniformsLib.displacementmap, + { + opacity: { value: 1.0 } + } + ] ), + + vertexShader: ShaderChunk.normal_vert, + fragmentShader: ShaderChunk.normal_frag + + }, + + sprite: { + + uniforms: mergeUniforms( [ + UniformsLib.sprite, + UniformsLib.fog + ] ), + + vertexShader: ShaderChunk.sprite_vert, + fragmentShader: ShaderChunk.sprite_frag + + }, + + background: { + + uniforms: { + uvTransform: { value: new Matrix3() }, + t2D: { value: null }, + }, + + vertexShader: ShaderChunk.background_vert, + fragmentShader: ShaderChunk.background_frag + + }, + /* ------------------------------------------------------------------------- + // Cube map shader + ------------------------------------------------------------------------- */ + + cube: { + + uniforms: { + tCube: { value: null }, + tFlip: { value: - 1 }, + opacity: { value: 1.0 } + }, + + vertexShader: ShaderChunk.cube_vert, + fragmentShader: ShaderChunk.cube_frag + + }, + + equirect: { + + uniforms: { + tEquirect: { value: null }, + }, + + vertexShader: ShaderChunk.equirect_vert, + fragmentShader: ShaderChunk.equirect_frag + + }, + + distanceRGBA: { + + uniforms: mergeUniforms( [ + UniformsLib.common, + UniformsLib.displacementmap, + { + referencePosition: { value: new Vector3() }, + nearDistance: { value: 1 }, + farDistance: { value: 1000 } + } + ] ), - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + vertexShader: ShaderChunk.distanceRGBA_vert, + fragmentShader: ShaderChunk.distanceRGBA_frag - for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { + }, - name = morphAttribute[ m ].name || String( m ); + shadow: { - this.morphTargetInfluences.push( 0 ); - this.morphTargetDictionary[ name ] = m; + uniforms: mergeUniforms( [ + UniformsLib.lights, + UniformsLib.fog, + { + color: { value: new Color( 0x00000 ) }, + opacity: { value: 1.0 } + }, + ] ), - } + vertexShader: ShaderChunk.shadow_vert, + fragmentShader: ShaderChunk.shadow_frag - } + } - } + }; - } else { + ShaderLib.physical = { - var morphTargets = geometry.morphTargets; + uniforms: mergeUniforms( [ + ShaderLib.standard.uniforms, + { + clearCoat: { value: 0 }, + clearCoatRoughness: { value: 0 } + } + ] ), - if ( morphTargets !== undefined && morphTargets.length > 0 ) { + vertexShader: ShaderChunk.meshphysical_vert, + fragmentShader: ShaderChunk.meshphysical_frag - console.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' ); + }; - } + /** + * @author mrdoob / http://mrdoob.com/ + */ - } + function WebGLAnimation() { - }, + var context = null; + var isAnimating = false; + var animationLoop = null; - raycast: ( function () { + function onAnimationFrame( time, frame ) { - var inverseMatrix = new Matrix4(); - var ray = new Ray(); - var sphere = new Sphere(); + if ( isAnimating === false ) return; - var vA = new Vector3(); - var vB = new Vector3(); - var vC = new Vector3(); + animationLoop( time, frame ); - var tempA = new Vector3(); - var tempB = new Vector3(); - var tempC = new Vector3(); + context.requestAnimationFrame( onAnimationFrame ); - var morphA = new Vector3(); - var morphB = new Vector3(); - var morphC = new Vector3(); + } - var uvA = new Vector2(); - var uvB = new Vector2(); - var uvC = new Vector2(); + return { - var intersectionPoint = new Vector3(); - var intersectionPointWorld = new Vector3(); + start: function () { - function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) { + if ( isAnimating === true ) return; + if ( animationLoop === null ) return; - var intersect; + context.requestAnimationFrame( onAnimationFrame ); - if ( material.side === BackSide ) { + isAnimating = true; - intersect = ray.intersectTriangle( pC, pB, pA, true, point ); + }, - } else { + stop: function () { - intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point ); + isAnimating = false; - } + }, - if ( intersect === null ) return null; + setAnimationLoop: function ( callback ) { - intersectionPointWorld.copy( point ); - intersectionPointWorld.applyMatrix4( object.matrixWorld ); + animationLoop = callback; - var distance = raycaster.ray.origin.distanceTo( intersectionPointWorld ); + }, - if ( distance < raycaster.near || distance > raycaster.far ) return null; + setContext: function ( value ) { - return { - distance: distance, - point: intersectionPointWorld.clone(), - object: object - }; + context = value; } - function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, uv, a, b, c ) { + }; - vA.fromBufferAttribute( position, a ); - vB.fromBufferAttribute( position, b ); - vC.fromBufferAttribute( position, c ); + } - var morphInfluences = object.morphTargetInfluences; + /** + * @author mrdoob / http://mrdoob.com/ + */ - if ( material.morphTargets && morphPosition && morphInfluences ) { + function WebGLAttributes( gl ) { - morphA.set( 0, 0, 0 ); - morphB.set( 0, 0, 0 ); - morphC.set( 0, 0, 0 ); + var buffers = new WeakMap(); - for ( var i = 0, il = morphPosition.length; i < il; i ++ ) { + function createBuffer( attribute, bufferType ) { - var influence = morphInfluences[ i ]; - var morphAttribute = morphPosition[ i ]; + var array = attribute.array; + var usage = attribute.dynamic ? 35048 : 35044; - if ( influence === 0 ) continue; + var buffer = gl.createBuffer(); - tempA.fromBufferAttribute( morphAttribute, a ); - tempB.fromBufferAttribute( morphAttribute, b ); - tempC.fromBufferAttribute( morphAttribute, c ); + gl.bindBuffer( bufferType, buffer ); + gl.bufferData( bufferType, array, usage ); - morphA.addScaledVector( tempA.sub( vA ), influence ); - morphB.addScaledVector( tempB.sub( vB ), influence ); - morphC.addScaledVector( tempC.sub( vC ), influence ); + attribute.onUploadCallback(); - } + var type = 5126; - vA.add( morphA ); - vB.add( morphB ); - vC.add( morphC ); + if ( array instanceof Float32Array ) { - } + type = 5126; - var intersection = checkIntersection( object, material, raycaster, ray, vA, vB, vC, intersectionPoint ); + } else if ( array instanceof Float64Array ) { - if ( intersection ) { + console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' ); - if ( uv ) { + } else if ( array instanceof Uint16Array ) { - uvA.fromBufferAttribute( uv, a ); - uvB.fromBufferAttribute( uv, b ); - uvC.fromBufferAttribute( uv, c ); + type = 5123; - intersection.uv = Triangle.getUV( intersectionPoint, vA, vB, vC, uvA, uvB, uvC, new Vector2() ); + } else if ( array instanceof Int16Array ) { - } + type = 5122; - var face = new Face3( a, b, c ); - Triangle.getNormal( vA, vB, vC, face.normal ); + } else if ( array instanceof Uint32Array ) { - intersection.face = face; + type = 5125; - } + } else if ( array instanceof Int32Array ) { - return intersection; + type = 5124; - } + } else if ( array instanceof Int8Array ) { - return function raycast( raycaster, intersects ) { + type = 5120; - var geometry = this.geometry; - var material = this.material; - var matrixWorld = this.matrixWorld; + } else if ( array instanceof Uint8Array ) { - if ( material === undefined ) return; + type = 5121; - // Checking boundingSphere distance to ray + } - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + return { + buffer: buffer, + type: type, + bytesPerElement: array.BYTES_PER_ELEMENT, + version: attribute.version + }; - sphere.copy( geometry.boundingSphere ); - sphere.applyMatrix4( matrixWorld ); + } - if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + function updateBuffer( buffer, attribute, bufferType ) { - // + var array = attribute.array; + var updateRange = attribute.updateRange; - inverseMatrix.getInverse( matrixWorld ); - ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix ); + gl.bindBuffer( bufferType, buffer ); - // Check boundingBox before continuing + if ( attribute.dynamic === false ) { - if ( geometry.boundingBox !== null ) { + gl.bufferData( bufferType, array, 35044 ); - if ( ray.intersectsBox( geometry.boundingBox ) === false ) return; + } else if ( updateRange.count === - 1 ) { - } + // Not using update ranges - var intersection; + gl.bufferSubData( bufferType, 0, array ); - if ( geometry.isBufferGeometry ) { + } else if ( updateRange.count === 0 ) { - var a, b, c; - var index = geometry.index; - var position = geometry.attributes.position; - var morphPosition = geometry.morphAttributes.position; - var uv = geometry.attributes.uv; - var groups = geometry.groups; - var drawRange = geometry.drawRange; - var i, j, il, jl; - var group, groupMaterial; - var start, end; + console.error( 'THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually.' ); - if ( index !== null ) { + } else { - // indexed buffer geometry + gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, + array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) ); - if ( Array.isArray( material ) ) { + updateRange.count = - 1; // reset range - for ( i = 0, il = groups.length; i < il; i ++ ) { + } - group = groups[ i ]; - groupMaterial = material[ group.materialIndex ]; + } - start = Math.max( group.start, drawRange.start ); - end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); + // - for ( j = start, jl = end; j < jl; j += 3 ) { + function get( attribute ) { - a = index.getX( j ); - b = index.getX( j + 1 ); - c = index.getX( j + 2 ); + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c ); + return buffers.get( attribute ); - if ( intersection ) { + } - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + function remove( attribute ) { - } + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - } + var data = buffers.get( attribute ); - } + if ( data ) { - } else { + gl.deleteBuffer( data.buffer ); - start = Math.max( 0, drawRange.start ); - end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); + buffers.delete( attribute ); - for ( i = start, il = end; i < il; i += 3 ) { + } - a = index.getX( i ); - b = index.getX( i + 1 ); - c = index.getX( i + 2 ); + } - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c ); + function update( attribute, bufferType ) { - if ( intersection ) { + if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics - intersects.push( intersection ); + var data = buffers.get( attribute ); - } + if ( data === undefined ) { - } + buffers.set( attribute, createBuffer( attribute, bufferType ) ); - } + } else if ( data.version < attribute.version ) { - } else if ( position !== undefined ) { + updateBuffer( data.buffer, attribute, bufferType ); - // non-indexed buffer geometry + data.version = attribute.version; - if ( Array.isArray( material ) ) { + } - for ( i = 0, il = groups.length; i < il; i ++ ) { + } - group = groups[ i ]; - groupMaterial = material[ group.materialIndex ]; + return { - start = Math.max( group.start, drawRange.start ); - end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ); + get: get, + remove: remove, + update: update - for ( j = start, jl = end; j < jl; j += 3 ) { + }; - a = j; - b = j + 1; - c = j + 2; + } - intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, ray, position, morphPosition, uv, a, b, c ); + /** + * @author mrdoob / http://mrdoob.com/ + * @author Mugen87 / https://github.com/Mugen87 + */ - if ( intersection ) { + // PlaneGeometry - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + function PlaneGeometry( width, height, widthSegments, heightSegments ) { - } + Geometry.call( this ); - } + this.type = 'PlaneGeometry'; - } + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - } else { + this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) ); + this.mergeVertices(); - start = Math.max( 0, drawRange.start ); - end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); + } - for ( i = start, il = end; i < il; i += 3 ) { + PlaneGeometry.prototype = Object.create( Geometry.prototype ); + PlaneGeometry.prototype.constructor = PlaneGeometry; - a = i; - b = i + 1; - c = i + 2; + // PlaneBufferGeometry - intersection = checkBufferGeometryIntersection( this, material, raycaster, ray, position, morphPosition, uv, a, b, c ); + function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) { - if ( intersection ) { + BufferGeometry.call( this ); - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics - intersects.push( intersection ); + this.type = 'PlaneBufferGeometry'; - } + this.parameters = { + width: width, + height: height, + widthSegments: widthSegments, + heightSegments: heightSegments + }; - } + width = width || 1; + height = height || 1; - } + var width_half = width / 2; + var height_half = height / 2; - } + var gridX = Math.floor( widthSegments ) || 1; + var gridY = Math.floor( heightSegments ) || 1; - } else if ( geometry.isGeometry ) { + var gridX1 = gridX + 1; + var gridY1 = gridY + 1; - var fvA, fvB, fvC; - var isMultiMaterial = Array.isArray( material ); + var segment_width = width / gridX; + var segment_height = height / gridY; - var vertices = geometry.vertices; - var faces = geometry.faces; - var uvs; + var ix, iy; - var faceVertexUvs = geometry.faceVertexUvs[ 0 ]; - if ( faceVertexUvs.length > 0 ) uvs = faceVertexUvs; + // buffers - for ( var f = 0, fl = faces.length; f < fl; f ++ ) { + var indices = []; + var vertices = []; + var normals = []; + var uvs = []; - var face = faces[ f ]; - var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material; + // generate vertices, normals and uvs - if ( faceMaterial === undefined ) continue; + for ( iy = 0; iy < gridY1; iy ++ ) { - fvA = vertices[ face.a ]; - fvB = vertices[ face.b ]; - fvC = vertices[ face.c ]; + var y = iy * segment_height - height_half; - intersection = checkIntersection( this, faceMaterial, raycaster, ray, fvA, fvB, fvC, intersectionPoint ); + for ( ix = 0; ix < gridX1; ix ++ ) { - if ( intersection ) { + var x = ix * segment_width - width_half; - if ( uvs && uvs[ f ] ) { + vertices.push( x, - y, 0 ); - var uvs_f = uvs[ f ]; - uvA.copy( uvs_f[ 0 ] ); - uvB.copy( uvs_f[ 1 ] ); - uvC.copy( uvs_f[ 2 ] ); + normals.push( 0, 0, 1 ); - intersection.uv = Triangle.getUV( intersectionPoint, fvA, fvB, fvC, uvA, uvB, uvC, new Vector2() ); + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); - } + } - intersection.face = face; - intersection.faceIndex = f; - intersects.push( intersection ); + } - } + // indices - } + 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; - }() ), + // faces - clone: function () { + indices.push( a, b, d ); + indices.push( b, c, d ); - return new this.constructor( this.geometry, this.material ).copy( this ); + } } - } ); + // build geometry + + this.setIndex( indices ); + this.addAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.addAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.addAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + + } + + PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype ); + PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry; /** * @author mrdoob / http://mrdoob.com/ @@ -16875,56 +17499,37 @@ * @author mrdoob / http://mrdoob.com/ */ - function addLineNumbers( string ) { - - var lines = string.split( '\n' ); - - for ( var i = 0; i < lines.length; i ++ ) { - - lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; - - } - - return lines.join( '\n' ); - - } - - function WebGLShader( gl, type, string, debug ) { + function WebGLShader( gl, type, string ) { var shader = gl.createShader( type ); gl.shaderSource( shader, string ); gl.compileShader( shader ); - if ( debug === true ) { + return shader; - if ( gl.getShaderParameter( shader, 35713 ) === false ) { + } - console.error( 'THREE.WebGLShader: Shader couldn\'t compile.' ); + /** + * @author mrdoob / http://mrdoob.com/ + */ - } + var programIdCount = 0; - if ( gl.getShaderInfoLog( shader ) !== '' ) { + function addLineNumbers( string ) { - console.warn( 'THREE.WebGLShader: gl.getShaderInfoLog()', type === 35633 ? 'vertex' : 'fragment', gl.getShaderInfoLog( shader ), addLineNumbers( string ) ); + var lines = string.split( '\n' ); - } + for ( var i = 0; i < lines.length; i ++ ) { - } + lines[ i ] = ( i + 1 ) + ': ' + lines[ i ]; - // --enable-privileged-webgl-extension - // console.log( type, gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); + } - return shader; + return lines.join( '\n' ); } - /** - * @author mrdoob / http://mrdoob.com/ - */ - - var programIdCount = 0; - function getEncodingComponents( encoding ) { switch ( encoding ) { @@ -16950,6 +17555,22 @@ } + function getShaderErrors( gl, shader, type ) { + + var status = gl.getShaderParameter( shader, 35713 ); + var log = gl.getShaderInfoLog( shader ).trim(); + + if ( status && log === '' ) return ''; + + // --enable-privileged-webgl-extension + // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); + + var source = gl.getShaderSource( shader ); + + return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers( source ); + + } + function getTexelDecodingFunction( functionName, encoding ) { var components = getEncodingComponents( encoding ); @@ -17122,7 +17743,7 @@ } - function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities, textures ) { + function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) { var gl = renderer.context; @@ -17499,8 +18120,8 @@ // console.log( '*VERTEX*', vertexGlsl ); // console.log( '*FRAGMENT*', fragmentGlsl ); - var glVertexShader = WebGLShader( gl, 35633, vertexGlsl, renderer.debug.checkShaderErrors ); - var glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl, renderer.debug.checkShaderErrors ); + var glVertexShader = WebGLShader( gl, 35633, vertexGlsl ); + var glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl ); gl.attachShader( program, glVertexShader ); gl.attachShader( program, glFragmentShader ); @@ -17530,14 +18151,14 @@ var runnable = true; var haveDiagnostics = true; - // console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) ); - // console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) ); - if ( gl.getProgramParameter( program, 35714 ) === false ) { runnable = false; - console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter( program, 35715 ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog ); + var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' ); + var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' ); + + console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter( program, 35715 ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors ); } else if ( programLog !== '' ) { @@ -17591,7 +18212,7 @@ if ( cachedUniforms === undefined ) { - cachedUniforms = new WebGLUniforms( gl, program, textures ); + cachedUniforms = new WebGLUniforms( gl, program ); } @@ -17624,31 +18245,6 @@ }; - // DEPRECATED - - Object.defineProperties( this, { - - uniforms: { - get: function () { - - console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' ); - return this.getUniforms(); - - } - }, - - attributes: { - get: function () { - - console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' ); - return this.getAttributes(); - - } - } - - } ); - - // this.name = shader.name; @@ -17667,7 +18263,7 @@ * @author mrdoob / http://mrdoob.com/ */ - function WebGLPrograms( renderer, extensions, capabilities, textures ) { + function WebGLPrograms( renderer, extensions, capabilities ) { var programs = []; @@ -17941,7 +18537,7 @@ if ( program === undefined ) { - program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities, textures ); + program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ); programs.push( program ); } @@ -18325,7 +18921,7 @@ } - var count = 0; + var nextVersion = 0; function WebGLLights() { @@ -18333,16 +18929,15 @@ var state = { - id: count ++, + version: 0, hash: { - stateID: - 1, directionalLength: - 1, pointLength: - 1, spotLength: - 1, rectAreaLength: - 1, hemiLength: - 1, - shadowsLength: - 1 + shadowsLength: - 1, }, ambient: [ 0, 0, 0 ], @@ -18556,19 +19151,31 @@ state.ambient[ 1 ] = g; state.ambient[ 2 ] = b; - state.directional.length = directionalLength; - state.spot.length = spotLength; - state.rectArea.length = rectAreaLength; - state.point.length = pointLength; - state.hemi.length = hemiLength; + var hash = state.hash; + + if ( hash.directionalLength !== directionalLength || + hash.pointLength !== pointLength || + hash.spotLength !== spotLength || + hash.rectAreaLength !== rectAreaLength || + hash.hemiLength !== hemiLength || + hash.shadowsLength !== shadows.length ) { - state.hash.stateID = state.id; - state.hash.directionalLength = directionalLength; - state.hash.pointLength = pointLength; - state.hash.spotLength = spotLength; - state.hash.rectAreaLength = rectAreaLength; - state.hash.hemiLength = hemiLength; - state.hash.shadowsLength = shadows.length; + state.directional.length = directionalLength; + state.spot.length = spotLength; + state.rectArea.length = rectAreaLength; + state.point.length = pointLength; + state.hemi.length = hemiLength; + + hash.directionalLength = directionalLength; + hash.pointLength = pointLength; + hash.spotLength = spotLength; + hash.rectAreaLength = rectAreaLength; + hash.hemiLength = hemiLength; + hash.shadowsLength = shadows.length; + + state.version = nextVersion ++; + + } } @@ -21037,7 +21644,7 @@ var samples = getRenderTargetSamples( renderTarget ); - _gl.renderbufferStorageMultisample( 36161, samples, 34041, renderTarget.width, renderTarget.height ); + _gl.renderbufferStorageMultisample( 36161, samples, 35056, renderTarget.width, renderTarget.height ); } else { @@ -21607,315 +22214,6 @@ } ); - /** - * @author mrdoob / http://mrdoob.com/ - * @author mikael emtinger / http://gomo.se/ - * @author WestLangley / http://github.com/WestLangley - */ - - function Camera() { - - Object3D.call( this ); - - this.type = 'Camera'; - - this.matrixWorldInverse = new Matrix4(); - - this.projectionMatrix = new Matrix4(); - this.projectionMatrixInverse = new Matrix4(); - - } - - Camera.prototype = Object.assign( Object.create( Object3D.prototype ), { - - constructor: Camera, - - isCamera: true, - - copy: function ( source, recursive ) { - - Object3D.prototype.copy.call( this, source, recursive ); - - this.matrixWorldInverse.copy( source.matrixWorldInverse ); - - this.projectionMatrix.copy( source.projectionMatrix ); - this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); - - return this; - - }, - - getWorldDirection: function ( target ) { - - if ( target === undefined ) { - - console.warn( 'THREE.Camera: .getWorldDirection() target is now required' ); - target = new Vector3(); - - } - - this.updateMatrixWorld( true ); - - var e = this.matrixWorld.elements; - - return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize(); - - }, - - updateMatrixWorld: function ( force ) { - - Object3D.prototype.updateMatrixWorld.call( this, force ); - - this.matrixWorldInverse.getInverse( this.matrixWorld ); - - }, - - clone: function () { - - return new this.constructor().copy( this ); - - } - - } ); - - /** - * @author mrdoob / http://mrdoob.com/ - * @author greggman / http://games.greggman.com/ - * @author zz85 / http://www.lab4games.net/zz85/blog - * @author tschw - */ - - function PerspectiveCamera( fov, aspect, near, far ) { - - Camera.call( this ); - - this.type = 'PerspectiveCamera'; - - this.fov = fov !== undefined ? fov : 50; - this.zoom = 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(); - - } - - PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), { - - constructor: PerspectiveCamera, - - isPerspectiveCamera: true, - - copy: function ( source, recursive ) { - - Camera.prototype.copy.call( this, source, recursive ); - - this.fov = source.fov; - this.zoom = source.zoom; - - 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; - - return this; - - }, - - /** - * 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 ) { - - // see http://www.bobatkins.com/photography/technical/field_of_view.html - var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - - this.fov = _Math.RAD2DEG * 2 * Math.atan( vExtentSlope ); - this.updateProjectionMatrix(); - - }, - - /** - * Calculates the focal length from the current .fov and .filmGauge. - */ - getFocalLength: function () { - - var vExtentSlope = Math.tan( _Math.DEG2RAD * 0.5 * this.fov ); - - return 0.5 * this.getFilmHeight() / vExtentSlope; - - }, - - getEffectiveFOV: function () { - - return _Math.RAD2DEG * 2 * Math.atan( - Math.tan( _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.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * --B-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * --C-- - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * --D-- - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * --E-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * --F-- - * camera.setViewOffset( 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; - - if ( this.view === null ) { - - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; - - } - - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; - - this.updateProjectionMatrix(); - - }, - - clearViewOffset: function () { - - if ( this.view !== null ) { - - this.view.enabled = false; - - } - - this.updateProjectionMatrix(); - - }, - - updateProjectionMatrix: function () { - - var near = this.near, - top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom, - height = 2 * top, - width = this.aspect * height, - left = - 0.5 * width, - view = this.view; - - if ( this.view !== null && this.view.enabled ) { - - 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.makePerspective( left, left + width, top, top - height, near, this.far ); - - this.projectionMatrixInverse.getInverse( this.projectionMatrix ); - - }, - - toJSON: function ( meta ) { - - var data = 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; - - } - - } ); - /** * @author mrdoob / http://mrdoob.com/ */ @@ -22072,6 +22370,8 @@ animation.start(); + scope.dispatchEvent( { type: 'sessionstart' } ); + } else { if ( scope.enabled ) { @@ -22082,6 +22382,8 @@ animation.stop(); + scope.dispatchEvent( { type: 'sessionend' } ); + } } @@ -22101,6 +22403,7 @@ if ( gamepad && ( gamepad.id === 'Daydream Controller' || gamepad.id === 'Gear VR Controller' || gamepad.id === 'Oculus Go Controller' || gamepad.id === 'OpenVR Gamepad' || gamepad.id.startsWith( 'Oculus Touch' ) || + gamepad.id.startsWith( 'HTC Vive Focus' ) || gamepad.id.startsWith( 'Spatial Controller' ) ) ) { if ( j === id ) return gamepad; @@ -22406,12 +22709,16 @@ } + Object.assign( WebVRManager.prototype, EventDispatcher.prototype ); + /** * @author mrdoob / http://mrdoob.com/ */ function WebXRManager( renderer ) { + var scope = this; + var gl = renderer.context; var session = null; @@ -22488,6 +22795,8 @@ renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830 animation.stop(); + scope.dispatchEvent( { type: 'sessionend' } ); + } function onRequestReferenceSpace( value ) { @@ -22497,6 +22806,8 @@ animation.setContext( session ); animation.start(); + scope.dispatchEvent( { type: 'sessionstart' } ); + } this.setFramebufferScaleFactor = function ( value ) { @@ -22509,6 +22820,12 @@ }; + this.getSession = function () { + + return session; + + }; + this.setSession = function ( value ) { session = value; @@ -22711,6 +23028,8 @@ } + Object.assign( WebXRManager.prototype, EventDispatcher.prototype ); + /** * @author supereggbert / http://www.paulbrunt.co.uk/ * @author mrdoob / http://mrdoob.com/ @@ -22945,8 +23264,8 @@ utils = new WebGLUtils( _gl, extensions, capabilities ); state = new WebGLState( _gl, extensions, utils, capabilities ); - state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); - state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); + state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() ); + state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() ); info = new WebGLInfo( _gl ); properties = new WebGLProperties(); @@ -22955,7 +23274,7 @@ geometries = new WebGLGeometries( _gl, attributes, info ); objects = new WebGLObjects( geometries, info ); morphtargets = new WebGLMorphtargets( _gl ); - programCache = new WebGLPrograms( _this, extensions, capabilities, textures ); + programCache = new WebGLPrograms( _this, extensions, capabilities ); renderLists = new WebGLRenderLists(); renderStates = new WebGLRenderStates(); @@ -23060,8 +23379,8 @@ _width = width; _height = height; - _canvas.width = width * _pixelRatio; - _canvas.height = height * _pixelRatio; + _canvas.width = Math.floor( width * _pixelRatio ); + _canvas.height = Math.floor( height * _pixelRatio ); if ( updateStyle !== false ) { @@ -23084,7 +23403,7 @@ } - return target.set( _width * _pixelRatio, _height * _pixelRatio ); + return target.set( _width * _pixelRatio, _height * _pixelRatio ).floor(); }; @@ -23095,8 +23414,8 @@ _pixelRatio = pixelRatio; - _canvas.width = width * pixelRatio; - _canvas.height = height * pixelRatio; + _canvas.width = Math.floor( width * pixelRatio ); + _canvas.height = Math.floor( height * pixelRatio ); this.setViewport( 0, 0, width, height ); @@ -23134,7 +23453,7 @@ } - state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ) ); + state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() ); }; @@ -23156,7 +23475,7 @@ } - state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ) ); + state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() ); }; @@ -23926,6 +24245,10 @@ groupOrder = object.renderOrder; + } else if ( object.isLOD ) { + + if ( object.autoUpdate === true ) object.update( camera ); + } else if ( object.isLight ) { currentRenderState.pushLight( object ); @@ -24111,8 +24434,7 @@ var lights = currentRenderState.state.lights; var shadowsArray = currentRenderState.state.shadowsArray; - var lightsHash = materialProperties.lightsHash; - var lightsStateHash = lights.state.hash; + var lightsStateVersion = lights.state.version; var parameters = programCache.getParameters( material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object ); @@ -24132,21 +24454,9 @@ // changed glsl or parameters releaseMaterialProgramReference( material ); - } else if ( lightsHash.stateID !== lightsStateHash.stateID || - lightsHash.directionalLength !== lightsStateHash.directionalLength || - lightsHash.pointLength !== lightsStateHash.pointLength || - lightsHash.spotLength !== lightsStateHash.spotLength || - lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength || - lightsHash.hemiLength !== lightsStateHash.hemiLength || - lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) { - - lightsHash.stateID = lightsStateHash.stateID; - lightsHash.directionalLength = lightsStateHash.directionalLength; - lightsHash.pointLength = lightsStateHash.pointLength; - lightsHash.spotLength = lightsStateHash.spotLength; - lightsHash.rectAreaLength = lightsStateHash.rectAreaLength; - lightsHash.hemiLength = lightsStateHash.hemiLength; - lightsHash.shadowsLength = lightsStateHash.shadowsLength; + } else if ( materialProperties.lightsStateVersion !== lightsStateVersion ) { + + materialProperties.lightsStateVersion = lightsStateVersion; programChange = false; @@ -24247,19 +24557,8 @@ materialProperties.fog = fog; // store the light setup it was created for - if ( lightsHash === undefined ) { - - materialProperties.lightsHash = lightsHash = {}; - - } - lightsHash.stateID = lightsStateHash.stateID; - lightsHash.directionalLength = lightsStateHash.directionalLength; - lightsHash.pointLength = lightsStateHash.pointLength; - lightsHash.spotLength = lightsStateHash.spotLength; - lightsHash.rectAreaLength = lightsStateHash.rectAreaLength; - lightsHash.hemiLength = lightsStateHash.hemiLength; - lightsHash.shadowsLength = lightsStateHash.shadowsLength; + materialProperties.lightsStateVersion = lightsStateVersion; if ( material.lights ) { @@ -24298,9 +24597,6 @@ var materialProperties = properties.get( material ); var lights = currentRenderState.state.lights; - var lightsHash = materialProperties.lightsHash; - var lightsStateHash = lights.state.hash; - if ( _clippingEnabled ) { if ( _localClippingEnabled || camera !== _currentCamera ) { @@ -24330,13 +24626,7 @@ material.needsUpdate = true; - } else if ( material.lights && ( lightsHash.stateID !== lightsStateHash.stateID || - lightsHash.directionalLength !== lightsStateHash.directionalLength || - lightsHash.pointLength !== lightsStateHash.pointLength || - lightsHash.spotLength !== lightsStateHash.spotLength || - lightsHash.rectAreaLength !== lightsStateHash.rectAreaLength || - lightsHash.hemiLength !== lightsStateHash.hemiLength || - lightsHash.shadowsLength !== lightsStateHash.shadowsLength ) ) { + } else if ( material.lights && materialProperties.lightsStateVersion !== lights.state.version ) { material.needsUpdate = true; @@ -25147,8 +25437,8 @@ } else { - _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ); - _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ); + _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor(); + _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor(); _currentScissorTest = _scissorTest; } @@ -25287,11 +25577,11 @@ }; - /* - if ( typeof __THREE_DEVTOOLS__ !== undefined ) { - __THREE_DEVTOOLS__.dispatchEvent( { type: 'renderer', value: this } ); + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef + } - */ } @@ -25370,70 +25660,6 @@ } ); - /** - * @author mrdoob / http://mrdoob.com/ - */ - - function Scene() { - - Object3D.call( this ); - - this.type = 'Scene'; - - this.background = null; - this.fog = null; - this.overrideMaterial = null; - - this.autoUpdate = true; // checked by the renderer - - /* - if ( typeof __THREE_DEVTOOLS__ !== undefined ) { - __THREE_DEVTOOLS__.dispatchEvent( { type: 'scene', value: this } ); - } - */ - - } - - Scene.prototype = Object.assign( Object.create( Object3D.prototype ), { - - constructor: Scene, - - isScene: true, - - copy: function ( source, recursive ) { - - Object3D.prototype.copy.call( this, source, recursive ); - - if ( source.background !== null ) this.background = source.background.clone(); - if ( source.fog !== null ) this.fog = source.fog.clone(); - if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); - - this.autoUpdate = source.autoUpdate; - this.matrixAutoUpdate = source.matrixAutoUpdate; - - return this; - - }, - - toJSON: function ( meta ) { - - var data = Object3D.prototype.toJSON.call( this, meta ); - - if ( this.background !== null ) data.object.background = this.background.toJSON( meta ); - if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); - - return data; - - }, - - dispose: function () { - - this.dispatchEvent( { type: 'dispose' } ); - - } - - } ); - /** * @author benaadams / https://twitter.com/ben_a_adams */ @@ -25821,9 +26047,18 @@ return function raycast( raycaster, intersects ) { worldScale.setFromMatrixScale( this.matrixWorld ); - viewWorldMatrix.getInverse( this.modelViewMatrix ).premultiply( this.matrixWorld ); + + viewWorldMatrix.copy( raycaster._camera.matrixWorld ); + this.modelViewMatrix.multiplyMatrices( raycaster._camera.matrixWorldInverse, this.matrixWorld ); + mvPosition.setFromMatrixPosition( this.modelViewMatrix ); + if ( raycaster._camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { + + worldScale.multiplyScalar( - mvPosition.z ); + + } + var rotation = this.material.rotation; var sin, cos; if ( rotation !== 0 ) { @@ -25917,6 +26152,8 @@ } } ); + this.autoUpdate = true; + } LOD.prototype = Object.assign( Object.create( Object3D.prototype ), { @@ -26850,6 +27087,8 @@ this.geometry = geometry !== undefined ? geometry : new BufferGeometry(); this.material = material !== undefined ? material : new PointsMaterial( { color: Math.random() * 0xffffff } ); + this.updateMorphTargets(); + } Points.prototype = Object.assign( Object.create( Object3D.prototype ), { @@ -26967,6 +27206,38 @@ }() ), + updateMorphTargets: function () { + + var geometry = this.geometry; + var m, ml, name; + + var morphAttributes = geometry.morphAttributes; + var keys = Object.keys( morphAttributes ); + + if ( keys.length > 0 ) { + + var morphAttribute = morphAttributes[ keys[ 0 ] ]; + + if ( morphAttribute !== undefined ) { + + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; + + for ( m = 0, ml = morphAttribute.length; m < ml; m ++ ) { + + name = morphAttribute[ m ].name || String( m ); + + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; + + } + + } + + } + + }, + clone: function () { return new this.constructor( this.geometry, this.material ).copy( this ); @@ -28550,7 +28821,7 @@ /** * @author Mugen87 / https://github.com/Mugen87 - * Port from https://github.com/mapbox/earcut (v2.1.2) + * Port from https://github.com/mapbox/earcut (v2.1.5) */ var Earcut = { @@ -28564,14 +28835,13 @@ outerNode = linkedList( data, 0, outerLen, dim, true ), triangles = []; - if ( ! outerNode ) return triangles; + if ( ! outerNode || outerNode.next === outerNode.prev ) return triangles; var minX, minY, maxX, maxY, x, y, invSize; if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox - if ( data.length > 80 * dim ) { minX = maxX = data[ 0 ]; @@ -28589,7 +28859,6 @@ } // minX, minY and invSize are later used to transform coords into integers for z-order calculation - invSize = Math.max( maxX - minX, maxY - minY ); invSize = invSize !== 0 ? 1 / invSize : 0; @@ -28604,7 +28873,6 @@ }; // create a circular doubly linked list from polygon points in the specified winding order - function linkedList( data, start, end, dim, clockwise ) { var i, last; @@ -28631,14 +28899,13 @@ } // eliminate colinear or duplicate points - function filterPoints( start, end ) { if ( ! start ) return start; if ( ! end ) end = start; - var p = start, again; - + var p = start, + again; do { again = false; @@ -28663,19 +28930,17 @@ } // main ear slicing loop which triangulates a polygon (given as a linked list) - function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) { if ( ! ear ) return; // interlink polygon nodes in z-order - if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize ); - var stop = ear, prev, next; + var stop = ear, + prev, next; // iterate through ears, slicing them one by one - while ( ear.prev !== ear.next ) { prev = ear.prev; @@ -28690,7 +28955,7 @@ removeNode( ear ); - // skipping the next vertice leads to less sliver triangles + // skipping the next vertex leads to less sliver triangles ear = next.next; stop = next.next; @@ -28701,11 +28966,9 @@ ear = next; // if we looped through the whole remaining polygon and can't find any more ears - if ( ear === stop ) { // try filtering points and slicing again - if ( ! pass ) { earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 ); @@ -28734,7 +28997,6 @@ } // check whether a polygon node forms a valid ear with adjacent nodes - function isEar( ear ) { var a = ear.prev, @@ -28748,12 +29010,8 @@ while ( p !== ear.prev ) { - if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) { - - return false; - - } - + if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + area( p.prev, p, p.next ) >= 0 ) return false; p = p.next; } @@ -28771,57 +29029,65 @@ if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear // triangle bbox; min & max are calculated like this for speed - var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ), minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ), maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ), maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y ); // z-order range for the current triangle bbox; - var minZ = zOrder( minTX, minTY, minX, minY, invSize ), maxZ = zOrder( maxTX, maxTY, minX, minY, invSize ); - // first look for points inside the triangle in increasing z-order - - var p = ear.nextZ; + var p = ear.prevZ, + n = ear.nextZ; - while ( p && p.z <= maxZ ) { + // look for points inside the triangle in both directions + while ( p && p.z >= minZ && n && n.z <= maxZ ) { if ( p !== ear.prev && p !== ear.next && - pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && - area( p.prev, p, p.next ) >= 0 ) return false; - p = p.nextZ; - - } + pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + area( p.prev, p, p.next ) >= 0 ) return false; + p = p.prevZ; - // then look for points in decreasing z-order + if ( n !== ear.prev && n !== ear.next && + pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) && + area( n.prev, n, n.next ) >= 0 ) return false; + n = n.nextZ; - p = ear.prevZ; + } + // look for remaining points in decreasing z-order while ( p && p.z >= minZ ) { if ( p !== ear.prev && p !== ear.next && - pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && - area( p.prev, p, p.next ) >= 0 ) return false; - + pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) && + area( p.prev, p, p.next ) >= 0 ) return false; p = p.prevZ; } + // look for remaining points in increasing z-order + while ( n && n.z <= maxZ ) { + + if ( n !== ear.prev && n !== ear.next && + pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) && + area( n.prev, n, n.next ) >= 0 ) return false; + n = n.nextZ; + + } + return true; } // go through all polygon nodes and cure small local self-intersections - function cureLocalIntersections( start, triangles, dim ) { var p = start; - do { - var a = p.prev, b = p.next.next; + var a = p.prev, + b = p.next.next; if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) { @@ -28830,7 +29096,6 @@ triangles.push( b.i / dim ); // remove two nodes involved - removeNode( p ); removeNode( p.next ); @@ -28847,32 +29112,25 @@ } // try splitting polygon into two and triangulate them independently - function splitEarcut( start, triangles, dim, minX, minY, invSize ) { // look for a valid diagonal that divides the polygon into two - var a = start; - do { var b = a.next.next; - while ( b !== a.prev ) { if ( a.i !== b.i && isValidDiagonal( a, b ) ) { // split the polygon in two by the diagonal - var c = splitPolygon( a, b ); // filter colinear points around the cuts - a = filterPoints( a, a.next ); c = filterPoints( c, c.next ); // run earcut on each half - earcutLinked( a, triangles, dim, minX, minY, invSize ); earcutLinked( c, triangles, dim, minX, minY, invSize ); return; @@ -28890,10 +29148,10 @@ } // link every hole into the outer loop, producing a single-ring polygon without holes - function eliminateHoles( data, holeIndices, outerNode, dim ) { - var queue = [], i, len, start, end, list; + var queue = [], + i, len, start, end, list; for ( i = 0, len = holeIndices.length; i < len; i ++ ) { @@ -28908,7 +29166,6 @@ queue.sort( compareX ); // process holes from left to right - for ( i = 0; i < queue.length; i ++ ) { eliminateHole( queue[ i ], outerNode ); @@ -28927,15 +29184,12 @@ } // find a bridge between vertices that connects hole with an outer ring and and link it - function eliminateHole( hole, outerNode ) { outerNode = findHoleBridge( hole, outerNode ); - if ( outerNode ) { var b = splitPolygon( outerNode, hole ); - filterPoints( b, b.next ); } @@ -28943,7 +29197,6 @@ } // David Eberly's algorithm for finding a bridge between hole and outer polygon - function findHoleBridge( hole, outerNode ) { var p = outerNode, @@ -28954,17 +29207,14 @@ // find a segment intersected by a ray from the hole's leftmost point to the left; // segment's endpoint with lesser x will be potential connection point - do { if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) { var x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y ); - if ( x <= hx && x > qx ) { qx = x; - if ( x === hx ) { if ( hy === p.y ) return p; @@ -29001,7 +29251,7 @@ while ( p !== stop ) { if ( hx >= p.x && p.x >= mx && hx !== p.x && - pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) { + pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) { tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential @@ -29023,11 +29273,9 @@ } // interlink polygon nodes in z-order - function indexCurve( start, minX, minY, invSize ) { var p = start; - do { if ( p.z === null ) p.z = zOrder( p.x, p.y, minX, minY, invSize ); @@ -29046,10 +29294,10 @@ // Simon Tatham's linked list merge sort algorithm // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html - function sortLinked( list ) { - var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1; + var i, p, q, e, tail, numMerges, pSize, qSize, + inSize = 1; do { @@ -29063,7 +29311,6 @@ numMerges ++; q = p; pSize = 0; - for ( i = 0; i < inSize; i ++ ) { pSize ++; @@ -29112,11 +29359,9 @@ } // z-order of a point given coords and inverse of the longer side of data bbox - function zOrder( x, y, minX, minY, invSize ) { // coords are transformed into non-negative 15-bit integer range - x = 32767 * ( x - minX ) * invSize; y = 32767 * ( y - minY ) * invSize; @@ -29135,14 +29380,13 @@ } // find the leftmost node of a polygon ring - function getLeftmost( start ) { - var p = start, leftmost = start; - + var p = start, + leftmost = start; do { - if ( p.x < leftmost.x ) leftmost = p; + if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p; p = p.next; } while ( p !== start ); @@ -29152,26 +29396,23 @@ } // check if a point lies within a convex triangle - function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) { return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 && - ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 && - ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0; + ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 && + ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0; } // check if a diagonal between two polygon nodes is valid (lies in polygon interior) - function isValidDiagonal( a, b ) { return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && - locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ); + locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ); } // signed area of a triangle - function area( p, q, r ) { return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y ); @@ -29179,7 +29420,6 @@ } // check if two points are equal - function equals( p1, p2 ) { return p1.x === p2.x && p1.y === p2.y; @@ -29187,32 +29427,23 @@ } // check if two segments intersect - function intersects( p1, q1, p2, q2 ) { - if ( ( equals( p1, q1 ) && equals( p2, q2 ) ) || - ( equals( p1, q2 ) && equals( p2, q1 ) ) ) return true; - + if ( ( equals( p1, p2 ) && equals( q1, q2 ) ) || + ( equals( p1, q2 ) && equals( p2, q1 ) ) ) return true; return area( p1, q1, p2 ) > 0 !== area( p1, q1, q2 ) > 0 && - area( p2, q2, p1 ) > 0 !== area( p2, q2, q1 ) > 0; + area( p2, q2, p1 ) > 0 !== area( p2, q2, q1 ) > 0; } // check if a polygon diagonal intersects any polygon segments - function intersectsPolygon( a, b ) { var p = a; - do { if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && - intersects( p, p.next, a, b ) ) { - - return true; - - } - + intersects( p, p.next, a, b ) ) return true; p = p.next; } while ( p !== a ); @@ -29222,7 +29453,6 @@ } // check if a polygon diagonal is locally inside the polygon - function locallyInside( a, b ) { return area( a.prev, a, a.next ) < 0 ? @@ -29232,23 +29462,17 @@ } // check if the middle point of a polygon diagonal is inside the polygon - function middleInside( a, b ) { var p = a, inside = false, px = ( a.x + b.x ) / 2, py = ( a.y + b.y ) / 2; - do { if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y && - ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) { - + ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) ) inside = ! inside; - - } - p = p.next; } while ( p !== a ); @@ -29259,7 +29483,6 @@ // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; // if one belongs to the outer ring and another to a hole, it merges it into a single ring - function splitPolygon( a, b ) { var a2 = new Node( a.i, a.x, a.y ), @@ -29284,7 +29507,6 @@ } // create a node and optionally link it with previous one (in a circular doubly linked list) - function insertNode( i, x, y, last ) { var p = new Node( i, x, y ); @@ -29319,14 +29541,14 @@ function Node( i, x, y ) { - // vertice index in coordinates array + // vertex index in coordinates array this.i = i; // vertex coordinates this.x = x; this.y = y; - // previous and next vertice nodes in a polygon ring + // previous and next vertex nodes in a polygon ring this.prev = null; this.next = null; @@ -29345,7 +29567,6 @@ function signedArea( data, start, end, dim ) { var sum = 0; - for ( var i = start, j = end - dim; i < end; i += dim ) { sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] ); @@ -37936,6 +38157,7 @@ if ( json.skinning !== undefined ) material.skinning = json.skinning; if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets; + if ( json.morphNormals !== undefined ) material.morphNormals = json.morphNormals; if ( json.dithering !== undefined ) material.dithering = json.dithering; if ( json.visible !== undefined ) material.visible = json.visible; @@ -38061,6 +38283,7 @@ if ( json.envMapIntensity !== undefined ) material.envMapIntensity = json.envMapIntensity; if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity; + if ( json.refractionRatio !== undefined ) material.refractionRatio = json.refractionRatio; if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap ); if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity; @@ -40395,19 +40618,19 @@ var coeff = this.coefficients; // band 0 - target = coeff[ 0 ] * 0.282095; + target.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 ); // band 1 - target += coeff[ 1 ] * 0.488603 * y; - target += coeff[ 2 ] * 0.488603 * z; - target += coeff[ 3 ] * 0.488603 * x; + target.addScale( coeff[ 1 ], 0.488603 * y ); + target.addScale( coeff[ 2 ], 0.488603 * z ); + target.addScale( coeff[ 3 ], 0.488603 * x ); // band 2 - target += coeff[ 4 ] * 1.092548 * ( x * y ); - target += coeff[ 5 ] * 1.092548 * ( y * z ); - target += coeff[ 6 ] * 0.315392 * ( 3.0 * z * z - 1.0 ); - target += coeff[ 7 ] * 1.092548 * ( x * z ); - target += coeff[ 8 ] * 0.546274 * ( x * x - y * y ); + target.addScale( coeff[ 4 ], 1.092548 * ( x * y ) ); + target.addScale( coeff[ 5 ], 1.092548 * ( y * z ) ); + target.addScale( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) ); + target.addScale( coeff[ 7 ], 1.092548 * ( x * z ) ); + target.addScale( coeff[ 8 ], 0.546274 * ( x * x - y * y ) ); return target; @@ -40425,19 +40648,19 @@ var coeff = this.coefficients; // band 0 - target = coeff[ 0 ] * 0.886227; // π * 0.282095 + target.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 ); // π * 0.282095 // band 1 - target += coeff[ 1 ] * 2.0 * 0.511664 * y; // ( 2 * π / 3 ) * 0.488603 - target += coeff[ 2 ] * 2.0 * 0.511664 * z; - target += coeff[ 3 ] * 2.0 * 0.511664 * x; + target.addScale( coeff[ 1 ], 2.0 * 0.511664 * y ); // ( 2 * π / 3 ) * 0.488603 + target.addScale( coeff[ 2 ], 2.0 * 0.511664 * z ); + target.addScale( coeff[ 3 ], 2.0 * 0.511664 * x ); // band 2 - target += coeff[ 4 ] * 2.0 * 0.429043 * x * y; // ( π / 4 ) * 1.092548 - target += coeff[ 5 ] * 2.0 * 0.429043 * y * z; - target += coeff[ 6 ] * ( 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3 - target += coeff[ 7 ] * 2.0 * 0.429043 * x * z; - target += coeff[ 8 ] * 0.429043 * ( x * x - y * y ); // ( π / 4 ) * 0.546274 + target.addScale( coeff[ 4 ], 2.0 * 0.429043 * x * y ); // ( π / 4 ) * 1.092548 + target.addScale( coeff[ 5 ], 2.0 * 0.429043 * y * z ); + target.addScale( coeff[ 6 ], 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3 + target.addScale( coeff[ 7 ], 2.0 * 0.429043 * x * z ); + target.addScale( coeff[ 8 ], 0.429043 * ( x * x - y * y ) ); // ( π / 4 ) * 0.546274 return target; @@ -40793,114 +41016,6 @@ } ); - /** - * Camera for rendering cube maps - * - renders scene into axis-aligned cube - * - * @author alteredq / http://alteredqualia.com/ - */ - - var fov = 90, aspect = 1; - - function CubeCamera( near, far, cubeResolution, options ) { - - Object3D.call( this ); - - this.type = 'CubeCamera'; - - var cameraPX = new PerspectiveCamera( fov, aspect, near, far ); - cameraPX.up.set( 0, - 1, 0 ); - cameraPX.lookAt( new Vector3( 1, 0, 0 ) ); - this.add( cameraPX ); - - var cameraNX = new PerspectiveCamera( fov, aspect, near, far ); - cameraNX.up.set( 0, - 1, 0 ); - cameraNX.lookAt( new Vector3( - 1, 0, 0 ) ); - this.add( cameraNX ); - - var cameraPY = new PerspectiveCamera( fov, aspect, near, far ); - cameraPY.up.set( 0, 0, 1 ); - cameraPY.lookAt( new Vector3( 0, 1, 0 ) ); - this.add( cameraPY ); - - var cameraNY = new PerspectiveCamera( fov, aspect, near, far ); - cameraNY.up.set( 0, 0, - 1 ); - cameraNY.lookAt( new Vector3( 0, - 1, 0 ) ); - this.add( cameraNY ); - - var cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraPZ.up.set( 0, - 1, 0 ); - cameraPZ.lookAt( new Vector3( 0, 0, 1 ) ); - this.add( cameraPZ ); - - var cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraNZ.up.set( 0, - 1, 0 ); - cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) ); - this.add( cameraNZ ); - - options = options || { format: RGBFormat, magFilter: LinearFilter, minFilter: LinearFilter }; - - this.renderTarget = new WebGLRenderTargetCube( cubeResolution, cubeResolution, options ); - this.renderTarget.texture.name = "CubeCamera"; - - this.update = function ( renderer, scene ) { - - if ( this.parent === null ) this.updateMatrixWorld(); - - var currentRenderTarget = renderer.getRenderTarget(); - - var renderTarget = this.renderTarget; - var generateMipmaps = renderTarget.texture.generateMipmaps; - - renderTarget.texture.generateMipmaps = false; - - renderer.setRenderTarget( renderTarget, 0 ); - renderer.render( scene, cameraPX ); - - renderer.setRenderTarget( renderTarget, 1 ); - renderer.render( scene, cameraNX ); - - renderer.setRenderTarget( renderTarget, 2 ); - renderer.render( scene, cameraPY ); - - renderer.setRenderTarget( renderTarget, 3 ); - renderer.render( scene, cameraNY ); - - renderer.setRenderTarget( renderTarget, 4 ); - renderer.render( scene, cameraPZ ); - - renderTarget.texture.generateMipmaps = generateMipmaps; - - renderer.setRenderTarget( renderTarget, 5 ); - renderer.render( scene, cameraNZ ); - - renderer.setRenderTarget( currentRenderTarget ); - - }; - - this.clear = function ( renderer, color, depth, stencil ) { - - var currentRenderTarget = renderer.getRenderTarget(); - - var renderTarget = this.renderTarget; - - for ( var i = 0; i < 6; i ++ ) { - - renderer.setRenderTarget( renderTarget, i ); - - renderer.clear( color, depth, stencil ); - - } - - renderer.setRenderTarget( currentRenderTarget ); - - }; - - } - - CubeCamera.prototype = Object.create( Object3D.prototype ); - CubeCamera.prototype.constructor = CubeCamera; - /** * @author alteredq / http://alteredqualia.com/ */ @@ -44040,9 +44155,7 @@ delete bindingByName[ trackName ]; - remove_empty_map: { - - for ( var _ in bindingByName ) break remove_empty_map; // eslint-disable-line no-unused-vars + if ( Object.keys( bindingByName ).length === 0 ) { delete bindingsByRoot[ rootUuid ]; @@ -44501,11 +44614,13 @@ this.ray.origin.setFromMatrixPosition( camera.matrixWorld ); this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize(); + this._camera = camera; } else if ( ( camera && camera.isOrthographicCamera ) ) { this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ); + this._camera = camera; } else { @@ -46621,13 +46736,13 @@ * @author WestLangley / http://github.com/WestLangley */ - function Box3Helper( box, hex ) { + function Box3Helper( box, color ) { this.type = 'Box3Helper'; this.box = box; - var color = ( hex !== undefined ) ? hex : 0xffff00; + color = color || 0xffff00; var indices = 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 ] ); @@ -46823,8 +46938,8 @@ ArrowHelper.prototype.setColor = function ( color ) { - this.line.material.color.copy( color ); - this.cone.material.color.copy( color ); + this.line.material.color.set( color ); + this.cone.material.color.set( color ); }; diff --git a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js index 0123525b..b5885b41 100644 --- a/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js +++ b/core/src/main/resources/org/treblereel/gwt/three4g/resources/js/three.min.js @@ -1,376 +1,375 @@ // threejs.org/license -(function(l,Ca){"object"===typeof exports&&"undefined"!==typeof module?Ca(exports):"function"===typeof define&&define.amd?define(["exports"],Ca):(l=l||self,Ca(l.THREE={}))})(this,function(l){function Ca(){}function D(a,b){this.x=a||0;this.y=b||0}function ea(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function n(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function ia(){this.elements=[1,0,0,0,1,0,0,0,1];0b&&(b=a[c]);return b}function E(){Object.defineProperty(this,"id",{value:ag+=2});this.uuid=P.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}} -function Ub(a,b,c,d,e,f){Q.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new wb(a,b,c,d,e,f));this.mergeVertices()}function wb(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,l,xa,Fa,F){var r=f/xa,u=g/Fa,w=f/2,x=g/2,y=l/2;g=xa+1;var z=Fa+1,ma=f=0,R,G,A=new n;for(G=0;Gc&&(c+=1);1c?b:c<2/3?a+6*(b-a)*(2/3-c):a}function ke(a){return.04045>a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}function le(a){return.0031308> +a?12.92*a:1.055*Math.pow(a,.41666)-.055}function Tb(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new B;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0}function L(){Object.defineProperty(this,"id",{value:dg++});this.uuid=P.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors= +0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.visible=!0;this.userData= +{};this.needsUpdate=!0}function ka(a){L.call(this);this.type="MeshBasicMaterial";this.color=new B(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function I(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array."); +this.name="";this.array=a;this.itemSize=b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function Ec(a,b,c){I.call(this,new Int8Array(a),b,c)}function Fc(a,b,c){I.call(this,new Uint8Array(a),b,c)}function Gc(a,b,c){I.call(this,new Uint8ClampedArray(a),b,c)}function Hc(a,b,c){I.call(this,new Int16Array(a),b,c)}function vb(a,b,c){I.call(this,new Uint16Array(a),b,c)}function Ic(a,b,c){I.call(this,new Int32Array(a),b,c)}function wb(a, +b,c){I.call(this,new Uint32Array(a),b,c)}function D(a,b,c){I.call(this,new Float32Array(a),b,c)}function Jc(a,b,c){I.call(this,new Float64Array(a),b,c)}function af(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function bf(a){if(0===a.length)return-Infinity; +for(var b=a[0],c=1,d=a.length;cb&&(b=a[c]);return b}function E(){Object.defineProperty(this,"id",{value:eg+=2});this.uuid=P.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}}function ra(a,b){G.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new E;this.material=void 0!==b?b:new ka({color:16777215*Math.random()}); +this.drawMode=0;this.updateMorphTargets()}function Q(){Object.defineProperty(this,"id",{value:fg+=2});this.uuid=P.generateUUID();this.name="";this.type="Geometry";this.vertices=[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphNormals=[];this.skinWeights=[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.lineDistancesNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.uvsNeedUpdate=this.verticesNeedUpdate= +this.elementsNeedUpdate=!1}function Ub(a,b,c,d,e,f){Q.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new ib(a,b,c,d,e,f));this.mergeVertices()}function ib(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,l,la,xa,F){var q=f/la,v=g/xa,y=f/2,x=g/2,z=l/2;g=la+1;var H=xa+1,Da=f=0,S,w,A=new n;for(w=0;wg;g++)a.setRenderTarget(f,g),a.clear(b,c, +d);a.setRenderTarget(e)}}function kb(a,b,c){Ta.call(this,a,b,c)}function Ab(a,b,c,d,e,f,g,h,k,m,r,p){X.call(this,null,f,g,h,k,m,d,e,r,p);this.image={data:a,width:b,height:c};this.magFilter=void 0!==k?k:1003;this.minFilter=void 0!==m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1}function Wa(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!==b?b:0}function Cd(a,b,c,d,e,f){this.planes=[void 0!==a?a:new Wa,void 0!==b?b:new Wa,void 0!==c?c:new Wa,void 0!==d?d:new Wa,void 0!== +e?e:new Wa,void 0!==f?f:new Wa]}function ne(){function a(e,f){!1!==c&&(d(e,f),b.requestAnimationFrame(a))}var b=null,c=!1,d=null;return{start:function(){!0!==c&&null!==d&&(b.requestAnimationFrame(a),c=!0)},stop:function(){c=!1},setAnimationLoop:function(a){d=a},setContext:function(a){b=a}}}function gg(a){function b(b,c){var d=b.array,e=b.dynamic?35048:35044,h=a.createBuffer();a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback();c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array? +console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data);return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&& +(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.versionm;m++){if(p=d[m])if(h=p[0],k=p[1]){q&&e.addAttribute("morphTarget"+m, -q[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=k;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function mg(a,b){var c={};return{update:function(d){var e=b.render.frame,f=d.geometry,g=a.get(d,f);c[g.id]!==e&&(f.isGeometry&&g.updateFromObject(d),a.update(g),c[g.id]=e);return g},dispose:function(){c={}}}}function cb(a,b,c,d,e,f,g,h,k,m){a=void 0!==a?a:[];X.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h,k,m);this.flipY=!1}function Vb(a,b,c,d){X.call(this,null); -this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Wb(a,b,c,d){X.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Xb(a,b,c){var d=a[0];if(0>=d||0/gm, -function(a,c){a=U[c];if(void 0===a)throw Error("Can not resolve #include <"+c+">");return me(a)})}function nf(a){return a.replace(/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);cc;c++)b.probe.push(new n);var d=new n,e=new O,f=new O;return{setup:function(c,h,k){for(var g=0,q=0,p=0,v=0;9>v;v++)b.probe[v].set(0,0,0);var l=0,r=0,u=0,n=0,z=0;k=k.matrixWorldInverse;v=0;for(var y=c.length;vFa;Fa++)b.probe[Fa].addScaledVector(x.sh.coefficients[Fa], -G);else if(x.isDirectionalLight){var F=a.get(x);F.color.copy(x.color).multiplyScalar(x.intensity);F.direction.setFromMatrixPosition(x.matrixWorld);d.setFromMatrixPosition(x.target.matrixWorld);F.direction.sub(d);F.direction.transformDirection(k);if(F.shadow=x.castShadow)G=x.shadow,F.shadowBias=G.bias,F.shadowRadius=G.radius,F.shadowMapSize=G.mapSize;b.directionalShadowMap[l]=Fa;b.directionalShadowMatrix[l]=x.shadow.matrix;b.directional[l]=F;l++}else if(x.isSpotLight){F=a.get(x);F.position.setFromMatrixPosition(x.matrixWorld); -F.position.applyMatrix4(k);F.color.copy(A).multiplyScalar(G);F.distance=xa;F.direction.setFromMatrixPosition(x.matrixWorld);d.setFromMatrixPosition(x.target.matrixWorld);F.direction.sub(d);F.direction.transformDirection(k);F.coneCos=Math.cos(x.angle);F.penumbraCos=Math.cos(x.angle*(1-x.penumbra));F.decay=x.decay;if(F.shadow=x.castShadow)G=x.shadow,F.shadowBias=G.bias,F.shadowRadius=G.radius,F.shadowMapSize=G.mapSize;b.spotShadowMap[u]=Fa;b.spotShadowMatrix[u]=x.shadow.matrix;b.spot[u]=F;u++}else if(x.isRectAreaLight)F= -a.get(x),F.color.copy(A).multiplyScalar(G),F.position.setFromMatrixPosition(x.matrixWorld),F.position.applyMatrix4(k),f.identity(),e.copy(x.matrixWorld),e.premultiply(k),f.extractRotation(e),F.halfWidth.set(.5*x.width,0,0),F.halfHeight.set(0,.5*x.height,0),F.halfWidth.applyMatrix4(f),F.halfHeight.applyMatrix4(f),b.rectArea[n]=F,n++;else if(x.isPointLight){F=a.get(x);F.position.setFromMatrixPosition(x.matrixWorld);F.position.applyMatrix4(k);F.color.copy(x.color).multiplyScalar(x.intensity);F.distance= -x.distance;F.decay=x.decay;if(F.shadow=x.castShadow)G=x.shadow,F.shadowBias=G.bias,F.shadowRadius=G.radius,F.shadowMapSize=G.mapSize,F.shadowCameraNear=G.camera.near,F.shadowCameraFar=G.camera.far;b.pointShadowMap[r]=Fa;b.pointShadowMatrix[r]=x.shadow.matrix;b.point[r]=F;r++}else x.isHemisphereLight&&(F=a.get(x),F.direction.setFromMatrixPosition(x.matrixWorld),F.direction.transformDirection(k),F.direction.normalize(),F.skyColor.copy(x.color).multiplyScalar(G),F.groundColor.copy(x.groundColor).multiplyScalar(G), -b.hemi[z]=F,z++)}b.ambient[0]=g;b.ambient[1]=q;b.ambient[2]=p;b.directional.length=l;b.spot.length=u;b.rectArea.length=n;b.point.length=r;b.hemi.length=z;b.hash.stateID=b.id;b.hash.directionalLength=l;b.hash.pointLength=r;b.hash.spotLength=u;b.hash.rectAreaLength=n;b.hash.hemiLength=z;b.hash.shadowsLength=h.length},state:b}}function pf(){var a=new gh,b=[],c=[];return{init:function(){b.length=0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)}, -pushShadow:function(a){c.push(a)}}}function ih(){function a(c){c=c.target;c.removeEventListener("dispose",a);delete b[c.id]}var b={};return{get:function(c,d){if(void 0===b[c.id]){var e=new pf;b[c.id]={};b[c.id][d.id]=e;c.addEventListener("dispose",a)}else void 0===b[c.id][d.id]?(e=new pf,b[c.id][d.id]=e):e=b[c.id][d.id];return e},dispose:function(){b={}}}}function kb(a){L.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap= -this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights=this.fog=!1;this.setValues(a)}function lb(a){L.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance=1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.lights=this.fog=!1;this.setValues(a)}function qf(a,b,c){function d(b,c,d,e,f,g){var h= -b.geometry;var k=p;var m=b.customDepthMaterial;d&&(k=v,m=b.customDistanceMaterial);m?k=m:(m=!1,c.morphTargets&&(h&&h.isBufferGeometry?m=h.morphAttributes&&h.morphAttributes.position&&0d||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof -HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?P.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),void 0===xb&&(xb=h(b,e)),c=c?h(b,e):xb,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+ -a.width+"x"+a.height+").")}return a}function m(a){return P.isPowerOfTwo(a.width)&&P.isPowerOfTwo(a.height)}function q(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function p(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function v(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&& -(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");return d}function l(a){return 1003===a||1004===a||1005===a?9728:9729}function r(b){b=b.target;b.removeEventListener("dispose",r);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&& -delete ib[b.id];g.memory.textures--}function u(b){b=b.target;b.removeEventListener("dispose",u);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer); -d.remove(b.texture);d.remove(b)}g.memory.textures--}function n(a,b){var e=d.get(a);if(a.isVideoTexture){var f=a.id,h=g.render.frame;ib[f]!==h&&(ib[f]=h,a.update())}if(0t;t++)r[t]=g||l?l?b.image[t].image:b.image[t]:k(b.image[t],!1,!0,e.maxCubemapSize);var u=r[0],n=m(u)||e.isWebGL2,w=f.convert(b.format),y=f.convert(b.type),G=v(w,y);x(34067,b,n);for(t=0;6>t;t++)if(g)for(var R,z=r[t].mipmaps, -ma=0,F=z.length;ma=e.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+e.maxTextures);Y+=1; -return a};this.resetTextureUnits=function(){Y=0};this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0r;r++)h.__webglFramebuffer[r]=a.createFramebuffer();else if(h.__webglFramebuffer=a.createFramebuffer(),r)if(e.isWebGL2){h.__webglMultisampledFramebuffer=a.createFramebuffer();h.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,h.__webglColorRenderbuffer);r= -f.convert(b.texture.format);var w=f.convert(b.texture.type);r=v(r,w);w=F(b);a.renderbufferStorageMultisample(36161,w,r,b.width,b.height);a.bindFramebuffer(36160,h.__webglMultisampledFramebuffer);a.framebufferRenderbuffer(36160,36064,36161,h.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);b.depthBuffer&&(h.__webglDepthRenderbuffer=a.createRenderbuffer(),D(h.__webglDepthRenderbuffer,b,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2."); -if(l){c.bindTexture(34067,k.__webglTexture);x(34067,b.texture,t);for(r=0;6>r;r++)xa(h.__webglFramebuffer[r],b,36064,34069+r);q(b.texture,t)&&p(34067,b.texture,b.width,b.height);c.bindTexture(34067,null)}else c.bindTexture(3553,k.__webglTexture),x(3553,b.texture,t),xa(h.__webglFramebuffer,b,36064,3553),q(b.texture,t)&&p(3553,b.texture,b.width,b.height),c.bindTexture(3553,null);if(b.depthBuffer){h=d.get(b);k=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(k)throw Error("target.depthTexture not supported in Cube render targets"); +f[a.id];if(c)return c;c=[];var d=a.index,e=a.attributes;if(null!==d){d=d.array;e=0;for(var g=d.length;em;m++){if(p=d[m])if(h=p[0],k=p[1]){r&&e.addAttribute("morphTarget"+m, +r[h]);f&&e.addAttribute("morphNormal"+m,f[h]);c[m]=k;continue}c[m]=0}g.getUniforms().setValue(a,"morphTargetInfluences",c)}}}function rg(a,b){var c={};return{update:function(d){var e=b.render.frame,f=d.geometry,g=a.get(d,f);c[g.id]!==e&&(f.isGeometry&&g.updateFromObject(d),a.update(g),c[g.id]=e);return g},dispose:function(){c={}}}}function cb(a,b,c,d,e,f,g,h,k,m){a=void 0!==a?a:[];X.call(this,a,void 0!==b?b:301,c,d,e,f,void 0!==g?g:1022,h,k,m);this.flipY=!1}function Wb(a,b,c,d){X.call(this,null); +this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Xb(a,b,c,d){X.call(this,null);this.image={data:a,width:b,height:c,depth:d};this.minFilter=this.magFilter=1003;this.wrapR=1001;this.flipY=this.generateMipmaps=!1}function Yb(a,b,c){var d=a[0];if(0>=d||0/gm,function(a,c){a=U[c];if(void 0===a)throw Error("Can not resolve #include <"+c+ +">");return pe(a)})}function sf(a){return a.replace(/#pragma unroll_loop[\s]+?for \( int i = (\d+); i < (\d+); i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);cc;c++)b.probe.push(new n);var d=new n,e=new O,f=new O;return{setup:function(c,h,k){for(var g=0,r=0,p=0,u=0;9>u;u++)b.probe[u].set(0,0,0);var l=0,q=0,v=0,n=0,z=0;k=k.matrixWorldInverse;u=0;for(var w=c.length;uxa;xa++)b.probe[xa].addScaledVector(x.sh.coefficients[xa],H);else if(x.isDirectionalLight){var F= +a.get(x);F.color.copy(x.color).multiplyScalar(x.intensity);F.direction.setFromMatrixPosition(x.matrixWorld);d.setFromMatrixPosition(x.target.matrixWorld);F.direction.sub(d);F.direction.transformDirection(k);if(F.shadow=x.castShadow)H=x.shadow,F.shadowBias=H.bias,F.shadowRadius=H.radius,F.shadowMapSize=H.mapSize;b.directionalShadowMap[l]=xa;b.directionalShadowMatrix[l]=x.shadow.matrix;b.directional[l]=F;l++}else if(x.isSpotLight){F=a.get(x);F.position.setFromMatrixPosition(x.matrixWorld);F.position.applyMatrix4(k); +F.color.copy(A).multiplyScalar(H);F.distance=la;F.direction.setFromMatrixPosition(x.matrixWorld);d.setFromMatrixPosition(x.target.matrixWorld);F.direction.sub(d);F.direction.transformDirection(k);F.coneCos=Math.cos(x.angle);F.penumbraCos=Math.cos(x.angle*(1-x.penumbra));F.decay=x.decay;if(F.shadow=x.castShadow)H=x.shadow,F.shadowBias=H.bias,F.shadowRadius=H.radius,F.shadowMapSize=H.mapSize;b.spotShadowMap[v]=xa;b.spotShadowMatrix[v]=x.shadow.matrix;b.spot[v]=F;v++}else if(x.isRectAreaLight)F=a.get(x), +F.color.copy(A).multiplyScalar(H),F.position.setFromMatrixPosition(x.matrixWorld),F.position.applyMatrix4(k),f.identity(),e.copy(x.matrixWorld),e.premultiply(k),f.extractRotation(e),F.halfWidth.set(.5*x.width,0,0),F.halfHeight.set(0,.5*x.height,0),F.halfWidth.applyMatrix4(f),F.halfHeight.applyMatrix4(f),b.rectArea[n]=F,n++;else if(x.isPointLight){F=a.get(x);F.position.setFromMatrixPosition(x.matrixWorld);F.position.applyMatrix4(k);F.color.copy(x.color).multiplyScalar(x.intensity);F.distance=x.distance; +F.decay=x.decay;if(F.shadow=x.castShadow)H=x.shadow,F.shadowBias=H.bias,F.shadowRadius=H.radius,F.shadowMapSize=H.mapSize,F.shadowCameraNear=H.camera.near,F.shadowCameraFar=H.camera.far;b.pointShadowMap[q]=xa;b.pointShadowMatrix[q]=x.shadow.matrix;b.point[q]=F;q++}else x.isHemisphereLight&&(F=a.get(x),F.direction.setFromMatrixPosition(x.matrixWorld),F.direction.transformDirection(k),F.direction.normalize(),F.skyColor.copy(x.color).multiplyScalar(H),F.groundColor.copy(x.groundColor).multiplyScalar(H), +b.hemi[z]=F,z++)}b.ambient[0]=g;b.ambient[1]=r;b.ambient[2]=p;c=b.hash;if(c.directionalLength!==l||c.pointLength!==q||c.spotLength!==v||c.rectAreaLength!==n||c.hemiLength!==z||c.shadowsLength!==h.length)b.directional.length=l,b.spot.length=v,b.rectArea.length=n,b.point.length=q,b.hemi.length=z,c.directionalLength=l,c.pointLength=q,c.spotLength=v,c.rectAreaLength=n,c.hemiLength=z,c.shadowsLength=h.length,b.version=lh++},state:b}}function uf(){var a=new kh,b=[],c=[];return{init:function(){b.length= +0;c.length=0},state:{lightsArray:b,shadowsArray:c,lights:a},setupLights:function(d){a.setup(b,c,d)},pushLight:function(a){b.push(a)},pushShadow:function(a){c.push(a)}}}function mh(){function a(c){c=c.target;c.removeEventListener("dispose",a);delete b[c.id]}var b={};return{get:function(c,d){if(void 0===b[c.id]){var e=new uf;b[c.id]={};b[c.id][d.id]=e;c.addEventListener("dispose",a)}else void 0===b[c.id][d.id]?(e=new uf,b[c.id][d.id]=e):e=b[c.id][d.id];return e},dispose:function(){b={}}}}function mb(a){L.call(this); +this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights=this.fog=!1;this.setValues(a)}function nb(a){L.call(this);this.type="MeshDistanceMaterial";this.referencePosition=new n;this.nearDistance=1;this.farDistance=1E3;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale= +1;this.displacementBias=0;this.lights=this.fog=!1;this.setValues(a)}function vf(a,b,c){function d(b,c,d,e,f,g){var h=b.geometry;var k=p;var m=b.customDepthMaterial;d&&(k=u,m=b.customDistanceMaterial);m?k=m:(m=!1,c.morphTargets&&(h&&h.isBufferGeometry?m=h.morphAttributes&&h.morphAttributes.position&&0 +d||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?P.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),void 0===xb&&(xb=h(b,e)),c=c?h(b,e):xb,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+ +a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return P.isPowerOfTwo(a.width)&&P.isPowerOfTwo(a.height)}function r(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function p(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function u(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131=== +c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");return d}function l(a){return 1003===a||1004===a||1005===a?9728:9729}function q(b){b=b.target;b.removeEventListener("dispose", +q);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&delete jb[b.id];g.memory.textures--}function v(b){b=b.target;b.removeEventListener("dispose",v);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]); +else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--}function n(a,b){var e=d.get(a);if(a.isVideoTexture){var f=a.id,h=g.render.frame;jb[f]!==h&&(jb[f]=h,a.update())}if(0t;t++)q[t]=g||l?l?b.image[t].image:b.image[t]:k(b.image[t],!1,!0,e.maxCubemapSize);var v=q[0],n=m(v)||e.isWebGL2,y=f.convert(b.format),w=f.convert(b.type), +S=u(y,w);x(34067,b,n);for(t=0;6>t;t++)if(g)for(var H,Da=q[t].mipmaps,z=0,F=Da.length;z=e.maxTextures&&console.warn("THREE.WebGLTextures: Trying to use "+a+" texture units while this GPU supports only "+e.maxTextures);Y+=1; +return a};this.resetTextureUnits=function(){Y=0};this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0q;q++)h.__webglFramebuffer[q]=a.createFramebuffer();else if(h.__webglFramebuffer=a.createFramebuffer(),q)if(e.isWebGL2){h.__webglMultisampledFramebuffer=a.createFramebuffer();h.__webglColorRenderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,h.__webglColorRenderbuffer);q= +f.convert(b.texture.format);var y=f.convert(b.texture.type);q=u(q,y);y=F(b);a.renderbufferStorageMultisample(36161,y,q,b.width,b.height);a.bindFramebuffer(36160,h.__webglMultisampledFramebuffer);a.framebufferRenderbuffer(36160,36064,36161,h.__webglColorRenderbuffer);a.bindRenderbuffer(36161,null);b.depthBuffer&&(h.__webglDepthRenderbuffer=a.createRenderbuffer(),C(h.__webglDepthRenderbuffer,b,!0));a.bindFramebuffer(36160,null)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2."); +if(l){c.bindTexture(34067,k.__webglTexture);x(34067,b.texture,t);for(q=0;6>q;q++)la(h.__webglFramebuffer[q],b,36064,34069+q);r(b.texture,t)&&p(34067,b.texture,b.width,b.height);c.bindTexture(34067,null)}else c.bindTexture(3553,k.__webglTexture),x(3553,b.texture,t),la(h.__webglFramebuffer,b,36064,3553),r(b.texture,t)&&p(3553,b.texture,b.width,b.height),c.bindTexture(3553,null);if(b.depthBuffer){h=d.get(b);k=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(k)throw Error("target.depthTexture not supported in Cube render targets"); if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported");a.bindFramebuffer(36160,h.__webglFramebuffer);if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width===b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0); -n(b.depthTexture,0);h=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,h,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,h,0);else throw Error("Unknown depthTexture format");}else if(k)for(h.__webglDepthbuffer=[],k=0;6>k;k++)a.bindFramebuffer(36160,h.__webglFramebuffer[k]),h.__webglDepthbuffer[k]=a.createRenderbuffer(),D(h.__webglDepthbuffer[k],b);else a.bindFramebuffer(36160,h.__webglFramebuffer),h.__webglDepthbuffer= -a.createRenderbuffer(),D(h.__webglDepthbuffer,b);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture,f=m(a)||e.isWebGL2;if(q(b,f)){f=a.isWebGLRenderTargetCube?34067:3553;var g=d.get(b).__webglTexture;c.bindTexture(f,g);p(f,b,a.width,a.height);c.bindTexture(f,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(e.isWebGL2){var c=d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer); -c=b.width;var f=b.height,g=16384;b.depthBuffer&&(g|=256);b.stencilBuffer&&(g|=1024);a.blitFramebuffer(0,0,c,f,0,0,c,f,g,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===C&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."),C=!0),a=a.texture);n(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&& -(!1===H&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."),H=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?z(a,b):y(a,b)}}function sf(a,b,c){return{convert:function(a){if(1E3===a)return 10497;if(1001===a)return 33071;if(1002===a)return 33648;if(1003===a)return 9728;if(1004===a)return 9984;if(1005===a)return 9986;if(1006===a)return 9729;if(1007===a)return 9985;if(1008===a)return 9987; +n(b.depthTexture,0);h=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(36160,36096,3553,h,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(36160,33306,3553,h,0);else throw Error("Unknown depthTexture format");}else if(k)for(h.__webglDepthbuffer=[],k=0;6>k;k++)a.bindFramebuffer(36160,h.__webglFramebuffer[k]),h.__webglDepthbuffer[k]=a.createRenderbuffer(),C(h.__webglDepthbuffer[k],b);else a.bindFramebuffer(36160,h.__webglFramebuffer),h.__webglDepthbuffer= +a.createRenderbuffer(),C(h.__webglDepthbuffer,b);a.bindFramebuffer(36160,null)}};this.updateRenderTargetMipmap=function(a){var b=a.texture,f=m(a)||e.isWebGL2;if(r(b,f)){f=a.isWebGLRenderTargetCube?34067:3553;var g=d.get(b).__webglTexture;c.bindTexture(f,g);p(f,b,a.width,a.height);c.bindTexture(f,null)}};this.updateMultisampleRenderTarget=function(b){if(b.isWebGLMultisampleRenderTarget)if(e.isWebGL2){var c=d.get(b);a.bindFramebuffer(36008,c.__webglMultisampledFramebuffer);a.bindFramebuffer(36009,c.__webglFramebuffer); +c=b.width;var f=b.height,g=16384;b.depthBuffer&&(g|=256);b.stencilBuffer&&(g|=1024);a.blitFramebuffer(0,0,c,f,0,0,c,f,g,9728)}else console.warn("THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.")};this.safeSetTexture2D=function(a,b){a&&a.isWebGLRenderTarget&&(!1===D&&(console.warn("THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead."),D=!0),a=a.texture);n(a,b)};this.safeSetTextureCube=function(a,b){a&&a.isWebGLRenderTargetCube&& +(!1===G&&(console.warn("THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead."),G=!0),a=a.texture);a&&a.isCubeTexture||Array.isArray(a.image)&&6===a.image.length?z(a,b):w(a,b)}}function xf(a,b,c){return{convert:function(a){if(1E3===a)return 10497;if(1001===a)return 33071;if(1002===a)return 33648;if(1003===a)return 9728;if(1004===a)return 9984;if(1005===a)return 9986;if(1006===a)return 9729;if(1007===a)return 9985;if(1008===a)return 9987; if(1009===a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)return 33635;if(1010===a)return 5120;if(1011===a)return 5122;if(1012===a)return 5123;if(1013===a)return 5124;if(1014===a)return 5125;if(1015===a)return 5126;if(1016===a){if(c.isWebGL2)return 5131;var d=b.get("OES_texture_half_float");if(null!==d)return d.HALF_FLOAT_OES}if(1021===a)return 6406;if(1022===a)return 6407;if(1023===a)return 6408;if(1024===a)return 6409;if(1025===a)return 6410;if(1026===a)return 6402;if(1027=== a)return 34041;if(1028===a)return 6403;if(100===a)return 32774;if(101===a)return 32778;if(102===a)return 32779;if(200===a)return 0;if(201===a)return 1;if(202===a)return 768;if(203===a)return 769;if(204===a)return 770;if(205===a)return 771;if(206===a)return 772;if(207===a)return 773;if(208===a)return 774;if(209===a)return 775;if(210===a)return 776;if(33776===a||33777===a||33778===a||33779===a)if(d=b.get("WEBGL_compressed_texture_s3tc"),null!==d){if(33776===a)return d.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777=== a)return d.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(33778===a)return d.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return d.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840===a||35841===a||35842===a||35843===a)if(d=b.get("WEBGL_compressed_texture_pvrtc"),null!==d){if(35840===a)return d.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return d.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return d.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return d.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196===a&&(d=b.get("WEBGL_compressed_texture_etc1"), null!==d))return d.COMPRESSED_RGB_ETC1_WEBGL;if(37808===a||37809===a||37810===a||37811===a||37812===a||37813===a||37814===a||37815===a||37816===a||37817===a||37818===a||37819===a||37820===a||37821===a)if(d=b.get("WEBGL_compressed_texture_astc"),null!==d)return a;if(103===a||104===a){if(c.isWebGL2){if(103===a)return 32775;if(104===a)return 32776}d=b.get("EXT_blend_minmax");if(null!==d){if(103===a)return d.MIN_EXT;if(104===a)return d.MAX_EXT}}if(1020===a){if(c.isWebGL2)return 34042;d=b.get("WEBGL_depth_texture"); -if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}function Yb(){H.call(this);this.type="Group"}function Xa(){H.call(this);this.type="Camera";this.matrixWorldInverse=new O;this.projectionMatrix=new O;this.projectionMatrixInverse=new O}function ja(a,b,c,d){Xa.call(this);this.type="PerspectiveCamera";this.fov=void 0!==a?a:50;this.zoom=1;this.near=void 0!==c?c:.1;this.far=void 0!==d?d:2E3;this.focus=10;this.aspect=void 0!==b?b:1;this.view=null;this.filmGauge=35;this.filmOffset=0;this.updateProjectionMatrix()} -function Lc(a){ja.call(this);this.cameras=a||[]}function tf(a,b,c){uf.setFromMatrixPosition(b.matrixWorld);vf.setFromMatrixPosition(c.matrixWorld);var d=uf.distanceTo(vf),e=b.projectionMatrix.elements,f=c.projectionMatrix.elements,g=e[14]/(e[10]-1);c=e[14]/(e[10]+1);var h=(e[9]+1)/e[5],k=(e[9]-1)/e[5],m=(e[8]-1)/e[0],q=(f[8]+1)/f[0];e=g*m;f=g*q;q=d/(-m+q);m=q*-m;b.matrixWorld.decompose(a.position,a.quaternion,a.scale);a.translateX(m);a.translateZ(q);a.matrixWorld.compose(a.position,a.quaternion,a.scale); -a.matrixWorldInverse.getInverse(a.matrixWorld);b=g+q;g=c+q;a.projectionMatrix.makePerspective(e-m,f+(d-m),h*c/g*b,k*c/g*b,b,g)}function wf(a){function b(){return null!==h&&!0===h.isPresenting}function c(){if(b()){var c=h.getEyeParameters("left");e=2*c.renderWidth*l;f=c.renderHeight*l;xa=a.getPixelRatio();a.getSize(G);a.setDrawingBufferSize(e,f,1);y.viewport.set(0,0,e/2,f);x.viewport.set(e/2,0,e/2,f);F.start()}else g.enabled&&a.setDrawingBufferSize(G.width,G.height,xa),F.stop()}function d(a,b){null!== -b&&4===b.length&&a.set(b[0]*e,b[1]*f,b[2]*e,b[3]*f)}var e,f,g=this,h=null,k=null,m=null,q=[],p=new O,v=new O,l=1,r="local-floor";"undefined"!==typeof window&&"VRFrameData"in window&&(k=new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var u=new O,w=new ea,z=new n,y=new ja;y.viewport=new ba;y.layers.enable(1);var x=new ja;x.viewport=new ba;x.layers.enable(2);var A=new Lc([y,x]);A.layers.enable(1);A.layers.enable(2);var G=new D,xa,C=[];this.enabled=!1;this.getController= -function(a){var b=q[a];void 0===b&&(b=new Yb,b.matrixAutoUpdate=!1,b.visible=!1,q[a]=b);return b};this.getDevice=function(){return h};this.setDevice=function(a){void 0!==a&&(h=a);F.setContext(a)};this.setFramebufferScaleFactor=function(a){l=a};this.setReferenceSpaceType=function(a){r=a};this.setPoseTarget=function(a){void 0!==a&&(m=a)};this.getCamera=function(a){var c="local-floor"===r?1.6:0;if(!1===b())return a.position.set(0,c,0),a.rotation.set(0,0,0),a;h.depthNear=a.near;h.depthFar=a.far;h.getFrameData(k); -if("local-floor"===r){var e=h.stageParameters;e?p.fromArray(e.sittingToStandingTransform):p.makeTranslation(0,c,0)}c=k.pose;e=null!==m?m:a;e.matrix.copy(p);e.matrix.decompose(e.position,e.quaternion,e.scale);null!==c.orientation&&(w.fromArray(c.orientation),e.quaternion.multiply(w));null!==c.position&&(w.setFromRotationMatrix(p),z.fromArray(c.position),z.applyQuaternion(w),e.position.add(z));e.updateMatrixWorld();y.near=a.near;x.near=a.near;y.far=a.far;x.far=a.far;y.matrixWorldInverse.fromArray(k.leftViewMatrix); -x.matrixWorldInverse.fromArray(k.rightViewMatrix);v.getInverse(p);"local-floor"===r&&(y.matrixWorldInverse.multiply(v),x.matrixWorldInverse.multiply(v));a=e.parent;null!==a&&(u.getInverse(a.matrixWorld),y.matrixWorldInverse.multiply(u),x.matrixWorldInverse.multiply(u));y.matrixWorld.getInverse(y.matrixWorldInverse);x.matrixWorld.getInverse(x.matrixWorldInverse);y.projectionMatrix.fromArray(k.leftProjectionMatrix);x.projectionMatrix.fromArray(k.rightProjectionMatrix);tf(A,y,x);a=h.getLayers();a.length&& -(a=a[0],d(y.viewport,a.leftBounds),d(x.viewport,a.rightBounds));a:for(a=0;af.matrixWorld.determinant();da.setMaterial(e,h);var k=l(a,c,e,f),m=!1;if(b!==d.id||I!==k.id||U!==(!0===e.wireframe))b=d.id,I=k.id,U=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(za.update(f,d,e,k),m=!0);h=d.index;var q=d.attributes.position;c=1;!0===e.wireframe&&(h=va.getWireframeAttribute(d), -c=2);a=Ba;if(null!==h){var p=ua.get(h);a=Ca;a.setIndex(p)}if(m){if(d&&d.isInstancedBufferGeometry&&!Ea.isWebGL2&&null===la.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");else{da.initAttributes();m=d.attributes;k=k.getAttributes();var v=e.defaultAttributeValues;for(A in k){var r=k[A];if(0<=r){var t=m[A];if(void 0!==t){var u=t.normalized,n=t.itemSize,w=ua.get(t); -if(void 0!==w){var x=w.buffer,y=w.type;w=w.bytesPerElement;if(t.isInterleavedBufferAttribute){var G=t.data,z=G.stride;t=t.offset;G&&G.isInstancedInterleavedBuffer?(da.enableAttributeAndDivisor(r,G.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=G.meshPerAttribute*G.count)):da.enableAttribute(r);M.bindBuffer(34962,x);M.vertexAttribPointer(r,n,y,u,z*w,t*w)}else t.isInstancedBufferAttribute?(da.enableAttributeAndDivisor(r,t.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount= -t.meshPerAttribute*t.count)):da.enableAttribute(r),M.bindBuffer(34962,x),M.vertexAttribPointer(r,n,y,u,0,0)}}else if(void 0!==v&&(u=v[A],void 0!==u))switch(u.length){case 2:M.vertexAttrib2fv(r,u);break;case 3:M.vertexAttrib3fv(r,u);break;case 4:M.vertexAttrib4fv(r,u);break;default:M.vertexAttrib1fv(r,u)}}}da.disableUnusedAttributes()}null!==h&&M.bindBuffer(34963,p.buffer)}p=Infinity;null!==h?p=h.count:void 0!==q&&(p=q.count);h=d.drawRange.start*c;q=null!==g?g.start*c:0;var A=Math.max(h,q);g=Math.max(0, -Math.min(p,h+d.drawRange.count*c,q+(null!==g?g.count*c:Infinity))-1-A+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)da.setLineWidth(e.wireframeLinewidth*(null===L?ca:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),da.setLineWidth(e*(null===L?ca:1)),f.isLineSegments?a.setMode(1):f.isLineLoop?a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);d&&d.isInstancedBufferGeometry? -0c;c++){var p=q[h[c]];var l=q[h[(c+1)%3]];f[0]=Math.min(p,l);f[1]=Math.max(p,l);p=f[0]+ -","+f[1];void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]})}}for(p in g)m=g[p],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){k=a.attributes.position;q=a.index;var t=a.groups;0===t.length&&(t=[{start:0,count:q.count,materialIndex:0}]);a=0;for(e=t.length;ac;c++)p=q.getX(m+c),l=q.getX(m+(c+1)%3),f[0]=Math.min(p,l),f[1]=Math.max(p,l),p=f[0]+","+ -f[1],void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]});for(p in g)m=g[p],h.fromBufferAttribute(k,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(k,m.index2),b.push(h.x,h.y,h.z)}else for(k=a.attributes.position,m=0,d=k.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z);this.addAttribute("position",new C(b,3))}function Sc(a,b,c){Q.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b, -stacks:c};this.fromBufferGeometry(new cc(a,b,c));this.mergeVertices()}function cc(a,b,c){E.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,k=new n,m=new n,q=new n,p=new n,l,t;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.");var r=b+1;for(l=0;l<=c;l++){var u=l/c;for(t=0;t<=b;t++){var w=t/b;a(w,u,k);e.push(k.x,k.y,k.z);0<=w-1E-5?(a(w-1E-5,u,m),q.subVectors(k,m)):(a(w+ -1E-5,u,m),q.subVectors(m,k));0<=u-1E-5?(a(w,u-1E-5,m),p.subVectors(k,m)):(a(w,u+1E-5,m),p.subVectors(m,k));h.crossVectors(q,p).normalize();f.push(h.x,h.y,h.z);g.push(w,u)}}for(l=0;ld&&1===a.x&&(k[b]=a.x-1);0===c.x&&0===c.z&&(k[b]=d/2/Math.PI+.5)}E.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],k=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(k[a+0]+=1),.2>c&&(k[a+2]+=1),.2>d&&(k[a+4]+=1))})();this.addAttribute("position",new C(h,3));this.addAttribute("normal",new C(h.slice(),3));this.addAttribute("uv",new C(k,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Uc(a,b){Q.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new dc(a,b));this.mergeVertices()} -function dc(a,b){oa.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Vc(a,b){Q.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Cb(a,b));this.mergeVertices()}function Cb(a,b){oa.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters= -{radius:a,detail:b}}function Wc(a,b){Q.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new ec(a,b));this.mergeVertices()}function ec(a,b){var c=(1+Math.sqrt(5))/2;oa.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters= -{radius:a,detail:b}}function Xc(a,b){Q.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new fc(a,b));this.mergeVertices()}function fc(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;oa.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2, -6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Yc(a,b,c,d,e,f){Q.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new Db(a,b,c,d,e);this.tangents=a.tangents;this.normals= -a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function Db(a,b,c,d,e){function f(e){q=a.getPointAt(e/b,q);var f=g.normals[e];e=g.binormals[e];for(l=0;l<=d;l++){var m=l/d*Math.PI*2,p=Math.sin(m);m=-Math.cos(m);k.x=m*f.x+p*e.x;k.y=m*f.y+p*e.y;k.z=m*f.z+p*e.z;k.normalize();r.push(k.x,k.y,k.z);h.x=q.x+c*k.x;h.y=q.y+c*k.y;h.z=q.z+c*k.z;t.push(h.x,h.y,h.z)}}E.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d, -closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,k=new n,m=new D,q=new n,p,l,t=[],r=[],u=[],w=[];for(p=0;p=b;e-=d)f=zf(e,a[e],a[e+1],f);f&&Eb(f,f.next)&&(ad(f),f=f.next);return f}function bd(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!Eb(a,a.next)&&0!==qa(a.prev,a,a.next))a=a.next;else{ad(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b}function cd(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,k=h;do null===k.z&&(k.z=qe(k.x,k.y,d,e,f)),k.prevZ=k.prev,k=k.nextZ= -k.next;while(k!==h);k.prevZ.nextZ=null;k.prevZ=null;h=k;var m,q,p,l,t=1;do{k=h;var r=h=null;for(q=0;k;){q++;var n=k;for(m=p=0;mp.x?q.x>t.x?q.x:t.x:p.x>t.x?p.x:t.x,x=q.y>p.y?q.y>t.y?q.y:t.y:p.y> -t.y?p.y:t.y;m=qe(q.x=m;){if(w!==r.prev&&w!==r.next&&Id(q.x,q.y,p.x,p.y,t.x,t.y,w.x,w.y)&&0<=qa(w.prev,w,w.next)){r=!1;break a}w=w.prevZ}r=!0}}else a:if(r=a,q=r.prev,p=r,t=r.next,0<=qa(q,p,t))r=!1;else{for(m=r.next.next;m!==r.prev;){if(Id(q.x,q.y, -p.x,p.y,t.x,t.y,m.x,m.y)&&0<=qa(m.prev,m,m.next)){r=!1;break a}m=m.next}r=!0}if(r)b.push(k.i/c),b.push(a.i/c),b.push(n.i/c),ad(a),h=a=n.next;else if(a=n,a===h){if(!g)cd(bd(a),b,c,d,e,f,1);else if(1===g){g=b;h=c;k=a;do n=k.prev,r=k.next.next,!Eb(n,r)&&Af(n,k,k.next,r)&&dd(n,r)&&dd(r,n)&&(g.push(n.i/h),g.push(k.i/h),g.push(r.i/h),ad(k),ad(k.next),k=a=r),k=k.next;while(k!==a);a=k;cd(a,b,c,d,e,f,2)}else if(2===g)a:{g=a;do{for(h=g.next.next;h!==g.prev;){if(k=g.i!==h.i){k=g;n=h;if(r=k.next.i!==n.i&&k.prev.i!== -n.i){b:{r=k;do{if(r.i!==k.i&&r.next.i!==k.i&&r.i!==n.i&&r.next.i!==n.i&&Af(r,r.next,k,n)){r=!0;break b}r=r.next}while(r!==k);r=!1}r=!r}if(r=r&&dd(k,n)&&dd(n,k)){r=k;q=!1;p=(k.x+n.x)/2;n=(k.y+n.y)/2;do r.y>n!==r.next.y>n&&r.next.y!==r.y&&p<(r.next.x-r.x)*(n-r.y)/(r.next.y-r.y)+r.x&&(q=!q),r=r.next;while(r!==k);r=q}k=r}if(k){a=Bf(g,h);g=bd(g,g.next);a=bd(a,a.next);cd(g,b,c,d,e,f);cd(a,b,c,d,e,f);break a}h=h.next}g=g.next}while(g!==a)}break}}}}function mh(a,b){return a.x-b.x}function nh(a,b){var c=b, -d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f=g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&Id(eh.x)&&dd(c,a)&&(h=c,m=q)}c=c.next}return h}function qe(a, -b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b|b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function oh(a){var b=a,c=a;do b.xqa(a.prev,a,a.next)?0<=qa(a,b,a.next)&&0<=qa(a,a.prev,b):0>qa(a,b,a.prev)||0>qa(a,a.next,b)}function Bf(a,b){var c=new re(a.i,a.x,a.y),d=new re(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function zf(a,b,c,d){a=new re(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a): -(a.prev=a,a.next=a);return a}function ad(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ=a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function re(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Cf(a){var b=a.length;2Number.EPSILON){var k=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/k;b=b.y+d/k;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new D(f,d);e=Math.sqrt(e/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?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new D(f/e,d/e)}function h(a,b){for(K=a.length;0<=--K;){var c=K;var f=K-1;0>f&&(f=a.length-1);var g,h=y+2*F;for(g=0;gq;q++){var l=m[f[q]];var n=m[f[(q+1)%3]];d[0]=Math.min(l,n);d[1]=Math.max(l,n);l=d[0]+","+d[1];void 0===e[l]?e[l]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[l].face2=h}for(l in e)if(d=e[l],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new C(c,3))}function Ib(a,b,c,d, -e,f,g,h){Q.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new eb(a,b,c,d,e,f,g,h));this.mergeVertices()}function eb(a,b,c,d,e,f,g,h){function k(c){var e,f=new D,k=new n,p=0,u=!0===c?a:b,y=!0===c?1:-1;var C=r;for(e=1;e<=d;e++)l.push(0,w*y,0),v.push(0,y,0),t.push(.5,.5),r++;var E=r;for(e=0;e<=d;e++){var B=e/d*h+g,H=Math.cos(B);B=Math.sin(B);k.x=u*B;k.y=w*y; -k.z=u*H;l.push(k.x,k.y,k.z);v.push(0,y,0);f.x=.5*H+.5;f.y=.5*B*y+.5;t.push(f.x,f.y);r++}for(e=0;ethis.duration&&this.resetDuration()}function qh(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return oc;case "vector":case "vector2":case "vector3":case "vector4":return pc; -case "color":return Md;case "quaternion":return md;case "bool":case "boolean":return Ld;case "string":return Od}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function rh(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=qh(a.type);if(void 0===a.times){var c=[],d=[];ra.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)}function se(a,b,c){var d=this,e= -!1,f=0,g=0,h=void 0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this}}function La(a){this.manager=void 0!==a?a:za}function Gf(a){this.manager= -void 0!==a?a:za}function Hf(a){this.manager=void 0!==a?a:za;this._parser=null}function te(a){this.manager=void 0!==a?a:za;this._parser=null}function nd(a){this.manager=void 0!==a?a:za}function ue(a){this.manager=void 0!==a?a:za}function Pd(a){this.manager=void 0!==a?a:za}function N(){this.type="Curve";this.arcLengthDivisions=200}function Aa(a,b,c,d,e,f,g,h){N.call(this);this.type="EllipseCurve";this.aX=a||0;this.aY=b||0;this.xRadius=c||1;this.yRadius=d||1;this.aStartAngle=e||0;this.aEndAngle=f||2* -Math.PI;this.aClockwise=g||!1;this.aRotation=h||0}function qc(a,b,c,d,e,f){Aa.call(this,a,b,c,c,d,e,f);this.type="ArcCurve"}function ve(){var a=0,b=0,c=0,d=0;return{initCatmullRom:function(e,f,g,h,k){e=k*(g-e);h=k*(h-f);a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},initNonuniformCatmullRom:function(e,f,g,h,k,m,q){e=((f-e)/k-(g-e)/(k+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+q)+(h-g)/q)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function ua(a,b,c,d){N.call(this); -this.type="CatmullRomCurve3";this.points=a||[];this.closed=b||!1;this.curveType=c||"centripetal";this.tension=d||.5}function If(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function od(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function pd(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}function Ma(a,b,c,d){N.call(this);this.type="CubicBezierCurve";this.v0=a||new D;this.v1=b||new D;this.v2=c||new D;this.v3=d||new D}function $a(a, -b,c,d){N.call(this);this.type="CubicBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n;this.v3=d||new n}function Ba(a,b){N.call(this);this.type="LineCurve";this.v1=a||new D;this.v2=b||new D}function Na(a,b){N.call(this);this.type="LineCurve3";this.v1=a||new n;this.v2=b||new n}function Oa(a,b,c){N.call(this);this.type="QuadraticBezierCurve";this.v0=a||new D;this.v1=b||new D;this.v2=c||new D}function ab(a,b,c){N.call(this);this.type="QuadraticBezierCurve3";this.v0=a||new n;this.v1=b|| -new n;this.v2=c||new n}function Pa(a){N.call(this);this.type="SplineCurve";this.points=a||[]}function fb(){N.call(this);this.type="CurvePath";this.curves=[];this.autoClose=!1}function Qa(a){fb.call(this);this.type="Path";this.currentPoint=new D;a&&this.setFromPoints(a)}function pb(a){Qa.call(this,a);this.uuid=P.generateUUID();this.type="Shape";this.holes=[]}function aa(a,b){H.call(this);this.type="Light";this.color=new B(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0}function Qd(a,b,c){aa.call(this, -a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(H.DefaultUp);this.updateMatrix();this.groundColor=new B(b)}function Qb(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new D(512,512);this.map=null;this.matrix=new O}function Rd(){Qb.call(this,new ja(50,1,.5,500))}function Sd(a,b,c,d,e,f){aa.call(this,a,b);this.type="SpotLight";this.position.copy(H.DefaultUp);this.updateMatrix();this.target=new H;Object.defineProperty(this,"power",{get:function(){return this.intensity* -Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Rd}function Td(a,b,c,d){aa.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new Qb(new ja(90,1,.5,500))}function qd(a,b,c,d,e, -f){Xa.call(this);this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=void 0!==a?a:-1;this.right=void 0!==b?b:1;this.top=void 0!==c?c:1;this.bottom=void 0!==d?d:-1;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function Ud(){Qb.call(this,new qd(-5,5,5,-5,.5,500))}function Vd(a,b){aa.call(this,a,b);this.type="DirectionalLight";this.position.copy(H.DefaultUp);this.updateMatrix();this.target=new H;this.shadow=new Ud}function Wd(a,b){aa.call(this,a,b); -this.type="AmbientLight";this.castShadow=void 0}function Xd(a,b,c,d){aa.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function Yd(a){this.manager=void 0!==a?a:za;this.textures={}}function Zd(){E.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function $d(a,b,c,d){"number"===typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument."));I.call(this,a,b, -c);this.meshPerAttribute=d||1}function we(a){this.manager=void 0!==a?a:za}function xe(a){this.manager=void 0!==a?a:za;this.resourcePath=""}function ye(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported.");this.manager=void 0!==a?a:za;this.options=void 0}function ze(){this.type="ShapePath";this.color=new B;this.subPaths=[];this.currentPath=null} -function Ae(a){this.type="Font";this.data=a}function Jf(a){this.manager=void 0!==a?a:za}function rd(){}function Be(a){this.manager=void 0!==a?a:za}function ae(){this.coefficients=[];for(var a=0;9>a;a++)this.coefficients.push(new n)}function Ra(a,b){aa.call(this,void 0,b);this.sh=void 0!==a?a:new ae}function Ce(a,b,c){Ra.call(this,void 0,c);a=(new B).set(a);c=(new B).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c); -this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)}function De(a,b){Ra.call(this,void 0,b);a=(new B).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))}function Kf(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new ja;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new ja;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1}function sd(a,b,c,d){H.call(this);this.type="CubeCamera";var e=new ja(90, -1,a,b);e.up.set(0,-1,0);e.lookAt(new n(1,0,0));this.add(e);var f=new ja(90,1,a,b);f.up.set(0,-1,0);f.lookAt(new n(-1,0,0));this.add(f);var g=new ja(90,1,a,b);g.up.set(0,0,1);g.lookAt(new n(0,1,0));this.add(g);var h=new ja(90,1,a,b);h.up.set(0,0,-1);h.lookAt(new n(0,-1,0));this.add(h);var k=new ja(90,1,a,b);k.up.set(0,-1,0);k.lookAt(new n(0,0,1));this.add(k);var m=new ja(90,1,a,b);m.up.set(0,-1,0);m.lookAt(new n(0,0,-1));this.add(m);d=d||{format:1022,magFilter:1006,minFilter:1006};this.renderTarget= -new rb(c,c,d);this.renderTarget.texture.name="CubeCamera";this.update=function(a,b){null===this.parent&&this.updateMatrixWorld();var c=a.getRenderTarget(),d=this.renderTarget,q=d.texture.generateMipmaps;d.texture.generateMipmaps=!1;a.setRenderTarget(d,0);a.render(b,e);a.setRenderTarget(d,1);a.render(b,f);a.setRenderTarget(d,2);a.render(b,g);a.setRenderTarget(d,3);a.render(b,h);a.setRenderTarget(d,4);a.render(b,k);d.texture.generateMipmaps=q;a.setRenderTarget(d,5);a.render(b,m);a.setRenderTarget(c)}; -this.clear=function(a,b,c,d){for(var e=a.getRenderTarget(),f=this.renderTarget,g=0;6>g;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function Ee(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function Fe(){H.call(this);this.type="AudioListener";this.context=Ge.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0}function rc(a){H.call(this);this.type="Audio"; -this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function He(a){rc.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function Ie(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)}function Je(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function Lf(a,b,c){c=c||va.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b, -c)}function va(a,b,c){this.path=b;this.parsedPath=c||va.parseTrackName(b);this.node=va.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Mf(){this.uuid=P.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length}, -get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function Nf(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop= -2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function Ke(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function be(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Le(a,b,c){Bb.call(this, -a,b);this.meshPerAttribute=c||1}function Of(a,b,c,d){this.ray=new Ab(a,b);this.near=c||0;this.far=d||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})}function Pf(a,b){return a.distance-b.distance}function Me(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;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 C(b,3));b=new V({fog:!1});this.cone=new S(a,b);this.add(this.cone);this.update()}function Sf(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;ca?-1:0b;b++)a[b]=(16>b?"0":"")+b.toString(16); -return function(){var b=4294967295*Math.random()|0,d=4294967295*Math.random()|0,e=4294967295*Math.random()|0,f=4294967295*Math.random()|0;return(a[b&255]+a[b>>8&255]+a[b>>16&255]+a[b>>24&255]+"-"+a[d&255]+a[d>>8&255]+"-"+a[d>>16&15|64]+a[d>>24&255]+"-"+a[e&63|128]+a[e>>8&255]+"-"+a[e>>16&255]+a[e>>24&255]+a[f&255]+a[f>>8&255]+a[f>>16&255]+a[f>>24&255]).toUpperCase()}}(),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)},lerp:function(a,b,c){return(1-c)*a+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)},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*P.DEG2RAD},radToDeg:function(a){return a* -P.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2,Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(D.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(D.prototype,{isVector2:!0,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);}return this},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){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y= -a[1]*b+a[4]*c+a[7];return this},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| -1).multiplyScalar(Math.max(a,Math.min(b,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},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(ea,{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 l=e[f+1],p=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==l||m!==p){f=1-g;var n=h*d+k*l+m*p+c*e,t=0<=n?1:-1,r=1-n*n;r>Number.EPSILON&&(r=Math.sqrt(r),n=Math.atan2(r,n*t),f=Math.sin(f*n)/r,g=Math.sin(g*n)/r);t*=g;h=h*f+d*t;k=k*f+l*t;m=m*f+p*t;c=c*f+e*t;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;a[b+3]=c}});Object.defineProperties(ea.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this.onChangeCallback()}}, -y:{get:function(){return this._y},set:function(a){this._y=a;this.onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this.onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this.onChangeCallback()}}});Object.assign(ea.prototype,{isQuaternion:!0,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(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),k=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f-c*d*e):"YXZ"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f-c*k*e,this._z=h* -k*e-c*d*f,this._w=h*k*f+c*d*e):"ZXY"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f-c*d*e):"ZYX"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f+c*d*e):"YZX"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f-c*d*e):"XZY"===a&&(this._x=c*k*f-h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f+c*d*e);if(!1!==b)this.onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b); -this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);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];var 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(a,b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(P.clamp(this.dot(a),-1,1)))},rotateTowards:function(a, -b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},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)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w; -var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;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;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g* -f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize();a=Math.sqrt(a);var h=Math.atan2(a,g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;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(n.prototype,{isVector3:!0,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);}return this},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){this.x*=a;this.y*=a;this.z*=a;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=new ea;return function(b){b&&b.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(a.setFromEuler(b))}}(),applyAxisAngle:function(){var a=new ea;return function(b,c){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;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(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)},unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a, -Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,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)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+ -Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},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){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this, -a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(){var a=new n;return function(b){a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a=new n;return function(b){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(P.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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)* -a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta,a.y)},setFromCylindricalCoords:function(a,b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},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){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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute()."); -this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});Object.assign(ia.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,k){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=k;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]= -a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToBufferAttribute:function(){var a=new n;return function(b){for(var c=0,d=b.count;cc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];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]; -return a}});var Ac,qb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===Ac&&(Ac=document.createElementNS("http://www.w3.org/1999/xhtml","canvas"));Ac.width=a.width;Ac.height=a.height;var b=Ac.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=Ac}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(X.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(ba.prototype,{isVector4:!0,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);}return this},getComponent:function(a){switch(a){case 0:return this.x; +if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}function Zb(){G.call(this);this.type="Group"}function Oc(a){ja.call(this);this.cameras=a||[]}function yf(a,b,c){zf.setFromMatrixPosition(b.matrixWorld);Af.setFromMatrixPosition(c.matrixWorld);var d=zf.distanceTo(Af),e=b.projectionMatrix.elements,f=c.projectionMatrix.elements,g=e[14]/(e[10]-1);c=e[14]/(e[10]+1);var h=(e[9]+1)/e[5],k=(e[9]-1)/e[5],m=(e[8]-1)/e[0],r=(f[8]+1)/f[0];e=g*m;f=g*r;r=d/(-m+r);m=r*-m;b.matrixWorld.decompose(a.position, +a.quaternion,a.scale);a.translateX(m);a.translateZ(r);a.matrixWorld.compose(a.position,a.quaternion,a.scale);a.matrixWorldInverse.getInverse(a.matrixWorld);b=g+r;g=c+r;a.projectionMatrix.makePerspective(e-m,f+(d-m),h*c/g*b,k*c/g*b,b,g)}function qe(a){function b(){return null!==h&&!0===h.isPresenting}function c(){if(b()){var c=h.getEyeParameters("left");e=2*c.renderWidth*t;f=c.renderHeight*t;la=a.getPixelRatio();a.getSize(H);a.setDrawingBufferSize(e,f,1);w.viewport.set(0,0,e/2,f);x.viewport.set(e/ +2,0,e/2,f);F.start();g.dispatchEvent({type:"sessionstart"})}else g.enabled&&a.setDrawingBufferSize(H.width,H.height,la),F.stop(),g.dispatchEvent({type:"sessionend"})}function d(a,b){null!==b&&4===b.length&&a.set(b[0]*e,b[1]*f,b[2]*e,b[3]*f)}var e,f,g=this,h=null,k=null,m=null,r=[],p=new O,l=new O,t=1,q="local-floor";"undefined"!==typeof window&&"VRFrameData"in window&&(k=new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var v=new O,y=new ea,z=new n,w=new ja;w.viewport= +new ba;w.layers.enable(1);var x=new ja;x.viewport=new ba;x.layers.enable(2);var A=new Oc([w,x]);A.layers.enable(1);A.layers.enable(2);var H=new C,la,xa=[];this.enabled=!1;this.getController=function(a){var b=r[a];void 0===b&&(b=new Zb,b.matrixAutoUpdate=!1,b.visible=!1,r[a]=b);return b};this.getDevice=function(){return h};this.setDevice=function(a){void 0!==a&&(h=a);F.setContext(a)};this.setFramebufferScaleFactor=function(a){t=a};this.setReferenceSpaceType=function(a){q=a};this.setPoseTarget=function(a){void 0!== +a&&(m=a)};this.getCamera=function(a){var c="local-floor"===q?1.6:0;if(!1===b())return a.position.set(0,c,0),a.rotation.set(0,0,0),a;h.depthNear=a.near;h.depthFar=a.far;h.getFrameData(k);if("local-floor"===q){var e=h.stageParameters;e?p.fromArray(e.sittingToStandingTransform):p.makeTranslation(0,c,0)}c=k.pose;e=null!==m?m:a;e.matrix.copy(p);e.matrix.decompose(e.position,e.quaternion,e.scale);null!==c.orientation&&(y.fromArray(c.orientation),e.quaternion.multiply(y));null!==c.position&&(y.setFromRotationMatrix(p), +z.fromArray(c.position),z.applyQuaternion(y),e.position.add(z));e.updateMatrixWorld();w.near=a.near;x.near=a.near;w.far=a.far;x.far=a.far;w.matrixWorldInverse.fromArray(k.leftViewMatrix);x.matrixWorldInverse.fromArray(k.rightViewMatrix);l.getInverse(p);"local-floor"===q&&(w.matrixWorldInverse.multiply(l),x.matrixWorldInverse.multiply(l));a=e.parent;null!==a&&(v.getInverse(a.matrixWorld),w.matrixWorldInverse.multiply(v),x.matrixWorldInverse.multiply(v));w.matrixWorld.getInverse(w.matrixWorldInverse); +x.matrixWorld.getInverse(x.matrixWorldInverse);w.projectionMatrix.fromArray(k.leftProjectionMatrix);x.projectionMatrix.fromArray(k.rightProjectionMatrix);yf(A,w,x);a=h.getLayers();a.length&&(a=a[0],d(w.viewport,a.leftBounds),d(x.viewport,a.rightBounds));a:for(a=0;af.matrixWorld.determinant();da.setMaterial(e,h);var k=l(a,c,e,f),m=!1;if(b!==d.id||I!==k.id||U!==(!0===e.wireframe))b=d.id,I=k.id,U=!0===e.wireframe,m=!0;f.morphTargetInfluences&&(za.update(f,d,e,k),m=!0);h=d.index;var r=d.attributes.position;c=1;!0===e.wireframe&&(h=wa.getWireframeAttribute(d),c=2);a=Aa;if(null!==h){var p=sa.get(h);a=Ca;a.setIndex(p)}if(m){if(d&&d.isInstancedBufferGeometry&&!Fa.isWebGL2&&null===ma.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays."); +else{da.initAttributes();m=d.attributes;k=k.getAttributes();var u=e.defaultAttributeValues;for(A in k){var q=k[A];if(0<=q){var t=m[A];if(void 0!==t){var n=t.normalized,v=t.itemSize,y=sa.get(t);if(void 0!==y){var w=y.buffer,x=y.type;y=y.bytesPerElement;if(t.isInterleavedBufferAttribute){var z=t.data,H=z.stride;t=t.offset;z&&z.isInstancedInterleavedBuffer?(da.enableAttributeAndDivisor(q,z.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=z.meshPerAttribute*z.count)):da.enableAttribute(q); +M.bindBuffer(34962,w);M.vertexAttribPointer(q,v,x,n,H*y,t*y)}else t.isInstancedBufferAttribute?(da.enableAttributeAndDivisor(q,t.meshPerAttribute),void 0===d.maxInstancedCount&&(d.maxInstancedCount=t.meshPerAttribute*t.count)):da.enableAttribute(q),M.bindBuffer(34962,w),M.vertexAttribPointer(q,v,x,n,0,0)}}else if(void 0!==u&&(n=u[A],void 0!==n))switch(n.length){case 2:M.vertexAttrib2fv(q,n);break;case 3:M.vertexAttrib3fv(q,n);break;case 4:M.vertexAttrib4fv(q,n);break;default:M.vertexAttrib1fv(q,n)}}}da.disableUnusedAttributes()}null!== +h&&M.bindBuffer(34963,p.buffer)}p=Infinity;null!==h?p=h.count:void 0!==r&&(p=r.count);h=d.drawRange.start*c;r=null!==g?g.start*c:0;var A=Math.max(h,r);g=Math.max(0,Math.min(p,h+d.drawRange.count*c,r+(null!==g?g.count*c:Infinity))-1-A+1);if(0!==g){if(f.isMesh)if(!0===e.wireframe)da.setLineWidth(e.wireframeLinewidth*(null===L?ca:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),da.setLineWidth(e* +(null===L?ca:1)),f.isLineSegments?a.setMode(1):f.isLineLoop?a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);d&&d.isInstancedBufferGeometry?0c;c++){var p=r[h[c]];var l=r[h[(c+1)%3]];f[0]=Math.min(p,l);f[1]=Math.max(p,l);p=f[0]+","+f[1];void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]})}}for(p in g)m=g[p],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&a.isBufferGeometry)if(h=new n,null!==a.index){k=a.attributes.position;r=a.index;var t=a.groups;0===t.length&&(t=[{start:0,count:r.count,materialIndex:0}]); +a=0;for(e=t.length;ac;c++)p=r.getX(m+c),l=r.getX(m+(c+1)%3),f[0]=Math.min(p,l),f[1]=Math.max(p,l),p=f[0]+","+f[1],void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]});for(p in g)m=g[p],h.fromBufferAttribute(k,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(k,m.index2),b.push(h.x,h.y,h.z)}else for(k=a.attributes.position,m=0,d=k.count/3;mc;c++)g=3*m+c,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(k, +g),b.push(h.x,h.y,h.z);this.addAttribute("position",new D(b,3))}function Vc(a,b,c){Q.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new dc(a,b,c));this.mergeVertices()}function dc(a,b,c){E.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,k=new n,m=new n,r=new n,p=new n,l,t;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter."); +var q=b+1;for(l=0;l<=c;l++){var v=l/c;for(t=0;t<=b;t++){var y=t/b;a(y,v,k);e.push(k.x,k.y,k.z);0<=y-1E-5?(a(y-1E-5,v,m),r.subVectors(k,m)):(a(y+1E-5,v,m),r.subVectors(m,k));0<=v-1E-5?(a(y,v-1E-5,m),p.subVectors(k,m)):(a(y,v+1E-5,m),p.subVectors(m,k));h.crossVectors(r,p).normalize();f.push(h.x,h.y,h.z);g.push(y,v)}}for(l=0;ld&&1===a.x&&(k[b]=a.x-1);0===c.x&&0===c.z&&(k[b]=d/2/Math.PI+.5)}E.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a, +indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],k=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;he&&(.2>b&&(k[a+0]+=1),.2>c&&(k[a+2]+=1),.2>d&&(k[a+4]+=1))})();this.addAttribute("position",new D(h,3));this.addAttribute("normal",new D(h.slice(),3));this.addAttribute("uv",new D(k,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Xc(a, +b){Q.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new ec(a,b));this.mergeVertices()}function ec(a,b){za.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Yc(a,b){Q.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Db(a,b));this.mergeVertices()}function Db(a,b){za.call(this,[1,0,0, +-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Zc(a,b){Q.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new fc(a,b));this.mergeVertices()}function fc(a,b){var c=(1+Math.sqrt(5))/2;za.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5, +11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function $c(a,b){Q.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new gc(a,b));this.mergeVertices()}function gc(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;za.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c, +0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function ad(a,b,c,d,e,f){Q.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d, +closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new Eb(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function Eb(a,b,c,d,e){function f(e){r=a.getPointAt(e/b,r);var f=g.normals[e];e=g.binormals[e];for(l=0;l<=d;l++){var m=l/d*Math.PI*2,p=Math.sin(m);m=-Math.cos(m);k.x=m*f.x+p*e.x;k.y=m*f.y+p*e.y;k.z=m*f.z+p*e.z;k.normalize();q.push(k.x,k.y,k.z);h.x=r.x+c*k.x;h.y=r.y+c*k.y;h.z= +r.z+c*k.z;t.push(h.x,h.y,h.z)}}E.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,k=new n,m=new C,r=new n,p,l,t=[],q=[],v=[],y=[];for(p=0;p=b;e-=d)f=Ef(e,a[e],a[e+1],f);f&&Fb(f,f.next)&&(dd(f),f=f.next);return f}function ed(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!Fb(a,a.next)&&0!==aa(a.prev,a,a.next))a=a.next;else{dd(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b} +function fd(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,k=h;do null===k.z&&(k.z=ue(k.x,k.y,d,e,f)),k.prevZ=k.prev,k=k.nextZ=k.next;while(k!==h);k.prevZ.nextZ=null;k.prevZ=null;h=k;var m,r,p,l,t=1;do{k=h;var q=h=null;for(r=0;k;){r++;var n=k;for(m=p=0;mn!==q.next.y>n&&q.next.y!==q.y&&p<(q.next.x-q.x)*(n-q.y)/(q.next.y-q.y)+q.x&&(r=!r),q=q.next;while(q!==k);q=r}k=q}if(k){a=Gf(g,h);g=ed(g,g.next);a=ed(a,a.next);fd(g,b,c,d,e,f);fd(a,b,c,d,e,f);break a}h= +h.next}g=g.next}while(g!==a)}break}}}}function ph(a,b,c,d){var e=a.prev,f=a.next;if(0<=aa(e,a,f))return!1;var g=e.x>a.x?e.x>f.x?e.x:f.x:a.x>f.x?a.x:f.x,h=e.y>a.y?e.y>f.y?e.y:f.y:a.y>f.y?a.y:f.y,k=ue(e.x=k&&d&&d.z<=b;){if(c!==a.prev&&c!==a.next&&jc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=aa(c.prev,c,c.next))return!1;c=c.prevZ;if(d!==a.prev&&d!==a.next&&jc(e.x,e.y,a.x,a.y, +f.x,f.y,d.x,d.y)&&0<=aa(d.prev,d,d.next))return!1;d=d.nextZ}for(;c&&c.z>=k;){if(c!==a.prev&&c!==a.next&&jc(e.x,e.y,a.x,a.y,f.x,f.y,c.x,c.y)&&0<=aa(c.prev,c,c.next))return!1;c=c.prevZ}for(;d&&d.z<=b;){if(d!==a.prev&&d!==a.next&&jc(e.x,e.y,a.x,a.y,f.x,f.y,d.x,d.y)&&0<=aa(d.prev,d,d.next))return!1;d=d.nextZ}return!0}function qh(a,b){return a.x-b.x}function rh(a,b){var c=b,d=a.x,e=a.y,f=-Infinity;do{if(e<=c.y&&e>=c.next.y&&c.next.y!==c.y){var g=c.x+(e-c.y)*(c.next.x-c.x)/(c.next.y-c.y);if(g<=d&&g>f){f= +g;if(g===d){if(e===c.y)return c;if(e===c.next.y)return c.next}var h=c.x=c.x&&c.x>=g&&d!==c.x&&jc(eh.x)&&gd(c,a)&&(h=c,m=r)}c=c.next}return h}function ue(a,b,c,d,e){a=32767*(a-c)*e;b=32767*(b-d)*e;a=(a|a<<8)&16711935;a=(a|a<<4)&252645135;a=(a|a<<2)&858993459;b=(b|b<<8)&16711935;b=(b| +b<<4)&252645135;b=(b|b<<2)&858993459;return(a|a<<1)&1431655765|((b|b<<1)&1431655765)<<1}function sh(a){var b=a,c=a;do{if(b.xaa(a.prev,a,a.next)?0<=aa(a,b,a.next)&&0<=aa(a,a.prev,b):0>aa(a,b,a.prev)||0>aa(a,a.next,b)}function Gf(a,b){var c=new ve(a.i,a.x,a.y),d=new ve(b.i,b.x,b.y),e=a.next,f=b.prev;a.next=b;b.prev=a;c.next=e;e.prev=c;d.next=c;c.prev=d;f.next=d;d.prev=f;return d}function Ef(a,b,c,d){a=new ve(a,b,c);d?(a.next=d.next,a.prev=d,d.next.prev=a,d.next=a):(a.prev=a,a.next=a);return a}function dd(a){a.next.prev=a.prev;a.prev.next=a.next;a.prevZ&&(a.prevZ.nextZ= +a.nextZ);a.nextZ&&(a.nextZ.prevZ=a.prevZ)}function ve(a,b,c){this.i=a;this.x=b;this.y=c;this.nextZ=this.prevZ=this.z=this.next=this.prev=null;this.steiner=!1}function Hf(a){var b=a.length;2Number.EPSILON){var k=Math.sqrt(h),m=Math.sqrt(f*f+g*g);h=b.x-e/k;b=b.y+d/k;g=((c.x-g/m-h)*g-(c.y+f/m-b)*f)/(d*g-e*f);f=h+d*g-a.x;d=b+e*g-a.y;e=f*f+d*d;if(2>=e)return new C(f,d);e=Math.sqrt(e/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?(f=-e,e=Math.sqrt(h)):(f=d,d=e,e=Math.sqrt(h/2));return new C(f/e,d/e)}function h(a,b){for(K=a.length;0<=--K;){var c=K;var f=K-1;0>f&&(f=a.length-1);var g,h=w+2*F;for(g=0;gr;r++){var l=m[f[r]];var n=m[f[(r+1)%3]];d[0]=Math.min(l,n);d[1]=Math.max(l,n);l=d[0]+","+d[1];void 0===e[l]?e[l]={index1:d[0],index2:d[1],face1:h,face2:void 0}:e[l].face2=h}for(l in e)if(d=e[l],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new D(c,3))}function Jb(a,b,c,d, +e,f,g,h){Q.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new eb(a,b,c,d,e,f,g,h));this.mergeVertices()}function eb(a,b,c,d,e,f,g,h){function k(c){var e,f=new C,k=new n,p=0,v=!0===c?a:b,w=!0===c?1:-1;var D=q;for(e=1;e<=d;e++)l.push(0,y*w,0),u.push(0,w,0),t.push(.5,.5),q++;var B=q;for(e=0;e<=d;e++){var E=e/d*h+g,G=Math.cos(E);E=Math.sin(E);k.x=v*E;k.y=y*w; +k.z=v*G;l.push(k.x,k.y,k.z);u.push(0,w,0);f.x=.5*G+.5;f.y=.5*E*w+.5;t.push(f.x,f.y);q++}for(e=0;ethis.duration&&this.resetDuration()}function uh(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return qc;case "vector":case "vector2":case "vector3":case "vector4":return rc; +case "color":return Md;case "quaternion":return pd;case "bool":case "boolean":return Ld;case "string":return Od}throw Error("THREE.KeyframeTrack: Unsupported typeName: "+a);}function vh(a){if(void 0===a.type)throw Error("THREE.KeyframeTrack: track type undefined, can not parse");var b=uh(a.type);if(void 0===a.times){var c=[],d=[];ta.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)}function we(a,b,c){var d=this,e= +!1,f=0,g=0,h=void 0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)};this.resolveURL=function(a){return h?h(a):a};this.setURLModifier=function(a){h=a;return this}}function La(a){this.manager=void 0!==a?a:Aa}function Lf(a){this.manager= +void 0!==a?a:Aa}function Mf(a){this.manager=void 0!==a?a:Aa;this._parser=null}function xe(a){this.manager=void 0!==a?a:Aa;this._parser=null}function qd(a){this.manager=void 0!==a?a:Aa}function ye(a){this.manager=void 0!==a?a:Aa}function Pd(a){this.manager=void 0!==a?a:Aa}function N(){this.type="Curve";this.arcLengthDivisions=200}function Ba(a,b,c,d,e,f,g,h){N.call(this);this.type="EllipseCurve";this.aX=a||0;this.aY=b||0;this.xRadius=c||1;this.yRadius=d||1;this.aStartAngle=e||0;this.aEndAngle=f||2* +Math.PI;this.aClockwise=g||!1;this.aRotation=h||0}function sc(a,b,c,d,e,f){Ba.call(this,a,b,c,c,d,e,f);this.type="ArcCurve"}function ze(){var a=0,b=0,c=0,d=0;return{initCatmullRom:function(e,f,g,h,k){e=k*(g-e);h=k*(h-f);a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},initNonuniformCatmullRom:function(e,f,g,h,k,m,l){e=((f-e)/k-(g-e)/(k+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+l)+(h-g)/l)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function wa(a,b,c,d){N.call(this); +this.type="CatmullRomCurve3";this.points=a||[];this.closed=b||!1;this.curveType=c||"centripetal";this.tension=d||.5}function Nf(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function rd(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function sd(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}function Ma(a,b,c,d){N.call(this);this.type="CubicBezierCurve";this.v0=a||new C;this.v1=b||new C;this.v2=c||new C;this.v3=d||new C}function $a(a, +b,c,d){N.call(this);this.type="CubicBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n;this.v3=d||new n}function Ca(a,b){N.call(this);this.type="LineCurve";this.v1=a||new C;this.v2=b||new C}function Na(a,b){N.call(this);this.type="LineCurve3";this.v1=a||new n;this.v2=b||new n}function Oa(a,b,c){N.call(this);this.type="QuadraticBezierCurve";this.v0=a||new C;this.v1=b||new C;this.v2=c||new C}function ab(a,b,c){N.call(this);this.type="QuadraticBezierCurve3";this.v0=a||new n;this.v1=b|| +new n;this.v2=c||new n}function Pa(a){N.call(this);this.type="SplineCurve";this.points=a||[]}function fb(){N.call(this);this.type="CurvePath";this.curves=[];this.autoClose=!1}function Qa(a){fb.call(this);this.type="Path";this.currentPoint=new C;a&&this.setFromPoints(a)}function rb(a){Qa.call(this,a);this.uuid=P.generateUUID();this.type="Shape";this.holes=[]}function Z(a,b){G.call(this);this.type="Light";this.color=new B(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0}function Qd(a,b,c){Z.call(this, +a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(G.DefaultUp);this.updateMatrix();this.groundColor=new B(b)}function Rb(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new C(512,512);this.map=null;this.matrix=new O}function Rd(){Rb.call(this,new ja(50,1,.5,500))}function Sd(a,b,c,d,e,f){Z.call(this,a,b);this.type="SpotLight";this.position.copy(G.DefaultUp);this.updateMatrix();this.target=new G;Object.defineProperty(this,"power",{get:function(){return this.intensity* +Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Rd}function Td(a,b,c,d){Z.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new Rb(new ja(90,1,.5,500))}function td(a,b,c,d,e,f){Va.call(this); +this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=void 0!==a?a:-1;this.right=void 0!==b?b:1;this.top=void 0!==c?c:1;this.bottom=void 0!==d?d:-1;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function Ud(){Rb.call(this,new td(-5,5,5,-5,.5,500))}function Vd(a,b){Z.call(this,a,b);this.type="DirectionalLight";this.position.copy(G.DefaultUp);this.updateMatrix();this.target=new G;this.shadow=new Ud}function Wd(a,b){Z.call(this,a,b);this.type="AmbientLight"; +this.castShadow=void 0}function Xd(a,b,c,d){Z.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function Yd(a){this.manager=void 0!==a?a:Aa;this.textures={}}function Zd(){E.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function $d(a,b,c,d){"number"===typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument."));I.call(this,a,b,c);this.meshPerAttribute= +d||1}function Ae(a){this.manager=void 0!==a?a:Aa}function Be(a){this.manager=void 0!==a?a:Aa;this.resourcePath=""}function Ce(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported.");this.manager=void 0!==a?a:Aa;this.options=void 0}function De(){this.type="ShapePath";this.color=new B;this.subPaths=[];this.currentPath=null}function Ee(a){this.type= +"Font";this.data=a}function Of(a){this.manager=void 0!==a?a:Aa}function ud(){}function Fe(a){this.manager=void 0!==a?a:Aa}function ae(){this.coefficients=[];for(var a=0;9>a;a++)this.coefficients.push(new n)}function Ra(a,b){Z.call(this,void 0,b);this.sh=void 0!==a?a:new ae}function Ge(a,b,c){Ra.call(this,void 0,c);a=(new B).set(a);c=(new B).set(b);b=new n(a.r,a.g,a.b);a=new n(c.r,c.g,c.b);c=Math.sqrt(Math.PI);var d=c*Math.sqrt(.75);this.sh.coefficients[0].copy(b).add(a).multiplyScalar(c);this.sh.coefficients[1].copy(b).sub(a).multiplyScalar(d)} +function He(a,b){Ra.call(this,void 0,b);a=(new B).set(a);this.sh.coefficients[0].set(a.r,a.g,a.b).multiplyScalar(2*Math.sqrt(Math.PI))}function Pf(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new ja;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new ja;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1}function Ie(a){this.autoStart=void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function Je(){G.call(this); +this.type="AudioListener";this.context=Ke.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0}function tc(a){G.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty"; +this.filters=[]}function Le(a){tc.call(this,a);this.panner=this.context.createPanner();this.panner.panningModel="HRTF";this.panner.connect(this.gain)}function Me(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)}function Ne(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select; +break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function Qf(a,b,c){c=c||qa.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function qa(a,b,c){this.path=b;this.parsedPath=c||qa.parseTrackName(b);this.node=qa.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Rf(){this.uuid=P.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var a={};this._indicesByUUID= +a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function Sf(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null); +c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function Oe(a){this._root=a;this._initMemoryManager(); +this.time=this._accuIndex=0;this.timeScale=1}function be(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Pe(a,b,c){Cb.call(this,a,b);this.meshPerAttribute=c||1}function Tf(a,b,c,d){this.ray=new ub(a,b);this.near=c||0;this.far=d||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points."); +return this.Points}}})}function Uf(a,b){return a.distance-b.distance}function Qe(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;dc;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 D(b,3));b=new V({fog:!1});this.cone=new R(a,b);this.add(this.cone);this.update()}function Xf(a){var b=[];a&&a.isBone&&b.push(a);for(var c= +0;ca?-1:0b;b++)a[b]=(16>b?"0":"")+b.toString(16);return function(){var b=4294967295*Math.random()|0,d=4294967295*Math.random()|0,e=4294967295* +Math.random()|0,f=4294967295*Math.random()|0;return(a[b&255]+a[b>>8&255]+a[b>>16&255]+a[b>>24&255]+"-"+a[d&255]+a[d>>8&255]+"-"+a[d>>16&15|64]+a[d>>24&255]+"-"+a[e&63|128]+a[e>>8&255]+"-"+a[e>>16&255]+a[e>>24&255]+a[f&255]+a[f>>8&255]+a[f>>16&255]+a[f>>24&255]).toUpperCase()}}(),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)},lerp:function(a,b,c){return(1-c)*a+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)},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*P.DEG2RAD},radToDeg:function(a){return a*P.RAD2DEG},isPowerOfTwo:function(a){return 0===(a&a-1)&&0!==a},ceilPowerOfTwo:function(a){return Math.pow(2, +Math.ceil(Math.log(a)/Math.LN2))},floorPowerOfTwo:function(a){return Math.pow(2,Math.floor(Math.log(a)/Math.LN2))}};Object.defineProperties(C.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(C.prototype,{isVector2:!0,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);}return this},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){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},applyMatrix3:function(a){var b=this.x,c=this.y;a=a.elements;this.x=a[0]*b+a[3]*c+a[6];this.y=a[1]*b+a[4]*c+a[7];return this},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,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},cross:function(a){return this.x*a.y-this.y*a.x},lengthSq:function(){return this.x* +this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||1)},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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+ +Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},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},fromBufferAttribute:function(a, +b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b);b=Math.sin(b);var d=this.x-a.x,e=this.y-a.y;this.x=d*c-e*b+a.x;this.y=d*b+e*c+a.y;return this}});Object.assign(ea,{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 l=e[f+1],p=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==l||m!== +p){f=1-g;var n=h*d+k*l+m*p+c*e,t=0<=n?1:-1,q=1-n*n;q>Number.EPSILON&&(q=Math.sqrt(q),n=Math.atan2(q,n*t),f=Math.sin(f*n)/q,g=Math.sin(g*n)/q);t*=g;h=h*f+d*t;k=k*f+l*t;m=m*f+p*t;c=c*f+e*t;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;a[b+3]=c}});Object.defineProperties(ea.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z}, +set:function(a){this._z=a;this._onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this._onChangeCallback()}}});Object.assign(ea.prototype,{isQuaternion:!0,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(!a|| +!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z;a=a.order;var f=Math.cos,g=Math.sin,h=f(c/2),k=f(d/2);f=f(e/2);c=g(c/2);d=g(d/2);e=g(e/2);"XYZ"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f-c*d*e):"YXZ"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f+c*d*e):"ZXY"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e+c*d*f,this._w= +h*k*f-c*d*e):"ZYX"===a?(this._x=c*k*f-h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f+c*d*e):"YZX"===a?(this._x=c*k*f+h*d*e,this._y=h*d*f+c*k*e,this._z=h*k*e-c*d*f,this._w=h*k*f-c*d*e):"XZY"===a&&(this._x=c*k*f-h*d*e,this._y=h*d*f-c*k*e,this._z=h*k*e+c*d*f,this._w=h*k*f+c*d*e);!1!==b&&this._onChangeCallback();return this},setFromAxisAngle:function(a,b){b/=2;var c=Math.sin(b);this._x=a.x*c;this._y=a.y*c;this._z=a.z*c;this._w=Math.cos(b);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];var 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(a, +b){var c=a.dot(b)+1;1E-6>c?(c=0,Math.abs(a.x)>Math.abs(a.z)?(this._x=-a.y,this._y=a.x,this._z=0):(this._x=0,this._y=-a.z,this._z=a.y)):(this._x=a.y*b.z-a.z*b.y,this._y=a.z*b.x-a.x*b.z,this._z=a.x*b.y-a.y*b.x);this._w=c;return this.normalize()},angleTo:function(a){return 2*Math.acos(Math.abs(P.clamp(this.dot(a),-1,1)))},rotateTowards:function(a,b){var c=this.angleTo(a);if(0===c)return this;this.slerp(a,Math.min(1,b/c));return this},inverse:function(){return this.conjugate()},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)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z;a=a._w;var f=b._x,g=b._y,h=b._z;b=b._w;this._x=c*b+a*f+d*h-e*g;this._y=d*b+a*g+e*f-c*h;this._z=e*b+a*h+c*g-d*f;this._w=a*b-c*f-d*g-e*h;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;a=1-g*g;if(a<=Number.EPSILON)return g=1-b,this._w=g*f+b*this._w,this._x=g*c+b*this._x,this._y=g*d+b*this._y,this._z=g*e+b*this._z,this.normalize(),this._onChangeCallback(),this;a=Math.sqrt(a);var h=Math.atan2(a, +g);g=Math.sin((1-b)*h)/a;b=Math.sin(b*h)/a;this._w=f*g+this._w*b;this._x=c*g+this._x*b;this._y=d*g+this._y*b;this._z=e*g+this._z*b;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(n.prototype,{isVector3:!0,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);}return this},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){this.x*=a;this.y*=a;this.z*=a;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=new ea; +return function(b){b&&b.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(a.setFromEuler(b))}}(),applyAxisAngle:function(){var a=new ea;return function(b,c){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;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(a){return this.applyMatrix4(a.matrixWorldInverse).applyMatrix4(a.projectionMatrix)}, +unproject:function(a){return this.applyMatrix4(a.projectionMatrixInverse).applyMatrix4(a.matrixWorld)},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(a,b){this.x=Math.max(a,Math.min(b,this.x));this.y=Math.max(a,Math.min(b,this.y));this.z=Math.max(a,Math.min(b,this.z));return this},clampLength:function(a,b){var c=this.length();return this.divideScalar(c|| +1).multiplyScalar(Math.max(a,Math.min(b,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)},manhattanLength:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)}, +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){return void 0!==b?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(a,b)):this.crossVectors(this,a)},crossVectors:function(a,b){var c=a.x,d=a.y;a=a.z;var e=b.x,f=b.y;b=b.z;this.x=d*b-a*f;this.y=a*e-c*b;this.z=c*f-d*e;return this}, +projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(){var a=new n;return function(b){a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a=new n;return function(b){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(P.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},manhattanDistanceTo:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){return this.setFromSphericalCoords(a.radius,a.phi,a.theta)},setFromSphericalCoords:function(a,b,c){var d=Math.sin(b)*a;this.x=d*Math.sin(c);this.y=Math.cos(b)*a;this.z=d*Math.cos(c);return this},setFromCylindrical:function(a){return this.setFromCylindricalCoords(a.radius,a.theta,a.y)},setFromCylindricalCoords:function(a, +b,c){this.x=a*Math.sin(b);this.y=c;this.z=a*Math.cos(b);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},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){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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});Object.assign(ia.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,k){var m=this.elements;m[0]=a; +m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=k;return this},identity:function(){this.set(1,0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToBufferAttribute:function(){var a= +new n;return function(b){for(var c=0,d=b.count;cc;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];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];return a}});var Cc,sb={getDataURL:function(a){if("undefined"==typeof HTMLCanvasElement)return a.src;if(!(a instanceof HTMLCanvasElement)){void 0===Cc&&(Cc=document.createElementNS("http://www.w3.org/1999/xhtml", +"canvas"));Cc.width=a.width;Cc.height=a.height;var b=Cc.getContext("2d");a instanceof ImageData?b.putImageData(a,0,0):b.drawImage(a,0,0,a.width,a.height);a=Cc}return 2048a.x||1a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y);return a}});Object.defineProperty(X.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.defineProperties(ba.prototype,{width:{get:function(){return this.z},set:function(a){this.z=a}},height:{get:function(){return this.w},set:function(a){this.w=a}}});Object.assign(ba.prototype,{isVector4:!0,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);}return this},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){this.x*=a;this.y*=a;this.z*=a;this.w*=a;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/ @@ -381,51 +380,192 @@ c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c 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)},manhattanLength: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()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},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){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},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute()."); -this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});Ta.prototype=Object.assign(Object.create(Ca.prototype),{constructor:Ta,isWebGLRenderTarget:!0,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"})}});he.prototype=Object.assign(Object.create(Ta.prototype),{constructor:he,isWebGLMultisampleRenderTarget:!0,copy:function(a){Ta.prototype.copy.call(this,a);this.samples=a.samples;return this}});rb.prototype=Object.create(Ta.prototype);rb.prototype.constructor=rb;rb.prototype.isWebGLRenderTargetCube=!0;sb.prototype=Object.create(X.prototype); -sb.prototype.constructor=sb;sb.prototype.isDataTexture=!0;Object.assign(Ha.prototype,{isBox3:!0,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=m);l>f&&(f=l);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity, -d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.count;he&&(e=m);l>f&&(f=l);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.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},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.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=new n;return function(b){this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(){function a(a){var e;var f=0;for(e=a.length-3;f<=e;f+=3){h.fromArray(a,f);var g=m.x*Math.abs(h.x)+m.y*Math.abs(h.y)+m.z*Math.abs(h.z),k=b.dot(h),l=c.dot(h),q=d.dot(h);if(Math.max(-Math.max(k,l,q),Math.min(k,l,q))>g)return!1}return!0}var b=new n,c=new n,d=new n,e=new n,f=new n,g=new n,h=new n, -k=new n,m=new n,l=new n;return function(h){if(this.isEmpty())return!1;this.getCenter(k);m.subVectors(this.max,k);b.subVectors(h.a,k);c.subVectors(h.b,k);d.subVectors(h.c,k);e.subVectors(c,b);f.subVectors(d,c);g.subVectors(b,d);h=[0,-e.z,e.y,0,-f.z,f.y,0,-g.z,g.y,e.z,0,-e.x,f.z,0,-f.x,g.z,0,-g.x,-e.y,e.x,0,-f.y,f.x,0,-g.y,g.x,0];if(!a(h))return!1;h=[1,0,0,0,1,0,0,0,1];if(!a(h))return!1;l.crossVectors(e,f);h=[l.x,l.y,l.z];return a(h)}}(),clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"), -b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new n;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new n;return function(b){void 0===b&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(b.center);b.radius=.5*this.getSize(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 n,new n,new n,new n,new n,new n,new n,new n];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)}});Object.assign(Ua.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(){var a=new Ha;return function(b,c){var d=this.center;void 0!==c?d.copy(c):a.setFromPoints(b).getCenter(d); -for(var e=c=0,f=b.length;e=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(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a);void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0=== -a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"),a=new Ha);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}});Object.assign(Va.prototype,{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 n,b=new n;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){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(){var a= -new n;return function(b,c){void 0===c&&(console.warn("THREE.Plane: .intersectLine() target is now required"),c=new n);var d=b.delta(a),e=this.normal.dot(d);if(0===e){if(0===this.distanceToPoint(b.start))return c.copy(b.start)}else if(e=-(b.start.dot(this.normal)+this.constant)/e,!(0>e||1b&&0a&&0this.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.copy(this);c=1/g;f=1/h;var 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}}(),makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); +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/(c-d);g[9]=(c+d)/(c-d);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},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),k=1/(c-d),m=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*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,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];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}});tb.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" "); +tb.DefaultOrder="XYZ";Object.defineProperties(tb.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this._onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this._onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this._onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;this._onChangeCallback()}}});Object.assign(tb.prototype,{isEuler:!0,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=P.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],m=e[9],l=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(-l,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(-l,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(l,-1,1)),.99999>Math.abs(l)?(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(-l,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;!1!==c&&this._onChangeCallback();return this},setFromQuaternion:function(){var a=new O;return function(b, +c,d){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 ea;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 n(this._x,this._y,this._z)},_onChange:function(a){this._onChangeCallback=a;return this},_onChangeCallback:function(){}});Object.assign(ie.prototype,{set:function(a){this.mask=1<e&&(e=m);l>f&&(f=l);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.count;he&&(e=m);l>f&&(f=l);p>g&&(g=p)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;bthis.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},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box3: .getParameter() target is now required"),b=new n);return b.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=new n;return function(b){this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){if(0=-a.constant},intersectsTriangle:function(){function a(a){var e;var f=0;for(e=a.length-3;f<=e;f+=3){h.fromArray(a,f);var g=m.x*Math.abs(h.x)+m.y*Math.abs(h.y)+m.z*Math.abs(h.z),k=b.dot(h),l=c.dot(h),r=d.dot(h);if(Math.max(-Math.max(k,l,r),Math.min(k,l,r))>g)return!1}return!0}var b=new n,c=new n,d=new n,e=new n,f=new n,g=new n,h=new n,k=new n,m=new n,l=new n;return function(h){if(this.isEmpty())return!1;this.getCenter(k);m.subVectors(this.max, +k);b.subVectors(h.a,k);c.subVectors(h.b,k);d.subVectors(h.c,k);e.subVectors(c,b);f.subVectors(d,c);g.subVectors(b,d);h=[0,-e.z,e.y,0,-f.z,f.y,0,-g.z,g.y,e.z,0,-e.x,f.z,0,-f.x,g.z,0,-g.x,-e.y,e.x,0,-f.y,f.x,0,-g.y,g.x,0];if(!a(h))return!1;h=[1,0,0,0,1,0,0,0,1];if(!a(h))return!1;l.crossVectors(e,f);h=[l.x,l.y,l.z];return a(h)}}(),clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box3: .clampPoint() target is now required"),b=new n);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a= +new n;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new n;return function(b){void 0===b&&console.error("THREE.Box3: .getBoundingSphere() target is now required");this.getCenter(b.center);b.radius=.5*this.getSize(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 n,new n,new n,new n,new n,new n,new n,new n];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)}});Object.assign(Ua.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(){var a=new Ha;return function(b,c){var d=this.center;void 0!==c?d.copy(c):a.setFromPoints(b).getCenter(d);for(var e=c=0,f=b.length;e=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(a.distanceToPoint(this.center))<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a);void 0===b&&(console.warn("THREE.Sphere: .clampPoint() target is now required"),b=new n);b.copy(a);c>this.radius*this.radius&&(b.sub(this.center).normalize(),b.multiplyScalar(this.radius).add(this.center));return b},getBoundingBox:function(a){void 0===a&&(console.warn("THREE.Sphere: .getBoundingBox() target is now required"), +a=new Ha);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}});Object.assign(ub.prototype,{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){void 0===b&&(console.warn("THREE.Ray: .at() target is now required"),b=new n);return b.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 n;return function(b){this.origin.copy(this.at(b,a));return this}}(),closestPointToPoint:function(a,b){void 0===b&&(console.warn("THREE.Ray: .closestPointToPoint() target is now required"), +b=new n);b.subVectors(a,this.origin);a=b.dot(this.direction);return 0>a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)},distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new n;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 n,b=new n,c=new n;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),l=-c.dot(b),p=c.lengthSq(),n=Math.abs(1-k*k);if(0=-t?e<=t?(h=1/n,d*=h,e*=h,k=d*(d+k*e+2*m)+e*(k*d+e+2*l)+p):(e=h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+p):(e=-h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+p):e<=-t?(d=Math.max(0,-(-k*h+m)),e=0b)return null; +b=Math.sqrt(b-e);e=d-b;d+=b;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<=a.radius*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){a=this.distanceToPlane(a);return null===a?null:this.at(a,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=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z,f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y-f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null; +if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(){var a=new n;return function(b){return null!==this.intersectBox(b,a)}}(),intersectTriangle:function(){var a=new n,b=new n,c=new n,d=new n;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null; +g=h*this.direction.dot(b.cross(a));if(0>g||e+g>f)return null;e=-h*a.dot(d);return 0>e?null:this.at(e/f,k)}}(),applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});Object.assign(ha,{getNormal:function(){var a=new n;return function(b,c,d,e){void 0===e&&(console.warn("THREE.Triangle: .getNormal() target is now required"),e=new n);e.subVectors(d,c);a.subVectors(b, +c);e.cross(a);b=e.lengthSq();return 0=a.x+a.y}}(),getUV:function(){var a=new n;return function(b,c,d,e,f,g,h,k){this.getBarycoord(b,c,d,e,a);k.set(0,0);k.addScaledVector(f,a.x);k.addScaledVector(g,a.y);k.addScaledVector(h,a.z);return k}}(),isFrontFacing:function(){var a=new n,b=new n;return function(c,d,e,f){a.subVectors(e,d);b.subVectors(c,d);return 0>a.cross(b).dot(f)?!0:!1}}()});Object.assign(ha.prototype,{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},getArea:function(){var a=new n,b=new n;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"), +a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return ha.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new n);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return ha.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return ha.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return ha.containsPoint(a, +this.a,this.b,this.c)},isFrontFacing:function(a){return ha.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(){var a=new n,b=new n,c=new n,d=new n,e=new n,f=new n;return function(g,h){void 0===h&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),h=new n);var k=this.a,m=this.b,l=this.c;a.subVectors(m,k);b.subVectors(l,k);d.subVectors(g,k);var p=a.dot(d),u=b.dot(d);if(0>=p&&0>=u)return h.copy(k); +e.subVectors(g,m);var t=a.dot(e),q=b.dot(e);if(0<=t&&q<=t)return h.copy(m);var v=p*q-t*u;if(0>=v&&0<=p&&0>=t)return m=p/(p-t),h.copy(k).addScaledVector(a,m);f.subVectors(g,l);g=a.dot(f);var y=b.dot(f);if(0<=y&&g<=y)return h.copy(l);p=g*u-p*y;if(0>=p&&0<=u&&0>=y)return v=u/(u-y),h.copy(k).addScaledVector(b,v);u=t*y-g*q;if(0>=u&&0<=q-t&&0<=g-y)return c.subVectors(l,m),v=(q-t)/(q-t+(g-y)),h.copy(m).addScaledVector(c,v);l=1/(u+p+v);m=p*l;v*=l;return h.copy(k).addScaledVector(a,m).addScaledVector(b,v)}}(), +equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}});var wh={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017, +darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671, +gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753, +lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739, +orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944, +slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Object.assign(B.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a= +Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(a,b,c){a=P.euclideanModulo(a,1);b=P.clamp(b,0,1);c=P.clamp(c,0,1);0===b?this.r=this.g=this.b=c:(b=.5>=c?c*(1+b):c+b-c*b,c=2*c-b,this.r=je(c,b,a+1/3),this.g=je(c,b,a),this.b=je(c,b,a-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)){d=parseFloat(c[1])/360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this; +if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c-d)/k+(cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;this.rotation&&0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&& +(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);this.linewidth&&1!==this.linewidth&&(d.linewidth=this.linewidth);void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize);void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0c.far?null:{distance:b, +point:w.clone(),object:a}}function b(b,c,d,e,r,n,w,D,B,E){f.fromBufferAttribute(r,D);g.fromBufferAttribute(r,B);h.fromBufferAttribute(r,E);r=b.morphTargetInfluences;if(c.morphTargets&&n&&r){p.set(0,0,0);u.set(0,0,0);t.set(0,0,0);for(var H=0,x=n.length;Hg;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;c\n\t#include \n}",fragmentShader:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}", +side:1,blending:0});d.uniforms.tEquirect.value=b;b=new ra(new ib(5,5,5),d);c.add(b);d=new Vb(1,10,1);d.renderTarget=this;d.renderTarget.texture.name="CubeCameraTexture";d.update(a,c);b.geometry.dispose();b.material.dispose();return this};Ab.prototype=Object.create(X.prototype);Ab.prototype.constructor=Ab;Ab.prototype.isDataTexture=!0;Object.assign(Wa.prototype,{isPlane:!0,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 n,b=new n;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){void 0===b&&(console.warn("THREE.Plane: .projectPoint() target is now required"),b=new n);return b.copy(this.normal).multiplyScalar(-this.distanceToPoint(a)).add(a)},intersectLine:function(){var a=new n; +return function(b,c){void 0===c&&(console.warn("THREE.Plane: .intersectLine() target is now required"),c=new n);var d=b.delta(a),e=this.normal.dot(d);if(0===e){if(0===this.distanceToPoint(b.start))return c.copy(b.start)}else if(e=-(b.start.dot(this.normal)+this.constant)/e,!(0>e||1b&&0a&&0c;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],l=c[8],p=c[9],n=c[10],t=c[11],r=c[12],u=c[13],w=c[14];c=c[15];b[0].setComponents(f-a,m-g,t-l,c-r).normalize();b[1].setComponents(f+a,m+g,t+l,c+r).normalize();b[2].setComponents(f+d,m+h,t+p,c+u).normalize();b[3].setComponents(f-d,m-h,t-p,c-u).normalize();b[4].setComponents(f-e,m-k,t-n,c-w).normalize();b[5].setComponents(f+e,m+k,t+n,c+w).normalize();return this},intersectsObject:function(){var a=new Ua;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere(); +return this},equals:function(a){return a.normal.equals(this.normal)&&a.constant===this.constant}});Object.assign(Cd.prototype,{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],l=c[8],p=c[9],n=c[10],t=c[11],q=c[12],v=c[13],y=c[14];c=c[15];b[0].setComponents(f-a,m-g,t-l,c-q).normalize();b[1].setComponents(f+a,m+g,t+l,c+q).normalize();b[2].setComponents(f+d,m+h,t+p,c+v).normalize();b[3].setComponents(f-d,m-h,t-p,c-v).normalize();b[4].setComponents(f-e,m-k,t-n,c-y).normalize();b[5].setComponents(f+e,m+k,t+n,c+y).normalize();return this},intersectsObject:function(){var a=new Ua;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 Ua;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)d;d++){var e=c[d]; -a.x=0e.distanceToPoint(a))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}});Object.assign(O.prototype,{isMatrix4:!0,set:function(a,b,c,d,e,f,g,h,k,m,l,p,n,t,r,u){var q=this.elements;q[0]=a;q[4]=b;q[8]=c;q[12]=d;q[1]=e;q[5]=f;q[9]=g;q[13]=h;q[2]=k;q[6]=m;q[10]=l;q[14]=p;q[3]=n;q[7]=t;q[11]=r;q[15]=u;return this},identity:function(){this.set(1, -0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new O).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},copyPosition:function(a){var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){a.setFromMatrixColumn(this,0); -b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(){var a=new n;return function(b){var c=this.elements,d=b.elements,e=1/a.setFromMatrixColumn(b,0).length(),f=1/a.setFromMatrixColumn(b,1).length();b=1/a.setFromMatrixColumn(b,2).length();c[0]=d[0]*e;c[1]=d[1]*e;c[2]=d[2]*e;c[3]=0;c[4]=d[4]*f;c[5]=d[5]*f;c[6]=d[6]*f;c[7]=0;c[8]=d[8]*b;c[9]=d[9]*b;c[10]=d[10]* -b;c[11]=0;c[12]=0;c[13]=0;c[14]=0;c[15]=1;return this}}(),makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c);c=Math.sin(c);var g=Math.cos(d);d=Math.sin(d);var h=Math.cos(e);e=Math.sin(e);if("XYZ"===a.order){a=f*h;var k=f*e,m=c*h,l=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=k+m*d;b[5]=a-l*d;b[9]=-c*g;b[2]=l-a*d;b[6]=m+k*d;b[10]=f*g}else"YXZ"=== -a.order?(a=g*h,k=g*e,m=d*h,l=d*e,b[0]=a+l*c,b[4]=m*c-k,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=k*c-m,b[6]=l+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,k=g*e,m=d*h,l=d*e,b[0]=a-l*c,b[4]=-f*e,b[8]=m+k*c,b[1]=k+m*c,b[5]=f*h,b[9]=l-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,k=f*e,m=c*h,l=c*e,b[0]=g*h,b[4]=m*d-k,b[8]=a*d+l,b[1]=g*e,b[5]=l*d+a,b[9]=k*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,k=f*d,m=c*g,l=c*d,b[0]=g*h,b[4]=l-a*e,b[8]=m*e+k,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=k* -e+m,b[10]=a-l*e):"XZY"===a.order&&(a=f*g,k=f*d,m=c*g,l=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+l,b[5]=f*h,b[9]=k*e-m,b[2]=m*e-k,b[6]=c*h,b[10]=l*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(){var a=new n(0,0,0),b=new n(1,1,1);return function(c){return this.compose(a,c,b)}}(),lookAt:function(){var a=new n,b=new n,c=new n;return function(d,e,f){var g=this.elements;c.subVectors(d,e);0===c.lengthSq()&&(c.z=1);c.normalize();a.crossVectors(f, -c);0===a.lengthSq()&&(1===Math.abs(f.z)?c.x+=1E-4:c.z+=1E-4,c.normalize(),a.crossVectors(f,c));a.normalize();b.crossVectors(c,a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)}, -multiplyMatrices:function(a,b){var c=a.elements,d=b.elements;b=this.elements;a=c[0];var e=c[4],f=c[8],g=c[12],h=c[1],k=c[5],m=c[9],l=c[13],p=c[2],n=c[6],t=c[10],r=c[14],u=c[3],w=c[7],z=c[11];c=c[15];var y=d[0],x=d[4],A=d[8],G=d[12],D=d[1],C=d[5],F=d[9],B=d[13],E=d[2],H=d[6],I=d[10],J=d[14],L=d[3],N=d[7],R=d[11];d=d[15];b[0]=a*y+e*D+f*E+g*L;b[4]=a*x+e*C+f*H+g*N;b[8]=a*A+e*F+f*I+g*R;b[12]=a*G+e*B+f*J+g*d;b[1]=h*y+k*D+m*E+l*L;b[5]=h*x+k*C+m*H+l*N;b[9]=h*A+k*F+m*I+l*R;b[13]=h*G+k*B+m*J+l*d;b[2]=p*y+n* -D+t*E+r*L;b[6]=p*x+n*C+t*H+r*N;b[10]=p*A+n*F+t*I+r*R;b[14]=p*G+n*B+t*J+r*d;b[3]=u*y+w*D+z*E+c*L;b[7]=u*x+w*C+z*H+c*N;b[11]=u*A+w*F+z*I+c*R;b[15]=u*G+w*B+z*J+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},applyToBufferAttribute:function(){var a=new n;return function(b){for(var c=0,d=b.count;cthis.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.copy(this);c=1/g;f=1/h;var 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}}(),makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs."); -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/(c-d);g[9]=(c+d)/(c-d);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},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),k=1/(c-d),m=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*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,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];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}});var U={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif", -alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif", -aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn 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\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn 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\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}", +a.x=0e.distanceToPoint(a))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}});var U={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif", +aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif",aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif", +begin_vertex:"vec3 transformed = vec3( position );",beginnormal_vertex:"vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif",bsdfs:"vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn 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\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn 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\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}", bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif", clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t#endif\n#endif", clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvarying vec3 vViewPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG ) && ! defined( MATCAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif", @@ -456,11 +596,11 @@ normal_fragment_maps:"#ifdef USE_NORMALMAP\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\t normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\t#ifdef OBJECTSPACE_NORMALMAP\n\t\tuniform mat3 normalMatrix;\n\t#else\n\t\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\t\tvec2 st0 = dFdx( vUv.st );\n\t\t\tvec2 st1 = dFdy( vUv.st );\n\t\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\t\tvec3 N = normalize( surf_norm );\n\t\t\tmat3 tsn = mat3( S, T, N );\n\t\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\t\tmapN.xy *= normalScale;\n\t\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\treturn normalize( tsn * mapN );\n\t\t}\n\t#endif\n#endif", packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\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\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}", premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#if defined( DITHERING )\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif", -roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", +roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif", shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif", shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif", shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\t#pragma unroll_loop\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}", -skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif", +skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform highp sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif", skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif", specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n\t#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn 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\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );\n}", uv_pars_fragment:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif", @@ -484,454 +624,318 @@ meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nun 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 \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\t#include \n}", meshphysical_frag:"#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\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 \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\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\t#include \n}", meshphysical_vert:"#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\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\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\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}", -normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", -normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\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#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", +normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\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\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}", +normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\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#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || ( defined( USE_NORMALMAP ) && ! defined( OBJECTSPACE_NORMALMAP ) )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}", points_frag:"uniform vec3 diffuse;\nuniform float opacity;\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}", points_vert:"uniform float size;\nuniform float scale;\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\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}", shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n}",shadow_vert:"#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}", sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\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\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include \n\t#include \n\t#include \n}", sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}"}, -sh={clone:Sb,merge:wa},th={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643, -darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055, -grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184, -lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130, -palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780, -teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};Object.assign(B.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255; -return this},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=P.euclideanModulo(b,1);c=P.clamp(c,0,1);d=P.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)){d=parseFloat(c[1])/360;var e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2), -16)/255,this;if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0a?.0773993808*a:Math.pow(.9478672986*a+.0521327014,2.4)}return function(b){this.r=a(b.r);this.g=a(b.g);this.b= -a(b.b);return this}}(),copyLinearToSRGB:function(){function a(a){return.0031308>a?12.92*a:1.055*Math.pow(a,.41666)-.055}return function(b){this.r=a(b.r);this.g=a(b.g);this.b=a(b.b);return this}}(),convertSRGBToLinear:function(){this.copySRGBToLinear(this);return this},convertLinearToSRGB:function(){this.copyLinearToSRGB(this);return this},getHex:function(){return 255*this.r<<16^255*this.g<<8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(a){void 0=== -a&&(console.warn("THREE.Color: .getHSL() target is now required"),a={h:0,s:0,l:0});var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),f=Math.min(b,c,d),g,h=(f+e)/2;if(f===e)f=g=0;else{var k=e-f;f=.5>=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c-d)/k+(cMath.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(-l,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(p,-1,1)),.99999>Math.abs(p)?(this._y=Math.atan2(-l,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(l, --1,1)),.99999>Math.abs(l)?(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(-l,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=new O;return function(b,c,d){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 ea;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 n(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}});Object.assign(je.prototype,{set:function(a){this.mask=1<g;g++)if(d[g]===d[(g+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(d=a[f],this.faces.splice(d,1),c=0,e=this.faceVertexUvs.length;cthis.opacity&&(d.opacity=this.opacity);!0===this.transparent&& -(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;0!==this.rotation&&(d.rotation=this.rotation);!0===this.polygonOffset&&(d.polygonOffset=!0);0!==this.polygonOffsetFactor&&(d.polygonOffsetFactor=this.polygonOffsetFactor);0!==this.polygonOffsetUnits&&(d.polygonOffsetUnits=this.polygonOffsetUnits);1!==this.linewidth&&(d.linewidth=this.linewidth);void 0!==this.dashSize&&(d.dashSize=this.dashSize);void 0!==this.gapSize&&(d.gapSize=this.gapSize); -void 0!==this.scale&&(d.scale=this.scale);!0===this.dithering&&(d.dithering=!0);0a?b.copy(this.origin):b.copy(this.direction).multiplyScalar(a).add(this.origin)}, -distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new n;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 n,b=new n,c=new n;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),l=-c.dot(b),p=c.lengthSq(),n=Math.abs(1-k*k);if(0=-t?e<=t?(h=1/n,d*=h,e*=h,k=d*(d+k*e+2*m)+e*(k*d+e+2*l)+p):(e=h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+p):(e=-h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*l)+p):e<=-t?(d=Math.max(0,-(-k*h+m)),e=0b)return null;b=Math.sqrt(b-e);e=d-b;d+=b;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceSqToPoint(a.center)<= -a.radius*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){a=this.distanceToPlane(a);return null===a?null:this.at(a,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=1/this.direction.x;var d=1/this.direction.y;var e=1/this.direction.z, -f=this.origin;if(0<=c){var g=(a.min.x-f.x)*c;c*=a.max.x-f.x}else g=(a.max.x-f.x)*c,c*=a.min.x-f.x;if(0<=d){var h=(a.min.y-f.y)*d;d*=a.max.y-f.y}else h=(a.max.y-f.y)*d,d*=a.min.y-f.y;if(g>d||h>c)return null;if(h>g||g!==g)g=h;if(da||h>c)return null;if(h>g||g!==g)g=h;if(ac?null:this.at(0<=g?g:c,b)},intersectsBox:function(){var a=new n;return function(b){return null!==this.intersectBox(b, -a)}}(),intersectTriangle:function(){var a=new n,b=new n,c=new n,d=new n;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null;g=h*this.direction.dot(b.cross(a));if(0>g||e+g>f)return null;e=-h*a.dot(d);return 0>e?null:this.at(e/f,k)}}(),applyMatrix4:function(a){this.origin.applyMatrix4(a); -this.direction.transformDirection(a);return this},equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});Object.assign(ta,{getNormal:function(){var a=new n;return function(b,c,d,e){void 0===e&&(console.warn("THREE.Triangle: .getNormal() target is now required"),e=new n);e.subVectors(d,c);a.subVectors(b,c);e.cross(a);b=e.lengthSq();return 0=a.x+a.y}}(),getUV:function(){var a=new n;return function(b,c,d, -e,f,g,h,k){this.getBarycoord(b,c,d,e,a);k.set(0,0);k.addScaledVector(f,a.x);k.addScaledVector(g,a.y);k.addScaledVector(h,a.z);return k}}(),isFrontFacing:function(){var a=new n,b=new n;return function(c,d,e,f){a.subVectors(e,d);b.subVectors(c,d);return 0>a.cross(b).dot(f)?!0:!1}}()});Object.assign(ta.prototype,{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},getArea:function(){var a=new n,b=new n;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),getMidpoint:function(a){void 0===a&&(console.warn("THREE.Triangle: .getMidpoint() target is now required"),a=new n);return a.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},getNormal:function(a){return ta.getNormal(this.a,this.b,this.c,a)},getPlane:function(a){void 0=== -a&&(console.warn("THREE.Triangle: .getPlane() target is now required"),a=new n);return a.setFromCoplanarPoints(this.a,this.b,this.c)},getBarycoord:function(a,b){return ta.getBarycoord(a,this.a,this.b,this.c,b)},getUV:function(a,b,c,d,e){return ta.getUV(a,this.a,this.b,this.c,b,c,d,e)},containsPoint:function(a){return ta.containsPoint(a,this.a,this.b,this.c)},isFrontFacing:function(a){return ta.isFrontFacing(this.a,this.b,this.c,a)},intersectsBox:function(a){return a.intersectsTriangle(this)},closestPointToPoint:function(){var a= -new n,b=new n,c=new n,d=new n,e=new n,f=new n;return function(g,h){void 0===h&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),h=new n);var k=this.a,m=this.b,l=this.c;a.subVectors(m,k);b.subVectors(l,k);d.subVectors(g,k);var p=a.dot(d),v=b.dot(d);if(0>=p&&0>=v)return h.copy(k);e.subVectors(g,m);var t=a.dot(e),r=b.dot(e);if(0<=t&&r<=t)return h.copy(m);var u=p*r-t*v;if(0>=u&&0<=p&&0>=t)return m=p/(p-t),h.copy(k).addScaledVector(a,m);f.subVectors(g,l);g=a.dot(f);var w= -b.dot(f);if(0<=w&&g<=w)return h.copy(l);p=g*v-p*w;if(0>=p&&0<=v&&0>=w)return u=v/(v-w),h.copy(k).addScaledVector(b,u);v=t*w-g*r;if(0>=v&&0<=r-t&&0<=g-w)return c.subVectors(l,m),u=(r-t)/(r-t+(g-w)),h.copy(m).addScaledVector(c,u);l=1/(v+p+u);m=p*l;u*=l;return h.copy(k).addScaledVector(a,m).addScaledVector(b,u)}}(),equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}});ka.prototype=Object.create(L.prototype);ka.prototype.constructor=ka;ka.prototype.isMeshBasicMaterial= -!0;ka.prototype.copy=function(a){L.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap; -this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;return this};ha.prototype=Object.assign(Object.create(H.prototype),{constructor:ha,isMesh:!0,setDrawMode:function(a){this.drawMode=a},copy:function(a){H.prototype.copy.call(this,a);this.drawMode=a.drawMode;void 0!==a.morphTargetInfluences&&(this.morphTargetInfluences=a.morphTargetInfluences.slice());void 0!==a.morphTargetDictionary&&(this.morphTargetDictionary=Object.assign({},a.morphTargetDictionary)); -return this},updateMorphTargets:function(){var a=this.geometry;if(a.isBufferGeometry){a=a.morphAttributes;var b=Object.keys(a);if(0c.far?null:{distance:b,point:y.clone(),object:a}}function b(b,c,d,e,q,n,y,C,B,E){f.fromBufferAttribute(q,C);g.fromBufferAttribute(q,B);h.fromBufferAttribute(q,E);q=b.morphTargetInfluences;if(c.morphTargets&&n&&q){p.set(0,0,0);v.set(0,0,0);t.set(0,0,0);for(var x= -0,G=n.length;xe.far||f.push({distance:r,point:b.clone(),uv:ta.getUV(b,h,k,m,l,p,v,new D),face:null,object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)}, -copy:function(a){H.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});Oc.prototype=Object.assign(Object.create(H.prototype),{constructor:Oc,isLOD:!0,copy:function(a){H.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;ef||(l.applyMatrix4(this.matrixWorld), -u=d.ray.origin.distanceTo(l),ud.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}else for(g=0,r=t.length/3-1;gf||(l.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(l),ud.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g.isGeometry)for(k= -g.vertices,m=k.length,g=0;gf||(l.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(l),ud.far||e.push({distance:u,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)}});S.prototype=Object.assign(Object.create(T.prototype),{constructor:S,isLineSegments:!0,computeLineDistances:function(){var a=new n, -b=new n;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[],f=0,g=d.count;fd.far||e.push({distance:a,distanceToRay:Math.sqrt(f),point:p.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); -c.radius+=m;if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);m/=(this.scale.x+this.scale.y+this.scale.z)/3;var l=m*m;m=new n;var p=new n;if(h.isBufferGeometry){var v=h.index;h=h.attributes.position.array;if(null!==v){var t=v.array;v=0;for(var r=t.length;v=a.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}});ac.prototype=Object.create(X.prototype);ac.prototype.constructor=ac;ac.prototype.isCompressedTexture=!0;Qc.prototype=Object.create(X.prototype);Qc.prototype.constructor=Qc;Qc.prototype.isCanvasTexture=!0;Rc.prototype=Object.create(X.prototype);Rc.prototype.constructor=Rc;Rc.prototype.isDepthTexture= -!0;bc.prototype=Object.create(E.prototype);bc.prototype.constructor=bc;Sc.prototype=Object.create(Q.prototype);Sc.prototype.constructor=Sc;cc.prototype=Object.create(E.prototype);cc.prototype.constructor=cc;Tc.prototype=Object.create(Q.prototype);Tc.prototype.constructor=Tc;oa.prototype=Object.create(E.prototype);oa.prototype.constructor=oa;Uc.prototype=Object.create(Q.prototype);Uc.prototype.constructor=Uc;dc.prototype=Object.create(oa.prototype);dc.prototype.constructor=dc;Vc.prototype=Object.create(Q.prototype); -Vc.prototype.constructor=Vc;Cb.prototype=Object.create(oa.prototype);Cb.prototype.constructor=Cb;Wc.prototype=Object.create(Q.prototype);Wc.prototype.constructor=Wc;ec.prototype=Object.create(oa.prototype);ec.prototype.constructor=ec;Xc.prototype=Object.create(Q.prototype);Xc.prototype.constructor=Xc;fc.prototype=Object.create(oa.prototype);fc.prototype.constructor=fc;Yc.prototype=Object.create(Q.prototype);Yc.prototype.constructor=Yc;Db.prototype=Object.create(E.prototype);Db.prototype.constructor= -Db;Db.prototype.toJSON=function(){var a=E.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON();return a};Zc.prototype=Object.create(Q.prototype);Zc.prototype.constructor=Zc;gc.prototype=Object.create(E.prototype);gc.prototype.constructor=gc;$c.prototype=Object.create(Q.prototype);$c.prototype.constructor=$c;hc.prototype=Object.create(E.prototype);hc.prototype.constructor=hc;var uh={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=yf(a,0,e,c,!0),g=[];if(!f)return g; -var h;if(d){var k=c;d=[];var m;var l=0;for(m=b.length;l80*c){var t=h=a[0];var r=d=a[1];for(k=c;kh&&(h=l),b>d&&(d=b);h=Math.max(h-t,d-r);h=0!==h?1/h:0}cd(f,g,c,t,r,h);return g}},db={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;edb.area(a)},triangulateShape:function(a,b){var c=[],d=[],e=[];Cf(a);Df(c,a);var f=a.length;b.forEach(Cf);for(a=0;aMath.abs(g-k)?[new D(a,1-c),new D(h,1-d),new D(m,1-e),new D(p,1-b)]:[new D(g,1-c),new D(k,1-d),new D(l,1-e),new D(n,1-b)]}};ed.prototype=Object.create(Q.prototype);ed.prototype.constructor=ed;ic.prototype=Object.create(Ya.prototype);ic.prototype.constructor=ic;fd.prototype=Object.create(Q.prototype);fd.prototype.constructor=fd;ob.prototype=Object.create(E.prototype);ob.prototype.constructor=ob;gd.prototype=Object.create(Q.prototype);gd.prototype.constructor=gd;jc.prototype= -Object.create(E.prototype);jc.prototype.constructor=jc;hd.prototype=Object.create(Q.prototype);hd.prototype.constructor=hd;kc.prototype=Object.create(E.prototype);kc.prototype.constructor=kc;Gb.prototype=Object.create(Q.prototype);Gb.prototype.constructor=Gb;Gb.prototype.toJSON=function(){var a=Q.prototype.toJSON.call(this);return Ff(this.parameters.shapes,a)};Hb.prototype=Object.create(E.prototype);Hb.prototype.constructor=Hb;Hb.prototype.toJSON=function(){var a=E.prototype.toJSON.call(this);return Ff(this.parameters.shapes, -a)};lc.prototype=Object.create(E.prototype);lc.prototype.constructor=lc;Ib.prototype=Object.create(Q.prototype);Ib.prototype.constructor=Ib;eb.prototype=Object.create(E.prototype);eb.prototype.constructor=eb;id.prototype=Object.create(Ib.prototype);id.prototype.constructor=id;jd.prototype=Object.create(eb.prototype);jd.prototype.constructor=jd;kd.prototype=Object.create(Q.prototype);kd.prototype.constructor=kd;mc.prototype=Object.create(E.prototype);mc.prototype.constructor=mc;var pa=Object.freeze({WireframeGeometry:bc, -ParametricGeometry:Sc,ParametricBufferGeometry:cc,TetrahedronGeometry:Uc,TetrahedronBufferGeometry:dc,OctahedronGeometry:Vc,OctahedronBufferGeometry:Cb,IcosahedronGeometry:Wc,IcosahedronBufferGeometry:ec,DodecahedronGeometry:Xc,DodecahedronBufferGeometry:fc,PolyhedronGeometry:Tc,PolyhedronBufferGeometry:oa,TubeGeometry:Yc,TubeBufferGeometry:Db,TorusKnotGeometry:Zc,TorusKnotBufferGeometry:gc,TorusGeometry:$c,TorusBufferGeometry:hc,TextGeometry:ed,TextBufferGeometry:ic,SphereGeometry:fd,SphereBufferGeometry:ob, -RingGeometry:gd,RingBufferGeometry:jc,PlaneGeometry:Ic,PlaneBufferGeometry:zb,LatheGeometry:hd,LatheBufferGeometry:kc,ShapeGeometry:Gb,ShapeBufferGeometry:Hb,ExtrudeGeometry:Fb,ExtrudeBufferGeometry:Ya,EdgesGeometry:lc,ConeGeometry:id,ConeBufferGeometry:jd,CylinderGeometry:Ib,CylinderBufferGeometry:eb,CircleGeometry:kd,CircleBufferGeometry:mc,BoxGeometry:Ub,BoxBufferGeometry:wb});Jb.prototype=Object.create(L.prototype);Jb.prototype.constructor=Jb;Jb.prototype.isShadowMaterial=!0;Jb.prototype.copy= -function(a){L.prototype.copy.call(this,a);this.color.copy(a.color);return this};nc.prototype=Object.create(sa.prototype);nc.prototype.constructor=nc;nc.prototype.isRawShaderMaterial=!0;Za.prototype=Object.create(L.prototype);Za.prototype.constructor=Za;Za.prototype.isMeshStandardMaterial=!0;Za.prototype.copy=function(a){L.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity= -a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap= -a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Kb.prototype=Object.create(Za.prototype);Kb.prototype.constructor=Kb;Kb.prototype.isMeshPhysicalMaterial= -!0;Kb.prototype.copy=function(a){Za.prototype.copy.call(this,a);this.defines={PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearCoat=a.clearCoat;this.clearCoatRoughness=a.clearCoatRoughness;return this};Ka.prototype=Object.create(L.prototype);Ka.prototype.constructor=Ka;Ka.prototype.isMeshPhongMaterial=!0;Ka.prototype.copy=function(a){L.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity= -a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap; -this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Lb.prototype=Object.create(Ka.prototype);Lb.prototype.constructor=Lb;Lb.prototype.isMeshToonMaterial=!0;Lb.prototype.copy=function(a){Ka.prototype.copy.call(this, -a);this.gradientMap=a.gradientMap;return this};Mb.prototype=Object.create(L.prototype);Mb.prototype.constructor=Mb;Mb.prototype.isMeshNormalMaterial=!0;Mb.prototype.copy=function(a){L.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe; -this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Nb.prototype=Object.create(L.prototype);Nb.prototype.constructor=Nb;Nb.prototype.isMeshLambertMaterial=!0;Nb.prototype.copy=function(a){L.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive); -this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this}; -Ob.prototype=Object.create(L.prototype);Ob.prototype.constructor=Ob;Ob.prototype.isMeshMatcapMaterial=!0;Ob.prototype.copy=function(a){L.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map=a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias= -a.displacementBias;this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Pb.prototype=Object.create(V.prototype);Pb.prototype.constructor=Pb;Pb.prototype.isLineDashedMaterial=!0;Pb.prototype.copy=function(a){V.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var vh=Object.freeze({ShadowMaterial:Jb,SpriteMaterial:nb,RawShaderMaterial:nc,ShaderMaterial:sa,PointsMaterial:Ja, -MeshPhysicalMaterial:Kb,MeshStandardMaterial:Za,MeshPhongMaterial:Ka,MeshToonMaterial:Lb,MeshNormalMaterial:Mb,MeshLambertMaterial:Nb,MeshDepthMaterial:kb,MeshDistanceMaterial:lb,MeshBasicMaterial:ka,MeshMatcapMaterial:Ob,LineDashedMaterial:Pb,LineBasicMaterial:V,Material:L}),ra={arraySlice:function(a,b,c){return ra.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&&a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT? -new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,k=0;k!==b;++k)e[g++]=a[h+k];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d]; -if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}}};Object.assign(Da.prototype,{evaluate:function(a){var b=this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=ra.arraySlice(c,e,f),this.values=ra.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times;b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: 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("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&ra.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: 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=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;ge.far||f.push({distance:q,point:b.clone(),uv:ha.getUV(b,h,k,m,l,p,u,new C),face:null, +object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)},copy:function(a){G.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});Rc.prototype=Object.assign(Object.create(G.prototype),{constructor:Rc,isLOD:!0,copy:function(a){G.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;ef||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}else for(g=0,q=t.length/3-1;gf||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,point:h.clone().applyMatrix4(this.matrixWorld), +index:g,face:null,faceIndex:null,object:this}))}else if(g.isGeometry)for(k=g.vertices,m=k.length,g=0;gf||(l.applyMatrix4(this.matrixWorld),v=d.ray.origin.distanceTo(l),vd.far||e.push({distance:v,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)}});R.prototype=Object.assign(Object.create(T.prototype), +{constructor:R,isLineSegments:!0,computeLineDistances:function(){var a=new n,b=new n;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[],f=0,g=d.count;fd.far||e.push({distance:a,distanceToRay:Math.sqrt(f),point:p.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);c.radius+=m;if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);m/=(this.scale.x+this.scale.y+this.scale.z)/3;var l=m*m;m=new n;var p=new n;if(h.isBufferGeometry){var u=h.index;h=h.attributes.position.array;if(null!==u){var t=u.array;u=0;for(var q=t.length;u=a.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}});bc.prototype=Object.create(X.prototype);bc.prototype.constructor=bc;bc.prototype.isCompressedTexture=!0;Tc.prototype=Object.create(X.prototype);Tc.prototype.constructor=Tc;Tc.prototype.isCanvasTexture=!0;Uc.prototype=Object.create(X.prototype);Uc.prototype.constructor=Uc;Uc.prototype.isDepthTexture=!0;cc.prototype=Object.create(E.prototype);cc.prototype.constructor=cc;Vc.prototype=Object.create(Q.prototype); +Vc.prototype.constructor=Vc;dc.prototype=Object.create(E.prototype);dc.prototype.constructor=dc;Wc.prototype=Object.create(Q.prototype);Wc.prototype.constructor=Wc;za.prototype=Object.create(E.prototype);za.prototype.constructor=za;Xc.prototype=Object.create(Q.prototype);Xc.prototype.constructor=Xc;ec.prototype=Object.create(za.prototype);ec.prototype.constructor=ec;Yc.prototype=Object.create(Q.prototype);Yc.prototype.constructor=Yc;Db.prototype=Object.create(za.prototype);Db.prototype.constructor= +Db;Zc.prototype=Object.create(Q.prototype);Zc.prototype.constructor=Zc;fc.prototype=Object.create(za.prototype);fc.prototype.constructor=fc;$c.prototype=Object.create(Q.prototype);$c.prototype.constructor=$c;gc.prototype=Object.create(za.prototype);gc.prototype.constructor=gc;ad.prototype=Object.create(Q.prototype);ad.prototype.constructor=ad;Eb.prototype=Object.create(E.prototype);Eb.prototype.constructor=Eb;Eb.prototype.toJSON=function(){var a=E.prototype.toJSON.call(this);a.path=this.parameters.path.toJSON(); +return a};bd.prototype=Object.create(Q.prototype);bd.prototype.constructor=bd;hc.prototype=Object.create(E.prototype);hc.prototype.constructor=hc;cd.prototype=Object.create(Q.prototype);cd.prototype.constructor=cd;ic.prototype=Object.create(E.prototype);ic.prototype.constructor=ic;var yh={triangulate:function(a,b,c){c=c||2;var d=b&&b.length,e=d?b[0]*c:a.length,f=Df(a,0,e,c,!0),g=[];if(!f||f.next===f.prev)return g;var h;if(d){var k=c;d=[];var m;var l=0;for(m=b.length;l80*c){var t=h=a[0];var q=d=a[1];for(k=c;kh&&(h=l),b>d&&(d=b);h=Math.max(h-t,d-q);h=0!==h?1/h:0}fd(f,g,c,t,q,h);return g}},db={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;edb.area(a)}, +triangulateShape:function(a,b){var c=[],d=[],e=[];Hf(a);If(c,a);var f=a.length;b.forEach(Hf);for(a=0;aMath.abs(g-k)?[new C(a,1-c),new C(h,1-d),new C(m,1-e),new C(n, +1-b)]:[new C(g,1-c),new C(k,1-d),new C(l,1-e),new C(u,1-b)]}};hd.prototype=Object.create(Q.prototype);hd.prototype.constructor=hd;kc.prototype=Object.create(Ya.prototype);kc.prototype.constructor=kc;id.prototype=Object.create(Q.prototype);id.prototype.constructor=id;qb.prototype=Object.create(E.prototype);qb.prototype.constructor=qb;jd.prototype=Object.create(Q.prototype);jd.prototype.constructor=jd;lc.prototype=Object.create(E.prototype);lc.prototype.constructor=lc;kd.prototype=Object.create(Q.prototype); +kd.prototype.constructor=kd;mc.prototype=Object.create(E.prototype);mc.prototype.constructor=mc;Hb.prototype=Object.create(Q.prototype);Hb.prototype.constructor=Hb;Hb.prototype.toJSON=function(){var a=Q.prototype.toJSON.call(this);return Kf(this.parameters.shapes,a)};Ib.prototype=Object.create(E.prototype);Ib.prototype.constructor=Ib;Ib.prototype.toJSON=function(){var a=E.prototype.toJSON.call(this);return Kf(this.parameters.shapes,a)};nc.prototype=Object.create(E.prototype);nc.prototype.constructor= +nc;Jb.prototype=Object.create(Q.prototype);Jb.prototype.constructor=Jb;eb.prototype=Object.create(E.prototype);eb.prototype.constructor=eb;ld.prototype=Object.create(Jb.prototype);ld.prototype.constructor=ld;md.prototype=Object.create(eb.prototype);md.prototype.constructor=md;nd.prototype=Object.create(Q.prototype);nd.prototype.constructor=nd;oc.prototype=Object.create(E.prototype);oc.prototype.constructor=oc;var ua=Object.freeze({WireframeGeometry:cc,ParametricGeometry:Vc,ParametricBufferGeometry:dc, +TetrahedronGeometry:Xc,TetrahedronBufferGeometry:ec,OctahedronGeometry:Yc,OctahedronBufferGeometry:Db,IcosahedronGeometry:Zc,IcosahedronBufferGeometry:fc,DodecahedronGeometry:$c,DodecahedronBufferGeometry:gc,PolyhedronGeometry:Wc,PolyhedronBufferGeometry:za,TubeGeometry:ad,TubeBufferGeometry:Eb,TorusKnotGeometry:bd,TorusKnotBufferGeometry:hc,TorusGeometry:cd,TorusBufferGeometry:ic,TextGeometry:hd,TextBufferGeometry:kc,SphereGeometry:id,SphereBufferGeometry:qb,RingGeometry:jd,RingBufferGeometry:lc, +PlaneGeometry:Lc,PlaneBufferGeometry:Bb,LatheGeometry:kd,LatheBufferGeometry:mc,ShapeGeometry:Hb,ShapeBufferGeometry:Ib,ExtrudeGeometry:Gb,ExtrudeBufferGeometry:Ya,EdgesGeometry:nc,ConeGeometry:ld,ConeBufferGeometry:md,CylinderGeometry:Jb,CylinderBufferGeometry:eb,CircleGeometry:nd,CircleBufferGeometry:oc,BoxGeometry:Ub,BoxBufferGeometry:ib});Kb.prototype=Object.create(L.prototype);Kb.prototype.constructor=Kb;Kb.prototype.isShadowMaterial=!0;Kb.prototype.copy=function(a){L.prototype.copy.call(this, +a);this.color.copy(a.color);return this};pc.prototype=Object.create(va.prototype);pc.prototype.constructor=pc;pc.prototype.isRawShaderMaterial=!0;Za.prototype=Object.create(L.prototype);Za.prototype.constructor=Za;Za.prototype.isMeshStandardMaterial=!0;Za.prototype.copy=function(a){L.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity; +this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap= +a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Lb.prototype=Object.create(Za.prototype);Lb.prototype.constructor=Lb;Lb.prototype.isMeshPhysicalMaterial=!0;Lb.prototype.copy=function(a){Za.prototype.copy.call(this, +a);this.defines={PHYSICAL:""};this.reflectivity=a.reflectivity;this.clearCoat=a.clearCoat;this.clearCoatRoughness=a.clearCoatRoughness;return this};Ka.prototype=Object.create(L.prototype);Ka.prototype.constructor=Ka;Ka.prototype.isMeshPhongMaterial=!0;Ka.prototype.copy=function(a){L.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity= +a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity= +a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Mb.prototype=Object.create(Ka.prototype);Mb.prototype.constructor=Mb;Mb.prototype.isMeshToonMaterial=!0;Mb.prototype.copy=function(a){Ka.prototype.copy.call(this,a);this.gradientMap=a.gradientMap; +return this};Nb.prototype=Object.create(L.prototype);Nb.prototype.constructor=Nb;Nb.prototype.isMeshNormalMaterial=!0;Nb.prototype.copy=function(a){L.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth= +a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Ob.prototype=Object.create(L.prototype);Ob.prototype.constructor=Ob;Ob.prototype.isMeshLambertMaterial=!0;Ob.prototype.copy=function(a){L.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap= +a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Pb.prototype= +Object.create(L.prototype);Pb.prototype.constructor=Pb;Pb.prototype.isMeshMatcapMaterial=!0;Pb.prototype.copy=function(a){L.prototype.copy.call(this,a);this.defines={MATCAP:""};this.color.copy(a.color);this.matcap=a.matcap;this.map=a.map;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalMapType=a.normalMapType;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias; +this.alphaMap=a.alphaMap;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};Qb.prototype=Object.create(V.prototype);Qb.prototype.constructor=Qb;Qb.prototype.isLineDashedMaterial=!0;Qb.prototype.copy=function(a){V.prototype.copy.call(this,a);this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var zh=Object.freeze({ShadowMaterial:Kb,SpriteMaterial:pb,RawShaderMaterial:pc,ShaderMaterial:va,PointsMaterial:Ja,MeshPhysicalMaterial:Lb, +MeshStandardMaterial:Za,MeshPhongMaterial:Ka,MeshToonMaterial:Mb,MeshNormalMaterial:Nb,MeshLambertMaterial:Ob,MeshDepthMaterial:mb,MeshDistanceMaterial:nb,MeshBasicMaterial:ka,MeshMatcapMaterial:Pb,LineDashedMaterial:Qb,LineBasicMaterial:V,Material:L}),ta={arraySlice:function(a,b,c){return ta.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&&a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)}, +isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,k=0;k!==b;++k)e[g++]=a[h+k];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g= +f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];while(void 0!==f)}}}};Object.assign(Ea.prototype,{evaluate:function(a){var b=this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a=e)break a;else{f=b[1];a=e)break b}d=c;c=0}}for(;c>>1,ab;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,1),e=f-1),a=this.getValueSize(),this.times=ta.arraySlice(c,e,f),this.values=ta.arraySlice(this.values,e*a,f*a);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrack: Invalid value size in track.",this),a=!1);var c=this.times;b=this.values;var d=c.length;0===d&&(console.error("THREE.KeyframeTrack: 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("THREE.KeyframeTrack: Time is not a valid number.",this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrack: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&ta.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrack: 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=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;gg)e=a+1;else if(0b&&(b=0);1Number.EPSILON&&(g.normalize(),c=Math.acos(P.clamp(d[k-1].dot(d[k]),-1,1)),e[k].applyMatrix4(h.makeRotationAxis(g,c))),f[k].crossVectors(d[k],e[k]);if(!0===b)for(c=Math.acos(P.clamp(e[0].dot(e[a]),-1,1)),c/=a,0d;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>k&&(k=e);Re.initNonuniformCatmullRom(f.x,g.x,h.x,c.x,d,e,k);Se.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,k);Te.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d,e,k)}else"catmullrom"===this.curveType&&(Re.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),Se.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),Te.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(Re.calc(a), -Se.calc(a),Te.calc(a));return b};ua.prototype.copy=function(a){N.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bd;)d+=c;for(;d>c;)d-=c;de&&(e=1);1E-4>d&&(d=e);1E-4>k&&(k=e);Ve.initNonuniformCatmullRom(f.x,g.x,h.x,c.x,d,e,k);We.initNonuniformCatmullRom(f.y,g.y,h.y,c.y,d,e,k);Xe.initNonuniformCatmullRom(f.z,g.z,h.z,c.z,d,e,k)}else"catmullrom"===this.curveType&&(Ve.initCatmullRom(f.x,g.x,h.x,c.x,this.tension),We.initCatmullRom(f.y,g.y,h.y,c.y,this.tension),Xe.initCatmullRom(f.z,g.z,h.z,c.z,this.tension));b.set(Ve.calc(a), +We.calc(a),Xe.calc(a));return b};wa.prototype.copy=function(a){N.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;bc.length-2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(If(d,e.x,f.x,g.x,c.x),If(d,e.y,f.y,g.y,c.y));return b};Pa.prototype.copy=function(a){N.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths(); +return a};Na.prototype.fromJSON=function(a){N.prototype.fromJSON.call(this,a);this.v1.fromArray(a.v1);this.v2.fromArray(a.v2);return this};Oa.prototype=Object.create(N.prototype);Oa.prototype.constructor=Oa;Oa.prototype.isQuadraticBezierCurve=!0;Oa.prototype.getPoint=function(a,b){b=b||new C;var c=this.v0,d=this.v1,e=this.v2;b.set(rd(a,c.x,d.x,e.x),rd(a,c.y,d.y,e.y));return b};Oa.prototype.copy=function(a){N.prototype.copy.call(this,a);this.v0.copy(a.v0);this.v1.copy(a.v1);this.v2.copy(a.v2);return this}; +Oa.prototype.toJSON=function(){var a=N.prototype.toJSON.call(this);a.v0=this.v0.toArray();a.v1=this.v1.toArray();a.v2=this.v2.toArray();return a};Oa.prototype.fromJSON=function(a){N.prototype.fromJSON.call(this,a);this.v0.fromArray(a.v0);this.v1.fromArray(a.v1);this.v2.fromArray(a.v2);return this};ab.prototype=Object.create(N.prototype);ab.prototype.constructor=ab;ab.prototype.isQuadraticBezierCurve3=!0;ab.prototype.getPoint=function(a,b){b=b||new n;var c=this.v0,d=this.v1,e=this.v2;b.set(rd(a,c.x, +d.x,e.x),rd(a,c.y,d.y,e.y),rd(a,c.z,d.z,e.z));return b};ab.prototype.copy=function(a){N.prototype.copy.call(this,a);this.v0.copy(a.v0);this.v1.copy(a.v1);this.v2.copy(a.v2);return this};ab.prototype.toJSON=function(){var a=N.prototype.toJSON.call(this);a.v0=this.v0.toArray();a.v1=this.v1.toArray();a.v2=this.v2.toArray();return a};ab.prototype.fromJSON=function(a){N.prototype.fromJSON.call(this,a);this.v0.fromArray(a.v0);this.v1.fromArray(a.v1);this.v2.fromArray(a.v2);return this};Pa.prototype=Object.create(N.prototype); +Pa.prototype.constructor=Pa;Pa.prototype.isSplineCurve=!0;Pa.prototype.getPoint=function(a,b){b=b||new C;var c=this.points,d=(c.length-1)*a;a=Math.floor(d);d-=a;var e=c[0===a?a:a-1],f=c[a],g=c[a>c.length-2?c.length-1:a+1];c=c[a>c.length-3?c.length-1:a+2];b.set(Nf(d,e.x,f.x,g.x,c.x),Nf(d,e.y,f.y,g.y,c.y));return b};Pa.prototype.copy=function(a){N.prototype.copy.call(this,a);this.points=[];for(var b=0,c=a.points.length;b=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths(); return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},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=db.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new pb;h.curves=g.curves;b.push(h);return b}var k=!e(f[0].getPoints());k=a?!k:k;h=[];var l=[],n=[],p=0;l[p]=void 0;n[p]=[];for(var v=0,t=f.length;vl.opacity&&(l.transparent=!0);d.setTextures(k);return d.parse(l)}}()});var ge,Ge={getContext:function(){void 0===ge&&(ge=new (window.AudioContext||window.webkitAudioContext));return ge},setContext:function(a){ge=a}};Object.assign(Be.prototype, -{load:function(a,b,c,d){var e=new La(this.manager);e.setResponseType("arraybuffer");e.setPath(this.path);e.load(a,function(a){a=a.slice(0);Ge.getContext().decodeAudioData(a,function(a){b(a)})},c,d)},setPath:function(a){this.path=a;return this}});Object.assign(ae.prototype,{isSphericalHarmonics3:!0,set:function(a){for(var b=0;9>b;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0,0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z; -var e=this.coefficients;b=.282095*e[0];b+=.488603*e[1]*d;b+=.488603*e[2]*a;b+=.488603*e[3]*c;b+=1.092548*e[4]*c*d;b+=1.092548*e[5]*d*a;b+=.315392*e[6]*(3*a*a-1);b+=1.092548*e[7]*c*a;return b+=.546274*e[8]*(c*c-d*d)},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b=.886227*e[0];b+=1.023328*e[1]*d;b+=1.023328*e[2]*a;b+=1.023328*e[3]*c;b+=.858086*e[4]*c*d;b+=.858086*e[5]*d*a;b+=e[6]*(.743125*a*a-.247708);b+=.858086*e[7]*c*a;return b+=.429043*e[8]*(c*c-d*d)},add:function(a){for(var b= -0;9>b;b++)this.coefficients[b].add(a.coefficients[b]);return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c],b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0},copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a){for(var b= -this.coefficients,c=0;9>c;c++)b[c].fromArray(a,3*c);return this},toArray:function(){for(var a=[],b=this.coefficients,c=0;9>c;c++)b[c].toArray(a,3*c);return a}});Object.assign(ae,{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d;b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});Ra.prototype=Object.assign(Object.create(aa.prototype),{constructor:Ra,isLightProbe:!0,copy:function(a){aa.prototype.copy.call(this, -a);this.sh.copy(a.sh);this.intensity=a.intensity;return this},toJSON:function(a){return aa.prototype.toJSON.call(this,a)}});Ce.prototype=Object.assign(Object.create(Ra.prototype),{constructor:Ce,isHemisphereLightProbe:!0,copy:function(a){Ra.prototype.copy.call(this,a);return this},toJSON:function(a){return Ra.prototype.toJSON.call(this,a)}});De.prototype=Object.assign(Object.create(Ra.prototype),{constructor:De,isAmbientLightProbe:!0,copy:function(a){Ra.prototype.copy.call(this,a);return this},toJSON:function(a){return Ra.prototype.toJSON.call(this, -a)}});Object.assign(Kf.prototype,{update:function(){var a,b,c,d,e,f,g,h,k=new O,l=new O;return function(m){if(a!==this||b!==m.focus||c!==m.fov||d!==m.aspect*this.aspect||e!==m.near||f!==m.far||g!==m.zoom||h!==this.eyeSep){a=this;b=m.focus;c=m.fov;d=m.aspect*this.aspect;e=m.near;f=m.far;g=m.zoom;var p=m.projectionMatrix.clone();h=this.eyeSep/2;var n=h*e/b,q=e*Math.tan(P.DEG2RAD*c*.5)/g;l.elements[12]=-h;k.elements[12]=h;var r=-q*d+n;var u=q*d+n;p.elements[0]=2*e/(u-r);p.elements[8]=(u+r)/(u-r);this.cameraL.projectionMatrix.copy(p); -r=-q*d-n;u=q*d-n;p.elements[0]=2*e/(u-r);p.elements[8]=(u+r)/(u-r);this.cameraR.projectionMatrix.copy(p)}this.cameraL.matrixWorld.copy(m.matrixWorld).multiply(l);this.cameraR.matrixWorld.copy(m.matrixWorld).multiply(k)}}()});sd.prototype=Object.create(H.prototype);sd.prototype.constructor=sd;Object.assign(Ee.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart= -this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});Fe.prototype=Object.assign(Object.create(H.prototype),{constructor:Fe,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter), -this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a, -this.context.currentTime,.01);return this},updateMatrixWorld:function(){var a=new n,b=new ea,c=new n,d=new n,e=new Ee;return function(f){H.prototype.updateMatrixWorld.call(this,f);f=this.context.listener;var g=this.up;this.timeDelta=e.getDelta();this.matrixWorld.decompose(a,b,c);d.set(0,0,-1).applyQuaternion(b);if(f.positionX){var h=this.context.currentTime+this.timeDelta;f.positionX.linearRampToValueAtTime(a.x,h);f.positionY.linearRampToValueAtTime(a.y,h);f.positionZ.linearRampToValueAtTime(a.z, -h);f.forwardX.linearRampToValueAtTime(d.x,h);f.forwardY.linearRampToValueAtTime(d.y,h);f.forwardZ.linearRampToValueAtTime(d.z,h);f.upX.linearRampToValueAtTime(g.x,h);f.upY.linearRampToValueAtTime(g.y,h);f.upZ.linearRampToValueAtTime(g.z,h)}else f.setPosition(a.x,a.y,a.z),f.setOrientation(d.x,d.y,d.z,g.x,g.y,g.z)}}()});rc.prototype=Object.assign(Object.create(H.prototype),{constructor:rc,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode"; -this.source=a;this.connect();return this},setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},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.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);this.startTime=this.context.currentTime;a.start(this.startTime,this.offset);this.isPlaying=!0;this.source=a;this.setDetune(this.detune);this.setPlaybackRate(this.playbackRate);return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return!0===this.isPlaying&&(this.source.stop(),this.source.onended= -null,this.offset+=(this.context.currentTime-this.startTime)*this.playbackRate,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.source.stop(),this.source.onended=null,this.offset=0,this.isPlaying=!1,this},connect:function(){if(0d&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var 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){ea.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}}});Object.assign(Lf.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings, -b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(va,{Composite:Lf,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new va.Composite(a,b,c):new va(a,b,c)},sanitizeNodeName:function(){var a=/[\[\]\.:\/]/g;return function(b){return b.replace(/\s/g,"_").replace(a,"")}}(),parseTrackName:function(){var a="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]", -b=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]");a=/(WCOD+)?/.source.replace("WCOD",a);var c=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC","[^\\[\\]\\.:\\/]"),d=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),e=new RegExp("^"+b+a+c+d+"$"),f=["material","materials","bones"];return function(a){var b=e.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&& -b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!==c){var d=b.nodeName.substring(c+1);-1!==f.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName=d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b}}(),findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c= -0;c=b){var n=b++,p=a[n];c[p.uuid]=l;a[l]=p;c[k]=n;a[n]=h;h=0;for(k=e;h!==k;++h){p=d[h];var v=p[l];p[l]=p[n];p[n]=v}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k=arguments[g].uuid,l=d[k];if(void 0!==l)if(delete d[k],lNumber.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=db.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);b=[];if(1===f.length){var g=f[0];var h=new rb;h.curves=g.curves; +b.push(h);return b}var k=!e(f[0].getPoints());k=a?!k:k;h=[];var l=[],n=[],p=0;l[p]=void 0;n[p]=[];for(var u=0,t=f.length;ul.opacity&&(l.transparent=!0);d.setTextures(k);return d.parse(l)}}()});var ge,Ke={getContext:function(){void 0===ge&&(ge=new (window.AudioContext||window.webkitAudioContext));return ge},setContext:function(a){ge=a}};Object.assign(Fe.prototype,{load:function(a,b,c,d){var e=new La(this.manager);e.setResponseType("arraybuffer");e.setPath(this.path);e.load(a,function(a){a=a.slice(0);Ke.getContext().decodeAudioData(a,function(a){b(a)})},c,d)},setPath:function(a){this.path=a; +return this}});Object.assign(ae.prototype,{isSphericalHarmonics3:!0,set:function(a){for(var b=0;9>b;b++)this.coefficients[b].copy(a[b]);return this},zero:function(){for(var a=0;9>a;a++)this.coefficients[a].set(0,0,0);return this},getAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.282095);b.addScale(e[1],.488603*d);b.addScale(e[2],.488603*a);b.addScale(e[3],.488603*c);b.addScale(e[4],1.092548*c*d);b.addScale(e[5],1.092548*d*a);b.addScale(e[6],.315392*(3* +a*a-1));b.addScale(e[7],1.092548*c*a);b.addScale(e[8],.546274*(c*c-d*d));return b},getIrradianceAt:function(a,b){var c=a.x,d=a.y;a=a.z;var e=this.coefficients;b.copy(e[0]).multiplyScalar(.886227);b.addScale(e[1],1.023328*d);b.addScale(e[2],1.023328*a);b.addScale(e[3],1.023328*c);b.addScale(e[4],.858086*c*d);b.addScale(e[5],.858086*d*a);b.addScale(e[6],.743125*a*a-.247708);b.addScale(e[7],.858086*c*a);b.addScale(e[8],.429043*(c*c-d*d));return b},add:function(a){for(var b=0;9>b;b++)this.coefficients[b].add(a.coefficients[b]); +return this},scale:function(a){for(var b=0;9>b;b++)this.coefficients[b].multiplyScalar(a);return this},lerp:function(a,b){for(var c=0;9>c;c++)this.coefficients[c].lerp(a.coefficients[c],b);return this},equals:function(a){for(var b=0;9>b;b++)if(!this.coefficients[b].equals(a.coefficients[b]))return!1;return!0},copy:function(a){return this.set(a.coefficients)},clone:function(){return(new this.constructor).copy(this)},fromArray:function(a){for(var b=this.coefficients,c=0;9>c;c++)b[c].fromArray(a,3*c); +return this},toArray:function(){for(var a=[],b=this.coefficients,c=0;9>c;c++)b[c].toArray(a,3*c);return a}});Object.assign(ae,{getBasisAt:function(a,b){var c=a.x,d=a.y;a=a.z;b[0]=.282095;b[1]=.488603*d;b[2]=.488603*a;b[3]=.488603*c;b[4]=1.092548*c*d;b[5]=1.092548*d*a;b[6]=.315392*(3*a*a-1);b[7]=1.092548*c*a;b[8]=.546274*(c*c-d*d)}});Ra.prototype=Object.assign(Object.create(Z.prototype),{constructor:Ra,isLightProbe:!0,copy:function(a){Z.prototype.copy.call(this,a);this.sh.copy(a.sh);this.intensity= +a.intensity;return this},toJSON:function(a){return Z.prototype.toJSON.call(this,a)}});Ge.prototype=Object.assign(Object.create(Ra.prototype),{constructor:Ge,isHemisphereLightProbe:!0,copy:function(a){Ra.prototype.copy.call(this,a);return this},toJSON:function(a){return Ra.prototype.toJSON.call(this,a)}});He.prototype=Object.assign(Object.create(Ra.prototype),{constructor:He,isAmbientLightProbe:!0,copy:function(a){Ra.prototype.copy.call(this,a);return this},toJSON:function(a){return Ra.prototype.toJSON.call(this, +a)}});Object.assign(Pf.prototype,{update:function(){var a,b,c,d,e,f,g,h,k=new O,l=new O;return function(m){if(a!==this||b!==m.focus||c!==m.fov||d!==m.aspect*this.aspect||e!==m.near||f!==m.far||g!==m.zoom||h!==this.eyeSep){a=this;b=m.focus;c=m.fov;d=m.aspect*this.aspect;e=m.near;f=m.far;g=m.zoom;var n=m.projectionMatrix.clone();h=this.eyeSep/2;var r=h*e/b,t=e*Math.tan(P.DEG2RAD*c*.5)/g;l.elements[12]=-h;k.elements[12]=h;var q=-t*d+r;var v=t*d+r;n.elements[0]=2*e/(v-q);n.elements[8]=(v+q)/(v-q);this.cameraL.projectionMatrix.copy(n); +q=-t*d-r;v=t*d-r;n.elements[0]=2*e/(v-q);n.elements[8]=(v+q)/(v-q);this.cameraR.projectionMatrix.copy(n)}this.cameraL.matrixWorld.copy(m.matrixWorld).multiply(l);this.cameraR.matrixWorld.copy(m.matrixWorld).multiply(k)}}()});Object.assign(Ie.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta(); +return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});Je.prototype=Object.assign(Object.create(G.prototype),{constructor:Je,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination), +this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this}, +updateMatrixWorld:function(){var a=new n,b=new ea,c=new n,d=new n,e=new Ie;return function(f){G.prototype.updateMatrixWorld.call(this,f);f=this.context.listener;var g=this.up;this.timeDelta=e.getDelta();this.matrixWorld.decompose(a,b,c);d.set(0,0,-1).applyQuaternion(b);if(f.positionX){var h=this.context.currentTime+this.timeDelta;f.positionX.linearRampToValueAtTime(a.x,h);f.positionY.linearRampToValueAtTime(a.y,h);f.positionZ.linearRampToValueAtTime(a.z,h);f.forwardX.linearRampToValueAtTime(d.x,h); +f.forwardY.linearRampToValueAtTime(d.y,h);f.forwardZ.linearRampToValueAtTime(d.z,h);f.upX.linearRampToValueAtTime(g.x,h);f.upY.linearRampToValueAtTime(g.y,h);f.upZ.linearRampToValueAtTime(g.z,h)}else f.setPosition(a.x,a.y,a.z),f.setOrientation(d.x,d.y,d.z,g.x,g.y,g.z)}}()});tc.prototype=Object.assign(Object.create(G.prototype),{constructor:tc,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this}, +setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},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.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);this.startTime=this.context.currentTime;a.start(this.startTime,this.offset);this.isPlaying=!0;this.source=a;this.setDetune(this.detune);this.setPlaybackRate(this.playbackRate);return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return!0===this.isPlaying&&(this.source.stop(),this.source.onended=null,this.offset+=(this.context.currentTime- +this.startTime)*this.playbackRate,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.source.stop(),this.source.onended=null,this.offset=0,this.isPlaying=!1,this},connect:function(){if(0d&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var 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){ea.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}}});Object.assign(Qf.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_, +c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(qa,{Composite:Qf,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new qa.Composite(a,b,c):new qa(a,b,c)},sanitizeNodeName:function(){var a=/[\[\]\.:\/]/g;return function(b){return b.replace(/\s/g,"_").replace(a,"")}}(),parseTrackName:function(){var a="[^"+"\\[\\]\\.:\\/".replace("\\.","")+"]",b=/((?:WC+[\/:])*)/.source.replace("WC","[^\\[\\]\\.:\\/]");a=/(WCOD+)?/.source.replace("WCOD",a);var c=/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC", +"[^\\[\\]\\.:\\/]"),d=/\.(WC+)(?:\[(.+)\])?/.source.replace("WC","[^\\[\\]\\.:\\/]"),e=new RegExp("^"+b+a+c+d+"$"),f=["material","materials","bones"];return function(a){var b=e.exec(a);if(!b)throw Error("PropertyBinding: Cannot parse trackName: "+a);b={nodeName:b[2],objectName:b[3],objectIndex:b[4],propertyName:b[5],propertyIndex:b[6]};var c=b.nodeName&&b.nodeName.lastIndexOf(".");if(void 0!==c&&-1!==c){var d=b.nodeName.substring(c+1);-1!==f.indexOf(d)&&(b.nodeName=b.nodeName.substring(0,c),b.objectName= +d)}if(null===b.propertyName||0===b.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+a);return b}}(),findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;if(a.skeleton){var c=a.skeleton.getBoneByName(b);if(void 0!==c)return c}if(a.children){var d=function(a){for(var c=0;c=b){var n=b++,p=a[n];c[p.uuid]=l;a[l]=p;c[k]=n;a[n]=h;h=0;for(k=e;h!==k;++h){p= +d[h];var u=p[l];p[l]=p[n];p[n]=u}}}this.nCachedObjects_=b},uncache:function(){for(var a=this._objects,b=a.length,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k=arguments[g].uuid,l=d[k];if(void 0!==l)if(delete d[k],lb||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){b=this.timeScale;var c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0]; 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,c=this._clip.duration,d=this.loop,e=this._loopCount,f=2202===d;if(0===a)return-1===e?b:f&&1===(e&1)?c-b:b;if(2200===d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else{this.time=b;break a}this.clampWhenFinished?this.paused=!0:this.enabled=!1;this.time=b;this._mixer.dispatchEvent({type:"finished", action:this,direction:0>a?-1:1})}else{-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,f)):this._setEndings(0===this.repetitions,!0,f));if(b>=c||0>b){d=Math.floor(b/c);b-=c*d;e+=Math.abs(d);var g=this.repetitions-e;0>=g?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=b=0a,this._setEndings(a,!a,f)):this._setEndings(!1,!1,f),this._loopCount=e,this.time=b,this._mixer.dispatchEvent({type:"loop", action:this,loopDelta:d}))}else this.time=b;if(f&&1===(e&1))return c-b}return b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd=b?this.zeroSlopeAtEnd?2401:2400:2402)},_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}});Ke.prototype=Object.assign(Object.create(Ca.prototype),{constructor:Ke,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName,k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var l=d[h],n=l.name,p=k[n];if(void 0===p){p=f[h];if(void 0!==p){null===p._cacheIndex&&(++p.referenceCount,this._addInactiveBinding(p,g,n));continue}p=new Je(va.create(c,n,b&&b._propertyBindings[h].binding.parsedPath), +c;return this}});Oe.prototype=Object.assign(Object.create(na.prototype),{constructor:Oe,_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings;a=a._interpolants;var g=c.uuid,h=this._bindingsByRootAndName,k=h[g];void 0===k&&(k={},h[g]=k);for(h=0;h!==e;++h){var l=d[h],n=l.name,p=k[n];if(void 0===p){p=f[h];if(void 0!==p){null===p._cacheIndex&&(++p.referenceCount,this._addInactiveBinding(p,g,n));continue}p=new Ne(qa.create(c,n,b&&b._propertyBindings[h].binding.parsedPath), l.ValueTypeName,l.getValueSize());++p.referenceCount;this._addInactiveBinding(p,g,n)}f[h]=p;a[h].resultBuffer=p.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,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)}}, _deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions=[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length}, get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}},_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&athis.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},getParameter:function(a,b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"), -b=new D);return b.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.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new D);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new D;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)}});Object.assign(Oe.prototype,{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},getCenter:function(a){void 0=== -a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.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){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b= -new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new n,b=new n;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);c=b.dot(b);c=b.dot(a)/c;d&&(c=P.clamp(c,0,1));return c}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new n);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)}});td.prototype=Object.create(H.prototype);td.prototype.constructor=td;td.prototype.isImmediateRenderObject=!0;ud.prototype=Object.create(S.prototype);ud.prototype.constructor=ud;ud.prototype.update=function(){var a=new n,b=new n,c=new ia;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&&g.isGeometry)for(var h=g.vertices,k=g.faces,l=g=0,n=k.length;lthis.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},getParameter:function(a, +b){void 0===b&&(console.warn("THREE.Box2: .getParameter() target is now required"),b=new C);return b.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.ythis.max.y?!1:!0},clampPoint:function(a,b){void 0===b&&(console.warn("THREE.Box2: .clampPoint() target is now required"),b=new C);return b.copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new C; +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)}});Object.assign(Se.prototype,{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},getCenter:function(a){void 0===a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.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){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b=new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new n,b=new n;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);c=b.dot(b);c=b.dot(a)/c;d&&(c=P.clamp(c,0,1));return c}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"), +c=new n);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)}});vd.prototype=Object.create(G.prototype);vd.prototype.constructor=vd;vd.prototype.isImmediateRenderObject=!0;wd.prototype=Object.create(R.prototype);wd.prototype.constructor=wd;wd.prototype.update=function(){var a=new n,b=new n,c=new ia;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&&g.isGeometry)for(var h=g.vertices,k=g.faces,l=g=0,n=k.length;lMath.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);H.prototype.updateMatrixWorld.call(this,a)};var ee,Pe;hb.prototype=Object.create(H.prototype);hb.prototype.constructor=hb;hb.prototype.setDirection=function(){var a=new n,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))}}();hb.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()};hb.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};hb.prototype.copy=function(a){H.prototype.copy.call(this,a,!1);this.line.copy(a.line); -this.cone.copy(a.cone);return this};hb.prototype.clone=function(){return(new this.constructor).copy(this)};zd.prototype=Object.create(S.prototype);zd.prototype.constructor=zd;N.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(N.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(fb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); +function(a){this.object=a;this.update();return this};gb.prototype.copy=function(a){R.prototype.copy.call(this,a);this.object=a.object;return this};gb.prototype.clone=function(){return(new this.constructor).copy(this)};zd.prototype=Object.create(R.prototype);zd.prototype.constructor=zd;zd.prototype.updateMatrixWorld=function(a){var b=this.box;b.isEmpty()||(b.getCenter(this.position),b.getSize(this.scale),this.scale.multiplyScalar(.5),G.prototype.updateMatrixWorld.call(this,a))};Ad.prototype=Object.create(T.prototype); +Ad.prototype.constructor=Ad;Ad.prototype.updateMatrixWorld=function(a){var b=-this.plane.constant;1E-8>Math.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);G.prototype.updateMatrixWorld.call(this,a)};var ee,Te;hb.prototype=Object.create(G.prototype);hb.prototype.constructor=hb;hb.prototype.setDirection=function(){var a=new n,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))}}();hb.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()};hb.prototype.setColor=function(a){this.line.material.color.set(a);this.cone.material.color.set(a)};hb.prototype.copy=function(a){G.prototype.copy.call(this,a,!1);this.line.copy(a.line); +this.cone.copy(a.cone);return this};hb.prototype.clone=function(){return(new this.constructor).copy(this)};Bd.prototype=Object.create(R.prototype);Bd.prototype.constructor=Bd;N.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(N.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(fb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead."); a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new Q,c=0,d=a.length;c * Created by treblereel on 3/18/18. @@ -51,7 +54,7 @@ public WebGlCamera() { cameraPerspectiveHelper = new CameraHelper(cameraPerspective); scene.add(cameraPerspectiveHelper); - cameraOrtho = new OrthographicCamera((float)(0.5 * frustumSize * aspect / -2), (float)(0.5 * frustumSize * aspect / 2), frustumSize / 2, frustumSize / -2, 150, 1000); + cameraOrtho = new OrthographicCamera((float) (0.5 * frustumSize * aspect / -2), (float) (0.5 * frustumSize * aspect / 2), frustumSize / 2, frustumSize / -2, 150, 1000); cameraOrthoHelper = new CameraHelper(cameraOrtho); scene.add(cameraOrthoHelper); @@ -97,26 +100,27 @@ public WebGlCamera() { mesh3.position.z = 150f; cameraRig.add(mesh3); - Geometry geometry = new Geometry(); + BufferGeometry geometry = new BufferGeometry(); + + JsArray vertices = new JsArray<>(); + for (int i = 0; i < 10000; i++) { - Vector3 vertex = new Vector3(); - vertex.x = org.treblereel.gwt.three4g.math.Math.randFloatSpread(2000f); - vertex.y = org.treblereel.gwt.three4g.math.Math.randFloatSpread(2000f); - vertex.z = org.treblereel.gwt.three4g.math.Math.randFloatSpread(2000f); - geometry.vertices.push(vertex); + vertices.push(org.treblereel.gwt.three4g.math.Math.randFloatSpread(2000f)); // x + vertices.push(org.treblereel.gwt.three4g.math.Math.randFloatSpread(2000f)); // y + vertices.push(org.treblereel.gwt.three4g.math.Math.randFloatSpread(2000f)); // z } + geometry.attributes.position = new Float32BufferAttribute(vertices, 3); PointsMaterialParameters pointsMaterialParameters = new PointsMaterialParameters(); pointsMaterialParameters.color = new Color(0x888888); + Points particles = new Points(geometry, new PointsMaterial(pointsMaterialParameters)); scene.add(particles); setupWebGLRenderer(renderer); renderer.autoClear = false; - document.addEventListener("keydown", evt -> onKeyDown(evt), false); - } private void onKeyDown(Event evt) { @@ -136,6 +140,18 @@ private void onKeyDown(Event evt) { } } + public void doAttachScene() { + root.appendChild(renderer.domElement); + onWindowResize(); + animate(); + } + + @Override + protected void doAttachInfo() { + AppSetup.infoDiv.show().setHrefToInfo("http://threejs.org").setTextContentToInfo("three.js").setInnetHtml("- cameras
\n" + + "\t\tO orthographic P perspective"); + } + @Override public void onWindowResize() { if (camera != null && renderer != null) { @@ -154,19 +170,6 @@ public void onWindowResize() { } } - public void doAttachScene() { - root.appendChild(renderer.domElement); - onWindowResize(); - animate(); - } - - @Override - protected void doAttachInfo() { - AppSetup.infoDiv.show().setHrefToInfo("http://threejs.org").setTextContentToInfo("three.js").setInnetHtml("- cameras
\n" + - "\t\tO orthographic P perspective"); - - } - private void animate() { StatsProducer.getStats().update(); @@ -211,6 +214,5 @@ private void render() { activeHelper.visible = true; renderer.setViewport((int) getWidth() / 2, 0, (int) getWidth() / 2, (int) getHeight()); renderer.render(scene, camera); - } } diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsPhysical.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsPhysical.java index 755461c3..ea7a8a36 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsPhysical.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/lights/WebglLightsPhysical.java @@ -1,16 +1,16 @@ package org.treblereel.gwt.three4g.demo.client.local.examples.lights; -import com.google.gwt.animation.client.AnimationScheduler; import java.util.Date; import java.util.HashMap; import java.util.Map; + +import elemental2.dom.DomGlobal; import org.treblereel.gwt.datgui4g.GUI; import org.treblereel.gwt.datgui4g.GUIProperty; import org.treblereel.gwt.datgui4g.OnChange; import org.treblereel.gwt.three4g.InjectJavaScriptFor; import org.treblereel.gwt.three4g.THREE; import org.treblereel.gwt.three4g.cameras.PerspectiveCamera; -import org.treblereel.gwt.three4g.core.Clock; import org.treblereel.gwt.three4g.demo.client.local.AppSetup; import org.treblereel.gwt.three4g.demo.client.local.Attachable; import org.treblereel.gwt.three4g.demo.client.local.utils.StatsProducer; @@ -20,14 +20,13 @@ import org.treblereel.gwt.three4g.geometries.SphereBufferGeometry; import org.treblereel.gwt.three4g.lights.HemisphereLight; import org.treblereel.gwt.three4g.lights.PointLight; -import org.treblereel.gwt.three4g.loaders.OnLoadCallback; import org.treblereel.gwt.three4g.loaders.TextureLoader; import org.treblereel.gwt.three4g.materials.MeshStandardMaterial; import org.treblereel.gwt.three4g.materials.parameters.MeshStandardMaterialParameters; import org.treblereel.gwt.three4g.math.Color; import org.treblereel.gwt.three4g.objects.Mesh; +import org.treblereel.gwt.three4g.renderers.WebGLRenderer; import org.treblereel.gwt.three4g.scenes.Scene; -import org.treblereel.gwt.three4g.textures.Texture; /** * @author Dmitrii Tikhomirov @@ -38,7 +37,6 @@ public class WebglLightsPhysical extends Attachable { public static final String name = "lights / physical"; - private Clock clock = new Clock(); private HemisphereLight hemiLight; private PointLight bulbLight; @@ -56,7 +54,6 @@ public class WebglLightsPhysical extends Attachable { put("180 lm (25W)", 180); put("20 lm (4W)", 20); put("Off", 0); - }}; private Map hemiLuminousIrradiances = new HashMap() {{ @@ -79,7 +76,6 @@ public class WebglLightsPhysical extends Attachable { private String bulbPower = "400 lm (40W)"; private String hemiIrradiance = "0.0001 lx (Moonless Night)"; - public WebglLightsPhysical() { camera = new PerspectiveCamera(50, aspect, 0.1f, 100); @@ -111,42 +107,31 @@ public WebglLightsPhysical() { floorMat = new MeshStandardMaterial(meshStandardMaterialParameters1); TextureLoader textureLoader = new TextureLoader(); - textureLoader.load("textures/hardwood2_diffuse.jpg", new OnLoadCallback() { - @Override - public void onLoad(Texture map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(10, 24); - floorMat.map = map; - floorMat.needsUpdate = true; - } + textureLoader.load("textures/hardwood2_diffuse.jpg", map -> { + map.wrapS = THREE.RepeatWrapping; + map.wrapT = THREE.RepeatWrapping; + map.anisotropy = 4; + map.repeat.set(10, 24); + floorMat.map = map; + floorMat.needsUpdate = true; }); - - textureLoader.load("textures/hardwood2_bump.jpg", new OnLoadCallback() { - @Override - public void onLoad(Texture map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(10, 24); - floorMat.bumpMap = map; - floorMat.needsUpdate = true; - } + textureLoader.load("textures/hardwood2_bump.jpg", map -> { + map.wrapS = THREE.RepeatWrapping; + map.wrapT = THREE.RepeatWrapping; + map.anisotropy = 4; + map.repeat.set(10, 24); + floorMat.bumpMap = map; + floorMat.needsUpdate = true; }); - - textureLoader.load("textures/hardwood2_roughness.jpg", new OnLoadCallback() { - @Override - public void onLoad(Texture map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(10, 24); - floorMat.roughnessMap = map; - floorMat.needsUpdate = true; - } + textureLoader.load("textures/hardwood2_roughness.jpg", map -> { + map.wrapS = THREE.RepeatWrapping; + map.wrapT = THREE.RepeatWrapping; + map.anisotropy = 4; + map.repeat.set(10, 24); + floorMat.roughnessMap = map; + floorMat.needsUpdate = true; }); MeshStandardMaterialParameters meshStandardMaterialParameters2 = new MeshStandardMaterialParameters(); @@ -157,34 +142,23 @@ public void onLoad(Texture map) { cubeMat = new MeshStandardMaterial(meshStandardMaterialParameters2); - - textureLoader.load("textures/brick_diffuse.jpg", new OnLoadCallback() { - @Override - public void onLoad(Texture map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(1, 1); - cubeMat.map = map; - cubeMat.needsUpdate = true; - } + textureLoader.load("textures/brick_diffuse.jpg", map -> { + map.wrapS = THREE.RepeatWrapping; + map.wrapT = THREE.RepeatWrapping; + map.anisotropy = 4; + map.repeat.set(1, 1); + cubeMat.map = map; + cubeMat.needsUpdate = true; }); - - textureLoader.load("textures/brick_bump.jpg", new - OnLoadCallback() { - @Override - public void onLoad(Texture map) { - map.wrapS = THREE.RepeatWrapping; - map.wrapT = THREE.RepeatWrapping; - map.anisotropy = 4; - map.repeat.set(1, 1); - cubeMat.bumpMap = map; - cubeMat.needsUpdate = true; - - } - }); - + textureLoader.load("textures/brick_bump.jpg", map -> { + map.wrapS = THREE.RepeatWrapping; + map.wrapT = THREE.RepeatWrapping; + map.anisotropy = 4; + map.repeat.set(1, 1); + cubeMat.bumpMap = map; + cubeMat.needsUpdate = true; + }); MeshStandardMaterialParameters meshStandardMaterialParameters3 = new MeshStandardMaterialParameters(); meshStandardMaterialParameters3.color = new Color(0xffffff); @@ -193,26 +167,18 @@ public void onLoad(Texture map) { ballMat = new MeshStandardMaterial(meshStandardMaterialParameters3); - textureLoader.load("textures/planets/earth_atmos_2048.jpg", new OnLoadCallback() { - @Override - public void onLoad(Texture map) { - map.anisotropy = 4; - ballMat.map = map; - ballMat.needsUpdate = true; - - } + textureLoader.load("textures/planets/earth_atmos_2048.jpg", map -> { + map.anisotropy = 4; + ballMat.map = map; + ballMat.needsUpdate = true; }); - textureLoader.load("textures/planets/earth_specular_2048.jpg", new OnLoadCallback() { - @Override - public void onLoad(Texture map) { - map.anisotropy = 4; - ballMat.metalnessMap = map; - ballMat.needsUpdate = true; - } + textureLoader.load("textures/planets/earth_specular_2048.jpg", map -> { + map.anisotropy = 4; + ballMat.metalnessMap = map; + ballMat.needsUpdate = true; }); - PlaneBufferGeometry floorGeometry = new PlaneBufferGeometry(20, 20); Mesh floorMesh = new Mesh(floorGeometry, floorMat); floorMesh.receiveShadow = true; @@ -239,6 +205,7 @@ public void onLoad(Texture map) { boxMesh3.castShadow = true; scene.add(boxMesh3); + renderer = new WebGLRenderer(); renderer.physicallyCorrectLights = true; renderer.gammaInput = true; renderer.gammaOutput = true; @@ -256,7 +223,6 @@ private void setupGui() { gui = new GUI(guiProperty); - gui.add("hemiIrradiance", hemiLuminousIrradiances.keySet().toArray(new String[hemiLuminousIrradiances.size()]), hemiIrradiance).onChange(new OnChange() { @Override public void onChange(Object result) { @@ -282,7 +248,6 @@ public void onChange(Number result) { gui.finishAndBuild(); AppSetup.guiDiv.get().appendChild(gui.getDomElement()); - } @Override @@ -295,13 +260,12 @@ public void doAttachScene() { @Override protected void doAttachInfo() { AppSetup.infoDiv.show().setHrefToInfo("http://threejs.org").setTextContentToInfo("three.js").setInnetHtml(" - Physically accurate lighting example using a incandescent bulb - by Ben Houston
\n" + - "\t\t\tUsing real world scale: Brick cube is 1 meter in size. Light is 2 meters from floor. Globe is 25 cm in diameter.
\n" + - "\t\t\tUsing Reinhard inline tonemapping with real-world light falloff (decay = 2)."); - + "\t\t\tUsing real world scale: Brick cube is 1 meter in size. Light is 2 meters from floor. Globe is 25 cm in diameter.
\n" + + "\t\t\tUsing Reinhard inline tonemapping with real-world light falloff (decay = 2)."); } private void animate() { - AnimationScheduler.get().requestAnimationFrame(timestamp -> { + DomGlobal.requestAnimationFrame(timestamp -> { if (root.parentNode != null) { StatsProducer.getStats().update(); render(); @@ -327,7 +291,6 @@ private void render() { bulbLight.position.y = (float) Math.cos(time) * 0.75f + 1.25f; renderer.render(scene, camera); } - } diff --git a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/loaders/WebglLoaderVrml.java b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/loaders/WebglLoaderVrml.java index 89991de0..de25f6d4 100644 --- a/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/loaders/WebglLoaderVrml.java +++ b/demo/src/main/java/org/treblereel/gwt/three4g/demo/client/local/examples/loaders/WebglLoaderVrml.java @@ -1,5 +1,6 @@ package org.treblereel.gwt.three4g.demo.client.local.examples.loaders; +import com.google.gwt.core.client.GWT; import elemental2.dom.DomGlobal; import org.treblereel.gwt.three4g.InjectJavaScriptFor; import org.treblereel.gwt.three4g.cameras.PerspectiveCamera; @@ -8,6 +9,7 @@ import org.treblereel.gwt.three4g.demo.client.local.utils.StatsProducer; import org.treblereel.gwt.three4g.extensions.controls.OrbitControls; import org.treblereel.gwt.three4g.extensions.loaders.VRMLLoader; +import org.treblereel.gwt.three4g.extensions.resources.Extensions; import org.treblereel.gwt.three4g.lights.DirectionalLight; import org.treblereel.gwt.three4g.loaders.OnLoadCallback; import org.treblereel.gwt.three4g.renderers.WebGLRenderer; @@ -23,6 +25,8 @@ public class WebglLoaderVrml extends Attachable { public static final String name = "loader / vrml"; + Extensions extensions = GWT.create(Extensions.class); + public WebglLoaderVrml() { camera = new PerspectiveCamera(60, aspect, 0.01f, 1e10f); diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/HDRCubeTextureLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/HDRCubeTextureLoader.java index 41f151d0..0434bdae 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/HDRCubeTextureLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/HDRCubeTextureLoader.java @@ -73,4 +73,9 @@ public HDRCubeTextureLoader(LoadingManager manager) { * @return instance of HDRCubeTextureLoader */ public native HDRCubeTextureLoader setPath(String path); + + + public native HDRCubeTextureLoader setType(int type); + + } diff --git a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java index 6267c496..eda23a54 100644 --- a/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java +++ b/extensions/src/main/java/org/treblereel/gwt/three4g/extensions/loaders/VRMLLoader.java @@ -8,11 +8,10 @@ /** * Virtual Reality Modeling Language loader - * * @author Dmitrii Tikhomirov * Created by treblereel on 10/9/18. */ -@Three4gElement(paths = "js/loaders/VRMLLoader.js") +@Three4gElement(paths = {"js/libs/chevrotain.min.js", "js/loaders/VRMLLoader.js"}) @JsType(isNative = true, namespace = "THREE") public class VRMLLoader extends AbstractLoader { diff --git a/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/libs/chevrotain.min.js b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/libs/chevrotain.min.js new file mode 100644 index 00000000..b13f38de --- /dev/null +++ b/extensions/src/main/resources/org/treblereel/gwt/three4g/extensions/resources/js/libs/chevrotain.min.js @@ -0,0 +1,2 @@ +/*! chevrotain - v4.6.0 */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("chevrotain",[],e):"object"==typeof exports?exports.chevrotain=e():t.chevrotain=e()}("undefined"!=typeof self?self:this,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=18)}([function(t,e,n){"use strict";function r(t){return t&&0===t.length}function i(t){return null==t?[]:Object.keys(t)}function o(t){for(var e=[],n=Object.keys(t),r=0;r0})},e.expandCategories=a,e.assignTokenDefaultProps=s,e.assignCategoriesTokensProp=u,e.assignCategoriesMapProp=c,e.singleAssignCategoriesToksMap=p,e.hasShortKeyProperty=l,e.hasCategoriesProperty=h,e.hasExtendingTokensTypesProperty=f,e.hasExtendingTokensTypesMapProperty=d,e.hasTokenNameProperty=E,e.isTokenType=function(t){return r.has(t,"tokenTypeIdx")}},function(t,e,n){"use strict";var r,i=this&&this.__extends||(r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)},function(t,e){function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)});Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),a=n(1),s=n(5),u=n(2);e.isSequenceProd=function(t){return t instanceof a.Flat||t instanceof a.Option||t instanceof a.Repetition||t instanceof a.RepetitionMandatory||t instanceof a.RepetitionMandatoryWithSeparator||t instanceof a.RepetitionWithSeparator||t instanceof a.Terminal||t instanceof a.Rule},e.isOptionalProd=function t(e,n){return void 0===n&&(n=[]),!!(e instanceof a.Option||e instanceof a.Repetition||e instanceof a.RepetitionWithSeparator)||(e instanceof a.Alternation?o.some(e.definition,function(e){return t(e,n)}):!(e instanceof a.NonTerminal&&o.contains(n,e))&&e instanceof a.AbstractProduction&&(e instanceof a.NonTerminal&&n.push(e),o.every(e.definition,function(e){return t(e,n)})))},e.isBranchingProd=function(t){return t instanceof a.Alternation},e.getProductionDslName=function(t){if(t instanceof a.NonTerminal)return"SUBRULE";if(t instanceof a.Option)return"OPTION";if(t instanceof a.Alternation)return"OR";if(t instanceof a.RepetitionMandatory)return"AT_LEAST_ONE";if(t instanceof a.RepetitionMandatoryWithSeparator)return"AT_LEAST_ONE_SEP";if(t instanceof a.RepetitionWithSeparator)return"MANY_SEP";if(t instanceof a.Repetition)return"MANY";if(t instanceof a.Terminal)return"CONSUME";throw Error("non exhaustive match")};var c=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.separator="-",e.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]},e}return i(e,t),e.prototype.visitTerminal=function(t){var e=u.tokenName(t.terminalType)+this.separator+"Terminal";o.has(this.dslMethods,e)||(this.dslMethods[e]=[]),this.dslMethods[e].push(t)},e.prototype.visitNonTerminal=function(t){var e=t.nonTerminalName+this.separator+"Terminal";o.has(this.dslMethods,e)||(this.dslMethods[e]=[]),this.dslMethods[e].push(t)},e.prototype.visitOption=function(t){this.dslMethods.option.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.dslMethods.repetitionWithSeparator.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.dslMethods.repetitionMandatory.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.dslMethods.repetitionMandatoryWithSeparator.push(t)},e.prototype.visitRepetition=function(t){this.dslMethods.repetition.push(t)},e.prototype.visitAlternation=function(t){this.dslMethods.alternation.push(t)},e}(s.GAstVisitor);e.DslMethodsCollectorVisitor=c},function(t,e,n){"use strict";function r(t,e,n){return n|e|t}Object.defineProperty(e,"__esModule",{value:!0}),e.BITS_FOR_METHOD_IDX=4,e.BITS_FOR_OCCURRENCE_IDX=4,e.BITS_FOR_RULE_IDX=24,e.BITS_FOR_ALT_IDX=8,e.OR_IDX=1<")+a}},Object.freeze(e.defaultParserErrorProvider),e.defaultGrammarResolverErrorProvider={buildRuleNotFoundError:function(t,e){return"Invalid grammar, reference to a rule which is not defined: ->"+e.nonTerminalName+"<-\ninside top level rule: ->"+t.name+"<-"}},e.defaultGrammarValidatorErrorProvider={buildDuplicateFoundError:function(t,e){var n,i=t.name,u=o.first(e),c=u.idx,p=s.getProductionDslName(u),l=(n=u)instanceof a.Terminal?r.tokenName(n.terminalType):n instanceof a.NonTerminal?n.nonTerminalName:"",h="->"+p+"<- with numerical suffix: ->"+c+"<-\n "+(l?"and argument: ->"+l+"<-":"")+"\n appears more than once ("+e.length+" times) in the top level rule: ->"+i+"<-.\n "+(0===c?"Also note that numerical suffix 0 means "+p+" without any suffix.":"")+"\n To fix this make sure each usage of "+p+" "+(l?"with the argument: ->"+l+"<-":"")+"\n in the rule ->"+i+"<- has a different occurrence index (0-5), as that combination acts as a unique\n position key in the grammar, which is needed by the parsing engine.\n \n For further details see: https://sap.github.io/chevrotain/docs/FAQ.html#NUMERICAL_SUFFIXES \n ";return h=(h=h.replace(/[ \t]+/g," ")).replace(/\s\s+/g,"\n")},buildInvalidNestedRuleNameError:function(t,e){return"Invalid nested rule name: ->"+e.name+"<- inside rule: ->"+t.name+"<-\nit must match the pattern: ->"+u.validNestedRuleName.toString()+"<-.\nNote that this means a nested rule name must start with the '$'(dollar) sign."},buildDuplicateNestedRuleNameError:function(t,e){return"Duplicate nested rule name: ->"+o.first(e).name+"<- inside rule: ->"+t.name+"<-\nA nested name must be unique in the scope of a top level grammar rule."},buildNamespaceConflictError:function(t){return"Namespace conflict found in grammar.\nThe grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <"+t.name+">.\nTo resolve this make sure each Terminal and Non-Terminal names are unique\nThis is easy to accomplish by using the convention that Terminal names start with an uppercase letter\nand Non-Terminal names start with a lower case letter."},buildAlternationPrefixAmbiguityError:function(t){var e=o.map(t.prefixPath,function(t){return r.tokenLabel(t)}).join(", "),n=0===t.alternation.idx?"":t.alternation.idx;return"Ambiguous alternatives: <"+t.ambiguityIndices.join(" ,")+"> due to common lookahead prefix\nin inside <"+t.topLevelRule.name+"> Rule,\n<"+e+"> may appears as a prefix path in all these alternatives.\nhttps://sap.github.io/chevrotain/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX\nFor Further details."},buildAlternationAmbiguityError:function(t){var e=o.map(t.prefixPath,function(t){return r.tokenLabel(t)}).join(", "),n=0===t.alternation.idx?"":t.alternation.idx,i="Ambiguous alternatives: <"+t.ambiguityIndices.join(" ,")+"> in inside <"+t.topLevelRule.name+"> Rule,\n<"+e+"> may appears as a prefix path in all these alternatives.\n",a=c.VERSION.replace(/\./g,"_");return i=i+"To Resolve this, try one of of the following: \n1. Refactor your grammar to be LL(K) for the current value of k (by default k="+p.DEFAULT_PARSER_CONFIG.maxLookahead+"})\n2. Increase the value of K for your grammar by providing a larger 'maxLookahead' value in the parser's config\n3. This issue can be ignored (if you know what you are doing...), see https://sap.github.io/chevrotain/documentation/"+a+"/interfaces/iparserconfig.html#ignoredissues for more details\n"},buildEmptyRepetitionError:function(t){var e=s.getProductionDslName(t.repetition);return 0!==t.repetition.idx&&(e+=t.repetition.idx),"The repetition <"+e+"> within Rule <"+t.topLevelRule.name+"> can never consume any tokens.\nThis could lead to an infinite loop."},buildTokenNameError:function(t){return"Invalid Grammar Token name: ->"+r.tokenName(t.tokenType)+"<- it must match the pattern: ->"+t.expectedPattern.toString()+"<-"},buildEmptyAlternationError:function(t){return"Ambiguous empty alternative: <"+(t.emptyChoiceIdx+1)+"> in inside <"+t.topLevelRule.name+"> Rule.\nOnly the last alternative may be an empty alternative."},buildTooManyAlternativesError:function(t){return"An Alternation cannot have more than 256 alternatives:\n inside <"+t.topLevelRule.name+"> Rule.\n has "+(t.alternation.definition.length+1)+" alternatives."},buildLeftRecursionError:function(t){var e=t.topLevelRule.name;return"Left Recursion found in grammar.\nrule: <"+e+"> can be invoked from itself (directly or indirectly)\nwithout consuming any Tokens. The grammar path that causes this is: \n "+(e+" --\x3e "+i.map(t.leftRecursionPath,function(t){return t.name}).concat([e]).join(" --\x3e "))+"\n To fix this refactor your grammar to remove the left recursion.\nsee: https://en.wikipedia.org/wiki/LL_parser#Left_Factoring."},buildInvalidRuleNameError:function(t){return"Invalid grammar rule name: ->"+t.topLevelRule.name+"<- it must match the pattern: ->"+t.expectedPattern.toString()+"<-"},buildDuplicateRuleNameError:function(t){return"Duplicate definition, rule: ->"+(t.topLevelRule instanceof a.Rule?t.topLevelRule.name:t.topLevelRule)+"<- is already defined in the grammar: ->"+t.grammarName+"<-"}}},function(t,e,n){"use strict";var r,i=this&&this.__extends||(r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(t,e)},function(t,e){function n(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(n.prototype=e.prototype,new n)});Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),a=n(0),s=n(3),u=n(8),c=n(2),p=n(12),l=n(16),h=n(13),f=n(1),d=n(5);function E(t){return u.getProductionDslName(t)+"_#_"+t.idx+"_#_"+m(t)}function m(t){return t instanceof f.Terminal?c.tokenName(t.terminalType):t instanceof f.NonTerminal?t.nonTerminalName:""}e.validateGrammar=function(t,e,n,r,i,p){var h=o.map(t,function(t){return function(t,e){var n=new y;t.accept(n);var r=n.allProductions,i=o.groupBy(r,E),a=o.pick(i,function(t){return t.length>1});return o.map(o.values(a),function(n){var r=o.first(n),i=e.buildDuplicateFoundError(t,n),a=u.getProductionDslName(r),c={message:i,type:s.ParserDefinitionErrorType.DUPLICATE_PRODUCTIONS,ruleName:t.name,dslName:a,occurrence:r.idx},p=m(r);return p&&(c.parameter=p),c})}(t,i)}),f=o.map(t,function(t){return R(t,t,i)}),d=[],A=[],N=[];a.every(f,a.isEmpty)&&(d=a.map(t,function(t){return O(t,i)}),A=a.map(t,function(t){return S(t,e,r,i)}),N=k(t,e,i));var I=function(t,e,n){var r=[],i=a.map(e,function(t){return c.tokenName(t)});return a.forEach(t,function(t){var e=t.name;if(a.contains(i,e)){var o=n.buildNamespaceConflictError(t);r.push({message:o,type:s.ParserDefinitionErrorType.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:e})}}),r}(t,n,i),P=o.map(n,function(t){return g(t,i)}),x=function(t,e){var n=[];return a.forEach(t,function(t){var r=new l.NamedDSLMethodsCollectorVisitor("");t.accept(r);var i=a.map(r.result,function(t){return t.orgProd});n.push(a.map(i,function(n){return v(t,n,e)}))}),a.flatten(n)}(t,i),C=function(t,e){var n=[];return a.forEach(t,function(t){var r=new l.NamedDSLMethodsCollectorVisitor("");t.accept(r);var i=a.groupBy(r.result,function(t){return t.name}),o=a.pick(i,function(t){return t.length>1});a.forEach(a.values(o),function(r){var i=a.map(r,function(t){return t.orgProd}),o=e.buildDuplicateNestedRuleNameError(t,i);n.push({message:o,type:s.ParserDefinitionErrorType.DUPLICATE_NESTED_NAME,ruleName:t.name})})}),n}(t,i),M=a.map(t,function(t){return L(t,i)}),F=a.map(t,function(t){return T(t,i)}),b=a.map(t,function(e){return _(e,t,p,i)});return o.flatten(h.concat(P,x,C,N,f,d,A,I,M,F,b))},e.identifyProductionForDuplicates=E;var y=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.allProductions=[],e}return i(e,t),e.prototype.visitNonTerminal=function(t){this.allProductions.push(t)},e.prototype.visitOption=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e.prototype.visitAlternation=function(t){this.allProductions.push(t)},e.prototype.visitTerminal=function(t){this.allProductions.push(t)},e}(d.GAstVisitor);function T(t,n){var r=[],i=t.name;return i.match(e.validTermsPattern)||r.push({message:n.buildInvalidRuleNameError({topLevelRule:t,expectedPattern:e.validTermsPattern}),type:s.ParserDefinitionErrorType.INVALID_RULE_NAME,ruleName:i}),r}function v(t,n,r){var i,o=[];return n.name.match(e.validNestedRuleName)||(i=r.buildInvalidNestedRuleNameError(t,n),o.push({message:i,type:s.ParserDefinitionErrorType.INVALID_NESTED_RULE_NAME,ruleName:t.name})),o}function g(t,n){var r=[];return c.tokenName(t).match(e.validTermsPattern)||r.push({message:n.buildTokenNameError({tokenType:t,expectedPattern:e.validTermsPattern}),type:s.ParserDefinitionErrorType.INVALID_TOKEN_NAME}),r}function _(t,e,n,r){var i=[];if(a.reduce(e,function(e,n){return n.name===t.name?e+1:e},0)>1){var o=r.buildDuplicateRuleNameError({topLevelRule:t,grammarName:n});i.push({message:o,type:s.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:t.name})}return i}function R(t,e,n,r){void 0===r&&(r=[]);var i=[],a=A(e.definition);if(o.isEmpty(a))return[];var u=t.name;o.contains(a,t)&&i.push({message:n.buildLeftRecursionError({topLevelRule:t,leftRecursionPath:r}),type:s.ParserDefinitionErrorType.LEFT_RECURSION,ruleName:u});var c=o.difference(a,r.concat([t])),p=o.map(c,function(e){var i=o.cloneArr(r);return i.push(e),R(t,e,n,i)});return i.concat(o.flatten(p))}function A(t){var e=[];if(o.isEmpty(t))return e;var n=o.first(t);if(n instanceof f.NonTerminal)e.push(n.referencedRule);else if(n instanceof f.Flat||n instanceof f.Option||n instanceof f.RepetitionMandatory||n instanceof f.RepetitionMandatoryWithSeparator||n instanceof f.RepetitionWithSeparator||n instanceof f.Repetition)e=e.concat(A(n.definition));else if(n instanceof f.Alternation)e=o.flatten(o.map(n.definition,function(t){return A(t.definition)}));else if(!(n instanceof f.Terminal))throw Error("non exhaustive match");var r=u.isOptionalProd(n),i=t.length>1;if(r&&i){var a=o.drop(t);return e.concat(A(a))}return e}e.OccurrenceValidationCollector=y,e.validTermsPattern=/^[a-zA-Z_]\w*$/,e.validNestedRuleName=new RegExp(e.validTermsPattern.source.replace("^","^\\$")),e.validateRuleName=T,e.validateNestedRuleName=v,e.validateTokenName=g,e.validateRuleDoesNotAlreadyExist=_,e.validateRuleIsOverridden=function(t,e,n){var r,i=[];return o.contains(e,t)||(r="Invalid rule override, rule: ->"+t+"<- cannot be overridden in the grammar: ->"+n+"<-as it is not defined in any of the super grammars ",i.push({message:r,type:s.ParserDefinitionErrorType.INVALID_RULE_OVERRIDE,ruleName:t})),i},e.validateNoLeftRecursion=R,e.getFirstNoneTerminal=A;var N=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.alternations=[],e}return i(e,t),e.prototype.visitAlternation=function(t){this.alternations.push(t)},e}(d.GAstVisitor);function O(t,e){var n=new N;t.accept(n);var r=n.alternations;return o.reduce(r,function(n,r){var i=o.dropRight(r.definition),a=o.map(i,function(n,i){var a=h.nextPossibleTokensAfter([n],[],null,1);return o.isEmpty(a)?{message:e.buildEmptyAlternationError({topLevelRule:t,alternation:r,emptyChoiceIdx:i}),type:s.ParserDefinitionErrorType.NONE_LAST_EMPTY_ALT,ruleName:t.name,occurrence:r.idx,alternative:i+1}:null});return n.concat(o.compact(a))},[])}function S(t,e,n,r){var i=new N;t.accept(i);var c=i.alternations,l=n[t.name];return l&&(c=a.reject(c,function(t){return l[u.getProductionDslName(t)+(0===t.idx?"":t.idx)]})),o.reduce(c,function(n,i){var u=i.idx,c=p.getLookaheadPathsForOr(u,t,e),l=function(t,e,n,r){var i=[],u=a.reduce(t,function(e,n,r){return a.forEach(n,function(n){var o=[r];a.forEach(t,function(t,e){r!==e&&p.containsPath(t,n)&&o.push(e)}),o.length>1&&!p.containsPath(i,n)&&(i.push(n),e.push({alts:o,path:n}))}),e},[]);return o.map(u,function(t){var i=a.map(t.alts,function(t){return t+1}),o=r.buildAlternationAmbiguityError({topLevelRule:n,alternation:e,ambiguityIndices:i,prefixPath:t.path});return{message:o,type:s.ParserDefinitionErrorType.AMBIGUOUS_ALTS,ruleName:n.name,occurrence:e.idx,alternatives:[t.alts]}})}(c,i,t,r),h=P(c,i,t,r);return n.concat(l,h)},[])}e.validateEmptyOrAlternative=O,e.validateAmbiguousAlternationAlternatives=S;var I=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.allProductions=[],e}return i(e,t),e.prototype.visitRepetitionWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatory=function(t){this.allProductions.push(t)},e.prototype.visitRepetitionMandatoryWithSeparator=function(t){this.allProductions.push(t)},e.prototype.visitRepetition=function(t){this.allProductions.push(t)},e}(d.GAstVisitor);function L(t,e){var n=new N;t.accept(n);var r=n.alternations;return o.reduce(r,function(n,r){return r.definition.length>255&&n.push({message:e.buildTooManyAlternativesError({topLevelRule:t,alternation:r}),type:s.ParserDefinitionErrorType.TOO_MANY_ALTS,ruleName:t.name,occurrence:r.idx}),n},[])}function k(t,e,n){var r=[];return a.forEach(t,function(t){var i=new I;t.accept(i);var o=i.allProductions;a.forEach(o,function(i){var o=p.getProdType(i),u=i.idx,c=p.getLookaheadPathsForOptionalProd(u,t,o,e)[0];if(a.isEmpty(a.flatten(c))){var l=n.buildEmptyRepetitionError({topLevelRule:t,repetition:i});r.push({message:l,type:s.ParserDefinitionErrorType.NO_NON_EMPTY_LOOKAHEAD,ruleName:t.name})}})}),r}function P(t,e,n,r){var i=[],o=a.reduce(t,function(t,e,n){var r=a.map(e,function(t){return{idx:n,path:t}});return t.concat(r)},[]);return a.forEach(o,function(t){var u=t.idx,c=t.path,l=a.findAll(o,function(t){return t.idx=0;L--){var k={idx:d,def:T.definition[L].definition.concat(a.drop(f)),ruleStack:E,occurrenceStack:m};l.push(k),l.push("EXIT_ALTERNATIVE")}else if(T instanceof c.Flat)l.push({idx:d,def:T.definition.concat(a.drop(f)),ruleStack:E,occurrenceStack:m});else{if(!(T instanceof c.Rule))throw Error("non exhaustive match");l.push(y(T,d,E,m))}}}else o&&a.last(l).idx<=u&&l.pop()}return p}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(0),i=n(1),o=function(){function t(){}return t.prototype.walk=function(t,e){var n=this;void 0===e&&(e=[]),r.forEach(t.definition,function(o,a){var s=r.drop(t.definition,a+1);if(o instanceof i.NonTerminal)n.walkProdRef(o,s,e);else if(o instanceof i.Terminal)n.walkTerminal(o,s,e);else if(o instanceof i.Flat)n.walkFlat(o,s,e);else if(o instanceof i.Option)n.walkOption(o,s,e);else if(o instanceof i.RepetitionMandatory)n.walkAtLeastOne(o,s,e);else if(o instanceof i.RepetitionMandatoryWithSeparator)n.walkAtLeastOneSep(o,s,e);else if(o instanceof i.RepetitionWithSeparator)n.walkManySep(o,s,e);else if(o instanceof i.Repetition)n.walkMany(o,s,e);else{if(!(o instanceof i.Alternation))throw Error("non exhaustive match");n.walkOr(o,s,e)}})},t.prototype.walkTerminal=function(t,e,n){},t.prototype.walkProdRef=function(t,e,n){},t.prototype.walkFlat=function(t,e,n){var r=e.concat(n);this.walk(t,r)},t.prototype.walkOption=function(t,e,n){var r=e.concat(n);this.walk(t,r)},t.prototype.walkAtLeastOne=function(t,e,n){var r=[new i.Option({definition:t.definition})].concat(e,n);this.walk(t,r)},t.prototype.walkAtLeastOneSep=function(t,e,n){var r=a(t,e,n);this.walk(t,r)},t.prototype.walkMany=function(t,e,n){var r=[new i.Option({definition:t.definition})].concat(e,n);this.walk(t,r)},t.prototype.walkManySep=function(t,e,n){var r=a(t,e,n);this.walk(t,r)},t.prototype.walkOr=function(t,e,n){var o=this,a=e.concat(n);r.forEach(t.definition,function(t){var e=new i.Flat({definition:[t]});o.walk(e,a)})},t}();function a(t,e,n){return[new i.Option({definition:[new i.Terminal({terminalType:t.separator})].concat(t.definition)})].concat(e,n)}e.RestWalker=o},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(27),i=n(0),o=n(7),a=n(20);!function(t){t[t.MISSING_PATTERN=0]="MISSING_PATTERN",t[t.INVALID_PATTERN=1]="INVALID_PATTERN",t[t.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",t[t.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",t[t.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",t[t.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",t[t.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",t[t.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",t[t.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",t[t.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",t[t.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",t[t.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",t[t.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",t[t.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",t[t.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",t[t.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",t[t.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK"}(e.LexerDefinitionErrorType||(e.LexerDefinitionErrorType={}));var s={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:["\n","\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:a.defaultLexerErrorProvider};Object.freeze(s);var u=function(){function t(t,e){var n=this;if(void 0===e&&(e=s),this.lexerDefinition=t,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.config=void 0,this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},"boolean"==typeof e)throw Error("The second argument to the Lexer constructor is now an ILexerConfig Object.\na boolean 2nd argument is no longer supported");if(this.config=i.merge(s,e),this.config.lineTerminatorsPattern===s.lineTerminatorsPattern)this.config.lineTerminatorsPattern=r.LineTerminatorOptimizedTester;else if(this.config.lineTerminatorCharacters===s.lineTerminatorCharacters)throw Error("Error: Missing property on the Lexer config.\n\tFor details See: https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS");if(e.safeMode&&e.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');this.trackStartLines=/full|onlyStart/i.test(this.config.positionTracking),this.trackEndLines=/full/i.test(this.config.positionTracking);var a,u=!0;i.isArray(t)?((a={modes:{}}).modes[r.DEFAULT_MODE]=i.cloneArr(t),a[r.DEFAULT_MODE]=r.DEFAULT_MODE):(u=!1,a=i.cloneObj(t)),this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(r.performRuntimeChecks(a,this.trackStartLines,this.config.lineTerminatorCharacters)),this.lexerDefinitionWarning=this.lexerDefinitionWarning.concat(r.performWarningRuntimeChecks(a,this.trackStartLines,this.config.lineTerminatorCharacters)),a.modes=a.modes?a.modes:{},i.forEach(a.modes,function(t,e){a.modes[e]=i.reject(t,function(t){return i.isUndefined(t)})});var c=i.keys(a.modes);if(i.forEach(a.modes,function(t,a){if(n.modes.push(a),n.lexerDefinitionErrors=n.lexerDefinitionErrors.concat(r.validatePatterns(t,c)),i.isEmpty(n.lexerDefinitionErrors)){o.augmentTokenTypes(t);var s=r.analyzeTokenTypes(t,{lineTerminatorCharacters:n.config.lineTerminatorCharacters,positionTracking:e.positionTracking,ensureOptimizations:e.ensureOptimizations,safeMode:e.safeMode});n.patternIdxToConfig[a]=s.patternIdxToConfig,n.charCodeToPatternIdxToConfig[a]=s.charCodeToPatternIdxToConfig,n.emptyGroups=i.merge(n.emptyGroups,s.emptyGroups),n.hasCustom=s.hasCustom||n.hasCustom,n.canModeBeOptimized[a]=s.canBeOptimized}}),this.defaultMode=a.defaultMode,!i.isEmpty(this.lexerDefinitionErrors)&&!this.config.deferDefinitionErrorsHandling){var p=i.map(this.lexerDefinitionErrors,function(t){return t.message}).join("-----------------------\n");throw new Error("Errors detected in definition of Lexer:\n"+p)}if(i.forEach(this.lexerDefinitionWarning,function(t){i.PRINT_WARNING(t.message)}),r.SUPPORT_STICKY?(this.chopInput=i.IDENTITY,this.match=this.matchWithTest):(this.updateLastIndex=i.NOOP,this.match=this.matchWithExec),u&&(this.handleModes=i.NOOP),!1===this.trackStartLines&&(this.computeNewColumn=i.IDENTITY),!1===this.trackEndLines&&(this.updateTokenEndLineColumnLocation=i.NOOP),/full/i.test(this.config.positionTracking))this.createTokenInstance=this.createFullToken;else if(/onlyStart/i.test(this.config.positionTracking))this.createTokenInstance=this.createStartOnlyToken;else{if(!/onlyOffset/i.test(this.config.positionTracking))throw Error('Invalid config option: "'+this.config.positionTracking+'"');this.createTokenInstance=this.createOffsetOnlyToken}this.hasCustom?this.addToken=this.addTokenUsingPush:this.addToken=this.addTokenUsingMemberAccess;var l=i.reduce(this.canModeBeOptimized,function(t,e,n){return!1===e&&t.push(n),t},[]);if(e.ensureOptimizations&&!i.isEmpty(l))throw Error("Lexer Modes: < "+l.join(", ")+' > cannot be optimized.\n\t Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode.\n\t Or inspect the console log for details on how to resolve these issues.')}return t.prototype.tokenize=function(t,e){if(void 0===e&&(e=this.defaultMode),!i.isEmpty(this.lexerDefinitionErrors)){var n=i.map(this.lexerDefinitionErrors,function(t){return t.message}).join("-----------------------\n");throw new Error("Unable to Tokenize because Errors detected in definition of Lexer:\n"+n)}return this.tokenizeInternal(t,e)},t.prototype.tokenizeInternal=function(t,e){var n,o,a,s,u,c,p,l,h,f,d,E,m=this,y=t,T=y.length,v=0,g=0,_=this.hasCustom?0:Math.floor(t.length/10),R=new Array(_),A=[],N=this.trackStartLines?1:void 0,O=this.trackStartLines?1:void 0,S=r.cloneEmptyGroups(this.emptyGroups),I=this.trackStartLines,L=this.config.lineTerminatorsPattern,k=0,P=[],x=[],C=[],M=[];Object.freeze(M);var F,b=void 0,D=function(t){if(1===C.length&&void 0===t.tokenType.PUSH_MODE){var e=m.config.errorMessageProvider.buildUnableToPopLexerModeMessage(t);A.push({offset:t.startOffset,line:void 0!==t.startLine?t.startLine:void 0,column:void 0!==t.startColumn?t.startColumn:void 0,length:t.image.length,message:e})}else{C.pop();var n=i.last(C);P=m.patternIdxToConfig[n],x=m.charCodeToPatternIdxToConfig[n],k=P.length;var r=m.canModeBeOptimized[n]&&!1===m.config.safeMode;b=x&&r?function(t){var e=x[t];return void 0===e?M:e}:function(){return P}}};function w(t){C.push(t),x=this.charCodeToPatternIdxToConfig[t],P=this.patternIdxToConfig[t],k=P.length,k=P.length;var e=this.canModeBeOptimized[t]&&!1===this.config.safeMode;b=x&&e?function(t){var e=x[t];return void 0===e?M:e}:function(){return P}}for(w.call(this,e);vu.length&&(u=a,F=W)}break}}if(null!==u){if(c=u.length,void 0!==(p=F.group)&&(l=F.tokenTypeIdx,h=this.createTokenInstance(u,v,l,F.tokenType,N,O,c),!1===p?g=this.addToken(R,g,h):S[p].push(h)),t=this.chopInput(t,c),v+=c,O=this.computeNewColumn(O,c),!0===I&&!0===F.canLineTerminator){var V=0,Y=void 0,H=void 0;L.lastIndex=0;do{!0===(Y=L.test(u))&&(H=L.lastIndex-1,V++)}while(Y);0!==V&&(N+=V,O=c-H,this.updateTokenEndLineColumnLocation(h,p,H,V,N,O,c))}this.handleModes(F,D,w,h)}else{for(var X=v,z=N,q=O,$=!1;!$&&v1;o.forEach(t.definition,function(r,i){if(!o.isUndefined(r.name)){var a=r.definition;a=n?[new u.Option({definition:r.definition})]:r.definition;var c=s.getKeyForAltIndex(e.ruleIdx,s.OR_IDX,t.idx,i);e.result.push({def:a,key:c,name:r.name,orgProd:r})}})},e}(c.GAstVisitor);e.NamedDSLMethodsCollectorVisitor=p,e.analyzeCst=function(t,e){var n={dictDef:new a.HashTable,allRuleNames:[]};return o.forEach(t,function(t){var r=e.get(t.name);n.allRuleNames.push(t.name);var i=new p(r);t.accept(i),o.forEach(i.result,function(e){e.def,e.key;var r=e.name;n.allRuleNames.push(t.name+r)})}),n}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.VERSION="4.6.0"},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=n(15),o=n(2),a=n(6),s=n(17),u=n(10),c=n(39),p=n(5),l=n(1),h=n(24),f=n(40),d=n(20),E={};E.VERSION=s.VERSION,E.Parser=r.Parser,E.CstParser=r.CstParser,E.EmbeddedActionsParser=r.EmbeddedActionsParser;E.ParserDefinitionErrorType=r.ParserDefinitionErrorType,E.Lexer=i.Lexer,E.LexerDefinitionErrorType=i.LexerDefinitionErrorType,E.EOF=o.EOF,E.tokenName=o.tokenName,E.tokenLabel=o.tokenLabel,E.tokenMatcher=o.tokenMatcher,E.createToken=o.createToken,E.createTokenInstance=o.createTokenInstance,E.EMPTY_ALT=r.EMPTY_ALT,E.defaultParserErrorProvider=u.defaultParserErrorProvider,E.isRecognitionException=a.isRecognitionException,E.EarlyExitException=a.EarlyExitException,E.MismatchedTokenException=a.MismatchedTokenException,E.NotAllInputParsedException=a.NotAllInputParsedException,E.NoViableAltException=a.NoViableAltException,E.defaultLexerErrorProvider=d.defaultLexerErrorProvider,E.Flat=l.Flat,E.Repetition=l.Repetition,E.RepetitionWithSeparator=l.RepetitionWithSeparator,E.RepetitionMandatory=l.RepetitionMandatory,E.RepetitionMandatoryWithSeparator=l.RepetitionMandatoryWithSeparator,E.Option=l.Option,E.Alternation=l.Alternation,E.NonTerminal=l.NonTerminal,E.Terminal=l.Terminal,E.Rule=l.Rule,E.GAstVisitor=p.GAstVisitor,E.serializeGrammar=l.serializeGrammar,E.serializeProduction=l.serializeProduction,E.resolveGrammar=h.resolveGrammar,E.defaultGrammarResolverErrorProvider=u.defaultGrammarResolverErrorProvider,E.validateGrammar=h.validateGrammar,E.defaultGrammarValidatorErrorProvider=u.defaultGrammarValidatorErrorProvider,E.assignOccurrenceIndices=h.assignOccurrenceIndices,E.clearCache=function(){console.warn("The clearCache function was 'soft' removed from the Chevrotain API.\n\t It performs no action other than printing this message.\n\t Please avoid using it as it will be completely removed in the future")},E.createSyntaxDiagramsCode=c.createSyntaxDiagramsCode,E.generateParserFactory=f.generateParserFactory,E.generateParserModule=f.generateParserModule,t.exports=E},function(t,e,n){var r,i,o;"undefined"!=typeof self&&self,i=[],void 0===(o="function"==typeof(r=function(){function t(){}t.prototype.saveState=function(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}},t.prototype.restoreState=function(t){this.idx=t.idx,this.input=t.input,this.groupIdx=t.groupIdx},t.prototype.pattern=function(t){this.idx=0,this.input=t,this.groupIdx=0,this.consumeChar("/");var e=this.disjunction();this.consumeChar("/");for(var n={type:"Flags",global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};this.isRegExpFlag();)switch(this.popChar()){case"g":s(n,"global");break;case"i":s(n,"ignoreCase");break;case"m":s(n,"multiLine");break;case"u":s(n,"unicode");break;case"y":s(n,"sticky")}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:n,value:e}},t.prototype.disjunction=function(){var t=[];for(t.push(this.alternative());"|"===this.peekChar();)this.consumeChar("|"),t.push(this.alternative());return{type:"Disjunction",value:t}},t.prototype.alternative=function(){for(var t=[];this.isTerm();)t.push(this.term());return{type:"Alternative",value:t}},t.prototype.term=function(){return this.isAssertion()?this.assertion():this.atom()},t.prototype.assertion=function(){switch(this.popChar()){case"^":return{type:"StartAnchor"};case"$":return{type:"EndAnchor"};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary"};case"B":return{type:"NonWordBoundary"}}throw Error("Invalid Assertion Escape");case"(":var t;switch(this.consumeChar("?"),this.popChar()){case"=":t="Lookahead";break;case"!":t="NegativeLookahead"}u(t);var e=this.disjunction();return this.consumeChar(")"),{type:t,value:e}}!function(){throw Error("Internal Error - Should never get here!")}()},t.prototype.quantifier=function(t){var e;switch(this.popChar()){case"*":e={atLeast:0,atMost:1/0};break;case"+":e={atLeast:1,atMost:1/0};break;case"?":e={atLeast:0,atMost:1};break;case"{":var n=this.integerIncludingZero();switch(this.popChar()){case"}":e={atLeast:n,atMost:n};break;case",":var r;this.isDigit()?(r=this.integerIncludingZero(),e={atLeast:n,atMost:r}):e={atLeast:n,atMost:1/0},this.consumeChar("}")}if(!0===t&&void 0===e)return;u(e)}if(!0!==t||void 0!==e)return u(e),"?"===this.peekChar(0)?(this.consumeChar("?"),e.greedy=!1):e.greedy=!0,e.type="Quantifier",e},t.prototype.atom=function(){var t;switch(this.peekChar()){case".":t=this.dotAll();break;case"\\":t=this.atomEscape();break;case"[":t=this.characterClass();break;case"(":t=this.group()}return void 0===t&&this.isPatternCharacter()&&(t=this.patternCharacter()),u(t),this.isQuantifier()&&(t.quantifier=this.quantifier()),t},t.prototype.dotAll=function(){return this.consumeChar("."),{type:"Set",complement:!0,value:[o("\n"),o("\r"),o("\u2028"),o("\u2029")]}},t.prototype.atomEscape=function(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}},t.prototype.decimalEscapeAtom=function(){var t=this.positiveInteger();return{type:"GroupBackReference",value:t}},t.prototype.characterClassEscape=function(){var t,e=!1;switch(this.popChar()){case"d":t=c;break;case"D":t=c,e=!0;break;case"s":t=l;break;case"S":t=l,e=!0;break;case"w":t=p;break;case"W":t=p,e=!0}return u(t),{type:"Set",value:t,complement:e}},t.prototype.controlEscapeAtom=function(){var t;switch(this.popChar()){case"f":t=o("\f");break;case"n":t=o("\n");break;case"r":t=o("\r");break;case"t":t=o("\t");break;case"v":t=o("\v")}return u(t),{type:"Character",value:t}},t.prototype.controlLetterEscapeAtom=function(){this.consumeChar("c");var t=this.popChar();if(!1===/[a-zA-Z]/.test(t))throw Error("Invalid ");var e=t.toUpperCase().charCodeAt(0)-64;return{type:"Character",value:e}},t.prototype.nulCharacterAtom=function(){return this.consumeChar("0"),{type:"Character",value:o("\0")}},t.prototype.hexEscapeSequenceAtom=function(){return this.consumeChar("x"),this.parseHexDigits(2)},t.prototype.regExpUnicodeEscapeSequenceAtom=function(){return this.consumeChar("u"),this.parseHexDigits(4)},t.prototype.identityEscapeAtom=function(){var t=this.popChar();return{type:"Character",value:o(t)}},t.prototype.classPatternCharacterAtom=function(){switch(this.peekChar()){case"\n":case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:var t=this.popChar();return{type:"Character",value:o(t)}}},t.prototype.characterClass=function(){var t=[],e=!1;for(this.consumeChar("["),"^"===this.peekChar(0)&&(this.consumeChar("^"),e=!0);this.isClassAtom();){var n=this.classAtom(),r="Character"===n.type;if(r&&this.isRangeDash()){this.consumeChar("-");var i=this.classAtom(),s="Character"===i.type;if(s){if(i.value=this.input.length)throw Error("Unexpected end of input");this.idx++};var e,n=/[0-9a-fA-F]/,r=/[0-9]/,i=/[1-9]/;function o(t){return t.charCodeAt(0)}function a(t,e){void 0!==t.length?t.forEach(function(t){e.push(t)}):e.push(t)}function s(t,e){if(!0===t[e])throw"duplicate flag "+e;t[e]=!0}function u(t){if(void 0===t)throw Error("Internal Error - Should never get here!")}var c=[];for(e=o("0");e<=o("9");e++)c.push(e);var p=[o("_")].concat(c);for(e=o("a");e<=o("z");e++)p.push(e);for(e=o("A");e<=o("Z");e++)p.push(e);var l=[o(" "),o("\f"),o("\n"),o("\r"),o("\t"),o("\v"),o("\t"),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o(" "),o("\u2028"),o("\u2029"),o(" "),o(" "),o(" "),o("\ufeff")];function h(){}return h.prototype.visitChildren=function(t){for(var e in t){var n=t[e];t.hasOwnProperty(e)&&(void 0!==n.type?this.visit(n):Array.isArray(n)&&n.forEach(function(t){this.visit(t)},this))}},h.prototype.visit=function(t){switch(t.type){case"Pattern":this.visitPattern(t);break;case"Flags":this.visitFlags(t);break;case"Disjunction":this.visitDisjunction(t);break;case"Alternative":this.visitAlternative(t);break;case"StartAnchor":this.visitStartAnchor(t);break;case"EndAnchor":this.visitEndAnchor(t);break;case"WordBoundary":this.visitWordBoundary(t);break;case"NonWordBoundary":this.visitNonWordBoundary(t);break;case"Lookahead":this.visitLookahead(t);break;case"NegativeLookahead":this.visitNegativeLookahead(t);break;case"Character":this.visitCharacter(t);break;case"Set":this.visitSet(t);break;case"Group":this.visitGroup(t);break;case"GroupBackReference":this.visitGroupBackReference(t);break;case"Quantifier":this.visitQuantifier(t)}this.visitChildren(t)},h.prototype.visitPattern=function(t){},h.prototype.visitFlags=function(t){},h.prototype.visitDisjunction=function(t){},h.prototype.visitAlternative=function(t){},h.prototype.visitStartAnchor=function(t){},h.prototype.visitEndAnchor=function(t){},h.prototype.visitWordBoundary=function(t){},h.prototype.visitNonWordBoundary=function(t){},h.prototype.visitLookahead=function(t){},h.prototype.visitNegativeLookahead=function(t){},h.prototype.visitCharacter=function(t){},h.prototype.visitSet=function(t){},h.prototype.visitGroup=function(t){},h.prototype.visitGroupBackReference=function(t){},h.prototype.visitQuantifier=function(t){},{RegExpParser:t,BaseRegExpVisitor:h,VERSION:"0.4.0"}})?r.apply(e,i):r)||(t.exports=o)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.defaultLexerErrorProvider={buildUnableToPopLexerModeMessage:function(t){return"Unable to pop Lexer Mode after encountering Token ->"+t.image+"<- The Mode Stack is empty"},buildUnexpectedCharactersMessage:function(t,e,n,r,i){return"unexpected character: ->"+t.charAt(e)+"<- at offset: "+e+", skipped "+n+" characters."}}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(0),i=n(1),o=n(8);function a(t){if(t instanceof i.NonTerminal)return a(t.referencedRule);if(t instanceof i.Terminal)return c(t);if(o.isSequenceProd(t))return s(t);if(o.isBranchingProd(t))return u(t);throw Error("non exhaustive match")}function s(t){for(var e,n=[],i=t.definition,s=0,u=i.length>s,c=!0;u&&c;)e=i[s],c=o.isOptionalProd(e),n=n.concat(a(e)),s+=1,u=i.length>s;return r.uniq(n)}function u(t){var e=r.map(t.definition,function(t){return a(t)});return r.uniq(r.flatten(e))}function c(t){return[t.terminalType]}e.first=a,e.firstForSequence=s,e.firstForBranching=u,e.firstForTerminal=c},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.IN="_~IN~_"},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r,i=n(29),o=n(0),a=n(1);!function(t){t[t.OPTION=0]="OPTION",t[t.OR=1]="OR",t[t.MANY=2]="MANY",t[t.MANY_SEP=3]="MANY_SEP",t[t.AT_LEAST_ONE=4]="AT_LEAST_ONE",t[t.AT_LEAST_ONE_SEP=5]="AT_LEAST_ONE_SEP",t[t.REF=6]="REF",t[t.TERMINAL=7]="TERMINAL",t[t.FLAT=8]="FLAT"}(r=e.ProdType||(e.ProdType={}));var s=/(?:\s*{\s*NAME\s*:\s*["'`]([\w$]*)["'`])?/,u=new RegExp(s.source.replace("{","").replace(")?","\\s*,)?")),c=/\.\s*CONSUME(\d+)?\s*\(\s*(?:[a-zA-Z_$]\w*\s*\.\s*)*([a-zA-Z_$]\w*)/,p=new RegExp(c.source,"g"),l=/\.\s*SUBRULE(\d+)?\s*\(\s*(?:[a-zA-Z_$]\w*\s*\.\s*)*([a-zA-Z_$]\w*)/,h=new RegExp(l.source,"g"),f=/\.\s*OPTION(\d+)?\s*\(/,d=new RegExp(f.source+s.source),E=new RegExp(f.source,"g"),m=/\.\s*MANY(\d+)?\s*\(/,y=new RegExp(m.source+s.source),T=new RegExp(m.source,"g"),v=/\s*SEP\s*:\s*(?:[a-zA-Z_$]\w*\s*\.\s*)*([a-zA-Z_$]\w*)/,g=new RegExp(/\.\s*MANY_SEP(\d+)?\s*\(\s*{/.source+u.source+v.source),_=new RegExp(g.source,"g"),R=new RegExp(/\.\s*AT_LEAST_ONE_SEP(\d+)?\s*\(\s*{/.source+u.source+v.source),A=new RegExp(R.source,"g"),N=/\.\s*AT_LEAST_ONE(\d+)?\s*\(/,O=new RegExp(N.source+s.source),S=new RegExp(N.source,"g"),I=/\.\s*OR(\d+)?\s*\(/,L=new RegExp(I.source+s.source),k=new RegExp(I.source,"g"),P=new RegExp(u.source+/\s*(ALT)\s*:/.source),x=new RegExp(P.source,"g");function C(t,n,i){switch(t.type){case r.AT_LEAST_ONE:return function(t,e,n){return M(O,new a.RepetitionMandatory({definition:[]}),t,e,n)}(t,n,i);case r.AT_LEAST_ONE_SEP:return function(t,e,n){return F(t,e,a.RepetitionMandatoryWithSeparator,R,n)}(t,n,i);case r.MANY_SEP:return function(t,e,n){return F(t,e,a.RepetitionWithSeparator,g,n)}(t,n,i);case r.MANY:return function(t,e,n){return M(y,new a.Repetition({definition:[]}),t,e,n)}(t,n,i);case r.OPTION:return function(t,e,n){return M(d,new a.Option({definition:[]}),t,e,n)}(t,n,i);case r.OR:return function(t,e,n){return M(L,new a.Alternation({definition:[]}),t,e,n)}(t,n,i);case r.FLAT:return function(t,e,n){var r=new a.Flat({definition:[]}),i=P.exec(t.text)[1];o.isUndefined(i)||(r.name=i);return b(r,t.range,e,n)}(t,n,i);case r.REF:return function(t){var e=l.exec(t.text),n=void 0===e[1]?0:parseInt(e[1],10),r=e[2];return new a.NonTerminal({nonTerminalName:r,idx:n})}(t);case r.TERMINAL:return function(t,n){var r=c.exec(t.text),i=void 0===r[1]?0:parseInt(r[1],10),o=r[2],s=e.terminalNameToConstructor[o];if(!s)throw Error("Terminal Token name: <"+o+"> not found in rule: <"+n+"> \n\tSee: https://sap.github.io/chevrotain/docs/guide/resolving_grammar_errors.html#TERMINAL_NAME_NOT_FOUND\n\tFor Further details.");return new a.Terminal({terminalType:s,idx:i})}(t,i);default:throw Error("non exhaustive match")}}function M(t,e,n,r,i){var a=t.exec(n.text),s=void 0===a[1];e.idx=s?0:parseInt(a[1],10);var u=a[2];return o.isUndefined(u)||(e.name=u),b(e,n.range,r,i)}function F(t,n,r,i,a){var s=i.exec(t.text),u=void 0===s[1]?0:parseInt(s[1],10),c=s[3],p=e.terminalNameToConstructor[c];if(!p)throw Error("Separator Terminal Token name: "+c+" not found");var l=new r({definition:[],separator:p,idx:u}),h=s[2];return o.isUndefined(h)||(l.name=h),b(l,t.range,n,a)}function b(t,e,n,r){var i=D(e,n),a=o.sortBy(i,function(t){return t.range.start}),s=[];return o.forEach(a,function(t){s.push(C(t,n,r))}),t.definition=s,t}function D(t,e){return o.filter(e,function(n){var r=t.strictlyContainsRange(n.range),i=o.every(e,function(e){var r=e.range.strictlyContainsRange(n.range),i=e.range.isStrictlyContainedInRange(t);return!(r&&i)});return r&&i})}e.terminalNameToConstructor={},e.buildTopProduction=function(t,n,r){e.terminalNameToConstructor=r;var o=V(j(K(" "+t)));return function(t,e,n,r){return b(new a.Rule({name:t,definition:[],orgText:r}),e,n,t)}(n,new i.Range(0,t.length+2),o,t)},e.buildProdGast=C,e.getDirectlyContainedRanges=D;var w=/\/\/.*/g,U=/\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\//g,G=/(NAME\s*:\s*)?"([^\\"]|\\([bfnrtv"\\\/]|u[0-9a-fA-F]{4}))*"/g,B=/(NAME\s*:\s*)?'([^\\']|\\([bfnrtv'\\\/]|u[0-9a-fA-F]{4}))*'/g;function K(t){return t.replace(w,"").replace(U,"")}function W(t,e){return void 0!==e?t:""}function j(t){return t.replace(G,W).replace(B,W)}function V(t){var e=Y(t),n=H(t),r=X(t),i=z(t),o=q(t),a=$(t),s=Z(t),u=Q(t);return[].concat(e,n,r,i,o,a,s,u)}function Y(t){return nt(t,r.TERMINAL,p)}function H(t){return nt(t,r.REF,h)}function X(t){return rt(t,r.AT_LEAST_ONE,S)}function z(t){return rt(t,r.AT_LEAST_ONE_SEP,A)}function q(t){return rt(t,r.MANY,T)}function $(t){return rt(t,r.MANY_SEP,_)}function Z(t){return rt(t,r.OPTION,E)}function Q(t){var e=rt(t,r.OR,k),n=et(e);return e.concat(n)}e.removeComments=K,e.removeStringLiterals=j,e.createRanges=V,e.createTerminalRanges=Y,e.createRefsRanges=H,e.createAtLeastOneRanges=X,e.createAtLeastOneSepRanges=z,e.createManyRanges=q,e.createManySepRanges=$,e.createOptionRanges=Z,e.createOrRanges=Q;var J=o.partial(ot,"{","}"),tt=o.partial(ot,"(",")");function et(t){var e=[];return o.forEach(t,function(t){var n=it(t.text,r.FLAT,x,J),i=t.range.start;o.forEach(n,function(t){t.range.start+=i,t.range.end+=i}),e=e.concat(n)}),o.uniq(e,function(t){return t.type+"~"+t.range.start+"~"+t.range.end+"~"+t.text})}function nt(t,e,n){for(var r,o=[];r=n.exec(t);){var a=r.index,s=n.lastIndex,u=new i.Range(a,s),c=r[0];o.push({range:u,text:c,type:e})}return o}function rt(t,e,n){return it(t,e,n,tt)}function it(t,e,n,r){for(var o,a=[];o=n.exec(t);){var s=o.index,u=r(s+o[0].length,t),c=new i.Range(s,u),p=t.substr(s,u-s+1);a.push({range:c,text:p,type:e})}return a}function ot(t,e,n,r){for(var i=[1],a=-1;!o.isEmpty(i)&&a+n"+a.tokenName(t)+"<- missing static 'PATTERN' property",type:s.LexerDefinitionErrorType.MISSING_PATTERN,tokenTypes:[t]}}),valid:u.difference(t,e)}}function f(t){var e=u.filter(t,function(t){var e=t[l];return!(u.isRegExp(e)||u.isFunction(e)||u.has(e,"exec")||u.isString(e))});return{errors:u.map(e,function(t){return{message:"Token Type: ->"+a.tokenName(t)+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:s.LexerDefinitionErrorType.INVALID_PATTERN,tokenTypes:[t]}}),valid:u.difference(t,e)}}e.DEFAULT_MODE="defaultMode",e.MODES="modes",e.SUPPORT_STICKY="boolean"==typeof new RegExp("(?:)").sticky,e.disableSticky=function(){e.SUPPORT_STICKY=!1},e.enableSticky=function(){e.SUPPORT_STICKY=!0},e.analyzeTokenTypes=function(t,n){n=u.defaults(n,{useSticky:e.SUPPORT_STICKY,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r","\n"]});var r=u.reject(t,function(t){return t[l]===s.Lexer.NA}),i=!1,o=u.map(r,function(t){var e=t[l];if(u.isRegExp(e)){var r=e.source;return 1===r.length&&"^"!==r&&"$"!==r&&"."!==r?r:2!==r.length||"\\"!==r[0]||u.contains(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],r[1])?n.useSticky?O(e):N(e):r[1]}if(u.isFunction(e))return i=!0,{exec:e};if(u.has(e,"exec"))return i=!0,e;if("string"==typeof e){if(1===e.length)return e;var o=e.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),a=new RegExp(o);return n.useSticky?O(a):N(a)}throw Error("non exhaustive match")}),p=u.map(r,function(t){return t.tokenTypeIdx}),h=u.map(r,function(t){var e=t.GROUP;if(e!==s.Lexer.SKIPPED){if(u.isString(e))return e;if(u.isUndefined(e))return!1;throw Error("non exhaustive match")}}),f=u.map(r,function(t){var e=t.LONGER_ALT;if(e)return u.indexOf(r,e)}),d=u.map(r,function(t){return t.PUSH_MODE}),E=u.map(r,function(t){return u.has(t,"POP_MODE")}),m=P(n.lineTerminatorCharacters),y=u.map(r,function(t){return!1});"onlyOffset"!==n.positionTracking&&(y=u.map(r,function(t){return u.has(t,"LINE_BREAKS")?t.LINE_BREAKS:!1===L(t,m)?c.canMatchCharCode(m,t.PATTERN):void 0}));var T=u.map(r,S),v=u.map(o,I),g=u.reduce(r,function(t,e){var n=e.GROUP;return u.isString(n)&&n!==s.Lexer.SKIPPED&&(t[n]=[]),t},{}),_=u.map(o,function(t,e){return{pattern:o[e],longerAlt:f[e],canLineTerminator:y[e],isCustom:T[e],short:v[e],group:h[e],push:d[e],pop:E[e],tokenTypeIdx:p[e],tokenType:r[e]}});function R(t,e,n){void 0===t[e]&&(t[e]=[]),t[e].push(n)}var A=!0,k=[];return n.safeMode||(k=u.reduce(r,function(t,e,r){if("string"==typeof e.PATTERN){var i=e.PATTERN.charCodeAt(0);R(t,i,_[r])}else if(u.isArray(e.START_CHARS_HINT))u.forEach(e.START_CHARS_HINT,function(e){var n="string"==typeof e?e.charCodeAt(0):e;R(t,n,_[r])});else if(u.isRegExp(e.PATTERN))if(e.PATTERN.unicode)A=!1,n.ensureOptimizations&&u.PRINT_ERROR(c.failedOptimizationPrefixMsg+"\tUnable to analyze < "+e.PATTERN.toString()+" > pattern.\n\tThe regexp unicode flag is not currently supported by the regexp-to-ast library.\n\tThis will disable the lexer's first char optimizations.\n\tFor details See: https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE");else{var o=c.getStartCodes(e.PATTERN,n.ensureOptimizations);u.isEmpty(o)&&(A=!1),u.forEach(o,function(e){R(t,e,_[r])})}else n.ensureOptimizations&&u.PRINT_ERROR(c.failedOptimizationPrefixMsg+"\tTokenType: <"+a.tokenName(e)+"> is using a custom token pattern without providing parameter.\n\tThis will disable the lexer's first char optimizations.\n\tFor details See: https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE"),A=!1;return t},[])),A&&k.length<65536&&(k=u.packArray(k)),{emptyGroups:g,patternIdxToConfig:_,charCodeToPatternIdxToConfig:k,hasCustom:i,canBeOptimized:A}},e.validatePatterns=function(t,e){var n=[],r=h(t);n=n.concat(r.errors);var i=f(r.valid),o=i.valid;return n=(n=(n=(n=(n=n.concat(i.errors)).concat(function(t){var e=[],n=u.filter(t,function(t){return u.isRegExp(t[l])});return e=(e=(e=(e=(e=e.concat(E(n))).concat(T(n))).concat(v(n))).concat(g(n))).concat(m(n))}(o))).concat(_(o))).concat(R(o,e))).concat(A(o))},e.findMissingPatterns=h,e.findInvalidPatterns=f;var d=/[^\\][\$]/;function E(t){var e=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.found=!1,e}return i(e,t),e.prototype.visitEndAnchor=function(t){this.found=!0},e}(o.BaseRegExpVisitor),n=u.filter(t,function(t){var n=t[l];try{var r=p.pattern(n.toString()),i=new e;return i.visit(r),i.found}catch(t){return d.test(n.source)}});return u.map(n,function(t){return{message:"Unexpected RegExp Anchor Error:\n\tToken Type: ->"+a.tokenName(t)+"<- static 'PATTERN' cannot contain end of input anchor '$'\n\tSee sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#ANCHORS\tfor details.",type:s.LexerDefinitionErrorType.EOI_ANCHOR_FOUND,tokenTypes:[t]}})}function m(t){var e=u.filter(t,function(t){return t[l].test("")});return u.map(e,function(t){return{message:"Token Type: ->"+a.tokenName(t)+"<- static 'PATTERN' must not match an empty string",type:s.LexerDefinitionErrorType.EMPTY_MATCH_PATTERN,tokenTypes:[t]}})}e.findEndOfInputAnchor=E,e.findEmptyMatchRegExps=m;var y=/[^\\[][\^]|^\^/;function T(t){var e=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.found=!1,e}return i(e,t),e.prototype.visitStartAnchor=function(t){this.found=!0},e}(o.BaseRegExpVisitor),n=u.filter(t,function(t){var n=t[l];try{var r=p.pattern(n.toString()),i=new e;return i.visit(r),i.found}catch(t){return y.test(n.source)}});return u.map(n,function(t){return{message:"Unexpected RegExp Anchor Error:\n\tToken Type: ->"+a.tokenName(t)+"<- static 'PATTERN' cannot contain start of input anchor '^'\n\tSee https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#ANCHORS\tfor details.",type:s.LexerDefinitionErrorType.SOI_ANCHOR_FOUND,tokenTypes:[t]}})}function v(t){var e=u.filter(t,function(t){var e=t[l];return e instanceof RegExp&&(e.multiline||e.global)});return u.map(e,function(t){return{message:"Token Type: ->"+a.tokenName(t)+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:s.LexerDefinitionErrorType.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[t]}})}function g(t){var e=[],n=u.map(t,function(n){return u.reduce(t,function(t,r){return n.PATTERN.source!==r.PATTERN.source||u.contains(e,r)||r.PATTERN===s.Lexer.NA?t:(e.push(r),t.push(r),t)},[])});n=u.compact(n);var r=u.filter(n,function(t){return t.length>1});return u.map(r,function(t){var e=u.map(t,function(t){return a.tokenName(t)});return{message:"The same RegExp pattern ->"+u.first(t).PATTERN+"<-has been used in all of the following Token Types: "+e.join(", ")+" <-",type:s.LexerDefinitionErrorType.DUPLICATE_PATTERNS_FOUND,tokenTypes:t}})}function _(t){var e=u.filter(t,function(t){if(!u.has(t,"GROUP"))return!1;var e=t.GROUP;return e!==s.Lexer.SKIPPED&&e!==s.Lexer.NA&&!u.isString(e)});return u.map(e,function(t){return{message:"Token Type: ->"+a.tokenName(t)+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:s.LexerDefinitionErrorType.INVALID_GROUP_TYPE_FOUND,tokenTypes:[t]}})}function R(t,e){var n=u.filter(t,function(t){return void 0!==t.PUSH_MODE&&!u.contains(e,t.PUSH_MODE)});return u.map(n,function(t){return{message:"Token Type: ->"+a.tokenName(t)+"<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->"+t.PUSH_MODE+"<-which does not exist",type:s.LexerDefinitionErrorType.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[t]}})}function A(t){var e=[],n=u.reduce(t,function(t,e,n){var r,i=e.PATTERN;return i===s.Lexer.NA?t:(u.isString(i)?t.push({str:i,idx:n,tokenType:e}):u.isRegExp(i)&&(r=i,void 0===u.find([".","\\","[","]","|","^","$","(",")","?","*","+","{"],function(t){return-1!==r.source.indexOf(t)}))&&t.push({str:i.source,idx:n,tokenType:e}),t)},[]);return u.forEach(t,function(t,r){u.forEach(n,function(n){var i=n.str,o=n.idx,c=n.tokenType;if(r"+a.tokenName(t)+"<-in the lexer's definition.\nSee https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#UNREACHABLE";e.push({message:p,type:s.LexerDefinitionErrorType.UNREACHABLE_PATTERN,tokenTypes:[t,c]})}})}),e}function N(t){var e=t.ignoreCase?"i":"";return new RegExp("^(?:"+t.source+")",e)}function O(t){var e=t.ignoreCase?"iy":"y";return new RegExp(""+t.source,e)}function S(t){var e=t.PATTERN;if(u.isRegExp(e))return!1;if(u.isFunction(e))return!0;if(u.has(e,"exec"))return!0;if(u.isString(e))return!1;throw Error("non exhaustive match")}function I(t){return!(!u.isString(t)||1!==t.length)&&t.charCodeAt(0)}function L(t,e){if(u.has(t,"LINE_BREAKS"))return!1;if(u.isRegExp(t.PATTERN)){try{c.canMatchCharCode(e,t.PATTERN)}catch(t){return{issue:s.LexerDefinitionErrorType.IDENTIFY_TERMINATOR,errMsg:t.message}}return!1}if(u.isString(t.PATTERN))return!1;if(S(t))return{issue:s.LexerDefinitionErrorType.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}function k(t,e){if(e.issue===s.LexerDefinitionErrorType.IDENTIFY_TERMINATOR)return"Warning: unable to identify line terminator usage in pattern.\n\tThe problem is in the <"+t.name+"> Token Type\n\t Root cause: "+e.errMsg+".\n\tFor details See: https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR";if(e.issue===s.LexerDefinitionErrorType.CUSTOM_LINE_BREAK)return"Warning: A Custom Token Pattern should specify the option.\n\tThe problem is in the <"+t.name+"> Token Type\n\tFor details See: https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK";throw Error("non exhaustive match")}function P(t){return u.map(t,function(t){return u.isString(t)&&t.length>0?t.charCodeAt(0):t})}e.findStartOfInputAnchor=T,e.findUnsupportedFlags=v,e.findDuplicatePatterns=g,e.findInvalidGroupType=_,e.findModesThatDoNotExist=R,e.findUnreachablePatterns=A,e.addStartOfInput=N,e.addStickyFlag=O,e.performRuntimeChecks=function(t,n,r){var i=[];return u.has(t,e.DEFAULT_MODE)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+e.DEFAULT_MODE+"> property in its definition\n",type:s.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),u.has(t,e.MODES)||i.push({message:"A MultiMode Lexer cannot be initialized without a <"+e.MODES+"> property in its definition\n",type:s.LexerDefinitionErrorType.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),u.has(t,e.MODES)&&u.has(t,e.DEFAULT_MODE)&&!u.has(t.modes,t.defaultMode)&&i.push({message:"A MultiMode Lexer cannot be initialized with a "+e.DEFAULT_MODE+": <"+t.defaultMode+">which does not exist\n",type:s.LexerDefinitionErrorType.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),u.has(t,e.MODES)&&u.forEach(t.modes,function(t,e){u.forEach(t,function(t,n){u.isUndefined(t)&&i.push({message:"A Lexer cannot be initialized using an undefined Token Type. Mode:<"+e+"> at index: <"+n+">\n",type:s.LexerDefinitionErrorType.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED})})}),i},e.performWarningRuntimeChecks=function(t,e,n){var r=[],i=!1,o=u.compact(u.flatten(u.mapValues(t.modes,function(t){return t}))),a=u.reject(o,function(t){return t[l]===s.Lexer.NA}),p=P(n);return e&&u.forEach(a,function(t){var e=L(t,p);if(!1!==e){var n={message:k(t,e),type:e.issue,tokenType:t};r.push(n)}else u.has(t,"LINE_BREAKS")?!0===t.LINE_BREAKS&&(i=!0):c.canMatchCharCode(p,t.PATTERN)&&(i=!0)}),e&&!i&&r.push({message:"Warning: No LINE_BREAKS Found.\n\tThis Lexer has been defined to track line and column information,\n\tBut none of the Token Types can be identified as matching a line terminator.\n\tSee https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#LINE_BREAKS \n\tfor details.",type:s.LexerDefinitionErrorType.NO_LINE_BREAKS_FLAGS}),r},e.cloneEmptyGroups=function(t){var e={},n=u.keys(t);return u.forEach(n,function(n){var r=t[n];if(!u.isArray(r))throw Error("non exhaustive match");e[n]=[]}),e},e.isCustomPattern=S,e.isShortPattern=I,e.LineTerminatorOptimizedTester={test:function(t){for(var e=t.length,n=this.lastIndex;n\n\tComplement Sets cannot be automatically optimized.\n\tThis will disable the lexer's first char optimizations.\n\tSee: https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.");else{var l="";n&&(l="\n\tThis will disable the lexer's first char optimizations.\n\tSee: https://sap.github.io/chevrotain/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details."),a.PRINT_ERROR(e.failedOptimizationPrefixMsg+"\n\tFailed parsing: < "+t.toString()+" >\n\tUsing the regexp-to-ast library version: "+o.VERSION+"\n\tPlease open an issue at: https://github.com/bd82/regexp-to-ast/issues"+l)}}return[]},e.firstChar=c,e.applyIgnoreCase=p;var f=function(t){function e(e){var n=t.call(this)||this;return n.targetCharCodes=e,n.found=!1,n}return i(e,t),e.prototype.visitChildren=function(e){switch(e.type){case"Lookahead":return void this.visitLookahead(e);case"NegativeLookahead":return void this.visitNegativeLookahead(e)}t.prototype.visitChildren.call(this,e)},e.prototype.visitCharacter=function(t){a.contains(this.targetCharCodes,t.value)&&(this.found=!0)},e.prototype.visitSet=function(t){t.complement?void 0===l(t,this.targetCharCodes)&&(this.found=!0):void 0!==l(t,this.targetCharCodes)&&(this.found=!0)},e}(o.BaseRegExpVisitor);e.canMatchCharCode=function(t,e){if(e instanceof RegExp){var n=s.pattern(e.toString()),r=new f(t);return r.visit(n),r.found}return void 0!==a.find(e,function(e){return a.contains(t,e.charCodeAt(0))})}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){if(this.start=t,this.end=e,!i(t,e))throw new Error("INVALID RANGE")}return t.prototype.contains=function(t){return this.start<=t&&this.end>=t},t.prototype.containsRange=function(t){return this.start<=t.start&&this.end>=t.end},t.prototype.isContainedInRange=function(t){return t.containsRange(this)},t.prototype.strictlyContainsRange=function(t){return this.startt.end},t.prototype.isStrictlyContainedInRange=function(t){return t.strictlyContainsRange(this)},t}();function i(t,e){return!(t<0||e on "+o.functionName(t.constructor)+" CST Visitor.",type:r.MISSING_METHOD,methodName:e}});return i.compact(n)}e.defaultVisit=s,e.createBaseSemanticVisitorConstructor=function(t,e){var n=function(){};return o.defineNameProp(n,t+"BaseSemantics"),(n.prototype={visit:function(t,e){if(i.isArray(t)&&(t=t[0]),!i.isUndefined(t))return void 0!==t.fullName?this[t.fullName](t.children,e):this[t.name](t.children,e)},validateVisitor:function(){var t=u(this,e);if(!i.isEmpty(t)){var n=i.map(t,function(t){return t.msg});throw Error("Errors Detected in CST Visitor <"+o.functionName(this.constructor)+">:\n\t"+n.join("\n\n").replace(/\n/g,"\n\t"))}}}).constructor=n,n._RULE_NAMES=e,n},e.createBaseVisitorConstructorWithDefaults=function(t,e,n){var r=function(){};o.defineNameProp(r,t+"BaseSemanticsWithDefaults");var a=Object.create(n.prototype);return i.forEach(e,function(t){a[t]=s}),(r.prototype=a).constructor=r,r},function(t){t[t.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",t[t.MISSING_METHOD=1]="MISSING_METHOD"}(r=e.CstVisitorDefinitionError||(e.CstVisitorDefinitionError={})),e.validateVisitor=u,e.validateMissingCstMethods=c;var p=["constructor","visit","validateVisitor"];function l(t,e){var n=[];for(var s in t)a.validTermsPattern.test(s)&&i.isFunction(t[s])&&!i.contains(p,s)&&!i.contains(e,s)&&n.push({msg:"Redundant visitor method: <"+s+"> on "+o.functionName(t.constructor)+" CST Visitor\nThere is no Grammar Rule corresponding to this method's name.\nFor utility methods on visitor classes use methods names that do not match /"+a.validTermsPattern.source+"/.",type:r.REDUNDANT_METHOD,methodName:s});return n}e.validateRedundantMethods=l},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(3),i=function(){function t(){}return t.prototype.initLexerAdapter=function(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1},Object.defineProperty(t.prototype,"input",{get:function(){return this.tokVector},set:function(t){this.reset(),this.tokVector=t,this.tokVectorLength=t.length},enumerable:!0,configurable:!0}),t.prototype.SKIP_TOKEN=function(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):r.END_OF_FILE},t.prototype.LA=function(t){return this.currIdx+t<0||this.tokVectorLength<=this.currIdx+t?r.END_OF_FILE:this.tokVector[this.currIdx+t]},t.prototype.consumeToken=function(){this.currIdx++},t.prototype.exportLexerState=function(){return this.currIdx},t.prototype.importLexerState=function(t){this.currIdx=t},t.prototype.resetLexerState=function(){this.currIdx=-1},t.prototype.moveToTerminatedState=function(){this.currIdx=this.tokVector.length-1},t.prototype.getLexerPosition=function(){return this.exportLexerState()},t}();e.LexerAdapter=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(0),i=n(6),o=n(3),a=n(10),s=n(23),u=n(11),c=n(1),p=function(){function t(){}return t.prototype.CONSUME=function(t,e){return this.consumeInternal(t,0,e)},t.prototype.CONSUME1=function(t,e){return this.consumeInternal(t,1,e)},t.prototype.CONSUME2=function(t,e){return this.consumeInternal(t,2,e)},t.prototype.CONSUME3=function(t,e){return this.consumeInternal(t,3,e)},t.prototype.CONSUME4=function(t,e){return this.consumeInternal(t,4,e)},t.prototype.CONSUME5=function(t,e){return this.consumeInternal(t,5,e)},t.prototype.CONSUME6=function(t,e){return this.consumeInternal(t,6,e)},t.prototype.CONSUME7=function(t,e){return this.consumeInternal(t,7,e)},t.prototype.CONSUME8=function(t,e){return this.consumeInternal(t,8,e)},t.prototype.CONSUME9=function(t,e){return this.consumeInternal(t,9,e)},t.prototype.SUBRULE=function(t,e){return this.subruleInternal(t,0,e)},t.prototype.SUBRULE1=function(t,e){return this.subruleInternal(t,1,e)},t.prototype.SUBRULE2=function(t,e){return this.subruleInternal(t,2,e)},t.prototype.SUBRULE3=function(t,e){return this.subruleInternal(t,3,e)},t.prototype.SUBRULE4=function(t,e){return this.subruleInternal(t,4,e)},t.prototype.SUBRULE5=function(t,e){return this.subruleInternal(t,5,e)},t.prototype.SUBRULE6=function(t,e){return this.subruleInternal(t,6,e)},t.prototype.SUBRULE7=function(t,e){return this.subruleInternal(t,7,e)},t.prototype.SUBRULE8=function(t,e){return this.subruleInternal(t,8,e)},t.prototype.SUBRULE9=function(t,e){return this.subruleInternal(t,9,e)},t.prototype.OPTION=function(t){return this.optionInternal(t,0)},t.prototype.OPTION1=function(t){return this.optionInternal(t,1)},t.prototype.OPTION2=function(t){return this.optionInternal(t,2)},t.prototype.OPTION3=function(t){return this.optionInternal(t,3)},t.prototype.OPTION4=function(t){return this.optionInternal(t,4)},t.prototype.OPTION5=function(t){return this.optionInternal(t,5)},t.prototype.OPTION6=function(t){return this.optionInternal(t,6)},t.prototype.OPTION7=function(t){return this.optionInternal(t,7)},t.prototype.OPTION8=function(t){return this.optionInternal(t,8)},t.prototype.OPTION9=function(t){return this.optionInternal(t,9)},t.prototype.OR=function(t){return this.orInternal(t,0)},t.prototype.OR1=function(t){return this.orInternal(t,1)},t.prototype.OR2=function(t){return this.orInternal(t,2)},t.prototype.OR3=function(t){return this.orInternal(t,3)},t.prototype.OR4=function(t){return this.orInternal(t,4)},t.prototype.OR5=function(t){return this.orInternal(t,5)},t.prototype.OR6=function(t){return this.orInternal(t,6)},t.prototype.OR7=function(t){return this.orInternal(t,7)},t.prototype.OR8=function(t){return this.orInternal(t,8)},t.prototype.OR9=function(t){return this.orInternal(t,9)},t.prototype.MANY=function(t){this.manyInternal(0,t)},t.prototype.MANY1=function(t){this.manyInternal(1,t)},t.prototype.MANY2=function(t){this.manyInternal(2,t)},t.prototype.MANY3=function(t){this.manyInternal(3,t)},t.prototype.MANY4=function(t){this.manyInternal(4,t)},t.prototype.MANY5=function(t){this.manyInternal(5,t)},t.prototype.MANY6=function(t){this.manyInternal(6,t)},t.prototype.MANY7=function(t){this.manyInternal(7,t)},t.prototype.MANY8=function(t){this.manyInternal(8,t)},t.prototype.MANY9=function(t){this.manyInternal(9,t)},t.prototype.MANY_SEP=function(t){this.manySepFirstInternal(0,t)},t.prototype.MANY_SEP1=function(t){this.manySepFirstInternal(1,t)},t.prototype.MANY_SEP2=function(t){this.manySepFirstInternal(2,t)},t.prototype.MANY_SEP3=function(t){this.manySepFirstInternal(3,t)},t.prototype.MANY_SEP4=function(t){this.manySepFirstInternal(4,t)},t.prototype.MANY_SEP5=function(t){this.manySepFirstInternal(5,t)},t.prototype.MANY_SEP6=function(t){this.manySepFirstInternal(6,t)},t.prototype.MANY_SEP7=function(t){this.manySepFirstInternal(7,t)},t.prototype.MANY_SEP8=function(t){this.manySepFirstInternal(8,t)},t.prototype.MANY_SEP9=function(t){this.manySepFirstInternal(9,t)},t.prototype.AT_LEAST_ONE=function(t){this.atLeastOneInternal(0,t)},t.prototype.AT_LEAST_ONE1=function(t){return this.atLeastOneInternal(1,t)},t.prototype.AT_LEAST_ONE2=function(t){this.atLeastOneInternal(2,t)},t.prototype.AT_LEAST_ONE3=function(t){this.atLeastOneInternal(3,t)},t.prototype.AT_LEAST_ONE4=function(t){this.atLeastOneInternal(4,t)},t.prototype.AT_LEAST_ONE5=function(t){this.atLeastOneInternal(5,t)},t.prototype.AT_LEAST_ONE6=function(t){this.atLeastOneInternal(6,t)},t.prototype.AT_LEAST_ONE7=function(t){this.atLeastOneInternal(7,t)},t.prototype.AT_LEAST_ONE8=function(t){this.atLeastOneInternal(8,t)},t.prototype.AT_LEAST_ONE9=function(t){this.atLeastOneInternal(9,t)},t.prototype.AT_LEAST_ONE_SEP=function(t){this.atLeastOneSepFirstInternal(0,t)},t.prototype.AT_LEAST_ONE_SEP1=function(t){this.atLeastOneSepFirstInternal(1,t)},t.prototype.AT_LEAST_ONE_SEP2=function(t){this.atLeastOneSepFirstInternal(2,t)},t.prototype.AT_LEAST_ONE_SEP3=function(t){this.atLeastOneSepFirstInternal(3,t)},t.prototype.AT_LEAST_ONE_SEP4=function(t){this.atLeastOneSepFirstInternal(4,t)},t.prototype.AT_LEAST_ONE_SEP5=function(t){this.atLeastOneSepFirstInternal(5,t)},t.prototype.AT_LEAST_ONE_SEP6=function(t){this.atLeastOneSepFirstInternal(6,t)},t.prototype.AT_LEAST_ONE_SEP7=function(t){this.atLeastOneSepFirstInternal(7,t)},t.prototype.AT_LEAST_ONE_SEP8=function(t){this.atLeastOneSepFirstInternal(8,t)},t.prototype.AT_LEAST_ONE_SEP9=function(t){this.atLeastOneSepFirstInternal(9,t)},t.prototype.RULE=function(t,e,n){if(void 0===n&&(n=o.DEFAULT_RULE_CONFIG),r.contains(this.definedRulesNames,t)){var i={message:a.defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({topLevelRule:t,grammarName:this.className}),type:o.ParserDefinitionErrorType.DUPLICATE_RULE_NAME,ruleName:t};this.definitionErrors.push(i)}if(this.definedRulesNames.push(t),!this.gastProductionsCache.containsKey(t)&&!this.serializedGrammar){var u=s.buildTopProduction(e.toString(),t,this.tokensMap);this.gastProductionsCache.put(t,u)}var c=this.defineRule(t,e,n);return this[t]=c,c},t.prototype.OVERRIDE_RULE=function(t,e,n){void 0===n&&(n=o.DEFAULT_RULE_CONFIG);var r=[];if(r=r.concat(u.validateRuleIsOverridden(t,this.definedRulesNames,this.className)),this.definitionErrors.push.apply(this.definitionErrors,r),!this.serializedGrammar){var i=s.buildTopProduction(e.toString(),t,this.tokensMap);this.gastProductionsCache.put(t,i)}var a=this.defineRule(t,e,n);return this[t]=a,a},t.prototype.BACKTRACK=function(t,e){return function(){this.isBackTrackingStack.push(1);var n=this.saveRecogState();try{return t.apply(this,e),!0}catch(t){if(i.isRecognitionException(t))return!1;throw t}finally{this.reloadRecogState(n),this.isBackTrackingStack.pop()}}},t.prototype.getGAstProductions=function(){return this.gastProductionsCache},t.prototype.getSerializedGastProductions=function(){return c.serializeGrammar(this.gastProductionsCache.values())},t}();e.RecognizerApi=p},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(0),i=n(9),o=n(6),a=n(12),s=n(13),u=n(3),c=n(25),p=n(2),l=n(7),h=n(4),f=function(){function t(){}return t.prototype.initRecognizerEngine=function(t,e){if(this.className=h.classNameFromInstance(this),this.shortRuleNameToFull=new h.HashTable,this.fullRuleNameToShort=new h.HashTable,this.ruleShortNameIdx=256,this.tokenMatcher=l.tokenStructuredMatcherNoCategories,this.definedRulesNames=[],this.tokensMap={},this.allRuleNames=[],this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache=new h.HashTable,this.serializedGrammar=r.has(e,"serializedGrammar")?e.serializedGrammar:u.DEFAULT_PARSER_CONFIG.serializedGrammar,r.isArray(t)){if(r.isEmpty(t))throw Error("A Token Vocabulary cannot be empty.\n\tNote that the first argument for the parser constructor\n\tis no longer a Token vector (since v4.0).");if("number"==typeof t[0].startOffset)throw Error("The Parser constructor no longer accepts a token vector as the first argument.\n\tSee: https://sap.github.io/chevrotain/docs/changes/BREAKING_CHANGES.html#_4-0-0\n\tFor Further details.")}if(r.isArray(t))this.tokensMap=r.reduce(t,function(t,e){return t[p.tokenName(e)]=e,t},{});else if(r.has(t,"modes")&&r.every(r.flatten(r.values(t.modes)),l.isTokenType)){var n=r.flatten(r.values(t.modes)),i=r.uniq(n);this.tokensMap=r.reduce(i,function(t,e){return t[p.tokenName(e)]=e,t},{})}else{if(!r.isObject(t))throw new Error(" argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap=r.cloneObj(t)}this.tokensMap.EOF=p.EOF;var o=r.every(r.values(t),function(t){return r.isEmpty(t.categoryMatches)});this.tokenMatcher=o?l.tokenStructuredMatcherNoCategories:l.tokenStructuredMatcher,l.augmentTokenTypes(r.values(this.tokensMap))},t.prototype.defineRule=function(t,e,n){if(this.selfAnalysisDone)throw Error("Grammar rule <"+t+"> may not be defined after the 'performSelfAnalysis' method has been called'\nMake sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.");var a,s=r.has(n,"resyncEnabled")?n.resyncEnabled:u.DEFAULT_RULE_CONFIG.resyncEnabled,c=r.has(n,"recoveryValueFunc")?n.recoveryValueFunc:u.DEFAULT_RULE_CONFIG.recoveryValueFunc,p=this.ruleShortNameIdx<e},t.prototype.orInternalNoCst=function(t,e){var n=r.isArray(t)?t:t.DEF,i=this.getLookaheadFuncForOr(e,n).call(this,n);if(void 0!==i)return n[i].ALT.call(this);this.raiseNoAltException(e,t.ERR_MSG)},t.prototype.orInternal=function(t,e){var n=this.getKeyForAutomaticLookahead(i.OR_IDX,e),o=this.nestedRuleBeforeClause(t,n);try{var a=r.isArray(t)?t:t.DEF,s=this.getLookaheadFuncForOr(e,a).call(this,a);if(void 0!==s){var u=a[s],c=this.nestedAltBeforeClause(u,e,i.OR_IDX,s);try{return u.ALT.call(this)}finally{void 0!==c&&this.nestedRuleFinallyClause(c.shortName,c.nestedName)}}this.raiseNoAltException(e,t.ERR_MSG)}finally{void 0!==o&&this.nestedRuleFinallyClause(n,o)}},t.prototype.ruleFinallyStateUpdate=function(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),0===this.RULE_STACK.length&&!this.isAtEndOfInput()){var t=this.LA(1),e=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:t,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new o.NotAllInputParsedException(e,t))}},t.prototype.subruleInternal=function(t,e,n){var r;try{var i=void 0!==n?n.ARGS:void 0;return r=t.call(this,e,i),this.cstPostNonTerminal(r,void 0!==n&&void 0!==n.LABEL?n.LABEL:t.ruleName),r}catch(e){throw o.isRecognitionException(e)&&void 0!==e.partialCstResult&&(this.cstPostNonTerminal(e.partialCstResult,void 0!==n&&void 0!==n.LABEL?n.LABEL:t.ruleName),delete e.partialCstResult),e}},t.prototype.consumeInternal=function(t,e,n){var r;try{var i=this.LA(1);if(!0!==this.tokenMatcher(i,t)){var a=void 0,s=this.LA(0);throw a=void 0!==n&&n.ERR_MSG?n.ERR_MSG:this.errorMessageProvider.buildMismatchTokenMessage({expected:t,actual:i,previous:s,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new o.MismatchedTokenException(a,i,s))}this.consumeToken(),r=i}catch(n){if(!this.recoveryEnabled||"MismatchedTokenException"!==n.name||this.isBackTracking())throw n;var u=this.getFollowsForInRuleRecovery(t,e);try{r=this.tryInRuleRecovery(t,u)}catch(t){throw t.name===c.IN_RULE_RECOVERY_EXCEPTION?n:t}}return this.cstPostTerminal(void 0!==n&&void 0!==n.LABEL?n.LABEL:t.tokenName,r),r},t.prototype.saveRecogState=function(){var t=this.errors,e=r.cloneArr(this.RULE_STACK);return{errors:t,lexerState:this.exportLexerState(),RULE_STACK:e,CST_STACK:this.CST_STACK,LAST_EXPLICIT_RULE_STACK:this.LAST_EXPLICIT_RULE_STACK}},t.prototype.reloadRecogState=function(t){this.errors=t.errors,this.importLexerState(t.lexerState),this.RULE_STACK=t.RULE_STACK},t.prototype.ruleInvocationStateUpdate=function(t,e,n){this.RULE_OCCURRENCE_STACK.push(n),this.RULE_STACK.push(t),this.cstInvocationStateUpdate(e,t)},t.prototype.isBackTracking=function(){return!r.isEmpty(this.isBackTrackingStack)},t.prototype.getCurrRuleFullName=function(){var t=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull.get(t)},t.prototype.shortRuleNameToFullName=function(t){return this.shortRuleNameToFull.get(t)},t.prototype.isAtEndOfInput=function(){return this.tokenMatcher(this.LA(1),p.EOF)},t.prototype.reset=function(){this.resetLexerState(),this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.LAST_EXPLICIT_RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]},t}();e.RecognizerEngine=f},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(6),i=n(0),o=n(12),a=n(3),s=function(){function t(){}return t.prototype.initErrorHandler=function(t){this._errors=[],this.errorMessageProvider=i.defaults(t.errorMessageProvider,a.DEFAULT_PARSER_CONFIG.errorMessageProvider)},t.prototype.SAVE_ERROR=function(t){if(r.isRecognitionException(t))return t.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:i.cloneArr(this.RULE_OCCURRENCE_STACK)},this._errors.push(t),t;throw Error("Trying to save an Error which is not a RecognitionException")},Object.defineProperty(t.prototype,"errors",{get:function(){return i.cloneArr(this._errors)},set:function(t){this._errors=t},enumerable:!0,configurable:!0}),t.prototype.raiseEarlyExitException=function(t,e,n){for(var i=this.getCurrRuleFullName(),a=this.getGAstProductions().get(i),s=o.getLookaheadPathsForOptionalProd(t,a,e,this.maxLookahead)[0],u=[],c=1;c"+t+"<- does not exist in this grammar.");return r.nextPossibleTokensAfter([n],e,this.tokenMatcher,this.maxLookahead)},t.prototype.getNextPossibleTokenTypes=function(t){var e=i.first(t.ruleStack),n=this.getGAstProductions().get(e);return new r.NextAfterTokenWalker(n,t).startWalking()},t}();e.ContentAssist=o},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(17);e.createSyntaxDiagramsCode=function(t,e){var n=void 0===e?{}:e,i=n.resourceBase,o=void 0===i?"https://unpkg.com/chevrotain@"+r.VERSION+"/diagrams/":i,a=n.css;return"\n\x3c!-- This is a generated file --\x3e\n\n\n\n\n\n\n\n