UNPKG

mandarjs

Version:

A package to apply interactive effects on images using Three.js

2,817 lines (1,702 loc) 1.08 MB
/** * @license * Copyright 2010-2025 Three.js Authors * SPDX-License-Identifier: MIT */ const REVISION = '173'; const CullFaceNone = 0; const CullFaceBack = 1; const CullFaceFront = 2; const PCFShadowMap = 1; const PCFSoftShadowMap = 2; const VSMShadowMap = 3; const FrontSide = 0; const BackSide = 1; const DoubleSide = 2; const NoBlending = 0; const NormalBlending = 1; const AdditiveBlending = 2; const SubtractiveBlending = 3; const MultiplyBlending = 4; const CustomBlending = 5; const AddEquation = 100; const SubtractEquation = 101; const ReverseSubtractEquation = 102; const MinEquation = 103; const MaxEquation = 104; const ZeroFactor = 200; const OneFactor = 201; const SrcColorFactor = 202; const OneMinusSrcColorFactor = 203; const SrcAlphaFactor = 204; const OneMinusSrcAlphaFactor = 205; const DstAlphaFactor = 206; const OneMinusDstAlphaFactor = 207; const DstColorFactor = 208; const OneMinusDstColorFactor = 209; const SrcAlphaSaturateFactor = 210; const ConstantColorFactor = 211; const OneMinusConstantColorFactor = 212; const ConstantAlphaFactor = 213; const OneMinusConstantAlphaFactor = 214; const NeverDepth = 0; const AlwaysDepth = 1; const LessDepth = 2; const LessEqualDepth = 3; const EqualDepth = 4; const GreaterEqualDepth = 5; const GreaterDepth = 6; const NotEqualDepth = 7; const MultiplyOperation = 0; const MixOperation = 1; const AddOperation = 2; const NoToneMapping = 0; const LinearToneMapping = 1; const ReinhardToneMapping = 2; const CineonToneMapping = 3; const ACESFilmicToneMapping = 4; const CustomToneMapping = 5; const AgXToneMapping = 6; const NeutralToneMapping = 7; const UVMapping = 300; const CubeReflectionMapping = 301; const CubeRefractionMapping = 302; const EquirectangularReflectionMapping = 303; const EquirectangularRefractionMapping = 304; const CubeUVReflectionMapping = 306; const RepeatWrapping = 1000; const ClampToEdgeWrapping = 1001; const MirroredRepeatWrapping = 1002; const NearestFilter = 1003; const NearestMipmapNearestFilter = 1004; const NearestMipmapLinearFilter = 1005; const LinearFilter = 1006; const LinearMipmapNearestFilter = 1007; const LinearMipmapLinearFilter = 1008; const UnsignedByteType = 1009; const ByteType = 1010; const ShortType = 1011; const UnsignedShortType = 1012; const IntType = 1013; const UnsignedIntType = 1014; const FloatType = 1015; const HalfFloatType = 1016; const UnsignedShort4444Type = 1017; const UnsignedShort5551Type = 1018; const UnsignedInt248Type = 1020; const UnsignedInt5999Type = 35902; const AlphaFormat = 1021; const RGBFormat = 1022; const RGBAFormat = 1023; const LuminanceFormat = 1024; const LuminanceAlphaFormat = 1025; const DepthFormat = 1026; const DepthStencilFormat = 1027; const RedFormat = 1028; const RedIntegerFormat = 1029; const RGFormat = 1030; const RGIntegerFormat = 1031; const RGBAIntegerFormat = 1033; const RGB_S3TC_DXT1_Format = 33776; const RGBA_S3TC_DXT1_Format = 33777; const RGBA_S3TC_DXT3_Format = 33778; const RGBA_S3TC_DXT5_Format = 33779; const RGB_PVRTC_4BPPV1_Format = 35840; const RGB_PVRTC_2BPPV1_Format = 35841; const RGBA_PVRTC_4BPPV1_Format = 35842; const RGBA_PVRTC_2BPPV1_Format = 35843; const RGB_ETC1_Format = 36196; const RGB_ETC2_Format = 37492; const RGBA_ETC2_EAC_Format = 37496; const RGBA_ASTC_4x4_Format = 37808; const RGBA_ASTC_5x4_Format = 37809; const RGBA_ASTC_5x5_Format = 37810; const RGBA_ASTC_6x5_Format = 37811; const RGBA_ASTC_6x6_Format = 37812; const RGBA_ASTC_8x5_Format = 37813; const RGBA_ASTC_8x6_Format = 37814; const RGBA_ASTC_8x8_Format = 37815; const RGBA_ASTC_10x5_Format = 37816; const RGBA_ASTC_10x6_Format = 37817; const RGBA_ASTC_10x8_Format = 37818; const RGBA_ASTC_10x10_Format = 37819; const RGBA_ASTC_12x10_Format = 37820; const RGBA_ASTC_12x12_Format = 37821; const RGBA_BPTC_Format = 36492; const RGB_BPTC_SIGNED_Format = 36494; const RGB_BPTC_UNSIGNED_Format = 36495; const RED_RGTC1_Format = 36283; const SIGNED_RED_RGTC1_Format = 36284; const RED_GREEN_RGTC2_Format = 36285; const SIGNED_RED_GREEN_RGTC2_Format = 36286; const BasicDepthPacking = 3200; const RGBADepthPacking = 3201; const TangentSpaceNormalMap = 0; const ObjectSpaceNormalMap = 1; // Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available. const NoColorSpace = ''; const SRGBColorSpace = 'srgb'; const LinearSRGBColorSpace = 'srgb-linear'; const LinearTransfer = 'linear'; const SRGBTransfer = 'srgb'; const KeepStencilOp = 7680; const AlwaysStencilFunc = 519; const NeverCompare = 512; const LessCompare = 513; const EqualCompare = 514; const LessEqualCompare = 515; const GreaterCompare = 516; const NotEqualCompare = 517; const GreaterEqualCompare = 518; const AlwaysCompare = 519; const StaticDrawUsage = 35044; const GLSL3 = '300 es'; const WebGLCoordinateSystem = 2000; const WebGPUCoordinateSystem = 2001; /** * https://github.com/mrdoob/eventdispatcher.js/ */ class EventDispatcher { addEventListener( type, listener ) { if ( this._listeners === undefined ) this._listeners = {}; const listeners = this._listeners; if ( listeners[ type ] === undefined ) { listeners[ type ] = []; } if ( listeners[ type ].indexOf( listener ) === -1 ) { listeners[ type ].push( listener ); } } hasEventListener( type, listener ) { const listeners = this._listeners; if ( listeners === undefined ) return false; return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== -1; } removeEventListener( type, listener ) { const listeners = this._listeners; if ( listeners === undefined ) return; const listenerArray = listeners[ type ]; if ( listenerArray !== undefined ) { const index = listenerArray.indexOf( listener ); if ( index !== -1 ) { listenerArray.splice( index, 1 ); } } } dispatchEvent( event ) { const listeners = this._listeners; if ( listeners === undefined ) return; const listenerArray = listeners[ event.type ]; if ( listenerArray !== undefined ) { event.target = this; // Make a copy, in case listeners are removed while iterating. const array = listenerArray.slice( 0 ); for ( let i = 0, l = array.length; i < l; i ++ ) { array[ i ].call( this, event ); } event.target = null; } } } const _lut = [ '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff' ]; const DEG2RAD = Math.PI / 180; const RAD2DEG = 180 / Math.PI; // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 function generateUUID() { const d0 = Math.random() * 0xffffffff | 0; const d1 = Math.random() * 0xffffffff | 0; const d2 = Math.random() * 0xffffffff | 0; const d3 = Math.random() * 0xffffffff | 0; const uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' + _lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' + _lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] + _lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ]; // .toLowerCase() here flattens concatenated strings to save heap memory space. return uuid.toLowerCase(); } function clamp$1( value, min, max ) { return Math.max( min, Math.min( max, value ) ); } // compute euclidean modulo of m % n // https://en.wikipedia.org/wiki/Modulo_operation function euclideanModulo( n, m ) { return ( ( n % m ) + m ) % m; } // https://en.wikipedia.org/wiki/Linear_interpolation function lerp( x, y, t ) { return ( 1 - t ) * x + t * y; } function denormalize( value, array ) { switch ( array.constructor ) { case Float32Array: return value; case Uint32Array: return value / 4294967295.0; case Uint16Array: return value / 65535.0; case Uint8Array: return value / 255.0; case Int32Array: return Math.max( value / 2147483647.0, -1 ); case Int16Array: return Math.max( value / 32767.0, -1 ); case Int8Array: return Math.max( value / 127.0, -1 ); default: throw new Error( 'Invalid component type.' ); } } function normalize$1( value, array ) { switch ( array.constructor ) { case Float32Array: return value; case Uint32Array: return Math.round( value * 4294967295.0 ); case Uint16Array: return Math.round( value * 65535.0 ); case Uint8Array: return Math.round( value * 255.0 ); case Int32Array: return Math.round( value * 2147483647.0 ); case Int16Array: return Math.round( value * 32767.0 ); case Int8Array: return Math.round( value * 127.0 ); default: throw new Error( 'Invalid component type.' ); } } class Vector2 { constructor( x = 0, y = 0 ) { Vector2.prototype.isVector2 = true; this.x = x; this.y = y; } get width() { return this.x; } set width( value ) { this.x = value; } get height() { return this.y; } set height( value ) { this.y = value; } set( x, y ) { this.x = x; this.y = y; return this; } setScalar( scalar ) { this.x = scalar; this.y = scalar; return this; } setX( x ) { this.x = x; return this; } setY( y ) { this.y = y; return this; } setComponent( index, value ) { switch ( index ) { case 0: this.x = value; break; case 1: this.y = value; break; default: throw new Error( 'index is out of range: ' + index ); } return this; } getComponent( index ) { switch ( index ) { case 0: return this.x; case 1: return this.y; default: throw new Error( 'index is out of range: ' + index ); } } clone() { return new this.constructor( this.x, this.y ); } copy( v ) { this.x = v.x; this.y = v.y; return this; } add( v ) { this.x += v.x; this.y += v.y; return this; } addScalar( s ) { this.x += s; this.y += s; return this; } addVectors( a, b ) { this.x = a.x + b.x; this.y = a.y + b.y; return this; } addScaledVector( v, s ) { this.x += v.x * s; this.y += v.y * s; return this; } sub( v ) { this.x -= v.x; this.y -= v.y; return this; } subScalar( s ) { this.x -= s; this.y -= s; return this; } subVectors( a, b ) { this.x = a.x - b.x; this.y = a.y - b.y; return this; } multiply( v ) { this.x *= v.x; this.y *= v.y; return this; } multiplyScalar( scalar ) { this.x *= scalar; this.y *= scalar; return this; } divide( v ) { this.x /= v.x; this.y /= v.y; return this; } divideScalar( scalar ) { return this.multiplyScalar( 1 / scalar ); } applyMatrix3( m ) { const x = this.x, y = this.y; const e = m.elements; this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ]; this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ]; return this; } min( v ) { this.x = Math.min( this.x, v.x ); this.y = Math.min( this.y, v.y ); return this; } max( v ) { this.x = Math.max( this.x, v.x ); this.y = Math.max( this.y, v.y ); return this; } clamp( min, max ) { // assumes min < max, componentwise this.x = clamp$1( this.x, min.x, max.x ); this.y = clamp$1( this.y, min.y, max.y ); return this; } clampScalar( minVal, maxVal ) { this.x = clamp$1( this.x, minVal, maxVal ); this.y = clamp$1( this.y, minVal, maxVal ); return this; } clampLength( min, max ) { const length = this.length(); return this.divideScalar( length || 1 ).multiplyScalar( clamp$1( length, min, max ) ); } floor() { this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); return this; } ceil() { this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); return this; } round() { this.x = Math.round( this.x ); this.y = Math.round( this.y ); return this; } roundToZero() { this.x = Math.trunc( this.x ); this.y = Math.trunc( this.y ); return this; } negate() { this.x = - this.x; this.y = - this.y; return this; } dot( v ) { return this.x * v.x + this.y * v.y; } cross( v ) { return this.x * v.y - this.y * v.x; } lengthSq() { return this.x * this.x + this.y * this.y; } length() { return Math.sqrt( this.x * this.x + this.y * this.y ); } manhattanLength() { return Math.abs( this.x ) + Math.abs( this.y ); } normalize() { return this.divideScalar( this.length() || 1 ); } angle() { // computes the angle in radians with respect to the positive x-axis const angle = Math.atan2( - this.y, - this.x ) + Math.PI; return angle; } angleTo( v ) { const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); if ( denominator === 0 ) return Math.PI / 2; const theta = this.dot( v ) / denominator; // clamp, to handle numerical problems return Math.acos( clamp$1( theta, -1, 1 ) ); } distanceTo( v ) { return Math.sqrt( this.distanceToSquared( v ) ); } distanceToSquared( v ) { const dx = this.x - v.x, dy = this.y - v.y; return dx * dx + dy * dy; } manhattanDistanceTo( v ) { return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ); } setLength( length ) { return this.normalize().multiplyScalar( length ); } lerp( v, alpha ) { this.x += ( v.x - this.x ) * alpha; this.y += ( v.y - this.y ) * alpha; return this; } lerpVectors( v1, v2, alpha ) { this.x = v1.x + ( v2.x - v1.x ) * alpha; this.y = v1.y + ( v2.y - v1.y ) * alpha; return this; } equals( v ) { return ( ( v.x === this.x ) && ( v.y === this.y ) ); } fromArray( array, offset = 0 ) { this.x = array[ offset ]; this.y = array[ offset + 1 ]; return this; } toArray( array = [], offset = 0 ) { array[ offset ] = this.x; array[ offset + 1 ] = this.y; return array; } fromBufferAttribute( attribute, index ) { this.x = attribute.getX( index ); this.y = attribute.getY( index ); return this; } rotateAround( center, angle ) { const c = Math.cos( angle ), s = Math.sin( angle ); const x = this.x - center.x; const y = this.y - center.y; this.x = x * c - y * s + center.x; this.y = x * s + y * c + center.y; return this; } random() { this.x = Math.random(); this.y = Math.random(); return this; } *[ Symbol.iterator ]() { yield this.x; yield this.y; } } class Matrix3 { constructor( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { Matrix3.prototype.isMatrix3 = true; this.elements = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; if ( n11 !== undefined ) { this.set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ); } } set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { const te = this.elements; te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; return this; } identity() { this.set( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); return this; } copy( m ) { const te = this.elements; const me = m.elements; 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 ]; return this; } extractBasis( xAxis, yAxis, zAxis ) { xAxis.setFromMatrix3Column( this, 0 ); yAxis.setFromMatrix3Column( this, 1 ); zAxis.setFromMatrix3Column( this, 2 ); return this; } setFromMatrix4( m ) { const me = m.elements; this.set( me[ 0 ], me[ 4 ], me[ 8 ], me[ 1 ], me[ 5 ], me[ 9 ], me[ 2 ], me[ 6 ], me[ 10 ] ); return this; } multiply( m ) { return this.multiplyMatrices( this, m ); } premultiply( m ) { return this.multiplyMatrices( m, this ); } multiplyMatrices( a, b ) { const ae = a.elements; const be = b.elements; const te = this.elements; const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; return this; } multiplyScalar( s ) { const te = this.elements; te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; return this; } determinant() { const te = this.elements; const a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; } invert() { const te = this.elements, n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n12 = te[ 3 ], n22 = te[ 4 ], n32 = te[ 5 ], n13 = te[ 6 ], n23 = te[ 7 ], n33 = te[ 8 ], t11 = n33 * n22 - n32 * n23, t12 = n32 * n13 - n33 * n12, t13 = n23 * n12 - n22 * n13, det = n11 * t11 + n21 * t12 + n31 * t13; if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); const detInv = 1 / det; te[ 0 ] = t11 * detInv; te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; te[ 3 ] = t12 * detInv; te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; te[ 6 ] = t13 * detInv; te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; return this; } transpose() { let tmp; const m = this.elements; tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; return this; } getNormalMatrix( matrix4 ) { return this.setFromMatrix4( matrix4 ).invert().transpose(); } transposeIntoArray( r ) { const m = this.elements; r[ 0 ] = m[ 0 ]; r[ 1 ] = m[ 3 ]; r[ 2 ] = m[ 6 ]; r[ 3 ] = m[ 1 ]; r[ 4 ] = m[ 4 ]; r[ 5 ] = m[ 7 ]; r[ 6 ] = m[ 2 ]; r[ 7 ] = m[ 5 ]; r[ 8 ] = m[ 8 ]; return this; } setUvTransform( tx, ty, sx, sy, rotation, cx, cy ) { const c = Math.cos( rotation ); const s = Math.sin( rotation ); this.set( sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, 0, 0, 1 ); return this; } // scale( sx, sy ) { this.premultiply( _m3.makeScale( sx, sy ) ); return this; } rotate( theta ) { this.premultiply( _m3.makeRotation( - theta ) ); return this; } translate( tx, ty ) { this.premultiply( _m3.makeTranslation( tx, ty ) ); return this; } // for 2D Transforms makeTranslation( x, y ) { if ( x.isVector2 ) { this.set( 1, 0, x.x, 0, 1, x.y, 0, 0, 1 ); } else { this.set( 1, 0, x, 0, 1, y, 0, 0, 1 ); } return this; } makeRotation( theta ) { // counterclockwise const c = Math.cos( theta ); const s = Math.sin( theta ); this.set( c, - s, 0, s, c, 0, 0, 0, 1 ); return this; } makeScale( x, y ) { this.set( x, 0, 0, 0, y, 0, 0, 0, 1 ); return this; } // equals( matrix ) { const te = this.elements; const me = matrix.elements; for ( let i = 0; i < 9; i ++ ) { if ( te[ i ] !== me[ i ] ) return false; } return true; } fromArray( array, offset = 0 ) { for ( let i = 0; i < 9; i ++ ) { this.elements[ i ] = array[ i + offset ]; } return this; } toArray( array = [], offset = 0 ) { const te = this.elements; array[ offset ] = te[ 0 ]; array[ offset + 1 ] = te[ 1 ]; array[ offset + 2 ] = te[ 2 ]; array[ offset + 3 ] = te[ 3 ]; array[ offset + 4 ] = te[ 4 ]; array[ offset + 5 ] = te[ 5 ]; array[ offset + 6 ] = te[ 6 ]; array[ offset + 7 ] = te[ 7 ]; array[ offset + 8 ] = te[ 8 ]; return array; } clone() { return new this.constructor().fromArray( this.elements ); } } const _m3 = /*@__PURE__*/ new Matrix3(); function arrayNeedsUint32( array ) { // assumes larger values usually on last for ( let i = array.length - 1; i >= 0; -- i ) { if ( array[ i ] >= 65535 ) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 } return false; } function createElementNS( name ) { return document.createElementNS( 'http://www.w3.org/1999/xhtml', name ); } function createCanvasElement() { const canvas = createElementNS( 'canvas' ); canvas.style.display = 'block'; return canvas; } const _cache = {}; function warnOnce( message ) { if ( message in _cache ) return; _cache[ message ] = true; console.warn( message ); } function probeAsync( gl, sync, interval ) { return new Promise( function ( resolve, reject ) { function probe() { switch ( gl.clientWaitSync( sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0 ) ) { case gl.WAIT_FAILED: reject(); break; case gl.TIMEOUT_EXPIRED: setTimeout( probe, interval ); break; default: resolve(); } } setTimeout( probe, interval ); } ); } function toNormalizedProjectionMatrix( projectionMatrix ) { const m = projectionMatrix.elements; // Convert [-1, 1] to [0, 1] projection matrix m[ 2 ] = 0.5 * m[ 2 ] + 0.5 * m[ 3 ]; m[ 6 ] = 0.5 * m[ 6 ] + 0.5 * m[ 7 ]; m[ 10 ] = 0.5 * m[ 10 ] + 0.5 * m[ 11 ]; m[ 14 ] = 0.5 * m[ 14 ] + 0.5 * m[ 15 ]; } function toReversedProjectionMatrix( projectionMatrix ) { const m = projectionMatrix.elements; const isPerspectiveMatrix = m[ 11 ] === -1; // Reverse [0, 1] projection matrix if ( isPerspectiveMatrix ) { m[ 10 ] = - m[ 10 ] - 1; m[ 14 ] = - m[ 14 ]; } else { m[ 10 ] = - m[ 10 ]; m[ 14 ] = - m[ 14 ] + 1; } } const LINEAR_REC709_TO_XYZ = /*@__PURE__*/ new Matrix3().set( 0.4123908, 0.3575843, 0.1804808, 0.2126390, 0.7151687, 0.0721923, 0.0193308, 0.1191948, 0.9505322 ); const XYZ_TO_LINEAR_REC709 = /*@__PURE__*/ new Matrix3().set( 3.2409699, -1.5373832, -0.4986108, -0.9692436, 1.8759675, 0.0415551, 0.0556301, -0.203977, 1.0569715 ); function createColorManagement() { const ColorManagement = { enabled: true, workingColorSpace: LinearSRGBColorSpace, /** * Implementations of supported color spaces. * * Required: * - primaries: chromaticity coordinates [ rx ry gx gy bx by ] * - whitePoint: reference white [ x y ] * - transfer: transfer function (pre-defined) * - toXYZ: Matrix3 RGB to XYZ transform * - fromXYZ: Matrix3 XYZ to RGB transform * - luminanceCoefficients: RGB luminance coefficients * * Optional: * - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace } * - workingColorSpaceConfig: { unpackColorSpace: ColorSpace } * * Reference: * - https://www.russellcottrell.com/photo/matrixCalculator.htm */ spaces: {}, convert: function ( color, sourceColorSpace, targetColorSpace ) { if ( this.enabled === false || sourceColorSpace === targetColorSpace || ! sourceColorSpace || ! targetColorSpace ) { return color; } if ( this.spaces[ sourceColorSpace ].transfer === SRGBTransfer ) { color.r = SRGBToLinear( color.r ); color.g = SRGBToLinear( color.g ); color.b = SRGBToLinear( color.b ); } if ( this.spaces[ sourceColorSpace ].primaries !== this.spaces[ targetColorSpace ].primaries ) { color.applyMatrix3( this.spaces[ sourceColorSpace ].toXYZ ); color.applyMatrix3( this.spaces[ targetColorSpace ].fromXYZ ); } if ( this.spaces[ targetColorSpace ].transfer === SRGBTransfer ) { color.r = LinearToSRGB( color.r ); color.g = LinearToSRGB( color.g ); color.b = LinearToSRGB( color.b ); } return color; }, fromWorkingColorSpace: function ( color, targetColorSpace ) { return this.convert( color, this.workingColorSpace, targetColorSpace ); }, toWorkingColorSpace: function ( color, sourceColorSpace ) { return this.convert( color, sourceColorSpace, this.workingColorSpace ); }, getPrimaries: function ( colorSpace ) { return this.spaces[ colorSpace ].primaries; }, getTransfer: function ( colorSpace ) { if ( colorSpace === NoColorSpace ) return LinearTransfer; return this.spaces[ colorSpace ].transfer; }, getLuminanceCoefficients: function ( target, colorSpace = this.workingColorSpace ) { return target.fromArray( this.spaces[ colorSpace ].luminanceCoefficients ); }, define: function ( colorSpaces ) { Object.assign( this.spaces, colorSpaces ); }, // Internal APIs _getMatrix: function ( targetMatrix, sourceColorSpace, targetColorSpace ) { return targetMatrix .copy( this.spaces[ sourceColorSpace ].toXYZ ) .multiply( this.spaces[ targetColorSpace ].fromXYZ ); }, _getDrawingBufferColorSpace: function ( colorSpace ) { return this.spaces[ colorSpace ].outputColorSpaceConfig.drawingBufferColorSpace; }, _getUnpackColorSpace: function ( colorSpace = this.workingColorSpace ) { return this.spaces[ colorSpace ].workingColorSpaceConfig.unpackColorSpace; } }; /****************************************************************************** * sRGB definitions */ const REC709_PRIMARIES = [ 0.640, 0.330, 0.300, 0.600, 0.150, 0.060 ]; const REC709_LUMINANCE_COEFFICIENTS = [ 0.2126, 0.7152, 0.0722 ]; const D65 = [ 0.3127, 0.3290 ]; ColorManagement.define( { [ LinearSRGBColorSpace ]: { primaries: REC709_PRIMARIES, whitePoint: D65, transfer: LinearTransfer, toXYZ: LINEAR_REC709_TO_XYZ, fromXYZ: XYZ_TO_LINEAR_REC709, luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS, workingColorSpaceConfig: { unpackColorSpace: SRGBColorSpace }, outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace } }, [ SRGBColorSpace ]: { primaries: REC709_PRIMARIES, whitePoint: D65, transfer: SRGBTransfer, toXYZ: LINEAR_REC709_TO_XYZ, fromXYZ: XYZ_TO_LINEAR_REC709, luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS, outputColorSpaceConfig: { drawingBufferColorSpace: SRGBColorSpace } }, } ); return ColorManagement; } const ColorManagement = /*@__PURE__*/ createColorManagement(); function SRGBToLinear( c ) { return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 ); } function LinearToSRGB( c ) { return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055; } let _canvas; class ImageUtils { static getDataURL( image ) { if ( /^data:/i.test( image.src ) ) { return image.src; } if ( typeof HTMLCanvasElement === 'undefined' ) { return image.src; } let canvas; if ( image instanceof HTMLCanvasElement ) { canvas = image; } else { if ( _canvas === undefined ) _canvas = createElementNS( 'canvas' ); _canvas.width = image.width; _canvas.height = image.height; const context = _canvas.getContext( '2d' ); if ( image instanceof ImageData ) { context.putImageData( image, 0, 0 ); } else { context.drawImage( image, 0, 0, image.width, image.height ); } canvas = _canvas; } return canvas.toDataURL( 'image/png' ); } static sRGBToLinear( image ) { if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) || ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) || ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) { const canvas = createElementNS( 'canvas' ); canvas.width = image.width; canvas.height = image.height; const context = canvas.getContext( '2d' ); context.drawImage( image, 0, 0, image.width, image.height ); const imageData = context.getImageData( 0, 0, image.width, image.height ); const data = imageData.data; for ( let i = 0; i < data.length; i ++ ) { data[ i ] = SRGBToLinear( data[ i ] / 255 ) * 255; } context.putImageData( imageData, 0, 0 ); return canvas; } else if ( image.data ) { const data = image.data.slice( 0 ); for ( let i = 0; i < data.length; i ++ ) { if ( data instanceof Uint8Array || data instanceof Uint8ClampedArray ) { data[ i ] = Math.floor( SRGBToLinear( data[ i ] / 255 ) * 255 ); } else { // assuming float data[ i ] = SRGBToLinear( data[ i ] ); } } return { data: data, width: image.width, height: image.height }; } else { console.warn( 'THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.' ); return image; } } } let _sourceId = 0; class Source { constructor( data = null ) { this.isSource = true; Object.defineProperty( this, 'id', { value: _sourceId ++ } ); this.uuid = generateUUID(); this.data = data; this.dataReady = true; this.version = 0; } set needsUpdate( value ) { if ( value === true ) this.version ++; } toJSON( meta ) { const isRootObject = ( meta === undefined || typeof meta === 'string' ); if ( ! isRootObject && meta.images[ this.uuid ] !== undefined ) { return meta.images[ this.uuid ]; } const output = { uuid: this.uuid, url: '' }; const data = this.data; if ( data !== null ) { let url; if ( Array.isArray( data ) ) { // cube texture url = []; for ( let i = 0, l = data.length; i < l; i ++ ) { if ( data[ i ].isDataTexture ) { url.push( serializeImage( data[ i ].image ) ); } else { url.push( serializeImage( data[ i ] ) ); } } } else { // texture url = serializeImage( data ); } output.url = url; } if ( ! isRootObject ) { meta.images[ this.uuid ] = output; } return output; } } function serializeImage( image ) { if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) || ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) || ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) { // default images return ImageUtils.getDataURL( image ); } else { if ( image.data ) { // images of DataTexture return { data: Array.from( image.data ), width: image.width, height: image.height, type: image.data.constructor.name }; } else { console.warn( 'THREE.Texture: Unable to serialize Texture.' ); return {}; } } } let _textureId = 0; class Texture extends EventDispatcher { constructor( image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = Texture.DEFAULT_ANISOTROPY, colorSpace = NoColorSpace ) { super(); this.isTexture = true; Object.defineProperty( this, 'id', { value: _textureId ++ } ); this.uuid = generateUUID(); this.name = ''; this.source = new Source( image ); this.mipmaps = []; this.mapping = mapping; this.channel = 0; this.wrapS = wrapS; this.wrapT = wrapT; this.magFilter = magFilter; this.minFilter = minFilter; this.anisotropy = anisotropy; this.format = format; this.internalFormat = null; this.type = type; this.offset = new Vector2( 0, 0 ); this.repeat = new Vector2( 1, 1 ); this.center = new Vector2( 0, 0 ); this.rotation = 0; this.matrixAutoUpdate = true; this.matrix = new Matrix3(); this.generateMipmaps = true; this.premultiplyAlpha = false; this.flipY = true; this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml) this.colorSpace = colorSpace; this.userData = {}; this.version = 0; this.onUpdate = null; this.renderTarget = null; // assign texture to a render target this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not this.pmremVersion = 0; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures) } get image() { return this.source.data; } set image( value = null ) { this.source.data = value; } updateMatrix() { this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y ); } clone() { return new this.constructor().copy( this ); } copy( source ) { this.name = source.name; this.source = source.source; this.mipmaps = source.mipmaps.slice( 0 ); this.mapping = source.mapping; this.channel = source.channel; this.wrapS = source.wrapS; this.wrapT = source.wrapT; this.magFilter = source.magFilter; this.minFilter = source.minFilter; this.anisotropy = source.anisotropy; this.format = source.format; this.internalFormat = source.internalFormat; this.type = source.type; this.offset.copy( source.offset ); this.repeat.copy( source.repeat ); this.center.copy( source.center ); this.rotation = source.rotation; this.matrixAutoUpdate = source.matrixAutoUpdate; this.matrix.copy( source.matrix ); this.generateMipmaps = source.generateMipmaps; this.premultiplyAlpha = source.premultiplyAlpha; this.flipY = source.flipY; this.unpackAlignment = source.unpackAlignment; this.colorSpace = source.colorSpace; this.renderTarget = source.renderTarget; this.isRenderTargetTexture = source.isRenderTargetTexture; this.userData = JSON.parse( JSON.stringify( source.userData ) ); this.needsUpdate = true; return this; } toJSON( meta ) { const isRootObject = ( meta === undefined || typeof meta === 'string' ); if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) { return meta.textures[ this.uuid ]; } const output = { metadata: { version: 4.6, type: 'Texture', generator: 'Texture.toJSON' }, uuid: this.uuid, name: this.name, image: this.source.toJSON( meta ).uuid, mapping: this.mapping, channel: this.channel, repeat: [ this.repeat.x, this.repeat.y ], offset: [ this.offset.x, this.offset.y ], center: [ this.center.x, this.center.y ], rotation: this.rotation, wrap: [ this.wrapS, this.wrapT ], format: this.format, internalFormat: this.internalFormat, type: this.type, colorSpace: this.colorSpace, minFilter: this.minFilter, magFilter: this.magFilter, anisotropy: this.anisotropy, flipY: this.flipY, generateMipmaps: this.generateMipmaps, premultiplyAlpha: this.premultiplyAlpha, unpackAlignment: this.unpackAlignment }; if ( Object.keys( this.userData ).length > 0 ) output.userData = this.userData; if ( ! isRootObject ) { meta.textures[ this.uuid ] = output; } return output; } dispose() { this.dispatchEvent( { type: 'dispose' } ); } transformUv( uv ) { if ( this.mapping !== UVMapping ) return uv; uv.applyMatrix3( this.matrix ); if ( uv.x < 0 || uv.x > 1 ) { switch ( this.wrapS ) { case RepeatWrapping: uv.x = uv.x - Math.floor( uv.x ); break; case ClampToEdgeWrapping: uv.x = uv.x < 0 ? 0 : 1; break; case MirroredRepeatWrapping: if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) { uv.x = Math.ceil( uv.x ) - uv.x; } else { uv.x = uv.x - Math.floor( uv.x ); } break; } } if ( uv.y < 0 || uv.y > 1 ) { switch ( this.wrapT ) { case RepeatWrapping: uv.y = uv.y - Math.floor( uv.y ); break; case ClampToEdgeWrapping: uv.y = uv.y < 0 ? 0 : 1; break; case MirroredRepeatWrapping: if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) { uv.y = Math.ceil( uv.y ) - uv.y; } else { uv.y = uv.y - Math.floor( uv.y ); } break; } } if ( this.flipY ) { uv.y = 1 - uv.y; } return uv; } set needsUpdate( value ) { if ( value === true ) { this.version ++; this.source.needsUpdate = true; } } set needsPMREMUpdate( value ) { if ( value === true ) { this.pmremVersion ++; } } } Texture.DEFAULT_IMAGE = null; Texture.DEFAULT_MAPPING = UVMapping; Texture.DEFAULT_ANISOTROPY = 1; class Vector4 { constructor( x = 0, y = 0, z = 0, w = 1 ) { Vector4.prototype.isVector4 = true; this.x = x; this.y = y; this.z = z; this.w = w; } get width() { return this.z; } set width( value ) { this.z = value; } get height() { return this.w; } set height( value ) { this.w = value; } set( x, y, z, w ) { this.x = x; this.y = y; this.z = z; this.w = w; return this; } setScalar( scalar ) { this.x = scalar; this.y = scalar; this.z = scalar; this.w = scalar; return this; } setX( x ) { this.x = x; return this; } setY( y ) { this.y = y; return this; } setZ( z ) { this.z = z; return this; } setW( w ) { this.w = w; return this; } setComponent( index, value ) { switch ( index ) { case 0: this.x = value; break; case 1: this.y = value; break; case 2: this.z = value; break; case 3: this.w = value; break; default: throw new Error( 'index is out of range: ' + index ); } return this; } getComponent( index ) { switch ( index ) { case 0: return this.x; case 1: return this.y; case 2: return this.z; case 3: return this.w; default: throw new Error( 'index is out of range: ' + index ); } } clone() { return new this.constructor( this.x, this.y, this.z, this.w ); } copy( v ) { this.x = v.x; this.y = v.y; this.z = v.z; this.w = ( v.w !== undefined ) ? v.w : 1; return this; } add( v ) { this.x += v.x; this.y += v.y; this.z += v.z; this.w += v.w; return this; } addScalar( s ) { this.x += s; this.y += s; this.z += s; this.w += s; return this; } addVectors( 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( v, s ) { this.x += v.x * s; this.y += v.y * s; this.z += v.z * s; this.w += v.w * s; return this; } sub( v ) { this.x -= v.x; this.y -= v.y; this.z -= v.z; this.w -= v.w; return this; } subScalar( s ) { this.x -= s; this.y -= s; this.z -= s; this.w -= s; return this; } subVectors( 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; } multiply( v ) { this.x *= v.x; this.y *= v.y; this.z *= v.z; this.w *= v.w; return this; } multiplyScalar( scalar ) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this; } applyMatrix4( m ) { const x = this.x, y = this.y, z = this.z, w = this.w; const e = m.elements; this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w; this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w; this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w; this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w; return this; } divide( v ) { this.x /= v.x; this.y /= v.y; this.z /= v.z; this.w /= v.w; return this; } divideScalar( scalar ) { return this.multiplyScalar( 1 / scalar ); } setAxisAngleFromQuaternion( q ) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm // q is assumed to be normalized this.w = 2 * Math.acos( q.w ); const s = Math.sqrt( 1 - q.w * q.w ); if ( s < 0.0001 ) { this.x = 1; this.y = 0; this.z = 0; } else { this.x = q.x / s; this.y = q.y / s; this.z = q.z / s; } return this; } setAxisAngleFromRotationMatrix( m ) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) let angle, x, y, z; // variables for result const epsilon = 0.01, // margin to allow for rounding errors epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees te = m.elements, m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; if ( ( Math.abs( m12 - m21 ) < epsilon ) && ( Math.abs( m13 - m31 ) < epsilon ) && ( Math.abs( m23 - m32 ) < epsilon ) ) { // singularity found // first check for identity matrix which must have +1 for all terms // in leading diagonal and zero in other terms if ( ( Math.abs( m12 + m21 ) < epsilon2 ) && ( Math.abs( m13 + m31 ) < epsilon2 ) && ( Math.abs( m23 + m32 ) < epsilon2 ) && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) { // this singularity is identity matrix so angle = 0 this.set( 1, 0, 0, 0 ); return this; // zero angle, arbitrary axis } // otherwise this singularity is angle = 180 angle = Math.PI; const xx = ( m11 + 1 ) / 2; const yy = ( m22 + 1 ) / 2; const zz = ( m33 + 1 ) / 2; const xy = ( m12 + m21 ) / 4; const xz = ( m13 + m31 ) / 4; const yz = ( m23 + m32 ) / 4; if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term if ( xx < epsilon ) { x = 0; y = 0.707106781; z = 0.707106781; } else { x = Math.sqrt( xx ); y = xy / x; z = xz / x; } } else if ( yy > zz ) { // m22 is the largest diagonal term if ( yy < epsilon ) { x = 0.707106781; y = 0; z = 0.707106781; } else { y = Math.sqrt( yy ); x = xy / y; z = yz / y; } } else { // m33 is the largest diagonal term so base result on this if ( zz < epsilon ) { x = 0.707106781; y = 0.707106781; z = 0; } else { z = Math.sqrt( zz ); x = xz / z; y = yz / z; } } this.set( x, y, z, angle ); return this; // return 180 deg rotation } // as we have reached here there are no singularities so we can handle normally let s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) + ( m13 - m31 ) * ( m13 - m31 ) + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize if ( Math.abs( s ) < 0.001 ) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be // caught by singularity test above, but I've left it in just in case this.x = ( m32 - m23 ) / s; this.y = ( m13 - m31 ) / s; this.z = ( m21 - m12 ) / s; this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 ); return this; } setFromMatrixPosition( m ) { const e = m.elements; this.x = e[ 12 ]; this.y = e[ 13 ]; this.z = e[ 14 ]; this.w = e[ 15 ]; return this; } min( v ) { this.x = Math.min( this.x, v.x ); this.y = Math.min( this.y, v.y ); this.z = Math.min( this.z, v.z ); this.w = Math.min( this.w, v.w ); return this; } max( v ) { this.x = Math.max( this.x, v.x ); this.y = Math.max( this.y, v.y ); this.z = Math.max( this.z, v.z ); this.w = Math.max( this.w, v.w ); return this; } clamp( min, max ) { // assumes min < max, componentwise this.x = clamp$1( this.x, min.x, max.x ); this.y = clamp$1( this.y, min.y, max.y ); this.z = clamp$1( this.z, min.z, max.z ); this.w = clamp$1( this.w, min.w, max.w ); return this; } clampScalar( minVal, maxVal ) { this.x = clamp$1( this.x, minVal, maxVal ); this.y = clamp$1( this.y, minVal, maxVal ); this.z = clamp$1( this.z, minVal, maxVal ); this.w = clamp$1( this.w, minVal, maxVal ); return this; } clampLength( min, max ) { const length = this.length(); return this.divideScalar( length || 1 ).multiplyScalar( clamp$1( length, min, max ) ); } floor() { this.x = Math.floor( this.x ); this.y = Math.floor( this.y ); this.z = Math.floor( this.z ); this.w = Math.floor( this.w ); return this; } ceil() { this.x = Math.ceil( this.x ); this.y = Math.ceil( this.y ); this.z = Math.ceil( this.z ); this.w = Math.ceil( this.w ); return this; } round() { this.x = Math.round( this.x ); this.y = Math.round( this.y ); this.z = Math.round( this.z ); this.w = Math.round( this.w ); return this; } roundToZero() { this.x = Math.trunc( this.x ); this.y = Math.trunc( this.y ); this.z = Math.trunc( this.z ); this.w = Math.trunc( this.w ); return this; } negate() { this.x = - this.x; this.y = - this.y; this.z = - this.z; this.w = - this.w; return this; } dot( v ) { return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; } lengthSq() { return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; } length() { return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); } manhattanLength() { return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w ); } normalize() { return this.divideScalar( this.length() || 1 ); } setLength( length ) { return this.normalize().multiplyScalar( length ); } lerp( v, alpha ) { this.x += ( v.x - this.x ) * alpha; this.y += ( v.y - this.y ) * alpha; this.z += ( v.z - this.z ) * alpha; this.w += ( v.w - this.w ) * alpha; return this; } lerpVectors( v1, v2, alpha ) { this.x = v1.x + ( v2.x - v1.x ) * alpha; this.y = v1.y + ( v2.y - v1.y ) * alpha; this.z = v1.z + ( v2.z - v1.z ) * alpha; this.w = v1.w + ( v2.w - v1.w ) * alpha; return this; } equals( v ) { return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) ); } fromArray( array, offset = 0 ) { this.x = array[ offset ]; this.y = array[ offset + 1 ]; this.z = array[ offset + 2 ]; this.w = array[ offset + 3 ]; return this; } toArray( array = [], offset = 0 ) { array[ offset ] = this.x; array[ offset + 1 ] = this.y; array[ offset + 2 ] = this.z; array[ offset + 3 ] = this.w; return array; } fromBufferAttribute( attribute, index ) { this.x = attribute.getX( index ); this.y = attribute.getY( index ); this.z = attribute.getZ( index ); this.w = attribute.getW( index ); return this; } random() { this.x = Math.random(); this.y = Math.random(); this.z = Math.random(); this.w = Math.random(); return this; } *[ Symbol.iterator ]() { yield this.x; yield this.y; yield this.z; yield this.w; } } /* In options, we can specify: * Texture parameters for an auto-generated target texture * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers */ class RenderTarget extends EventDispatcher { constructor( width = 1, height = 1, options = {} ) { super(); this.isRenderTarget = true; this.width = width; this.height = height; this.depth = 1; this.scissor = new Vector4( 0, 0, width, height ); this.scissorTest = false; this.viewport = new Vector4( 0, 0, width, height ); const image = { width: width, height: height, depth: 1 }; options = Object.assign( { generateMipmaps: false, internalFormat: null, minFilter: LinearFilter, depthBuffer: true, stencilBuffer: false, resolveDepthBuffer: true, resolveStencilBuffer: true, depthTexture: null, samples: 0, count: 1 }, options ); const texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace ); texture.flipY = false; texture.generateMipmaps = options.generateMipmaps; texture.internalFormat = options.internalFormat; this.textures = []; const count = options.count; for ( let i = 0; i < count; i ++ ) { this.textures[ i ] = texture.clone(); this.textures[ i ].isRenderTargetTexture = true; this.textures[ i ].renderTarget = this; } this.depthBuffer = options.depthBuffer; this.stencilBuffer = options.stencilBuffer; this.resolveDepthBuffer = options.resolveDepthBuffer; this.resolveStencilBuffer = options.resolveStencilBuffer; this._depthTexture = null; this.depthTexture = options.depthTexture; this.samples = options.samples; } get texture() { return this.textures[ 0 ]; } set texture( value ) { this.textures[ 0 ] = value;