PageSourceSearch

https://tessernaut.com/assets/js/three.js

js tessernaut.com collected 2026-09-24 14:54:08 UTC 1,255,450 bytes, 51,876 lines download raw bytes

1(function (global, factory) {
2	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3	typeof define === 'function' && define.amd ? define(['exports'], factory) :
4	(global = global || self, factory(global.THREE = {}));
5}(this, (function (exports) { 'use strict';
6
7	// Polyfills
8
9	if ( Number.EPSILON === undefined ) {
10
11		Number.EPSILON = Math.pow( 2, - 52 );
12
13	}
14
15	if ( Number.isInteger === undefined ) {
16
17		// Missing in IE
18		// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
19
20		Number.isInteger = function ( value ) {
21
22			return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value;
23
24		};
25
26	}
27
28	//
29
30	if ( Math.sign === undefined ) {
31
32		// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
33
34		Math.sign = function ( x ) {
35
36			return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;
37
38		};
39
40	}
41
42	if ( 'name' in Function.prototype === false ) {
43
44		// Missing in IE
45		// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
46
47		Object.defineProperty( Function.prototype, 'name', {
48
49			get: function () {
50
51				return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ];
52
53			}
54
55		} );
56
57	}
58
59	if ( Object.assign === undefined ) {
60
61		// Missing in IE
62		// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
63
64		Object.assign = function ( target ) {
65
66			if ( target === undefined || target === null ) {
67
68				throw new TypeError( 'Cannot convert undefined or null to object' );
69
70			}
71
72			var output = Object( target );
73
74			for ( var index = 1; index < arguments.length; index ++ ) {
75
76				var source = arguments[ index ];
77
78				if ( source !== undefined && source !== null ) {
79
80					for ( var nextKey in source ) {
81
82						if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
83
84							output[ nextKey ] = source[ nextKey ];
85
86						}
87
88					}
89
90				}
91
92			}
93
94			return output;
95
96		};
97
98	}
99
100	var REVISION = '118dev';
101	var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
102	var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
103	var CullFaceNone = 0;
104	var CullFaceBack = 1;
105	var CullFaceFront = 2;
106	var CullFaceFrontBack = 3;
107	var FrontFaceDirectionCW = 0;
108	var FrontFaceDirectionCCW = 1;
109	var BasicShadowMap = 0;
110	var PCFShadowMap = 1;
111	var PCFSoftShadowMap = 2;
112	var VSMShadowMap = 3;
113	var FrontSide = 0;
114	var BackSide = 1;
115	var DoubleSide = 2;
116	var FlatShading = 1;
117	var SmoothShading = 2;
118	var NoBlending = 0;
119	var NormalBlending = 1;
120	var AdditiveBlending = 2;
121	var SubtractiveBlending = 3;
122	var MultiplyBlending = 4;
123	var CustomBlending = 5;
124	var AddEquation = 100;
125	var SubtractEquation = 101;
126	var ReverseSubtractEquation = 102;
127	var MinEquation = 103;
128	var MaxEquation = 104;
129	var ZeroFactor = 200;
130	var OneFactor = 201;
131	var SrcColorFactor = 202;
132	var OneMinusSrcColorFactor = 203;
133	var SrcAlphaFactor = 204;
134	var OneMinusSrcAlphaFactor = 205;
135	var DstAlphaFactor = 206;
136	var OneMinusDstAlphaFactor = 207;
137	var DstColorFactor = 208;
138	var OneMinusDstColorFactor = 209;
139	var SrcAlphaSaturateFactor = 210;
140	var NeverDepth = 0;
141	var AlwaysDepth = 1;
142	var LessDepth = 2;
143	var LessEqualDepth = 3;
144	var EqualDepth = 4;
145	var GreaterEqualDepth = 5;
146	var GreaterDepth = 6;
147	var NotEqualDepth = 7;
148	var MultiplyOperation = 0;
149	var MixOperation = 1;
150	var AddOperation = 2;
151	var NoToneMapping = 0;
152	var LinearToneMapping = 1;
153	var ReinhardToneMapping = 2;
154	var CineonToneMapping = 3;
155	var ACESFilmicToneMapping = 4;
156	var CustomToneMapping = 5;
157
158	var UVMapping = 300;
159	var CubeReflectionMapping = 301;
160	var CubeRefractionMapping = 302;
161	var EquirectangularReflectionMapping = 303;
162	var EquirectangularRefractionMapping = 304;
163	var CubeUVReflectionMapping = 306;
164	var CubeUVRefractionMapping = 307;
165	var RepeatWrapping = 1000;
166	var ClampToEdgeWrapping = 1001;
167	var MirroredRepeatWrapping = 1002;
168	var NearestFilter = 1003;
169	var NearestMipmapNearestFilter = 1004;
170	var NearestMipMapNearestFilter = 1004;
171	var NearestMipmapLinearFilter = 1005;
172	var NearestMipMapLinearFilter = 1005;
173	var LinearFilter = 1006;
174	var LinearMipmapNearestFilter = 1007;
175	var LinearMipMapNearestFilter = 1007;
176	var LinearMipmapLinearFilter = 1008;
177	var LinearMipMapLinearFilter = 1008;
178	var UnsignedByteType = 1009;
179	var ByteType = 1010;
180	var ShortType = 1011;
181	var UnsignedShortType = 1012;
182	var IntType = 1013;
183	var UnsignedIntType = 1014;
184	var FloatType = 1015;
185	var HalfFloatType = 1016;
186	var UnsignedShort4444Type = 1017;
187	var UnsignedShort5551Type = 1018;
188	var UnsignedShort565Type = 1019;
189	var UnsignedInt248Type = 1020;
190	var AlphaFormat = 1021;
191	var RGBFormat = 1022;
192	var RGBAFormat = 1023;
193	var LuminanceFormat = 1024;
194	var LuminanceAlphaFormat = 1025;
195	var RGBEFormat = RGBAFormat;
196	var DepthFormat = 1026;
197	var DepthStencilFormat = 1027;
198	var RedFormat = 1028;
199	var RedIntegerFormat = 1029;
200	var RGFormat = 1030;
201	var RGIntegerFormat = 1031;
202	var RGBIntegerFormat = 1032;
203	var RGBAIntegerFormat = 1033;
204
205	var RGB_S3TC_DXT1_Format = 33776;
206	var RGBA_S3TC_DXT1_Format = 33777;
207	var RGBA_S3TC_DXT3_Format = 33778;
208	var RGBA_S3TC_DXT5_Format = 33779;
209	var RGB_PVRTC_4BPPV1_Format = 35840;
210	var RGB_PVRTC_2BPPV1_Format = 35841;
211	var RGBA_PVRTC_4BPPV1_Format = 35842;
212	var RGBA_PVRTC_2BPPV1_Format = 35843;
213	var RGB_ETC1_Format = 36196;
214	var RGB_ETC2_Format = 37492;
215	var RGBA_ETC2_EAC_Format = 37496;
216	var RGBA_ASTC_4x4_Format = 37808;
217	var RGBA_ASTC_5x4_Format = 37809;
218	var RGBA_ASTC_5x5_Format = 37810;
219	var RGBA_ASTC_6x5_Format = 37811;
220	var RGBA_ASTC_6x6_Format = 37812;
221	var RGBA_ASTC_8x5_Format = 37813;
222	var RGBA_ASTC_8x6_Format = 37814;
223	var RGBA_ASTC_8x8_Format = 37815;
224	var RGBA_ASTC_10x5_Format = 37816;
225	var RGBA_ASTC_10x6_Format = 37817;
226	var RGBA_ASTC_10x8_Format = 37818;
227	var RGBA_ASTC_10x10_Format = 37819;
228	var RGBA_ASTC_12x10_Format = 37820;
229	var RGBA_ASTC_12x12_Format = 37821;
230	var RGBA_BPTC_Format = 36492;
231	var SRGB8_ALPHA8_ASTC_4x4_Format = 37840;
232	var SRGB8_ALPHA8_ASTC_5x4_Format = 37841;
233	var SRGB8_ALPHA8_ASTC_5x5_Format = 37842;
234	var SRGB8_ALPHA8_ASTC_6x5_Format = 37843;
235	var SRGB8_ALPHA8_ASTC_6x6_Format = 37844;
236	var SRGB8_ALPHA8_ASTC_8x5_Format = 37845;
237	var SRGB8_ALPHA8_ASTC_8x6_Format = 37846;
238	var SRGB8_ALPHA8_ASTC_8x8_Format = 37847;
239	var SRGB8_ALPHA8_ASTC_10x5_Format = 37848;
240	var SRGB8_ALPHA8_ASTC_10x6_Format = 37849;
241	var SRGB8_ALPHA8_ASTC_10x8_Format = 37850;
242	var SRGB8_ALPHA8_ASTC_10x10_Format = 37851;
243	var SRGB8_ALPHA8_ASTC_12x10_Format = 37852;
244	var SRGB8_ALPHA8_ASTC_12x12_Format = 37853;
245	var LoopOnce = 2200;
246	var LoopRepeat = 2201;
247	var LoopPingPong = 2202;
248	var InterpolateDiscrete = 2300;
249	var InterpolateLinear = 2301;
250	var InterpolateSmooth = 2302;
251	var ZeroCurvatureEnding = 2400;
252	var ZeroSlopeEnding = 2401;
253	var WrapAroundEnding = 2402;
254	var NormalAnimationBlendMode = 2500;
255	var AdditiveAnimationBlendMode = 2501;
256	var TrianglesDrawMode = 0;
257	var TriangleStripDrawMode = 1;
258	var TriangleFanDrawMode = 2;
259	var LinearEncoding = 3000;
260	var sRGBEncoding = 3001;
261	var GammaEncoding = 3007;
262	var RGBEEncoding = 3002;
263	var LogLuvEncoding = 3003;
264	var RGBM7Encoding = 3004;
265	var RGBM16Encoding = 3005;
266	var RGBDEncoding = 3006;
267	var BasicDepthPacking = 3200;
268	var RGBADepthPacking = 3201;
269	var TangentSpaceNormalMap = 0;
270	var ObjectSpaceNormalMap = 1;
271
272	var ZeroStencilOp = 0;
273	var KeepStencilOp = 7680;
274	var ReplaceStencilOp = 7681;
275	var IncrementStencilOp = 7682;
276	var DecrementStencilOp = 7683;
277	var IncrementWrapStencilOp = 34055;
278	var DecrementWrapStencilOp = 34056;
279	var InvertStencilOp = 5386;
280
281	var NeverStencilFunc = 512;
282	var LessStencilFunc = 513;
283	var EqualStencilFunc = 514;
284	var LessEqualStencilFunc = 515;
285	var GreaterStencilFunc = 516;
286	var NotEqualStencilFunc = 517;
287	var GreaterEqualStencilFunc = 518;
288	var AlwaysStencilFunc = 519;
289
290	var StaticDrawUsage = 35044;
291	var DynamicDrawUsage = 35048;
292	var StreamDrawUsage = 35040;
293	var StaticReadUsage = 35045;
294	var DynamicReadUsage = 35049;
295	var StreamReadUsage = 35041;
296	var StaticCopyUsage = 35046;
297	var DynamicCopyUsage = 35050;
298	var StreamCopyUsage = 35042;
299
300	/**
301	 * https://github.com/mrdoob/eventdispatcher.js/
302	 */
303
304	function EventDispatcher() {}
305
306	Object.assign( EventDispatcher.prototype, {
307
308		addEventListener: function ( type, listener ) {
309
310			if ( this._listeners === undefined ) { this._listeners = {}; }
311
312			var listeners = this._listeners;
313
314			if ( listeners[ type ] === undefined ) {
315
316				listeners[ type ] = [];
317
318			}
319
320			if ( listeners[ type ].indexOf( listener ) === - 1 ) {
321
322				listeners[ type ].push( listener );
323
324			}
325
326		},
327
328		hasEventListener: function ( type, listener ) {
329
330			if ( this._listeners === undefined ) { return false; }
331
332			var listeners = this._listeners;
333
334			return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
335
336		},
337
338		removeEventListener: function ( type, listener ) {
339
340			if ( this._listeners === undefined ) { return; }
341
342			var listeners = this._listeners;
343			var listenerArray = listeners[ type ];
344
345			if ( listenerArray !== undefined ) {
346
347				var index = listenerArray.indexOf( listener );
348
349				if ( index !== - 1 ) {
350
351					listenerArray.splice( index, 1 );
352
353				}
354
355			}
356
357		},
358
359		dispatchEvent: function ( event ) {
360
361			if ( this._listeners === undefined ) { return; }
362
363			var listeners = this._listeners;
364			var listenerArray = listeners[ event.type ];
365
366			if ( listenerArray !== undefined ) {
367
368				event.target = this;
369
370				// Make a copy, in case listeners are removed while iterating.
371				var array = listenerArray.slice( 0 );
372
373				for ( var i = 0, l = array.length; i < l; i ++ ) {
374
375					array[ i ].call( this, event );
376
377				}
378
379			}
380
381		}
382
383	} );
384
385	/**
386	 * @author alteredq / http://alteredqualia.com/
387	 * @author mrdoob / http://mrdoob.com/
388	 * @author WestLangley / http://github.com/WestLangley
389	 * @author thezwap
390	 */
391
392	var _lut = [];
393
394	for ( var i = 0; i < 256; i ++ ) {
395
396		_lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 );
397
398	}
399
400	var MathUtils = {
401
402		DEG2RAD: Math.PI / 180,
403		RAD2DEG: 180 / Math.PI,
404
405		generateUUID: function () {
406
407			// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136
408
409			var d0 = Math.random() * 0xffffffff | 0;
410			var d1 = Math.random() * 0xffffffff | 0;
411			var d2 = Math.random() * 0xffffffff | 0;
412			var d3 = Math.random() * 0xffffffff | 0;
413			var uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' +
414				_lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' +
415				_lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] +
416				_lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ];
417
418			// .toUpperCase() here flattens concatenated strings to save heap memory space.
419			return uuid.toUpperCase();
420
421		},
422
423		clamp: function ( value, min, max ) {
424
425			return Math.max( min, Math.min( max, value ) );
426
427		},
428
429		// compute euclidian modulo of m % n
430		// https://en.wikipedia.org/wiki/Modulo_operation
431
432		euclideanModulo: function ( n, m ) {
433
434			return ( ( n % m ) + m ) % m;
435
436		},
437
438		// Linear mapping from range <a1, a2> to range <b1, b2>
439
440		mapLinear: function ( x, a1, a2, b1, b2 ) {
441
442			return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
443
444		},
445
446		// https://en.wikipedia.org/wiki/Linear_interpolation
447
448		lerp: function ( x, y, t ) {
449
450			return ( 1 - t ) * x + t * y;
451
452		},
453
454		// http://en.wikipedia.org/wiki/Smoothstep
455
456		smoothstep: function ( x, min, max ) {
457
458			if ( x <= min ) { return 0; }
459			if ( x >= max ) { return 1; }
460
461			x = ( x - min ) / ( max - min );
462
463			return x * x * ( 3 - 2 * x );
464
465		},
466
467		smootherstep: function ( x, min, max ) {
468
469			if ( x <= min ) { return 0; }
470			if ( x >= max ) { return 1; }
471
472			x = ( x - min ) / ( max - min );
473
474			return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
475
476		},
477
478		// Random integer from <low, high> interval
479
480		randInt: function ( low, high ) {
481
482			return low + Math.floor( Math.random() * ( high - low + 1 ) );
483
484		},
485
486		// Random float from <low, high> interval
487
488		randFloat: function ( low, high ) {
489
490			return low + Math.random() * ( high - low );
491
492		},
493
494		// Random float from <-range/2, range/2> interval
495
496		randFloatSpread: function ( range ) {
497
498			return range * ( 0.5 - Math.random() );
499
500		},
501
502		degToRad: function ( degrees ) {
503
504			return degrees * MathUtils.DEG2RAD;
505
506		},
507
508		radToDeg: function ( radians ) {
509
510			return radians * MathUtils.RAD2DEG;
511
512		},
513
514		isPowerOfTwo: function ( value ) {
515
516			return ( value & ( value - 1 ) ) === 0 && value !== 0;
517
518		},
519
520		ceilPowerOfTwo: function ( value ) {
521
522			return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) );
523
524		},
525
526		floorPowerOfTwo: function ( value ) {
527
528			return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) );
529
530		},
531
532		setQuaternionFromProperEuler: function ( q, a, b, c, order ) {
533
534			// Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles
535
536			// rotations are applied to the axes in the order specified by 'order'
537			// rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c'
538			// angles are in radians
539
540			var cos = Math.cos;
541			var sin = Math.sin;
542
543			var c2 = cos( b / 2 );
544			var s2 = sin( b / 2 );
545
546			var c13 = cos( ( a + c ) / 2 );
547			var s13 = sin( ( a + c ) / 2 );
548
549			var c1_3 = cos( ( a - c ) / 2 );
550			var s1_3 = sin( ( a - c ) / 2 );
551
552			var c3_1 = cos( ( c - a ) / 2 );
553			var s3_1 = sin( ( c - a ) / 2 );
554
555			switch ( order ) {
556
557				case 'XYX':
558					q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 );
559					break;
560
561				case 'YZY':
562					q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 );
563					break;
564
565				case 'ZXZ':
566					q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 );
567					break;
568
569				case 'XZX':
570					q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 );
571					break;
572
573				case 'YXY':
574					q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 );
575					break;
576
577				case 'ZYZ':
578					q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 );
579					break;
580
581				default:
582					console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order );
583
584			}
585
586		}
587
588	};
589
590	/**
591	 * @author mrdoob / http://mrdoob.com/
592	 * @author philogb / http://blog.thejit.org/
593	 * @author egraether / http://egraether.com/
594	 * @author zz85 / http://www.lab4games.net/zz85/blog
595	 */
596
597	function Vector2( x, y ) {
598		if ( x === void 0 ) x = 0;
599		if ( y === void 0 ) y = 0;
600
601
602		this.x = x;
603		this.y = y;
604
605	}
606
607	Object.defineProperties( Vector2.prototype, {
608
609		"width": {
610
611			get: function () {
612
613				return this.x;
614
615			},
616
617			set: function ( value ) {
618
619				this.x = value;
620
621			}
622
623		},
624
625		"height": {
626
627			get: function () {
628
629				return this.y;
630
631			},
632
633			set: function ( value ) {
634
635				this.y = value;
636
637			}
638
639		}
640
641	} );
642
643	Object.assign( Vector2.prototype, {
644
645		isVector2: true,
646
647		set: function ( x, y ) {
648
649			this.x = x;
650			this.y = y;
651
652			return this;
653
654		},
655
656		setScalar: function ( scalar ) {
657
658			this.x = scalar;
659			this.y = scalar;
660
661			return this;
662
663		},
664
665		setX: function ( x ) {
666
667			this.x = x;
668
669			return this;
670
671		},
672
673		setY: function ( y ) {
674
675			this.y = y;
676
677			return this;
678
679		},
680
681		setComponent: function ( index, value ) {
682
683			switch ( index ) {
684
685				case 0: this.x = value; break;
686				case 1: this.y = value; break;
687				default: throw new Error( 'index is out of range: ' + index );
688
689			}
690
691			return this;
692
693		},
694
695		getComponent: function ( index ) {
696
697			switch ( index ) {
698
699				case 0: return this.x;
700				case 1: return this.y;
701				default: throw new Error( 'index is out of range: ' + index );
702
703			}
704
705		},
706
707		clone: function () {
708
709			return new this.constructor( this.x, this.y );
710
711		},
712
713		copy: function ( v ) {
714
715			this.x = v.x;
716			this.y = v.y;
717
718			return this;
719
720		},
721
722		add: function ( v, w ) {
723
724			if ( w !== undefined ) {
725
726				console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
727				return this.addVectors( v, w );
728
729			}
730
731			this.x += v.x;
732			this.y += v.y;
733
734			return this;
735
736		},
737
738		addScalar: function ( s ) {
739
740			this.x += s;
741			this.y += s;
742
743			return this;
744
745		},
746
747		addVectors: function ( a, b ) {
748
749			this.x = a.x + b.x;
750			this.y = a.y + b.y;
751
752			return this;
753
754		},
755
756		addScaledVector: function ( v, s ) {
757
758			this.x += v.x * s;
759			this.y += v.y * s;
760
761			return this;
762
763		},
764
765		sub: function ( v, w ) {
766
767			if ( w !== undefined ) {
768
769				console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
770				return this.subVectors( v, w );
771
772			}
773
774			this.x -= v.x;
775			this.y -= v.y;
776
777			return this;
778
779		},
780
781		subScalar: function ( s ) {
782
783			this.x -= s;
784			this.y -= s;
785
786			return this;
787
788		},
789
790		subVectors: function ( a, b ) {
791
792			this.x = a.x - b.x;
793			this.y = a.y - b.y;
794
795			return this;
796
797		},
798
799		multiply: function ( v ) {
800
801			this.x *= v.x;
802			this.y *= v.y;
803
804			return this;
805
806		},
807
808		multiplyScalar: function ( scalar ) {
809
810			this.x *= scalar;
811			this.y *= scalar;
812
813			return this;
814
815		},
816
817		divide: function ( v ) {
818
819			this.x /= v.x;
820			this.y /= v.y;
821
822			return this;
823
824		},
825
826		divideScalar: function ( scalar ) {
827
828			return this.multiplyScalar( 1 / scalar );
829
830		},
831
832		applyMatrix3: function ( m ) {
833
834			var x = this.x, y = this.y;
835			var e = m.elements;
836
837			this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ];
838			this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ];
839
840			return this;
841
842		},
843
844		min: function ( v ) {
845
846			this.x = Math.min( this.x, v.x );
847			this.y = Math.min( this.y, v.y );
848
849			return this;
850
851		},
852
853		max: function ( v ) {
854
855			this.x = Math.max( this.x, v.x );
856			this.y = Math.max( this.y, v.y );
857
858			return this;
859
860		},
861
862		clamp: function ( min, max ) {
863
864			// assumes min < max, componentwise
865
866			this.x = Math.max( min.x, Math.min( max.x, this.x ) );
867			this.y = Math.max( min.y, Math.min( max.y, this.y ) );
868
869			return this;
870
871		},
872
873		clampScalar: function ( minVal, maxVal ) {
874
875			this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
876			this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
877
878			return this;
879
880		},
881
882		clampLength: function ( min, max ) {
883
884			var length = this.length();
885
886			return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
887
888		},
889
890		floor: function () {
891
892			this.x = Math.floor( this.x );
893			this.y = Math.floor( this.y );
894
895			return this;
896
897		},
898
899		ceil: function () {
900
901			this.x = Math.ceil( this.x );
902			this.y = Math.ceil( this.y );
903
904			return this;
905
906		},
907
908		round: function () {
909
910			this.x = Math.round( this.x );
911			this.y = Math.round( this.y );
912
913			return this;
914
915		},
916
917		roundToZero: function () {
918
919			this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
920			this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
921
922			return this;
923
924		},
925
926		negate: function () {
927
928			this.x = - this.x;
929			this.y = - this.y;
930
931			return this;
932
933		},
934
935		dot: function ( v ) {
936
937			return this.x * v.x + this.y * v.y;
938
939		},
940
941		cross: function ( v ) {
942
943			return this.x * v.y - this.y * v.x;
944
945		},
946
947		lengthSq: function () {
948
949			return this.x * this.x + this.y * this.y;
950
951		},
952
953		length: function () {
954
955			return Math.sqrt( this.x * this.x + this.y * this.y );
956
957		},
958
959		manhattanLength: function () {
960
961			return Math.abs( this.x ) + Math.abs( this.y );
962
963		},
964
965		normalize: function () {
966
967			return this.divideScalar( this.length() || 1 );
968
969		},
970
971		angle: function () {
972
973			// computes the angle in radians with respect to the positive x-axis
974
975			var angle = Math.atan2( - this.y, - this.x ) + Math.PI;
976
977			return angle;
978
979		},
980
981		distanceTo: function ( v ) {
982
983			return Math.sqrt( this.distanceToSquared( v ) );
984
985		},
986
987		distanceToSquared: function ( v ) {
988
989			var dx = this.x - v.x, dy = this.y - v.y;
990			return dx * dx + dy * dy;
991
992		},
993
994		manhattanDistanceTo: function ( v ) {
995
996			return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );
997
998		},
999
1000		setLength: function ( length ) {
1001
1002			return this.normalize().multiplyScalar( length );
1003
1004		},
1005
1006		lerp: function ( v, alpha ) {
1007
1008			this.x += ( v.x - this.x ) * alpha;
1009			this.y += ( v.y - this.y ) * alpha;
1010
1011			return this;
1012
1013		},
1014
1015		lerpVectors: function ( v1, v2, alpha ) {
1016
1017			this.x = v1.x + ( v2.x - v1.x ) * alpha;
1018			this.y = v1.y + ( v2.y - v1.y ) * alpha;
1019
1020			return this;
1021
1022		},
1023
1024		equals: function ( v ) {
1025
1026			return ( ( v.x === this.x ) && ( v.y === this.y ) );
1027
1028		},
1029
1030		fromArray: function ( array, offset ) {
1031
1032			if ( offset === undefined ) { offset = 0; }
1033
1034			this.x = array[ offset ];
1035			this.y = array[ offset + 1 ];
1036
1037			return this;
1038
1039		},
1040
1041		toArray: function ( array, offset ) {
1042
1043			if ( array === undefined ) { array = []; }
1044			if ( offset === undefined ) { offset = 0; }
1045
1046			array[ offset ] = this.x;
1047			array[ offset + 1 ] = this.y;
1048
1049			return array;
1050
1051		},
1052
1053		fromBufferAttribute: function ( attribute, index, offset ) {
1054
1055			if ( offset !== undefined ) {
1056
1057				console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );
1058
1059			}
1060
1061			this.x = attribute.getX( index );
1062			this.y = attribute.getY( index );
1063
1064			return this;
1065
1066		},
1067
1068		rotateAround: function ( center, angle ) {
1069
1070			var c = Math.cos( angle ), s = Math.sin( angle );
1071
1072			var x = this.x - center.x;
1073			var y = this.y - center.y;
1074
1075			this.x = x * c - y * s + center.x;
1076			this.y = x * s + y * c + center.y;
1077
1078			return this;
1079
1080		},
1081
1082		random: function () {
1083
1084			this.x = Math.random();
1085			this.y = Math.random();
1086
1087			return this;
1088
1089		}
1090
1091	} );
1092
1093	/**
1094	 * @author alteredq / http://alteredqualia.com/
1095	 * @author WestLangley / http://github.com/WestLangley
1096	 * @author bhouston / http://clara.io
1097	 * @author tschw
1098	 */
1099
1100	function Matrix3() {
1101
1102		this.elements = [
1103
1104			1, 0, 0,
1105			0, 1, 0,
1106			0, 0, 1
1107
1108		];
1109
1110		if ( arguments.length > 0 ) {
1111
1112			console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
1113
1114		}
1115
1116	}
1117
1118	Object.assign( Matrix3.prototype, {
1119
1120		isMatrix3: true,
1121
1122		set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
1123
1124			var te = this.elements;
1125
1126			te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
1127			te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
1128			te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
1129
1130			return this;
1131
1132		},
1133
1134		identity: function () {
1135
1136			this.set(
1137
1138				1, 0, 0,
1139				0, 1, 0,
1140				0, 0, 1
1141
1142			);
1143
1144			return this;
1145
1146		},
1147
1148		clone: function () {
1149
1150			return new this.constructor().fromArray( this.elements );
1151
1152		},
1153
1154		copy: function ( m ) {
1155
1156			var te = this.elements;
1157			var me = m.elements;
1158
1159			te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
1160			te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
1161			te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
1162
1163			return this;
1164
1165		},
1166
1167		extractBasis: function ( xAxis, yAxis, zAxis ) {
1168
1169			xAxis.setFromMatrix3Column( this, 0 );
1170			yAxis.setFromMatrix3Column( this, 1 );
1171			zAxis.setFromMatrix3Column( this, 2 );
1172
1173			return this;
1174
1175		},
1176
1177		setFromMatrix4: function ( m ) {
1178
1179			var me = m.elements;
1180
1181			this.set(
1182
1183				me[ 0 ], me[ 4 ], me[ 8 ],
1184				me[ 1 ], me[ 5 ], me[ 9 ],
1185				me[ 2 ], me[ 6 ], me[ 10 ]
1186
1187			);
1188
1189			return this;
1190
1191		},
1192
1193		multiply: function ( m ) {
1194
1195			return this.multiplyMatrices( this, m );
1196
1197		},
1198
1199		premultiply: function ( m ) {
1200
1201			return this.multiplyMatrices( m, this );
1202
1203		},
1204
1205		multiplyMatrices: function ( a, b ) {
1206
1207			var ae = a.elements;
1208			var be = b.elements;
1209			var te = this.elements;
1210
1211			var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
1212			var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
1213			var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
1214
1215			var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
1216			var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
1217			var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
1218
1219			te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
1220			te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
1221			te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
1222
1223			te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
1224			te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
1225			te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
1226
1227			te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
1228			te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
1229			te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
1230
1231			return this;
1232
1233		},
1234
1235		multiplyScalar: function ( s ) {
1236
1237			var te = this.elements;
1238
1239			te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
1240			te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
1241			te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
1242
1243			return this;
1244
1245		},
1246
1247		determinant: function () {
1248
1249			var te = this.elements;
1250
1251			var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
1252				d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
1253				g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
1254
1255			return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
1256
1257		},
1258
1259		getInverse: function ( matrix, throwOnDegenerate ) {
1260
1261			if ( throwOnDegenerate !== undefined ) {
1262
1263				console.warn( "THREE.Matrix3: .getInverse() can no longer be configured to throw on degenerate." );
1264
1265			}
1266
1267			var me = matrix.elements,
1268				te = this.elements,
1269
1270				n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
1271				n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
1272				n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],
1273
1274				t11 = n33 * n22 - n32 * n23,
1275				t12 = n32 * n13 - n33 * n12,
1276				t13 = n23 * n12 - n22 * n13,
1277
1278				det = n11 * t11 + n21 * t12 + n31 * t13;
1279
1280			if ( det === 0 ) { return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); }
1281
1282			var detInv = 1 / det;
1283
1284			te[ 0 ] = t11 * detInv;
1285			te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
1286			te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
1287
1288			te[ 3 ] = t12 * detInv;
1289			te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
1290			te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
1291
1292			te[ 6 ] = t13 * detInv;
1293			te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
1294			te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
1295
1296			return this;
1297
1298		},
1299
1300		transpose: function () {
1301
1302			var tmp;
1303			var m = this.elements;
1304
1305			tmp = m[ 1 ]; m[ 1 ] = m[ 3 ];
1305 m[ 3 ] = tmp;
1306			tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
1307			tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
1308
1309			return this;
1310
1311		},
1312
1313		getNormalMatrix: function ( matrix4 ) {
1314
1315			return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();
1316
1317		},
1318
1319		transposeIntoArray: function ( r ) {
1320
1321			var m = this.elements;
1322
1323			r[ 0 ] = m[ 0 ];
1324			r[ 1 ] = m[ 3 ];
1325			r[ 2 ] = m[ 6 ];
1326			r[ 3 ] = m[ 1 ];
1327			r[ 4 ] = m[ 4 ];
1328			r[ 5 ] = m[ 7 ];
1329			r[ 6 ] = m[ 2 ];
1330			r[ 7 ] = m[ 5 ];
1331			r[ 8 ] = m[ 8 ];
1332
1333			return this;
1334
1335		},
1336
1337		setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) {
1338
1339			var c = Math.cos( rotation );
1340			var s = Math.sin( rotation );
1341
1342			this.set(
1343				sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,
1344				- sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,
1345				0, 0, 1
1346			);
1347
1348		},
1349
1350		scale: function ( sx, sy ) {
1351
1352			var te = this.elements;
1353
1354			te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx;
1355			te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy;
1356
1357			return this;
1358
1359		},
1360
1361		rotate: function ( theta ) {
1362
1363			var c = Math.cos( theta );
1364			var s = Math.sin( theta );
1365
1366			var te = this.elements;
1367
1368			var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ];
1369			var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ];
1370
1371			te[ 0 ] = c * a11 + s * a21;
1372			te[ 3 ] = c * a12 + s * a22;
1373			te[ 6 ] = c * a13 + s * a23;
1374
1375			te[ 1 ] = - s * a11 + c * a21;
1376			te[ 4 ] = - s * a12 + c * a22;
1377			te[ 7 ] = - s * a13 + c * a23;
1378
1379			return this;
1380
1381		},
1382
1383		translate: function ( tx, ty ) {
1384
1385			var te = this.elements;
1386
1387			te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ];
1388			te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ];
1389
1390			return this;
1391
1392		},
1393
1394		equals: function ( matrix ) {
1395
1396			var te = this.elements;
1397			var me = matrix.elements;
1398
1399			for ( var i = 0; i < 9; i ++ ) {
1400
1401				if ( te[ i ] !== me[ i ] ) { return false; }
1402
1403			}
1404
1405			return true;
1406
1407		},
1408
1409		fromArray: function ( array, offset ) {
1410
1411			if ( offset === undefined ) { offset = 0; }
1412
1413			for ( var i = 0; i < 9; i ++ ) {
1414
1415				this.elements[ i ] = array[ i + offset ];
1416
1417			}
1418
1419			return this;
1420
1421		},
1422
1423		toArray: function ( array, offset ) {
1424
1425			if ( array === undefined ) { array = []; }
1426			if ( offset === undefined ) { offset = 0; }
1427
1428			var te = this.elements;
1429
1430			array[ offset ] = te[ 0 ];
1431			array[ offset + 1 ] = te[ 1 ];
1432			array[ offset + 2 ] = te[ 2 ];
1433
1434			array[ offset + 3 ] = te[ 3 ];
1435			array[ offset + 4 ] = te[ 4 ];
1436			array[ offset + 5 ] = te[ 5 ];
1437
1438			array[ offset + 6 ] = te[ 6 ];
1439			array[ offset + 7 ] = te[ 7 ];
1440			array[ offset + 8 ] = te[ 8 ];
1441
1442			return array;
1443
1444		}
1445
1446	} );
1447
1448	/**
1449	 * @author mrdoob / http://mrdoob.com/
1450	 * @author alteredq / http://alteredqualia.com/
1451	 * @author szimek / https://github.com/szimek/
1452	 */
1453
1454	var _canvas;
1455
1456	var ImageUtils = {
1457
1458		getDataURL: function ( image ) {
1459
1460			if ( /^data:/i.test( image.src ) ) {
1461
1462				return image.src;
1463
1464			}
1465
1466			if ( typeof HTMLCanvasElement == 'undefined' ) {
1467
1468				return image.src;
1469
1470			}
1471
1472			var canvas;
1473
1474			if ( image instanceof HTMLCanvasElement ) {
1475
1476				canvas = image;
1477
1478			} else {
1479
1480				if ( _canvas === undefined ) { _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); }
1481
1482				_canvas.width = image.width;
1483				_canvas.height = image.height;
1484
1485				var context = _canvas.getContext( '2d' );
1486
1487				if ( image instanceof ImageData ) {
1488
1489					context.putImageData( image, 0, 0 );
1490
1491				} else {
1492
1493					context.drawImage( image, 0, 0, image.width, image.height );
1494
1495				}
1496
1497				canvas = _canvas;
1498
1499			}
1500
1501			if ( canvas.width > 2048 || canvas.height > 2048 ) {
1502
1503				return canvas.toDataURL( 'image/jpeg', 0.6 );
1504
1505			} else {
1506
1507				return canvas.toDataURL( 'image/png' );
1508
1509			}
1510
1511		}
1512
1513	};
1514
1515	/**
1516	 * @author mrdoob / http://mrdoob.com/
1517	 * @author alteredq / http://alteredqualia.com/
1518	 * @author szimek / https://github.com/szimek/
1519	 */
1520
1521	var textureId = 0;
1522
1523	function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
1524
1525		Object.defineProperty( this, 'id', { value: textureId ++ } );
1526
1527		this.uuid = MathUtils.generateUUID();
1528
1529		this.name = '';
1530
1531		this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
1532		this.mipmaps = [];
1533
1534		this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
1535
1536		this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
1537		this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
1538
1539		this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
1540		this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter;
1541
1542		this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
1543
1544		this.format = format !== undefined ? format : RGBAFormat;
1545		this.internalFormat = null;
1546		this.type = type !== undefined ? type : UnsignedByteType;
1547
1548		this.offset = new Vector2( 0, 0 );
1549		this.repeat = new Vector2( 1, 1 );
1550		this.center = new Vector2( 0, 0 );
1551		this.rotation = 0;
1552
1553		this.matrixAutoUpdate = true;
1554		this.matrix = new Matrix3();
1555
1556		this.generateMipmaps = true;
1557		this.premultiplyAlpha = false;
1558		this.flipY = true;
1559		this.unpackAlignment = 4;	// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
1560
1561		// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
1562		//
1563		// Also changing the encoding after already used by a Material will not automatically make the Material
1564		// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
1565		this.encoding = encoding !== undefined ? encoding : LinearEncoding;
1566
1567		this.version = 0;
1568		this.onUpdate = null;
1569
1570	}
1571
1572	Texture.DEFAULT_IMAGE = undefined;
1573	Texture.DEFAULT_MAPPING = UVMapping;
1574
1575	Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
1576
1577		constructor: Texture,
1578
1579		isTexture: true,
1580
1581		updateMatrix: function () {
1582
1583			this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y );
1584
1585		},
1586
1587		clone: function () {
1588
1589			return new this.constructor().copy( this );
1590
1591		},
1592
1593		copy: function ( source ) {
1594
1595			this.name = source.name;
1596
1597			this.image = source.image;
1598			this.mipmaps = source.mipmaps.slice( 0 );
1599
1600			this.mapping = source.mapping;
1601
1602			this.wrapS = source.wrapS;
1603			this.wrapT = source.wrapT;
1604
1605			this.magFilter = source.magFilter;
1606			this.minFilter = source.minFilter;
1607
1608			this.anisotropy = source.anisotropy;
1609
1610			this.format = source.format;
1611			this.internalFormat = source.internalFormat;
1612			this.type = source.type;
1613
1614			this.offset.copy( source.offset );
1615			this.repeat.copy( source.repeat );
1616			this.center.copy( source.center );
1617			this.rotation = source.rotation;
1618
1619			this.matrixAutoUpdate = source.matrixAutoUpdate;
1620			this.matrix.copy( source.matrix );
1621
1622			this.generateMipmaps = source.generateMipmaps;
1623			this.premultiplyAlpha = source.premultiplyAlpha;
1624			this.flipY = source.flipY;
1625			this.unpackAlignment = source.unpackAlignment;
1626			this.encoding = source.encoding;
1627
1628			return this;
1629
1630		},
1631
1632		toJSON: function ( meta ) {
1633
1634			var isRootObject = ( meta === undefined || typeof meta === 'string' );
1635
1636			if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) {
1637
1638				return meta.textures[ this.uuid ];
1639
1640			}
1641
1642			var output = {
1643
1644				metadata: {
1645					version: 4.5,
1646					type: 'Texture',
1647					generator: 'Texture.toJSON'
1648				},
1649
1650				uuid: this.uuid,
1651				name: this.name,
1652
1653				mapping: this.mapping,
1654
1655				repeat: [ this.repeat.x, this.repeat.y ],
1656				offset: [ this.offset.x, this.offset.y ],
1657				center: [ this.center.x, this.center.y ],
1658				rotation: this.rotation,
1659
1660				wrap: [ this.wrapS, this.wrapT ],
1661
1662				format: this.format,
1663				type: this.type,
1664				encoding: this.encoding,
1665
1666				minFilter: this.minFilter,
1667				magFilter: this.magFilter,
1668				anisotropy: this.anisotropy,
1669
1670				flipY: this.flipY,
1671
1672				premultiplyAlpha: this.premultiplyAlpha,
1673				unpackAlignment: this.unpackAlignment
1674
1675			};
1676
1677			if ( this.image !== undefined ) {
1678
1679				// TODO: Move to THREE.Image
1680
1681				var image = this.image;
1682
1683				if ( image.uuid === undefined ) {
1684
1685					image.uuid = MathUtils.generateUUID(); // UGH
1686
1687				}
1688
1689				if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) {
1690
1691					var url;
1692
1693					if ( Array.isArray( image ) ) {
1694
1695						// process array of images e.g. CubeTexture
1696
1697						url = [];
1698
1699						for ( var i = 0, l = image.length; i < l; i ++ ) {
1700
1701							url.push( ImageUtils.getDataURL( image[ i ] ) );
1702
1703						}
1704
1705					} else {
1706
1707						// process single image
1708
1709						url = ImageUtils.getDataURL( image );
1710
1711					}
1712
1713					meta.images[ image.uuid ] = {
1714						uuid: image.uuid,
1715						url: url
1716					};
1717
1718				}
1719
1720				output.image = image.uuid;
1721
1722			}
1723
1724			if ( ! isRootObject ) {
1725
1726				meta.textures[ this.uuid ] = output;
1727
1728			}
1729
1730			return output;
1731
1732		},
1733
1734		dispose: function () {
1735
1736			this.dispatchEvent( { type: 'dispose' } );
1737
1738		},
1739
1740		transformUv: function ( uv ) {
1741
1742			if ( this.mapping !== UVMapping ) { return uv; }
1743
1744			uv.applyMatrix3( this.matrix );
1745
1746			if ( uv.x < 0 || uv.x > 1 ) {
1747
1748				switch ( this.wrapS ) {
1749
1750					case RepeatWrapping:
1751
1752						uv.x = uv.x - Math.floor( uv.x );
1753						break;
1754
1755					case ClampToEdgeWrapping:
1756
1757						uv.x = uv.x < 0 ? 0 : 1;
1758						break;
1759
1760					case MirroredRepeatWrapping:
1761
1762						if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
1763
1764							uv.x = Math.ceil( uv.x ) - uv.x;
1765
1766						} else {
1767
1768							uv.x = uv.x - Math.floor( uv.x );
1769
1770						}
1771
1772						break;
1773
1774				}
1775
1776			}
1777
1778			if ( uv.y < 0 || uv.y > 1 ) {
1779
1780				switch ( this.wrapT ) {
1781
1782					case RepeatWrapping:
1783
1784						uv.y = uv.y - Math.floor( uv.y );
1785						break;
1786
1787					case ClampToEdgeWrapping:
1788
1789						uv.y = uv.y < 0 ? 0 : 1;
1790						break;
1791
1792					case MirroredRepeatWrapping:
1793
1794						if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
1795
1796							uv.y = Math.ceil( uv.y ) - uv.y;
1797
1798						} else {
1799
1800							uv.y = uv.y - Math.floor( uv.y );
1801
1802						}
1803
1804						break;
1805
1806				}
1807
1808			}
1809
1810			if ( this.flipY ) {
1811
1812				uv.y = 1 - uv.y;
1813
1814			}
1815
1816			return uv;
1817
1818		}
1819
1820	} );
1821
1822	Object.defineProperty( Texture.prototype, "needsUpdate", {
1823
1824		set: function ( value ) {
1825
1826			if ( value === true ) { this.version ++; }
1827
1828		}
1829
1830	} );
1831
1832	/**
1833	 * @author supereggbert / http://www.paulbrunt.co.uk/
1834	 * @author philogb / http://blog.thejit.org/
1835	 * @author mikael emtinger / http://gomo.se/
1836	 * @author egraether / http://egraether.com/
1837	 * @author WestLangley / http://github.com/WestLangley
1838	 */
1839
1840	function Vector4( x, y, z, w ) {
1841		if ( x === void 0 ) x = 0;
1842		if ( y === void 0 ) y = 0;
1843		if ( z === void 0 ) z = 0;
1844		if ( w === void 0 ) w = 1;
1845
1846
1847		this.x = x;
1848		this.y = y;
1849		this.z = z;
1850		this.w = w;
1851
1852	}
1853
1854	Object.defineProperties( Vector4.prototype, {
1855
1856		"width": {
1857
1858			get: function () {
1859
1860				return this.z;
1861
1862			},
1863
1864			set: function ( value ) {
1865
1866				this.z = value;
1867
1868			}
1869
1870		},
1871
1872		"height": {
1873
1874			get: function () {
1875
1876				return this.w;
1877
1878			},
1879
1880			set: function ( value ) {
1881
1882				this.w = value;
1883
1884			}
1885
1886		}
1887
1888	} );
1889
1890	Object.assign( Vector4.prototype, {
1891
1892		isVector4: true,
1893
1894		set: function ( x, y, z, w ) {
1895
1896			this.x = x;
1897			this.y = y;
1898			this.z = z;
1899			this.w = w;
1900
1901			return this;
1902
1903		},
1904
1905		setScalar: function ( scalar ) {
1906
1907			this.x = scalar;
1908			this.y = scalar;
1909			this.z = scalar;
1910			this.w = scalar;
1911
1912			return this;
1913
1914		},
1915
1916		setX: function ( x ) {
1917
1918			this.x = x;
1919
1920			return this;
1921
1922		},
1923
1924		setY: function ( y ) {
1925
1926			this.y = y;
1927
1928			return this;
1929
1930		},
1931
1932		setZ: function ( z ) {
1933
1934			this.z = z;
1935
1936			return this;
1937
1938		},
1939
1940		setW: function ( w ) {
1941
1942			this.w = w;
1943
1944			return this;
1945
1946		},
1947
1948		setComponent: function ( index, value ) {
1949
1950			switch ( index ) {
1951
1952				case 0: this.x = value; break;
1953				case 1: this.y = value; break;
1954				case 2: this.z = value; break;
1955				case 3: this.w = value; break;
1956				default: throw new Error( 'index is out of range: ' + index );
1957
1958			}
1959
1960			return this;
1961
1962		},
1963
1964		getComponent: function ( index ) {
1965
1966			switch ( index ) {
1967
1968				case 0: return this.x;
1969				case 1: return this.y;
1970				case 2: return this.z;
1971				case 3: return this.w;
1972				default: throw new Error( 'index is out of range: ' + index );
1973
1974			}
1975
1976		},
1977
1978		clone: function () {
1979
1980			return new this.constructor( this.x, this.y, this.z, this.w );
1981
1982		},
1983
1984		copy: function ( v ) {
1985
1986			this.x = v.x;
1987			this.y = v.y;
1988			this.z = v.z;
1989			this.w = ( v.w !== undefined ) ? v.w : 1;
1990
1991			return this;
1992
1993		},
1994
1995		add: function ( v, w ) {
1996
1997			if ( w !== undefined ) {
1998
1999				console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
2000				return this.addVectors( v, w );
2001
2002			}
2003
2004			this.x += v.x;
2005			this.y += v.y;
2006			this.z += v.z;
2007			this.w += v.w;
2008
2009			return this;
2010
2011		},
2012
2013		addScalar: function ( s ) {
2014
2015			this.x += s;
2016			this.y += s;
2017			this.z += s;
2018			this.w += s;
2019
2020			return this;
2021
2022		},
2023
2024		addVectors: function ( a, b ) {
2025
2026			this.x = a.x + b.x;
2027			this.y = a.y + b.y;
2028			this.z = a.z + b.z;
2029			this.w = a.w + b.w;
2030
2031			return this;
2032
2033		},
2034
2035		addScaledVector: function ( v, s ) {
2036
2037			this.x += v.x * s;
2038			this.y += v.y * s;
2039			this.z += v.z * s;
2040			this.w += v.w * s;
2041
2042			return this;
2043
2044		},
2045
2046		sub: function ( v, w ) {
2047
2048			if ( w !== undefined ) {
2049
2050				console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
2051				return this.subVectors( v, w );
2052
2053			}
2054
2055			this.x -= v.x;
2056			this.y -= v.y;
2057			this.z -= v.z;
2058			this.w -= v.w;
2059
2060			return this;
2061
2062		},
2063
2064		subScalar: function ( s ) {
2065
2066			this.x -= s;
2067			this.y -= s;
2068			this.z -= s;
2069			this.w -= s;
2070
2071			return this;
2072
2073		},
2074
2075		subVectors: function ( a, b ) {
2076
2077			this.x = a.x - b.x;
2078			this.y = a.y - b.y;
2079			this.z = a.z - b.z;
2080			this.w = a.w - b.w;
2081
2082			return this;
2083
2084		},
2085
2086		multiplyScalar: function ( scalar ) {
2087
2088			this.x *= scalar;
2089			this.y *= scalar;
2090			this.z *= scalar;
2091			this.w *= scalar;
2092
2093			return this;
2094
2095		},
2096
2097		applyMatrix4: function ( m ) {
2098
2099			var x = this.x, y = this.y, z = this.z, w = this.w;
2100			var e = m.elements;
2101
2102			this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
2103			this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
2104			this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
2105			this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;
2106
2107			return this;
2108
2109		},
2110
2111		divideScalar: function ( scalar ) {
2112
2113			return this.multiplyScalar( 1 / scalar );
2114
2115		},
2116
2117		setAxisAngleFromQuaternion: function ( q ) {
2118
2119			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
2120
2121			// q is assumed to be normalized
2122
2123			this.w = 2 * Math.acos( q.w );
2124
2125			var s = Math.sqrt( 1 - q.w * q.w );
2126
2127			if ( s < 0.0001 ) {
2128
2129				this.x = 1;
2130				this.y = 0;
2131				this.z = 0;
2132
2133			} else {
2134
2135				this.x = q.x / s;
2136				this.y = q.y / s;
2137				this.z = q.z / s;
2138
2139			}
2140
2141			return this;
2142
2143		},
2144
2145		setAxisAngleFromRotationMatrix: function ( m ) {
2146
2147			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
2148
2149			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
2150
2151			var angle, x, y, z; // variables for result
2152			var epsilon = 0.01,		// margin to allow for rounding errors
2153				epsilon2 = 0.1,		// margin to distinguish between 0 and 180 degrees
2154
2155				te = m.elements,
2156
2157				m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
2158				m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
2159				m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
2160
2161			if ( ( Math.abs( m12 - m21 ) < epsilon ) &&
2162			     ( Math.abs( m13 - m31 ) < epsilon ) &&
2163			     ( Math.abs( m23 - m32 ) < epsilon ) ) {
2164
2165				// singularity found
2166				// first check for identity matrix which must have +1 for all terms
2167				// in leading diagonal and zero in other terms
2168
2169				if ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&
2170				     ( Math.abs( m13 + m31 ) < epsilon2 ) &&
2171				     ( Math.abs( m23 + m32 ) < epsilon2 ) &&
2172				     ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
2173
2174					// this singularity is identity matrix so angle = 0
2175
2176					this.set( 1, 0, 0, 0 );
2177
2178					return this; // zero angle, arbitrary axis
2179
2180				}
2181
2182				// otherwise this singularity is angle = 180
2183
2184				angle = Math.PI;
2185
2186				var xx = ( m11 + 1 ) / 2;
2187				var yy = ( m22 + 1 ) / 2;
2188				var zz = ( m33 + 1 ) / 2;
2189				var xy = ( m12 + m21 ) / 4;
2190				var xz = ( m13 + m31 ) / 4;
2191				var yz = ( m23 + m32 ) / 4;
2192
2193				if ( ( xx > yy ) && ( xx > zz ) ) {
2194
2195					// m11 is the largest diagonal term
2196
2197					if ( xx < epsilon ) {
2198
2199						x = 0;
2200						y = 0.707106781;
2201						z = 0.707106781;
2202
2203					} else {
2204
2205						x = Math.sqrt( xx );
2206						y = xy / x;
2207						z = xz / x;
2208
2209					}
2210
2211				} else if ( yy > zz ) {
2212
2213					// m22 is the largest diagonal term
2214
2215					if ( yy < epsilon ) {
2216
2217						x = 0.707106781;
2218						y = 0;
2219						z = 0.707106781;
2220
2221					} else {
2222
2223						y = Math.sqrt( yy );
2224						x = xy / y;
2225						z = yz / y;
2226
2227					}
2228
2229				} else {
2230
2231					// m33 is the largest diagonal term so base result on this
2232
2233					if ( zz < epsilon ) {
2234
2235						x = 0.707106781;
2236						y = 0.707106781;
2237						z = 0;
2238
2239					} else {
2240
2241						z = Math.sqrt( zz );
2242						x = xz / z;
2243						y = yz / z;
2244
2245					}
2246
2247				}
2248
2249				this.set( x, y, z, angle );
2250
2251				return this; // return 180 deg rotation
2252
2253			}
2254
2255			// as we have reached here there are no singularities so we can handle normally
2256
2257			var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +
2258				( m13 - m31 ) * ( m13 - m31 ) +
2259				( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
2260
2261			if ( Math.abs( s ) < 0.001 ) { s = 1; }
2262
2263			// prevent divide by zero, should not happen if matrix is orthogonal and should be
2264			// caught by singularity test above, but I've left it in just in case
2265
2266			this.x = ( m32 - m23 ) / s;
2267			this.y = ( m13 - m31 ) / s;
2268			this.z = ( m21 - m12 ) / s;
2269			this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
2270
2271			return this;
2272
2273		},
2274
2275		min: function ( v ) {
2276
2277			this.x = Math.min( this.x, v.x );
2278			this.y = Math.min( this.y, v.y );
2279			this.z = Math.min( this.z, v.z );
2280			this.w = Math.min( this.w, v.w );
2281
2282			return this;
2283
2284		},
2285
2286		max: function ( v ) {
2287
2288			this.x = Math.max( this.x, v.x );
2289			this.y = Math.max( this.y, v.y );
2290			this.z = Math.max( this.z, v.z );
2291			this.w = Math.max( this.w, v.w );
2292
2293			return this;
2294
2295		},
2296
2297		clamp: function ( min, max ) {
2298
2299			// assumes min < max, componentwise
2300
2301			this.x = Math.max( min.x, Math.min( max.x, this.x ) );
2302			this.y = Math.max( min.y, Math.min( max.y, this.y ) );
2303			this.z = Math.max( min.z, Math.min( max.z, this.z ) );
2304			this.w = Math.max( min.w, Math.min( max.w, this.w ) );
2305
2306			return this;
2307
2308		},
2309
2310		clampScalar: function ( minVal, maxVal ) {
2311
2312			this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
2313			this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
2314			this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
2315			this.w = Math.max( minVal, Math.min( maxVal, this.w ) );
2316
2317			return this;
2318
2319		},
2320
2321		clampLength: function ( min, max ) {
2322
2323			var length = this.length();
2324
2325			return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
2326
2327		},
2328
2329		floor: function () {
2330
2331			this.x = Math.floor( this.x );
2332			this.y = Math.floor( this.y );
2333			this.z = Math.floor( this.z );
2334			this.w = Math.floor( this.w );
2335
2336			return this;
2337
2338		},
2339
2340		ceil: function () {
2341
2342			this.x = Math.ceil( this.x );
2343			this.y = Math.ceil( this.y );
2344			this.z = Math.ceil( this.z );
2345			this.w = Math.ceil( this.w );
2346
2347			return this;
2348
2349		},
2350
2351		round: function () {
2352
2353			this.x = Math.round( this.x );
2354			this.y = Math.round( this.y );
2355			this.z = Math.round( this.z );
2356			this.w = Math.round( this.w );
2357
2358			return this;
2359
2360		},
2361
2362		roundToZero: function () {
2363
2364			this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
2365			this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
2366			this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
2367			this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );
2368
2369			return this;
2370
2371		},
2372
2373		negate: function () {
2374
2375			this.x = - this.x;
2376			this.y = - this.y;
2377			this.z = - this.z;
2378			this.w = - this.w;
2379
2380			return this;
2381
2382		},
2383
2384		dot: function ( v ) {
2385
2386			return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
2387
2388		},
2389
2390		lengthSq: function () {
2391
2392			return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
2393
2394		},
2395
2396		length: function () {
2397
2398			return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
2399
2400		},
2401
2402		manhattanLength: function () {
2403
2404			return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
2405
2406		},
2407
2408		normalize: function () {
2409
2410			return this.divideScalar( this.length() || 1 );
2411
2412		},
2413
2414		setLength: function ( length ) {
2415
2416			return this.normalize().multiplyScalar( length );
2417
2418		},
2419
2420		lerp: function ( v, alpha ) {
2421
2422			this.x += ( v.x - this.x ) * alpha;
2423			this.y += ( v.y - this.y ) * alpha;
2424			this.z += ( v.z - this.z ) * alpha;
2425			this.w += ( v.w - this.w ) * alpha;
2426
2427			return this;
2428
2429		},
2430
2431		lerpVectors: function ( v1, v2, alpha ) {
2432
2433			this.x = v1.x + ( v2.x - v1.x ) * alpha;
2434			this.y = v1.y + ( v2.y - v1.y ) * alpha;
2435			this.z = v1.z + ( v2.z - v1.z ) * alpha;
2436			this.w = v1.w + ( v2.w - v1.w ) * alpha;
2437
2438			return this;
2439
2440		},
2441
2442		equals: function ( v ) {
2443
2444			return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
2445
2446		},
2447
2448		fromArray: function ( array, offset ) {
2449
2450			if ( offset === undefined ) { offset = 0; }
2451
2452			this.x = array[ offset ];
2453			this.y = array[ offset + 1 ];
2454			this.z = array[ offset + 2 ];
2455			this.w = array[ offset + 3 ];
2456
2457			return this;
2458
2459		},
2460
2461		toArray: function ( array, offset ) {
2462
2463			if ( array === undefined ) { array = []; }
2464			if ( offset === undefined ) { offset = 0; }
2465
2466			array[ offset ] = this.x;
2467			array[ offset + 1 ] = this.y;
2468			array[ offset + 2 ] = this.z;
2469			array[ offset + 3 ] = this.w;
2470
2471			return array;
2472
2473		},
2474
2475		fromBufferAttribute: function ( attribute, index, offset ) {
2476
2477			if ( offset !== undefined ) {
2478
2479				console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );
2480
2481			}
2482
2483			this.x = attribute.getX( index );
2484			this.y = attribute.getY( index );
2485			this.z = attribute.getZ( index );
2486			this.w = attribute.getW( index );
2487
2488			return this;
2489
2490		},
2491
2492		random: function () {
2493
2494			this.x = Math.random();
2495			this.y = Math.random();
2496			this.z = Math.random();
2497			this.w = Math.random();
2498
2499			return this;
2500
2501		}
2502
2503	} );
2504
2505	/**
2506	 * @author szimek / https://github.com/szimek/
2507	 * @author alteredq / http://alteredqualia.com/
2508	 * @author Marius Kintel / https://github.com/kintel
2509	 */
2510
2511	/*
2512	 In options, we can specify:
2513	 * Texture parameters for an auto-generated target texture
2514	 * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
2515	*/
2516	function WebGLRenderTarget( width, height, options ) {
2517
2518		this.width = width;
2519		this.height = height;
2520
2521		this.scissor = new Vector4( 0, 0, width, height );
2522		this.scissorTest = false;
2523
2524		this.viewport = new Vector4( 0, 0, width, height );
2525
2526		options = options || {};
2527
2528		this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
2529
2530		this.texture.image = {};
2531		this.texture.image.width = width;
2532		this.texture.image.height = height;
2533
2534		this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
2535		this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
2536
2537		this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
2538		this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
2539		this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
2540
2541	}
2542
2543	WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
2544
2545		constructor: WebGLRenderTarget,
2546
2547		isWebGLRenderTarget: true,
2548
2549		setSize: function ( width, height ) {
2550
2551			if ( this.width !== width || this.height !== height ) {
2552
2553				this.width = width;
2554				this.height = height;
2555
2556				this.texture.image.width = width;
2557				this.texture.image.height = height;
2558
2559				this.dispose();
2560
2561			}
2562
2563			this.viewport.set( 0, 0, width, height );
2564			this.scissor.set( 0, 0, width, height );
2565
2566		},
2567
2568		clone: function () {
2569
2570			return new this.constructor().copy( this );
2571
2572		},
2573
2574		copy: function ( source ) {
2575
2576			this.width = source.width;
2577			this.height = source.height;
2578
2579			this.viewport.copy( source.viewport );
2580
2581			this.texture = source.texture.clone();
2582
2583			this.depthBuffer = source.depthBuffer;
2584			this.stencilBuffer = source.stencilBuffer;
2585			this.depthTexture = source.depthTexture;
2586
2587			return this;
2588
2589		},
2590
2591		dispose: function () {
2592
2593			this.dispatchEvent( { type: 'dispose' } );
2594
2595		}
2596
2597	} );
2598
2599	/**
2600	 * @author Mugen87 / https://github.com/Mugen87
2601	 * @author Matt DesLauriers / @mattdesl
2602	 */
2603
2604	function WebGLMultisampleRenderTarget( width, height, options ) {
2605
2606		WebGLRenderTarget.call( this, width, height, options );
2607
2608		this.samples = 4;
2609
2610	}
2611
2612	WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), {
2613
2614		constructor: WebGLMultisampleRenderTarget,
2615
2616		isWebGLMultisampleRenderTarget: true,
2617
2618		copy: function ( source ) {
2619
2620			WebGLRenderTarget.prototype.copy.call( this, source );
2621
2622			this.samples = source.samples;
2623
2624			return this;
2625
2626		}
2627
2628	} );
2629
2630	/**
2631	 * @author mikael emtinger / http://gomo.se/
2632	 * @author alteredq / http://alteredqualia.com/
2633	 * @author WestLangley / http://github.com/WestLangley
2634	 * @author bhouston / http://clara.io
2635	 */
2636
2637	function Quaternion( x, y, z, w ) {
2638		if ( x === void 0 ) x = 0;
2639		if ( y === void 0 ) y = 0;
2640		if ( z === void 0 ) z = 0;
2641		if ( w === void 0 ) w = 1;
2642
2643
2644		this._x = x;
2645		this._y = y;
2646		this._z = z;
2647		this._w = w;
2648
2649	}
2650
2651	Object.assign( Quaternion, {
2652
2653		slerp: function ( qa, qb, qm, t ) {
2654
2655			return qm.copy( qa ).slerp( qb, t );
2656
2657		},
2658
2659		slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
2660
2661			// fuzz-free, array-based Quaternion SLERP operation
2662
2663			var x0 = src0[ srcOffset0 + 0 ],
2664				y0 = src0[ srcOffset0 + 1 ],
2665				z0 = src0[ srcOffset0 + 2 ],
2666				w0 = src0[ srcOffset0 + 3 ];
2667
2668			var x1 = src1[ srcOffset1 + 0 ],
2669				y1 = src1[ srcOffset1 + 1 ],
2670				z1 = src1[ srcOffset1 + 2 ],
2671				w1 = src1[ srcOffset1 + 3 ];
2672
2673			if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
2674
2675				var s = 1 - t,
2676
2677					cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
2678
2679					dir = ( cos >= 0 ? 1 : - 1 ),
2680					sqrSin = 1 - cos * cos;
2681
2682				// Skip the Slerp for tiny steps to avoid numeric problems:
2683				if ( sqrSin > Number.EPSILON ) {
2684
2685					var sin = Math.sqrt( sqrSin ),
2686						len = Math.atan2( sin, cos * dir );
2687
2688					s = Math.sin( s * len ) / sin;
2689					t = Math.sin( t * len ) / sin;
2690
2691				}
2692
2693				var tDir = t * dir;
2694
2695				x0 = x0 * s + x1 * tDir;
2696				y0 = y0 * s + y1 * tDir;
2697				z0 = z0 * s + z1 * tDir;
2698				w0 = w0 * s + w1 * tDir;
2699
2700				// Normalize in case we just did a lerp:
2701				if ( s === 1 - t ) {
2702
2703					var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
2704
2705					x0 *= f;
2706					y0 *= f;
2707					z0 *= f;
2708					w0 *= f;
2709
2710				}
2711
2712			}
2713
2714			dst[ dstOffset ] = x0;
2715			dst[ dstOffset + 1 ] = y0;
2716			dst[ dstOffset + 2 ] = z0;
2717			dst[ dstOffset + 3 ] = w0;
2718
2719		},
2720
2721		multiplyQuaternionsFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) {
2722
2723			var x0 = src0[ srcOffset0 ];
2724			var y0 = src0[ srcOffset0 + 1 ];
2725			var z0 = src0[ srcOffset0 + 2 ];
2726			var w0 = src0[ srcOffset0 + 3 ];
2727
2728			var x1 = src1[ srcOffset1 ];
2729			var y1 = src1[ srcOffset1 + 1 ];
2730			var z1 = src1[ srcOffset1 + 2 ];
2731			var w1 = src1[ srcOffset1 + 3 ];
2732
2733			dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
2734			dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
2735			dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
2736			dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
2737
2738			return dst;
2739
2740		}
2741
2742	} );
2743
2744	Object.defineProperties( Quaternion.prototype, {
2745
2746		x: {
2747
2748			get: function () {
2749
2750				return this._x;
2751
2752			},
2753
2754			set: function ( value ) {
2755
2756				this._x = value;
2757				this._onChangeCallback();
2758
2759			}
2760
2761		},
2762
2763		y: {
2764
2765			get: function () {
2766
2767				return this._y;
2768
2769			},
2770
2771			set: function ( value ) {
2772
2773				this._y = value;
2774				this._onChangeCallback();
2775
2776			}
2777
2778		},
2779
2780		z: {
2781
2782			get: function () {
2783
2784				return this._z;
2785
2786			},
2787
2788			set: function ( value ) {
2789
2790				this._z = value;
2791				this._onChangeCallback();
2792
2793			}
2794
2795		},
2796
2797		w: {
2798
2799			get: function () {
2800
2801				return this._w;
2802
2803			},
2804
2805			set: function ( value ) {
2806
2807				this._w = value;
2808				this._onChangeCallback();
2809
2810			}
2811
2812		}
2813
2814	} );
2815
2816	Object.assign( Quaternion.prototype, {
2817
2818		isQuaternion: true,
2819
2820		set: function ( x, y, z, w ) {
2821
2822			this._x = x;
2823			this._y = y;
2824			this._z = z;
2825			this._w = w;
2826
2827			this._onChangeCallback();
2828
2829			return this;
2830
2831		},
2832
2833		clone: function () {
2834
2835			return new this.constructor( this._x, this._y, this._z, this._w );
2836
2837		},
2838
2839		copy: function ( quaternion ) {
2840
2841			this._x = quaternion.x;
2842			this._y = quaternion.y;
2843			this._z = quaternion.z;
2844			this._w = quaternion.w;
2845
2846			this._onChangeCallback();
2847
2848			return this;
2849
2850		},
2851
2852		setFromEuler: function ( euler, update ) {
2853
2854			if ( ! ( euler && euler.isEuler ) ) {
2855
2856				throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );
2857
2858			}
2859
2860			var x = euler._x, y = euler._y, z = euler._z, order = euler.order;
2861
2862			// http://www.mathworks.com/matlabcentral/fileexchange/
2863			// 	20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
2864			//	content/SpinCalc.m
2865
2866			var cos = Math.cos;
2867			var sin = Math.sin;
2868
2869			var c1 = cos( x / 2 );
2870			var c2 = cos( y / 2 );
2871			var c3 = cos( z / 2 );
2872
2873			var s1 = sin( x / 2 );
2874			var s2 = sin( y / 2 );
2875			var s3 = sin( z / 2 );
2876
2877			switch ( order ) {
2878
2879				case 'XYZ':
2880					this._x = s1 * c2 * c3 + c1 * s2 * s3;
2881					this._y = c1 * s2 * c3 - s1 * c2 * s3;
2882					this._z = c1 * c2 * s3 + s1 * s2 * c3;
2883					this._w = c1 * c2 * c3 - s1 * s2 * s3;
2884					break;
2885
2886				case 'YXZ':
2887					this._x = s1 * c2 * c3 + c1 * s2 * s3;
2888					this._y = c1 * s2 * c3 - s1 * c2 * s3;
2889					this._z = c1 * c2 * s3 - s1 * s2 * c3;
2890					this._w = c1 * c2 * c3 + s1 * s2 * s3;
2891					break;
2892
2893				case 'ZXY':
2894					this._x = s1 * c2 * c3 - c1 * s2 * s3;
2895					this._y = c1 * s2 * c3 + s1 * c2 * s3;
2896					this._z = c1 * c2 * s3 + s1 * s2 * c3;
2897					this._w = c1 * c2 * c3 - s1 * s2 * s3;
2898					break;
2899
2900				case 'ZYX':
2901					this._x = s1 * c2 * c3 - c1 * s2 * s3;
2902					this._y = c1 * s2 * c3 + s1 * c2 * s3;
2903					this._z = c1 * c2 * s3 - s1 * s2 * c3;
2904					this._w = c1 * c2 * c3 + s1 * s2 * s3;
2905					break;
2906
2907				case 'YZX':
2908					this._x = s1 * c2 * c3 + c1 * s2 * s3;
2909					this._y = c1 * s2 * c3 + s1 * c2 * s3;
2910					this._z = c1 * c2 * s3 - s1 * s2 * c3;
2911					this._w = c1 * c2 * c3 - s1 * s2 * s3;
2912					break;
2913
2914				case 'XZY':
2915					this._x = s1 * c2 * c3 - c1 * s2 * s3;
2916					this._y = c1 * s2 * c3 - s1 * c2 * s3;
2917					this._z = c1 * c2 * s3 + s1 * s2 * c3;
2918					this._w = c1 * c2 * c3 + s1 * s2 * s3;
2919					break;
2920
2921				default:
2922					console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order );
2923
2924			}
2925
2926			if ( update !== false ) { this._onChangeCallback(); }
2927
2928			return this;
2929
2930		},
2931
2932		setFromAxisAngle: function ( axis, angle ) {
2933
2934			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
2935
2936			// assumes axis is normalized
2937
2938			var halfAngle = angle / 2, s = Math.sin( halfAngle );
2939
2940			this._x = axis.x * s;
2941			this._y = axis.y * s;
2942			this._z = axis.z * s;
2943			this._w = Math.cos( halfAngle );
2944
2945			this._onChangeCallback();
2946
2947			return this;
2948
2949		},
2950
2951		setFromRotationMatrix: function ( m ) {
2952
2953			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
2954
2955			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
2956
2957			var te = m.elements,
2958
2959				m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
2960				m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
2961				m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
2962
2963				trace = m11 + m22 + m33;
2964
2965			if ( trace > 0 ) {
2966
2967				var s = 0.5 / Math.sqrt( trace + 1.0 );
2968
2969				this._w = 0.25 / s;
2970				this._x = ( m32 - m23 ) * s;
2971				this._y = ( m13 - m31 ) * s;
2972				this._z = ( m21 - m12 ) * s;
2973
2974			} else if ( m11 > m22 && m11 > m33 ) {
2975
2976				var s$1 = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
2977
2978				this._w = ( m32 - m23 ) / s$1;
2979				this._x = 0.25 * s$1;
2980				this._y = ( m12 + m21 ) / s$1;
2981				this._z = ( m13 + m31 ) / s$1;
2982
2983			} else if ( m22 > m33 ) {
2984
2985				var s$2 = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
2986
2987				this._w = ( m13 - m31 ) / s$2;
2988				this._x = ( m12 + m21 ) / s$2;
2989				this._y = 0.25 * s$2;
2990				this._z = ( m23 + m32 ) / s$2;
2991
2992			} else {
2993
2994				var s$3 = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
2995
2996				this._w = ( m21 - m12 ) / s$3;
2997				this._x = ( m13 + m31 ) / s$3;
2998				this._y = ( m23 + m32 ) / s$3;
2999				this._z = 0.25 * s$3;
3000
3001			}
3002
3003			this._onChangeCallback();
3004
3005			return this;
3006
3007		},
3008
3009		setFromUnitVectors: function ( vFrom, vTo ) {
3010
3011			// assumes direction vectors vFrom and vTo are normalized
3012
3013			var EPS = 0.000001;
3014
3015			var r = vFrom.dot( vTo ) + 1;
3016
3017			if ( r < EPS ) {
3018
3019				r = 0;
3020
3021				if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
3022
3023					this._x = - vFrom.y;
3024					this._y = vFrom.x;
3025					this._z = 0;
3026					this._w = r;
3027
3028				} else {
3029
3030					this._x = 0;
3031					this._y = - vFrom.z;
3032					this._z = vFrom.y;
3033					this._w = r;
3034
3035				}
3036
3037			} else {
3038
3039				// crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3
3040
3041				this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
3042				this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
3043				this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
3044				this._w = r;
3045
3046			}
3047
3048			return this.normalize();
3049
3050		},
3051
3052		angleTo: function ( q ) {
3053
3054			return 2 * Math.acos( Math.abs( MathUtils.clamp( this.dot( q ), - 1, 1 ) ) );
3055
3056		},
3057
3058		rotateTowards: function ( q, step ) {
3059
3060			var angle = this.angleTo( q );
3061
3062			if ( angle === 0 ) { return this; }
3063
3064			var t = Math.min( 1, step / angle );
3065
3066			this.slerp( q, t );
3067
3068			return this;
3069
3070		},
3071
3072		inverse: function () {
3073
3074			// quaternion is assumed to have unit length
3075
3076			return this.conjugate();
3077
3078		},
3079
3080		conjugate: function () {
3081
3082			this._x *= - 1;
3083			this._y *= - 1;
3084			this._z *= - 1;
3085
3086			this._onChangeCallback();
3087
3088			return this;
3089
3090		},
3091
3092		dot: function ( v ) {
3093
3094			return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
3095
3096		},
3097
3098		lengthSq: function () {
3099
3100			return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
3101
3102		},
3103
3104		length: function () {
3105
3106			return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
3107
3108		},
3109
3110		normalize: function () {
3111
3112			var l = this.length();
3113
3114			if ( l === 0 ) {
3115
3116				this._x = 0;
3117				this._y = 0;
3118				this._z = 0;
3119				this._w = 1;
3120
3121			} else {
3122
3123				l = 1 / l;
3124
3125				this._x = this._x * l;
3126				this._y = this._y * l;
3127				this._z = this._z * l;
3128				this._w = this._w * l;
3129
3130			}
3131
3132			this._onChangeCallback();
3133
3134			return this;
3135
3136		},
3137
3138		multiply: function ( q, p ) {
3139
3140			if ( p !== undefined ) {
3141
3142				console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
3143				return this.multiplyQuaternions( q, p );
3144
3145			}
3146
3147			return this.multiplyQuaternions( this, q );
3148
3149		},
3150
3151		premultiply: function ( q ) {
3152
3153			return this.multiplyQuaternions( q, this );
3154
3155		},
3156
3157		multiplyQuaternions: function ( a, b ) {
3158
3159			// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
3160
3161			var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
3162			var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
3163
3164			this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
3165			this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
3166			this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
3167			this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
3168
3169			this._onChangeCallback();
3170
3171			return this;
3172
3173		},
3174
3175		slerp: function ( qb, t ) {
3176
3177			if ( t === 0 ) { return this; }
3178			if ( t === 1 ) { return this.copy( qb ); }
3179
3180			var x = this._x, y = this._y, z = this._z, w = this._w;
3181
3182			// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
3183
3184			var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
3185
3186			if ( cosHalfTheta < 0 ) {
3187
3188				this._w = - qb._w;
3189				this._x = - qb._x;
3190				this._y = - qb._y;
3191				this._z = - qb._z;
3192
3193				cosHalfTheta = - cosHalfTheta;
3194
3195			} else {
3196
3197				this.copy( qb );
3198
3199			}
3200
3201			if ( cosHalfTheta >= 1.0 ) {
3202
3203				this._w = w;
3204				this._x = x;
3205				this._y = y;
3206				this._z = z;
3207
3208				return this;
3209
3210			}
3211
3212			var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
3213
3214			if ( sqrSinHalfTheta <= Number.EPSILON ) {
3215
3216				var s = 1 - t;
3217				this._w = s * w + t * this._w;
3218				this._x = s * x + t * this._x;
3219				this._y = s * y + t * this._y;
3220				this._z = s * z + t * this._z;
3221
3222				this.normalize();
3223				this._onChangeCallback();
3224
3225				return this;
3226
3227			}
3228
3229			var sinHalfTheta = Math.sqrt( sqrSinHalfTheta );
3230			var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
3231			var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
3232				ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
3233
3234			this._w = ( w * ratioA + this._w * ratioB );
3235			this._x = ( x * ratioA + this._x * ratioB );
3236			this._y = ( y * ratioA + this._y * ratioB );
3237			this._z = ( z * ratioA + this._z * ratioB );
3238
3239			this._onChangeCallback();
3240
3241			return this;
3242
3243		},
3244
3245		equals: function ( quaternion ) {
3246
3247			return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
3248
3249		},
3250
3251		fromArray: function ( array, offset ) {
3252
3253			if ( offset === undefined ) { offset = 0; }
3254
3255			this._x = array[ offset ];
3256			this._y = array[ offset + 1 ];
3257			this._z = array[ offset + 2 ];
3258			this._w = array[ offset + 3 ];
3259
3260			this._onChangeCallback();
3261
3262			return this;
3263
3264		},
3265
3266		toArray: function ( array, offset ) {
3267
3268			if ( array === undefined ) { array = []; }
3269			if ( offset === undefined ) { offset = 0; }
3270
3271			array[ offset ] = this._x;
3272			array[ offset + 1 ] = this._y;
3273			array[ offset + 2 ] = this._z;
3274			array[ offset + 3 ] = this._w;
3275
3276			return array;
3277
3278		},
3279
3280		fromBufferAttribute: function ( attribute, index ) {
3281
3282			this._x = attribute.getX( index );
3283			this._y = attribute.getY( index );
3284			this._z = attribute.getZ( index );
3285			this._w = attribute.getW( index );
3286
3287			return this;
3288
3289		},
3290
3291		_onChange: function ( callback ) {
3292
3293			this._onChangeCallback = callback;
3294
3295			return this;
3296
3297		},
3298
3299		_onChangeCallback: function () {}
3300
3301	} );
3302
3303	/**
3304	 * @author mrdoob / http://mrdoob.com/
3305	 * @author kile / http://kile.stravaganza.org/
3306	 * @author philogb / http://blog.thejit.org/
3307	 * @author mikael emtinger / http://gomo.se/
3308	 * @author egraether / http://egraether.com/
3309	 * @author WestLangley / http://github.com/WestLangley
3310	 */
3311
3312	var _vector = new Vector3();
3313	var _quaternion = new Quaternion();
3314
3315	function Vector3( x, y, z ) {
3316		if ( x === void 0 ) x = 0;
3317		if ( y === void 0 ) y = 0;
3318		if ( z === void 0 ) z = 0;
3319
3320
3321		this.x = x;
3322		this.y = y;
3323		this.z = z;
3324
3325	}
3326
3327	Object.assign( Vector3.prototype, {
3328
3329		isVector3: true,
3330
3331		set: function ( x, y, z ) {
3332
3333			this.x = x;
3334			this.y = y;
3335			this.z = z;
3336
3337			return this;
3338
3339		},
3340
3341		setScalar: function ( scalar ) {
3342
3343			this.x = scalar;
3344			this.y = scalar;
3345			this.z = scalar;
3346
3347			return this;
3348
3349		},
3350
3351		setX: function ( x ) {
3352
3353			this.x = x;
3354
3355			return this;
3356
3357		},
3358
3359		setY: function ( y ) {
3360
3361			this.y = y;
3362
3363			return this;
3364
3365		},
3366
3367		setZ: function ( z ) {
3368
3369			this.z = z;
3370
3371			return this;
3372
3373		},
3374
3375		setComponent: function ( index, value ) {
3376
3377			switch ( index ) {
3378
3379				case 0: this.x = value; break;
3380				case 1: this.y = value; break;
3381				case 2: this.z = value; break;
3382				default: throw new Error( 'index is out of range: ' + index );
3383
3384			}
3385
3386			return this;
3387
3388		},
3389
3390		getComponent: function ( index ) {
3391
3392			switch ( index ) {
3393
3394				case 0: return this.x;
3395				case 1: return this.y;
3396				case 2: return this.z;
3397				default: throw new Error( 'index is out of range: ' + index );
3398
3399			}
3400
3401		},
3402
3403		clone: function () {
3404
3405			return new this.constructor( this.x, this.y, this.z );
3406
3407		},
3408
3409		copy: function ( v ) {
3410
3411			this.x = v.x;
3412			this.y = v.y;
3413			this.z = v.z;
3414
3415			return this;
3416
3417		},
3418
3419		add: function ( v, w ) {
3420
3421			if ( w !== undefined ) {
3422
3423				console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
3424				return this.addVectors( v, w );
3425
3426			}
3427
3428			this.x += v.x;
3429			this.y += v.y;
3430			this.z += v.z;
3431
3432			return this;
3433
3434		},
3435
3436		addScalar: function ( s ) {
3437
3438			this.x += s;
3439			this.y += s;
3440			this.z += s;
3441
3442			return this;
3443
3444		},
3445
3446		addVectors: function ( a, b ) {
3447
3448			this.x = a.x + b.x;
3449			this.y = a.y + b.y;
3450			this.z = a.z + b.z;
3451
3452			return this;
3453
3454		},
3455
3456		addScaledVector: function ( v, s ) {
3457
3458			this.x += v.x * s;
3459			this.y += v.y * s;
3460			this.z += v.z * s;
3461
3462			return this;
3463
3464		},
3465
3466		sub: function ( v, w ) {
3467
3468			if ( w !== undefined ) {
3469
3470				console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
3471				return this.subVectors( v, w );
3472
3473			}
3474
3475			this.x -= v.x;
3476			this.y -= v.y;
3477			this.z -= v.z;
3478
3479			return this;
3480
3481		},
3482
3483		subScalar: function ( s ) {
3484
3485			this.x -= s;
3486			this.y -= s;
3487			this.z -= s;
3488
3489			return this;
3490
3491		},
3492
3493		subVectors: function ( a, b ) {
3494
3495			this.x = a.x - b.x;
3496			this.y = a.y - b.y;
3497			this.z = a.z - b.z;
3498
3499			return this;
3500
3501		},
3502
3503		multiply: function ( v, w ) {
3504
3505			if ( w !== undefined ) {
3506
3507				console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
3508				return this.multiplyVectors( v, w );
3509
3510			}
3511
3512			this.x *= v.x;
3513			this.y *= v.y;
3514			this.z *= v.z;
3515
3516			return this;
3517
3518		},
3519
3520		multiplyScalar: function ( scalar ) {
3521
3522			this.x *= scalar;
3523			this.y *= scalar;
3524			this.z *= scalar;
3525
3526			return this;
3527
3528		},
3529
3530		multiplyVectors: function ( a, b ) {
3531
3532			this.x = a.x * b.x;
3533			this.y = a.y * b.y;
3534			this.z = a.z * b.z;
3535
3536			return this;
3537
3538		},
3539
3540		applyEuler: function ( euler ) {
3541
3542			if ( ! ( euler && euler.isEuler ) ) {
3543
3544				console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
3545
3546			}
3547
3548			return this.applyQuaternion( _quaternion.setFromEuler( euler ) );
3549
3550		},
3551
3552		applyAxisAngle: function ( axis, angle ) {
3553
3554			return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) );
3555
3556		},
3557
3558		applyMatrix3: function ( m ) {
3559
3560			var x = this.x, y = this.y, z = this.z;
3561			var e = m.elements;
3562
3563			this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
3564			this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
3565			this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
3566
3567			return this;
3568
3569		},
3570
3571		applyNormalMatrix: function ( m ) {
3572
3573			return this.applyMatrix3( m ).normalize();
3574
3575		},
3576
3577		applyMatrix4: function ( m ) {
3578
3579			var x = this.x, y = this.y, z = this.z;
3580			var e = m.elements;
3581
3582			var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
3583
3584			this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
3585			this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
3586			this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
3587
3588			return this;
3589
3590		},
3591
3592		applyQuaternion: function ( q ) {
3593
3594			var x = this.x, y = this.y, z = this.z;
3595			var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
3596
3597			// calculate quat * vector
3598
3599			var ix = qw * x + qy * z - qz * y;
3600			var iy = qw * y + qz * x - qx * z;
3601			var iz = qw * z + qx * y - qy * x;
3602			var iw = - qx * x - qy * y - qz * z;
3603
3604			// calculate result * inverse quat
3605
3606			this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
3607			this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
3608			this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
3609
3610			return this;
3611
3612		},
3613
3614		project: function ( camera ) {
3615
3616			return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );
3617
3618		},
3619
3620		unproject: function ( camera ) {
3621
3622			return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );
3623
3624		},
3625
3626		transformDirection: function ( m ) {
3627
3628			// input: THREE.Matrix4 affine matrix
3629			// vector interpreted as a direction
3630
3631			var x = this.x, y = this.y, z = this.z;
3632			var e = m.elements;
3633
3634			this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
3635			this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
3636			this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
3637
3638			return this.normalize();
3639
3640		},
3641
3642		divide: function ( v ) {
3643
3644			this.x /= v.x;
3645			this.y /= v.y;
3646			this.z /= v.z;
3647
3648			return this;
3649
3650		},
3651
3652		divideScalar: function ( scalar ) {
3653
3654			return this.multiplyScalar( 1 / scalar );
3655
3656		},
3657
3658		min: function ( v ) {
3659
3660			this.x = Math.min( this.x, v.x );
3661			this.y = Math.min( this.y, v.y );
3662			this.z = Math.min( this.z, v.z );
3663
3664			return this;
3665
3666		},
3667
3668		max: function ( v ) {
3669
3670			this.x = Math.max( this.x, v.x );
3671			this.y = Math.max( this.y, v.y );
3672			this.z = Math.max( this.z, v.z );
3673
3674			return this;
3675
3676		},
3677
3678		clamp: function ( min, max ) {
3679
3680			// assumes min < max, componentwise
3681
3682			this.x = Math.max( min.x, Math.min( max.x, this.x ) );
3683			this.y = Math.max( min.y, Math.min( max.y, this.y ) );
3684			this.z = Math.max( min.z, Math.min( max.z, this.z ) );
3685
3686			return this;
3687
3688		},
3689
3690		clampScalar: function ( minVal, maxVal ) {
3691
3692			this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
3693			this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
3694			this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
3695
3696			return this;
3697
3698		},
3699
3700		clampLength: function ( min, max ) {
3701
3702			var length = this.length();
3703
3704			return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
3705
3706		},
3707
3708		floor: function () {
3709
3710			this.x = Math.floor( this.x );
3711			this.y = Math.floor( this.y );
3712			this.z = Math.floor( this.z );
3713
3714			return this;
3715
3716		},
3717
3718		ceil: function () {
3719
3720			this.x = Math.ceil( this.x );
3721			this.y = Math.ceil( this.y );
3722			this.z = Math.ceil( this.z );
3723
3724			return this;
3725
3726		},
3727
3728		round: function () {
3729
3730			this.x = Math.round( this.x );
3731			this.y = Math.round( this.y );
3732			this.z = Math.round( this.z );
3733
3734			return this;
3735
3736		},
3737
3738		roundToZero: function () {
3739
3740			this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
3741			this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
3742			this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
3743
3744			return this;
3745
3746		},
3747
3748		negate: function () {
3749
3750			this.x = - this.x;
3751			this.y = - this.y;
3752			this.z = - this.z;
3753
3754			return this;
3755
3756		},
3757
3758		dot: function ( v ) {
3759
3760			return this.x * v.x + this.y * v.y + this.z * v.z;
3761
3762		},
3763
3764		// TODO lengthSquared?
3765
3766		lengthSq: function () {
3767
3768			return this.x * this.x + this.y * this.y + this.z * this.z;
3769
3770		},
3771
3772		length: function () {
3773
3774			return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
3775
3776		},
3777
3778		manhattanLength: function () {
3779
3780			return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
3781
3782		},
3783
3784		normalize: function () {
3785
3786			return this.divideScalar( this.length() || 1 );
3787
3788		},
3789
3790		setLength: function ( length ) {
3791
3792			return this.normalize().multiplyScalar( length );
3793
3794		},
3795
3796		lerp: function ( v, alpha ) {
3797
3798			this.x += ( v.x - this.x ) * alpha;
3799			this.y += ( v.y - this.y ) * alpha;
3800			this.z += ( v.z - this.z ) * alpha;
3801
3802			return this;
3803
3804		},
3805
3806		lerpVectors: function ( v1, v2, alpha ) {
3807
3808			this.x = v1.x + ( v2.x - v1.x ) * alpha;
3809			this.y = v1.y + ( v2.y - v1.y ) * alpha;
3810			this.z = v1.z + ( v2.z - v1.z ) * alpha;
3811
3812			return this;
3813
3814		},
3815
3816		cross: function ( v, w ) {
3817
3818			if ( w !== undefined ) {
3819
3820				console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
3821				return this.crossVectors( v, w );
3822
3823			}
3824
3825			return this.crossVectors( this, v );
3826
3827		},
3828
3829		crossVectors: function ( a, b ) {
3830
3831			var ax = a.x, ay = a.y, az = a.z;
3832			var bx = b.x, by = b.y, bz = b.z;
3833
3834			this.x = ay * bz - az * by;
3835			this.y = az * bx - ax * bz;
3836			this.z = ax * by - ay * bx;
3837
3838			return this;
3839
3840		},
3841
3842		projectOnVector: function ( v ) {
3843
3844			var denominator = v.lengthSq();
3845
3846			if ( denominator === 0 ) { return this.set( 0, 0, 0 ); }
3847
3848			var scalar = v.dot( this ) / denominator;
3849
3850			return this.copy( v ).multiplyScalar( scalar );
3851
3852		},
3853
3854		projectOnPlane: function ( planeNormal ) {
3855
3856			_vector.copy( this ).projectOnVector( planeNormal );
3857
3858			return this.sub( _vector );
3859
3860		},
3861
3862		reflect: function ( normal ) {
3863
3864			// reflect incident vector off plane orthogonal to normal
3865			// normal is assumed to have unit length
3866
3867			return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
3868
3869		},
3870
3871		angleTo: function ( v ) {
3872
3873			var denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );
3874
3875			if ( denominator === 0 ) { return Math.PI / 2; }
3876
3877			var theta = this.dot( v ) / denominator;
3878
3879			// clamp, to handle numerical problems
3880
3881			return Math.acos( MathUtils.clamp( theta, - 1, 1 ) );
3882
3883		},
3884
3885		distanceTo: function ( v ) {
3886
3887			return Math.sqrt( this.distanceToSquared( v ) );
3888
3889		},
3890
3891		distanceToSquared: function ( v ) {
3892
3893			var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
3894
3895			return dx * dx + dy * dy + dz * dz;
3896
3897		},
3898
3899		manhattanDistanceTo: function ( v ) {
3900
3901			return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
3902
3903		},
3904
3905		setFromSpherical: function ( s ) {
3906
3907			return this.setFromSphericalCoords( s.radius, s.phi, s.theta );
3908
3909		},
3910
3911		setFromSphericalCoords: function ( radius, phi, theta ) {
3912
3913			var sinPhiRadius = Math.sin( phi ) * radius;
3914
3915			this.x = sinPhiRadius * Math.sin( theta );
3916			this.y = Math.cos( phi ) * radius;
3917			this.z = sinPhiRadius * Math.cos( theta );
3918
3919			return this;
3920
3921		},
3922
3923		setFromCylindrical: function ( c ) {
3924
3925			return this.setFromCylindricalCoords( c.radius, c.theta, c.y );
3926
3927		},
3928
3929		setFromCylindricalCoords: function ( radius, theta, y ) {
3930
3931			this.x = radius * Math.sin( theta );
3932			this.y = y;
3933			this.z = radius * Math.cos( theta );
3934
3935			return this;
3936
3937		},
3938
3939		setFromMatrixPosition: function ( m ) {
3940
3941			var e = m.elements;
3942
3943			this.x = e[ 12 ];
3944			this.y = e[ 13 ];
3945			this.z = e[ 14 ];
3946
3947			return this;
3948
3949		},
3950
3951		setFromMatrixScale: function ( m ) {
3952
3953			var sx = this.setFromMatrixColumn( m, 0 ).length();
3954			var sy = this.setFromMatrixColumn( m, 1 ).length();
3955			var sz = this.setFromMatrixColumn( m, 2 ).length();
3956
3957			this.x = sx;
3958			this.y = sy;
3959			this.z = sz;
3960
3961			return this;
3962
3963		},
3964
3965		setFromMatrixColumn: function ( m, index ) {
3966
3967			return this.fromArray( m.elements, index * 4 );
3968
3969		},
3970
3971		setFromMatrix3Column: function ( m, index ) {
3972
3973			return this.fromArray( m.elements, index * 3 );
3974
3975		},
3976
3977		equals: function ( v ) {
3978
3979			return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
3980
3981		},
3982
3983		fromArray: function ( array, offset ) {
3984
3985			if ( offset === undefined ) { offset = 0; }
3986
3987			this.x = array[ offset ];
3988			this.y = array[ offset + 1 ];
3989			this.z = array[ offset + 2 ];
3990
3991			return this;
3992
3993		},
3994
3995		toArray: function ( array, offset ) {
3996
3997			if ( array === undefined ) { array = []; }
3998			if ( offset === undefined ) { offset = 0; }
3999
4000			array[ offset ] = this.x;
4001			array[ offset + 1 ] = this.y;
4002			array[ offset + 2 ] = this.z;
4003
4004			return array;
4005
4006		},
4007
4008		fromBufferAttribute: function ( attribute, index, offset ) {
4009
4010			if ( offset !== undefined ) {
4011
4012				console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
4013
4014			}
4015
4016			this.x = attribute.getX( index );
4017			this.y = attribute.getY( index );
4018			this.z = attribute.getZ( index );
4019
4020			return this;
4021
4022		},
4023
4024		random: function () {
4025
4026			this.x = Math.random();
4027			this.y = Math.random();
4028			this.z = Math.random();
4029
4030			return this;
4031
4032		}
4033
4034	} );
4035
4036	var _v1 = new Vector3();
4037	var _m1 = new Matrix4();
4038	var _zero = new Vector3( 0, 0, 0 );
4039	var _one = new Vector3( 1, 1, 1 );
4040	var _x = new Vector3();
4041	var _y = new Vector3();
4042	var _z = new Vector3();
4043
4044	/**
4045	 * @author mrdoob / http://mrdoob.com/
4046	 * @author supereggbert / http://www.paulbrunt.co.uk/
4047	 * @author philogb / http://blog.thejit.org/
4048	 * @author jordi_ros / http://plattsoft.com
4049	 * @author D1plo1d / http://github.com/D1plo1d
4050	 * @author alteredq / http://alteredqualia.com/
4051	 * @author mikael emtinger / http://gomo.se/
4052	 * @author timknip / http://www.floorplanner.com/
4053	 * @author bhouston / http://clara.io
4054	 * @author WestLangley / http://github.com/WestLangley
4055	 */
4056
4057	function Matrix4() {
4058
4059		this.elements = [
4060
4061			1, 0, 0, 0,
4062			0, 1, 0, 0,
4063			0, 0, 1, 0,
4064			0, 0, 0, 1
4065
4066		];
4067
4068		if ( arguments.length > 0 ) {
4069
4070			console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
4071
4072		}
4073
4074	}
4075
4076	Object.assign( Matrix4.prototype, {
4077
4078		isMatrix4: true,
4079
4080		set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
4081
4082			var te = this.elements;
4083
4084			te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
4085			te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
4086			te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
4087			te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
4088
4089			return this;
4090
4091		},
4092
4093		identity: function () {
4094
4095			this.set(
4096
4097				1, 0, 0, 0,
4098				0, 1, 0, 0,
4099				0, 0, 1, 0,
4100				0, 0, 0, 1
4101
4102			);
4103
4104			return this;
4105
4106		},
4107
4108		clone: function () {
4109
4110			return new Matrix4().fromArray( this.elements );
4111
4112		},
4113
4114		copy: function ( m ) {
4115
4116			var te = this.elements;
4117			var me = m.elements;
4118
4119			te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];
4120			te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];
4121			te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];
4122			te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];
4123
4124			return this;
4125
4126		},
4127
4128		copyPosition: function ( m ) {
4129
4130			var te = this.elements, me = m.elements;
4131
4132			te[ 12 ] = me[ 12 ];
4133			te[ 13 ] = me[ 13 ];
4134			te[ 14 ] = me[ 14 ];
4135
4136			return this;
4137
4138		},
4139
4140		extractBasis: function ( xAxis, yAxis, zAxis ) {
4141
4142			xAxis.setFromMatrixColumn( this, 0 );
4143			yAxis.setFromMatrixColumn( this, 1 );
4144			zAxis.setFromMatrixColumn( this, 2 );
4145
4146			return this;
4147
4148		},
4149
4150		makeBasis: function ( xAxis, yAxis, zAxis ) {
4151
4152			this.set(
4153				xAxis.x, yAxis.x, zAxis.x, 0,
4154				xAxis.y, yAxis.y, zAxis.y, 0,
4155				xAxis.z, yAxis.z, zAxis.z, 0,
4156				0, 0, 0, 1
4157			);
4158
4159			return this;
4160
4161		},
4162
4163		extractRotation: function ( m ) {
4164
4165			// this method does not support reflection matrices
4166
4167			var te = this.elements;
4168			var me = m.elements;
4169
4170			var scaleX = 1 / _v1.setFromMatrixColumn( m, 0 ).length();
4171			var scaleY = 1 / _v1.setFromMatrixColumn( m, 1 ).length();
4172			var scaleZ = 1 / _v1.setFromMatrixColumn( m, 2 ).length();
4173
4174			te[ 0 ] = me[ 0 ] * scaleX;
4175			te[ 1 ] = me[ 1 ] * scaleX;
4176			te[ 2 ] = me[ 2 ] * scaleX;
4177			te[ 3 ] = 0;
4178
4179			te[ 4 ] = me[ 4 ] * scaleY;
4180			te[ 5 ] = me[ 5 ] * scaleY;
4181			te[ 6 ] = me[ 6 ] * scaleY;
4182			te[ 7 ] = 0;
4183
4184			te[ 8 ] = me[ 8 ] * scaleZ;
4185			te[ 9 ] = me[ 9 ] * scaleZ;
4186			te[ 10 ] = me[ 10 ] * scaleZ;
4187			te[ 11 ] = 0;
4188
4189			te[ 12 ] = 0;
4190			te[ 13 ] = 0;
4191			te[ 14 ] = 0;
4192			te[ 15 ] = 1;
4193
4194			return this;
4195
4196		},
4197
4198		makeRotationFromEuler: function ( euler ) {
4199
4200			if ( ! ( euler && euler.isEuler ) ) {
4201
4202				console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
4203
4204			}
4205
4206			var te = this.elements;
4207
4208			var x = euler.x, y = euler.y, z = euler.z;
4209			var a = Math.cos( x ), b = Math.sin( x );
4210			var c = Math.cos( y ), d = Math.sin( y );
4211			var e = Math.cos( z ), f = Math.sin( z );
4212
4213			if ( euler.order === 'XYZ' ) {
4214
4215				var ae = a * e, af = a * f, be = b * e, bf = b * f;
4216
4217				te[ 0 ] = c * e;
4218				te[ 4 ] = - c * f;
4219				te[ 8 ] = d;
4220
4221				te[ 1 ] = af + be * d;
4222				te[ 5 ] = ae - bf * d;
4223				te[ 9 ] = - b * c;
4224
4225				te[ 2 ] = bf - ae * d;
4226				te[ 6 ] = be + af * d;
4227				te[ 10 ] = a * c;
4228
4229			} else if ( euler.order === 'YXZ' ) {
4230
4231				var ce = c * e, cf = c * f, de = d * e, df = d * f;
4232
4233				te[ 0 ] = ce + df * b;
4234				te[ 4 ] = de * b - cf;
4235				te[ 8 ] = a * d;
4236
4237				te[ 1 ] = a * f;
4238				te[ 5 ] = a * e;
4239				te[ 9 ] = - b;
4240
4241				te[ 2 ] = cf * b - de;
4242				te[ 6 ] = df + ce * b;
4243				te[ 10 ] = a * c;
4244
4245			} else if ( euler.order === 'ZXY' ) {
4246
4247				var ce$1 = c * e, cf$1 = c * f, de$1 = d * e, df$1 = d * f;
4248
4249				te[ 0 ] = ce$1 - df$1 * b;
4250				te[ 4 ] = - a * f;
4251				te[ 8 ] = de$1 + cf$1 * b;
4252
4253				te[ 1 ] = cf$1 + de$1 * b;
4254				te[ 5 ] = a * e;
4255				te[ 9 ] = df$1 - ce$1 * b;
4256
4257				te[ 2 ] = - a * d;
4258				te[ 6 ] = b;
4259				te[ 10 ] = a * c;
4260
4261			} else if ( euler.order === 'ZYX' ) {
4262
4263				var ae$1 = a * e, af$1 = a * f, be$1 = b * e, bf$1 = b * f;
4264
4265				te[ 0 ] = c * e;
4266				te[ 4 ] = be$1 * d - af$1;
4267				te[ 8 ] = ae$1 * d + bf$1;
4268
4269				te[ 1 ] = c * f;
4270				te[ 5 ] = bf$1 * d + ae$1;
4271				te[ 9 ] = af$1 * d - be$1;
4272
4273				te[ 2 ] = - d;
4274				te[ 6 ] = b * c;
4275				te[ 10 ] = a * c;
4276
4277			} else if ( euler.order === 'YZX' ) {
4278
4279				var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
4280
4281				te[ 0 ] = c * e;
4282				te[ 4 ] = bd - ac * f;
4283				te[ 8 ] = bc * f + ad;
4284
4285				te[ 1 ] = f;
4286				te[ 5 ] = a * e;
4287				te[ 9 ] = - b * e;
4288
4289				te[ 2 ] = - d * e;
4290				te[ 6 ] = ad * f + bc;
4291				te[ 10 ] = ac - bd * f;
4292
4293			} else if ( euler.order === 'XZY' ) {
4294
4295				var ac$1 = a * c, ad$1 = a * d, bc$1 = b * c, bd$1 = b * d;
4296
4297				te[ 0 ] = c * e;
4298				te[ 4 ] = - f;
4299				te[ 8 ] = d * e;
4300
4301				te[ 1 ] = ac$1 * f + bd$1;
4302				te[ 5 ] = a * e;
4303				te[ 9 ] = ad$1 * f - bc$1;
4304
4305				te[ 2 ] = bc$1 * f - ad$1;
4306				te[ 6 ] = b * e;
4307				te[ 10 ] = bd$1 * f + ac$1;
4308
4309			}
4310
4311			// bottom row
4312			te[ 3 ] = 0;
4313			te[ 7 ] = 0;
4314			te[ 11 ] = 0;
4315
4316			// last column
4317			te[ 12 ] = 0;
4318			te[ 13 ] = 0;
4319			te[ 14 ] = 0;
4320			te[ 15 ] = 1;
4321
4322			return this;
4323
4324		},
4325
4326		makeRotationFromQuaternion: function ( q ) {
4327
4328			return this.compose( _zero, q, _one );
4329
4330		},
4331
4332		lookAt: function ( eye, target, up ) {
4333
4334			var te = this.elements;
4335
4336			_z.subVectors( eye, target );
4337
4338			if ( _z.lengthSq() === 0 ) {
4339
4340				// eye and target are in the same position
4341
4342				_z.z = 1;
4343
4344			}
4345
4346			_z.normalize();
4347			_x.crossVectors( up, _z );
4348
4349			if ( _x.lengthSq() === 0 ) {
4350
4351				// up and z are parallel
4352
4353				if ( Math.abs( up.z ) === 1 ) {
4354
4355					_z.x += 0.0001;
4356
4357				} else {
4358
4359					_z.z += 0.0001;
4360
4361				}
4362
4363				_z.normalize();
4364				_x.crossVectors( up, _z );
4365
4366			}
4367
4368			_x.normalize();
4369			_y.crossVectors( _z, _x );
4370
4371			te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x;
4372			te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y;
4373			te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z;
4374
4375			return this;
4376
4377		},
4378
4379		multiply: function ( m, n ) {
4380
4381			if ( n !== undefined ) {
4382
4383				console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
4384				return this.multiplyMatrices( m, n );
4385
4386			}
4387
4388			return this.multiplyMatrices( this, m );
4389
4390		},
4391
4392		premultiply: function ( m ) {
4393
4394			return this.multiplyMatrices( m, this );
4395
4396		},
4397
4398		multiplyMatrices: function ( a, b ) {
4399
4400			var ae = a.elements;
4401			var be = b.elements;
4402			var te = this.elements;
4403
4404			var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
4405			var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
4406			var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
4407			var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
4408
4409			var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
4410			var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
4411			var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
4412			var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
4413
4414			te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
4415			te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
4416			te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
4417			te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
4418
4419			te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
4420			te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
4421			te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
4422			te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
4423
4424			te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
4425			te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
4426			te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
4427			te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
4428
4429			te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
4430			te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
4431			te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
4432			te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
4433
4434			return this;
4435
4436		},
4437
4438		multiplyScalar: function ( s ) {
4439
4440			var te = this.elements;
4441
4442			te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s;
4442 te[ 12 ] *= s;
4443			te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
4444			te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
4445			te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
4446
4447			return this;
4448
4449		},
4450
4451		determinant: function () {
4452
4453			var te = this.elements;
4454
4455			var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
4456			var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
4457			var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
4458			var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
4459
4460			//TODO: make this more efficient
4461			//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
4462
4463			return (
4464				n41 * (
4465					+ n14 * n23 * n32
4466					 - n13 * n24 * n32
4467					 - n14 * n22 * n33
4468					 + n12 * n24 * n33
4469					 + n13 * n22 * n34
4470					 - n12 * n23 * n34
4471				) +
4472				n42 * (
4473					+ n11 * n23 * n34
4474					 - n11 * n24 * n33
4475					 + n14 * n21 * n33
4476					 - n13 * n21 * n34
4477					 + n13 * n24 * n31
4478					 - n14 * n23 * n31
4479				) +
4480				n43 * (
4481					+ n11 * n24 * n32
4482					 - n11 * n22 * n34
4483					 - n14 * n21 * n32
4484					 + n12 * n21 * n34
4485					 + n14 * n22 * n31
4486					 - n12 * n24 * n31
4487				) +
4488				n44 * (
4489					- n13 * n22 * n31
4490					 - n11 * n23 * n32
4491					 + n11 * n22 * n33
4492					 + n13 * n21 * n32
4493					 - n12 * n21 * n33
4494					 + n12 * n23 * n31
4495				)
4496
4497			);
4498
4499		},
4500
4501		transpose: function () {
4502
4503			var te = this.elements;
4504			var tmp;
4505
4506			tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
4507			tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
4508			tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
4509
4510			tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
4511			tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
4512			tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
4513
4514			return this;
4515
4516		},
4517
4518		setPosition: function ( x, y, z ) {
4519
4520			var te = this.elements;
4521
4522			if ( x.isVector3 ) {
4523
4524				te[ 12 ] = x.x;
4525				te[ 13 ] = x.y;
4526				te[ 14 ] = x.z;
4527
4528			} else {
4529
4530				te[ 12 ] = x;
4531				te[ 13 ] = y;
4532				te[ 14 ] = z;
4533
4534			}
4535
4536			return this;
4537
4538		},
4539
4540		getInverse: function ( m, throwOnDegenerate ) {
4541
4542			if ( throwOnDegenerate !== undefined ) {
4543
4544				console.warn( "THREE.Matrix4: .getInverse() can no longer be configured to throw on degenerate." );
4545
4546			}
4547
4548			// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
4549			var te = this.elements,
4550				me = m.elements,
4551
4552				n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
4553				n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
4554				n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
4555				n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
4556
4557				t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
4558				t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
4559				t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
4560				t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
4561
4562			var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
4563
4564			if ( det === 0 ) { return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); }
4565
4566			var detInv = 1 / det;
4567
4568			te[ 0 ] = t11 * detInv;
4569			te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
4570			te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
4571			te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
4572
4573			te[ 4 ] = t12 * detInv;
4574			te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
4575			te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
4576			te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
4577
4578			te[ 8 ] = t13 * detInv;
4579			te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 
4579+ n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
4580			te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
4581			te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
4582
4583			te[ 12 ] = t14 * detInv;
4584			te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
4585			te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
4586			te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
4587
4588			return this;
4589
4590		},
4591
4592		scale: function ( v ) {
4593
4594			var te = this.elements;
4595			var x = v.x, y = v.y, z = v.z;
4596
4597			te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
4598			te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
4599			te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
4600			te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
4601
4602			return this;
4603
4604		},
4605
4606		getMaxScaleOnAxis: function () {
4607
4608			var te = this.elements;
4609
4610			var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
4611			var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
4612			var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
4613
4614			return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
4615
4616		},
4617
4618		makeTranslation: function ( x, y, z ) {
4619
4620			this.set(
4621
4622				1, 0, 0, x,
4623				0, 1, 0, y,
4624				0, 0, 1, z,
4625				0, 0, 0, 1
4626
4627			);
4628
4629			return this;
4630
4631		},
4632
4633		makeRotationX: function ( theta ) {
4634
4635			var c = Math.cos( theta ), s = Math.sin( theta );
4636
4637			this.set(
4638
4639				1, 0, 0, 0,
4640				0, c, - s, 0,
4641				0, s, c, 0,
4642				0, 0, 0, 1
4643
4644			);
4645
4646			return this;
4647
4648		},
4649
4650		makeRotationY: function ( theta ) {
4651
4652			var c = Math.cos( theta ), s = Math.sin( theta );
4653
4654			this.set(
4655
4656				 c, 0, s, 0,
4657				 0, 1, 0, 0,
4658				- s, 0, c, 0,
4659				 0, 0, 0, 1
4660
4661			);
4662
4663			return this;
4664
4665		},
4666
4667		makeRotationZ: function ( theta ) {
4668
4669			var c = Math.cos( theta ), s = Math.sin( theta );
4670
4671			this.set(
4672
4673				c, - s, 0, 0,
4674				s, c, 0, 0,
4675				0, 0, 1, 0,
4676				0, 0, 0, 1
4677
4678			);
4679
4680			return this;
4681
4682		},
4683
4684		makeRotationAxis: function ( axis, angle ) {
4685
4686			// Based on http://www.gamedev.net/reference/articles/article1199.asp
4687
4688			var c = Math.cos( angle );
4689			var s = Math.sin( angle );
4690			var t = 1 - c;
4691			var x = axis.x, y = axis.y, z = axis.z;
4692			var tx = t * x, ty = t * y;
4693
4694			this.set(
4695
4696				tx * x + c, tx * y - s * z, tx * z + s * y, 0,
4697				tx * y + s * z, ty * y + c, ty * z - s * x, 0,
4698				tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
4699				0, 0, 0, 1
4700
4701			);
4702
4703			 return this;
4704
4705		},
4706
4707		makeScale: function ( x, y, z ) {
4708
4709			this.set(
4710
4711				x, 0, 0, 0,
4712				0, y, 0, 0,
4713				0, 0, z, 0,
4714				0, 0, 0, 1
4715
4716			);
4717
4718			return this;
4719
4720		},
4721
4722		makeShear: function ( x, y, z ) {
4723
4724			this.set(
4725
4726				1, y, z, 0,
4727				x, 1, z, 0,
4728				x, y, 1, 0,
4729				0, 0, 0, 1
4730
4731			);
4732
4733			return this;
4734
4735		},
4736
4737		compose: function ( position, quaternion, scale ) {
4738
4739			var te = this.elements;
4740
4741			var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
4742			var x2 = x + x,	y2 = y + y, z2 = z + z;
4743			var xx = x * x2, xy = x * y2, xz = x * z2;
4744			var yy = y * y2, yz = y * z2, zz = z * z2;
4745			var wx = w * x2, wy = w * y2, wz = w * z2;
4746
4747			var sx = scale.x, sy = scale.y, sz = scale.z;
4748
4749			te[ 0 ] = ( 1 - ( yy + zz ) ) * sx;
4750			te[ 1 ] = ( xy + wz ) * sx;
4751			te[ 2 ] = ( xz - wy ) * sx;
4752			te[ 3 ] = 0;
4753
4754			te[ 4 ] = ( xy - wz ) * sy;
4755			te[ 5 ] = ( 1 - ( xx + zz ) ) * sy;
4756			te[ 6 ] = ( yz + wx ) * sy;
4757			te[ 7 ] = 0;
4758
4759			te[ 8 ] = ( xz + wy ) * sz;
4760			te[ 9 ] = ( yz - wx ) * sz;
4761			te[ 10 ] = ( 1 - ( xx + yy ) ) * sz;
4762			te[ 11 ] = 0;
4763
4764			te[ 12 ] = position.x;
4765			te[ 13 ] = position.y;
4766			te[ 14 ] = position.z;
4767			te[ 15 ] = 1;
4768
4769			return this;
4770
4771		},
4772
4773		decompose: function ( position, quaternion, scale ) {
4774
4775			var te = this.elements;
4776
4777			var sx = _v1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
4778			var sy = _v1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
4779			var sz = _v1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
4780
4781			// if determine is negative, we need to invert one scale
4782			var det = this.determinant();
4783			if ( det < 0 ) { sx = - sx; }
4784
4785			position.x = te[ 12 ];
4786			position.y = te[ 13 ];
4787			position.z = te[ 14 ];
4788
4789			// scale the rotation part
4790			_m1.copy( this );
4791
4792			var invSX = 1 / sx;
4793			var invSY = 1 / sy;
4794			var invSZ = 1 / sz;
4795
4796			_m1.elements[ 0 ] *= invSX;
4797			_m1.elements[ 1 ] *= invSX;
4798			_m1.elements[ 2 ] *= invSX;
4799
4800			_m1.elements[ 4 ] *= invSY;
4801			_m1.elements[ 5 ] *= invSY;
4802			_m1.elements[ 6 ] *= invSY;
4803
4804			_m1.elements[ 8 ] *= invSZ;
4805			_m1.elements[ 9 ] *= invSZ;
4806			_m1.elements[ 10 ] *= invSZ;
4807
4808			quaternion.setFromRotationMatrix( _m1 );
4809
4810			scale.x = sx;
4811			scale.y = sy;
4812			scale.z = sz;
4813
4814			return this;
4815
4816		},
4817
4818		makePerspective: function ( left, right, top, bottom, near, far ) {
4819
4820			if ( far === undefined ) {
4821
4822				console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a 
4822new signature. Please check the docs.' );
4823
4824			}
4825
4826			var te = this.elements;
4827			var x = 2 * near / ( right - left );
4828			var y = 2 * near / ( top - bottom );
4829
4830			var a = ( right + left ) / ( right - left );
4831			var b = ( top + bottom ) / ( top - bottom );
4832			var c = - ( far + near ) / ( far - near );
4833			var d = - 2 * far * near / ( far - near );
4834
4835			te[ 0 ] = x;	te[ 4 ] = 0;	te[ 8 ] = a;	te[ 12 ] = 0;
4836			te[ 1 ] = 0;	te[ 5 ] = y;	te[ 9 ] = b;	te[ 13 ] = 0;
4837			te[ 2 ] = 0;	te[ 6 ] = 0;	te[ 10 ] = c;	te[ 14 ] = d;
4838			te[ 3 ] = 0;	te[ 7 ] = 0;	te[ 11 ] = - 1;	te[ 15 ] = 0;
4839
4840			return this;
4841
4842		},
4843
4844		makeOrthographic: function ( left, right, top, bottom, near, far ) {
4845
4846			var te = this.elements;
4847			var w = 1.0 / ( right - left );
4848			var h = 1.0 / ( top - bottom );
4849			var p = 1.0 / ( far - near );
4850
4851			var x = ( right + left ) * w;
4852			var y = ( top + bottom ) * h;
4853			var z = ( far + near ) * p;
4854
4855			te[ 0 ] = 2 * w;	te[ 4 ] = 0;	te[ 8 ] = 0;	te[ 12 ] = - x;
4856			te[ 1 ] = 0;	te[ 5 ] = 2 * h;	te[ 9 ] = 0;	te[ 13 ] = - y;
4857			te[ 2 ] = 0;	te[ 6 ] = 0;	te[ 10 ] = - 2 * p;	te[ 14 ] = - z;
4858			te[ 3 ] = 0;	te[ 7 ] = 0;	te[ 11 ] = 0;	te[ 15 ] = 1;
4859
4860			return this;
4861
4862		},
4863
4864		equals: function ( matrix ) {
4865
4866			var te = this.elements;
4867			var me = matrix.elements;
4868
4869			for ( var i = 0; i < 16; i ++ ) {
4870
4871				if ( te[ i ] !== me[ i ] ) { return false; }
4872
4873			}
4874
4875			return true;
4876
4877		},
4878
4879		fromArray: function ( array, offset ) {
4880
4881			if ( offset === undefined ) { offset = 0; }
4882
4883			for ( var i = 0; i < 16; i ++ ) {
4884
4885				this.elements[ i ] = array[ i + offset ];
4886
4887			}
4888
4889			return this;
4890
4891		},
4892
4893		toArray: function ( array, offset ) {
4894
4895			if ( array === undefined ) { array = []; }
4896			if ( offset === undefined ) { offset = 0; }
4897
4898			var te = this.elements;
4899
4900			array[ offset ] = te[ 0 ];
4901			array[ offset + 1 ] = te[ 1 ];
4902			array[ offset + 2 ] = te[ 2 ];
4903			array[ offset + 3 ] = te[ 3 ];
4904
4905			array[ offset + 4 ] = te[ 4 ];
4906			array[ offset + 5 ] = te[ 5 ];
4907			array[ offset + 6 ] = te[ 6 ];
4908			array[ offset + 7 ] = te[ 7 ];
4909
4910			array[ offset + 8 ] = te[ 8 ];
4911			array[ offset + 9 ] = te[ 9 ];
4912			array[ offset + 10 ] = te[ 10 ];
4913			array[ offset + 11 ] = te[ 11 ];
4914
4915			array[ offset + 12 ] = te[ 12 ];
4916			array[ offset + 13 ] = te[ 13 ];
4917			array[ offset + 14 ] = te[ 14 ];
4918			array[ offset + 15 ] = te[ 15 ];
4919
4920			return array;
4921
4922		}
4923
4924	} );
4925
4926	/**
4927	 * @author mrdoob / http://mrdoob.com/
4928	 * @author WestLangley / http://github.com/WestLangley
4929	 * @author bhouston / http://clara.io
4930	 */
4931
4932	var _matrix = new Matrix4();
4933	var _quaternion$1 = new Quaternion();
4934
4935	function Euler( x, y, z, order ) {
4936		if ( x === void 0 ) x = 0;
4937		if ( y === void 0 ) y = 0;
4938		if ( z === void 0 ) z = 0;
4939		if ( order === void 0 ) order = Euler.DefaultOrder;
4940
4941
4942		this._x = x;
4943		this._y = y;
4944		this._z = z;
4945		this._order = order;
4946
4947	}
4948
4949	Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
4950
4951	Euler.DefaultOrder = 'XYZ';
4952
4953	Object.defineProperties( Euler.prototype, {
4954
4955		x: {
4956
4957			get: function () {
4958
4959				return this._x;
4960
4961			},
4962
4963			set: function ( value ) {
4964
4965				this._x = value;
4966				this._onChangeCallback();
4967
4968			}
4969
4970		},
4971
4972		y: {
4973
4974			get: function () {
4975
4976				return this._y;
4977
4978			},
4979
4980			set: function ( value ) {
4981
4982				this._y = value;
4983				this._onChangeCallback();
4984
4985			}
4986
4987		},
4988
4989		z: {
4990
4991			get: function () {
4992
4993				return this._z;
4994
4995			},
4996
4997			set: function ( value ) {
4998
4999				this._z = value;
5000				this._onChangeCallback();
5001
5002			}
5003
5004		},
5005
5006		order: {
5007
5008			get: function () {
5009
5010				return this._order;
5011
5012			},
5013
5014			set: function ( value ) {
5015
5016				this._order = value;
5017				this._onChangeCallback();
5018
5019			}
5020
5021		}
5022
5023	} );
5024
5025	Object.assign( Euler.prototype, {
5026
5027		isEuler: true,
5028
5029		set: function ( x, y, z, order ) {
5030
5031			this._x = x;
5032			this._y = y;
5033			this._z = z;
5034			this._order = order || this._order;
5035
5036			this._onChangeCallback();
5037
5038			return this;
5039
5040		},
5041
5042		clone: function () {
5043
5044			return new this.constructor( this._x, this._y, this._z, this._order );
5045
5046		},
5047
5048		copy: function ( euler ) {
5049
5050			this._x = euler._x;
5051			this._y = euler._y;
5052			this._z = euler._z;
5053			this._order = euler._order;
5054
5055			this._onChangeCallback();
5056
5057			return this;
5058
5059		},
5060
5061		setFromRotationMatrix: function ( m, order, update ) {
5062
5063			var clamp = MathUtils.clamp;
5064
5065			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
5066
5067			var te = m.elements;
5068			var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
5069			var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
5070			var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
5071
5072			order = order || this._order;
5073
5074			switch ( order ) {
5075
5076				case 'XYZ':
5077
5078					this._y = Math.asin( clamp( m13, - 1, 1 ) );
5079
5080					if ( Math.abs( m13 ) < 0.9999999 ) {
5081
5082						this._x = Math.atan2( - m23, m33 );
5083						this._z = Math.atan2( - m12, m11 );
5084
5085					} else {
5086
5087						this._x = Math.atan2( m32, m22 );
5088						this._z = 0;
5089
5090					}
5091
5092					break;
5093
5094				case 'YXZ':
5095
5096					this._x = Math.asin( - clamp( m23, - 1, 1 ) );
5097
5098					if ( Math.abs( m23 ) < 0.9999999 ) {
5099
5100						this._y = Math.atan2( m13, m33 );
5101						this._z = Math.atan2( m21, m22 );
5102
5103					} else {
5104
5105						this._y = Math.atan2( - m31, m11 );
5106						this._z = 0;
5107
5108					}
5109
5110					break;
5111
5112				case 'ZXY':
5113
5114					this._x = Math.asin( clamp( m32, - 1, 1 ) );
5115
5116					if ( Math.abs( m32 ) < 0.9999999 ) {
5117
5118						this._y = Math.atan2( - m31, m33 );
5119						this._z = Math.atan2( - m12, m22 );
5120
5121					} else {
5122
5123						this._y = 0;
5124						this._z = Math.atan2( m21, m11 );
5125
5126					}
5127
5128					break;
5129
5130				case 'ZYX':
5131
5132					this._y = Math.asin( - clamp( m31, - 1, 1 ) );
5133
5134					if ( Math.abs( m31 ) < 0.9999999 ) {
5135
5136						this._x = Math.atan2( m32, m33 );
5137						this._z = Math.atan2( m21, m11 );
5138
5139					} else {
5140
5141						this._x = 0;
5142						this._z = Math.atan2( - m12, m22 );
5143
5144					}
5145
5146					break;
5147
5148				case 'YZX':
5149
5150					this._z = Math.asin( clamp( m21, - 1, 1 ) );
5151
5152					if ( Math.abs( m21 ) < 0.9999999 ) {
5153
5154						this._x = Math.atan2( - m23, m22 );
5155						this._y = Math.atan2( - m31, m11 );
5156
5157					} else {
5158
5159						this._x = 0;
5160						this._y = Math.atan2( m13, m33 );
5161
5162					}
5163
5164					break;
5165
5166				case 'XZY':
5167
5168					this._z = Math.asin( - clamp( m12, - 1, 1 ) );
5169
5170					if ( Math.abs( m12 ) < 0.9999999 ) {
5171
5172						this._x = Math.atan2( m32, m22 );
5173						this._y = Math.atan2( m13, m11 );
5174
5175					} else {
5176
5177						this._x = Math.atan2( - m23, m33 );
5178						this._y = 0;
5179
5180					}
5181
5182					break;
5183
5184				default:
5185
5186					console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );
5187
5188			}
5189
5190			this._order = order;
5191
5192			if ( update !== false ) { this._onChangeCallback(); }
5193
5194			return this;
5195
5196		},
5197
5198		setFromQuaternion: function ( q, order, update ) {
5199
5200			_matrix.makeRotationFromQuaternion( q );
5201
5202			return this.setFromRotationMatrix( _matrix, order, update );
5203
5204		},
5205
5206		setFromVector3: function ( v, order ) {
5207
5208			return this.set( v.x, v.y, v.z, order || this._order );
5209
5210		},
5211
5212		reorder: function ( newOrder ) {
5213
5214			// WARNING: this discards revolution information -bhouston
5215
5216			_quaternion$1.setFromEuler( this );
5217
5218			return this.setFromQuaternion( _quaternion$1, newOrder );
5219
5220		},
5221
5222		equals: function ( euler ) {
5223
5224			return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
5225
5226		},
5227
5228		fromArray: function ( array ) {
5229
5230			this._x = array[ 0 ];
5231			this._y = array[ 1 ];
5232			this._z = array[ 2 ];
5233			if ( array[ 3 ] !== undefined ) { this._order = array[ 3 ]; }
5234
5235			this._onChangeCallback();
5236
5237			return this;
5238
5239		},
5240
5241		toArray: function ( array, offset ) {
5242
5243			if ( array === undefined ) { array = []; }
5244			if ( offset === undefined ) { offset = 0; }
5245
5246			array[ offset ] = this._x;
5247			array[ offset + 1 ] = this._y;
5248			array[ offset + 2 ] = this._z;
5249			array[ offset + 3 ] = this._order;
5250
5251			return array;
5252
5253		},
5254
5255		toVector3: function ( optionalResult ) {
5256
5257			if ( optionalResult ) {
5258
5259				return optionalResult.set( this._x, this._y, this._z );
5260
5261			} else {
5262
5263				return new Vector3( this._x, this._y, this._z );
5264
5265			}
5266
5267		},
5268
5269		_onChange: function ( callback ) {
5270
5271			this._onChangeCallback = callback;
5272
5273			return this;
5274
5275		},
5276
5277		_onChangeCallback: function () {}
5278
5279	} );
5280
5281	/**
5282	 * @author mrdoob / http://mrdoob.com/
5283	 */
5284
5285	function Layers() {
5286
5287		this.mask = 1 | 0;
5288
5289	}
5290
5291	Object.assign( Layers.prototype, {
5292
5293		set: function ( channel ) {
5294
5295			this.mask = 1 << channel | 0;
5296
5297		},
5298
5299		enable: function ( channel ) {
5300
5301			this.mask |= 1 << channel | 0;
5302
5303		},
5304
5305		enableAll: function () {
5306
5307			this.mask = 0xffffffff | 0;
5308
5309		},
5310
5311		toggle: function ( channel ) {
5312
5313			this.mask ^= 1 << channel | 0;
5314
5315		},
5316
5317		disable: function ( channel ) {
5318
5319			this.mask &= ~ ( 1 << channel | 0 );
5320
5321		},
5322
5323		disableAll: function () {
5324
5325			this.mask = 0;
5326
5327		},
5328
5329		test: function ( layers ) {
5330
5331			return ( this.mask & layers.mask ) !== 0;
5332
5333		}
5334
5335	} );
5336
5337	var _object3DId = 0;
5338
5339	var _v1$1 = new Vector3();
5340	var _q1 = new Quaternion();
5341	var _m1$1 = new Matrix4();
5342	var _target = new Vector3();
5343
5344	var _position = new Vector3();
5345	var _scale = new Vector3();
5346	var _quaternion$2 = new Quaternion();
5347
5348	var _xAxis = new Vector3( 1, 0, 0 );
5349	var _yAxis = new Vector3( 0, 1, 0 );
5350	var _zAxis = new Vector3( 0, 0, 1 );
5351
5352	var _addedEvent = { type: 'added' };
5353	var _removedEvent = { type: 'removed' };
5354
5355	/**
5356	 * @author mrdoob / http://mrdoob.com/
5357	 * @author mikael emtinger / http://gomo.se/
5358	 * @author alteredq / http://alteredqualia.com/
5359	 * @author WestLangley / http://github.com/WestLangley
5360	 * @author elephantatwork / www.elephantatwork.ch
5361	 */
5362
5363	function Object3D() {
5364
5365		Object.defineProperty( this, 'id', { value: _object3DId ++ } );
5366
5367		this.uuid = MathUtils.generateUUID();
5368
5369		this.name = '';
5370		this.type = 'Object3D';
5371
5372		this.parent = null;
5373		this.children = [];
5374
5375		this.up = Object3D.DefaultUp.clone();
5376
5377		var position = new Vector3();
5378		var rotation = new Euler();
5379		var quaternion = new Quaternion();
5380		var scale = new Vector3( 1, 1, 1 );
5381
5382		function onRotationChange() {
5383
5384			quaternion.setFromEuler( rotation, false );
5385
5386		}
5387
5388		function onQuaternionChange() {
5389
5390			rotation.setFromQuaternion( quaternion, undefined, false );
5391
5392		}
5393
5394		rotation._onChange( onRotationChange );
5395		quaternion._onChange( onQuaternionChange );
5396
5397		Object.defineProperties( this, {
5398			position: {
5399				configurable: true,
5400				enumerable: true,
5401				value: position
5402			},
5403			rotation: {
5404				configurable: true,
5405				enumerable: true,
5406				value: rotation
5407			},
5408			quaternion: {
5409				configurable: true,
5410				enumerable: true,
5411				value: quaternion
5412			},
5413			scale: {
5414				configurable: true,
5415				enumerable: true,
5416				value: scale
5417			},
5418			modelViewMatrix: {
5419				value: new Matrix4()
5420			},
5421			normalMatrix: {
5422				value: new Matrix3()
5423			}
5424		} );
5425
5426		this.matrix = new Matrix4();
5427		this.matrixWorld = new Matrix4();
5428
5429		this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
5430		this.matrixWorldNeedsUpdate = false;
5431
5432		this.layers = new Layers();
5433		this.visible = true;
5434
5435		this.castShadow = false;
5436		this.receiveShadow = false;
5437
5438		this.frustumCulled = true;
5439		this.renderOrder = 0;
5440
5441		this.userData = {};
5442
5443	}
5444
5445	Object3D.DefaultUp = new Vector3( 0, 1, 0 );
5446	Object3D.DefaultMatrixAutoUpdate = true;
5447
5448	Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
5449
5450		constructor: Object3D,
5451
5452		isObject3D: true,
5453
5454		onBeforeRender: function () {},
5455		onAfterRender: function () {},
5456
5457		applyMatrix4: function ( matrix ) {
5458
5459			if ( this.matrixAutoUpdate ) { this.updateMatrix(); }
5460
5461			this.matrix.premultiply( matrix );
5462
5463			this.matrix.decompose( this.position, this.quaternion, this.scale );
5464
5465		},
5466
5467		applyQuaternion: function ( q ) {
5468
5469			this.quaternion.premultiply( q );
5470
5471			return this;
5472
5473		},
5474
5475		setRotationFromAxisAngle: function ( axis, angle ) {
5476
5477			// assumes axis is normalized
5478
5479			this.quaternion.setFromAxisAngle( axis, angle );
5480
5481		},
5482
5483		setRotationFromEuler: function ( euler ) {
5484
5485			this.quaternion.setFromEuler( euler, true );
5486
5487		},
5488
5489		setRotationFromMatrix: function ( m ) {
5490
5491			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
5492
5493			this.quaternion.setFromRotationMatrix( m );
5494
5495		},
5496
5497		setRotationFromQuaternion: function ( q ) {
5498
5499			// assumes q is normalized
5500
5501			this.quaternion.copy( q );
5502
5503		},
5504
5505		rotateOnAxis: function ( axis, angle ) {
5506
5507			// rotate object on axis in object space
5508			// axis is assumed to be normalized
5509
5510			_q1.setFromAxisAngle( axis, angle );
5511
5512			this.quaternion.multiply( _q1 );
5513
5514			return this;
5515
5516		},
5517
5518		rotateOnWorldAxis: function ( axis, angle ) {
5519
5520			// rotate object on axis in world space
5521			// axis is assumed to be normalized
5522			// method assumes no rotated parent
5523
5524			_q1.setFromAxisAngle( axis, angle );
5525
5526			this.quaternion.premultiply( _q1 );
5527
5528			return this;
5529
5530		},
5531
5532		rotateX: function ( angle ) {
5533
5534			return this.rotateOnAxis( _xAxis, angle );
5535
5536		},
5537
5538		rotateY: function ( angle ) {
5539
5540			return this.rotateOnAxis( _yAxis, angle );
5541
5542		},
5543
5544		rotateZ: function ( angle ) {
5545
5546			return this.rotateOnAxis( _zAxis, angle );
5547
5548		},
5549
5550		translateOnAxis: function ( axis, distance ) {
5551
5552			// translate object by distance along axis in object space
5553			// axis is assumed to be normalized
5554
5555			_v1$1.copy( axis ).applyQuaternion( this.quaternion );
5556
5557			this.position.add( _v1$1.multiplyScalar( distance ) );
5558
5559			return this;
5560
5561		},
5562
5563		translateX: function ( distance ) {
5564
5565			return this.translateOnAxis( _xAxis, distance );
5566
5567		},
5568
5569		translateY: function ( distance ) {
5570
5571			return this.translateOnAxis( _yAxis, distance );
5572
5573		},
5574
5575		translateZ: function ( distance ) {
5576
5577			return this.translateOnAxis( _zAxis, distance );
5578
5579		},
5580
5581		localToWorld: function ( vector ) {
5582
5583			return vector.applyMatrix4( this.matrixWorld );
5584
5585		},
5586
5587		worldToLocal: function ( vector ) {
5588
5589			return vector.applyMatrix4( _m1$1.getInverse( this.matrixWorld ) );
5590
5591		},
5592
5593		lookAt: function ( x, y, z ) {
5594
5595			// This method does not support objects having non-uniformly-scaled parent(s)
5596
5597			if ( x.isVector3 ) {
5598
5599				_target.copy( x );
5600
5601			} else {
5602
5603				_target.set( x, y, z );
5604
5605			}
5606
5607			var parent = this.parent;
5608
5609			this.updateWorldMatrix( true, false );
5610
5611			_position.setFromMatrixPosition( this.matrixWorld );
5612
5613			if ( this.isCamera || this.isLight ) {
5614
5615				_m1$1.lookAt( _position, _target, this.up );
5616
5617			} else {
5618
5619				_m1$1.lookAt( _target, _position, this.up );
5620
5621			}
5622
5623			this.quaternion.setFromRotationMatrix( _m1$1 );
5624
5625			if ( parent ) {
5626
5627				_m1$1.extractRotation( parent.matrixWorld );
5628				_q1.setFromRotationMatrix( _m1$1 );
5629				this.quaternion.premultiply( _q1.inverse() );
5630
5631			}
5632
5633		},
5634
5635		add: function ( object ) {
5636
5637			if ( arguments.length > 1 ) {
5638
5639				for ( var i = 0; i < arguments.length; i ++ ) {
5640
5641					this.add( arguments[ i ] );
5642
5643				}
5644
5645				return this;
5646
5647			}
5648
5649			if ( object === this ) {
5650
5651				console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
5652				return this;
5653
5654			}
5655
5656			if ( ( object && object.isObject3D ) ) {
5657
5658				if ( object.parent !== null ) {
5659
5660					object.parent.remove( object );
5661
5662				}
5663
5664				object.parent = this;
5665				this.children.push( object );
5666
5667				object.dispatchEvent( _addedEvent );
5668
5669			} else {
5670
5671				console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
5672
5673			}
5674
5675			return this;
5676
5677		},
5678
5679		remove: function ( object ) {
5680
5681			if ( arguments.length > 1 ) {
5682
5683				for ( var i = 0; i < arguments.length; i ++ ) {
5684
5685					this.remove( arguments[ i ] );
5686
5687				}
5688
5689				return this;
5690
5691			}
5692
5693			var index = this.children.indexOf( object );
5694
5695			if ( index !== - 1 ) {
5696
5697				object.parent = null;
5698				this.children.splice( index, 1 );
5699
5700				object.dispatchEvent( _removedEvent );
5701
5702			}
5703
5704			return this;
5705
5706		},
5707
5708		attach: function ( object ) {
5709
5710			// adds object as a child of this, while maintaining the object's world transform
5711
5712			this.updateWorldMatrix( true, false );
5713
5714			_m1$1.getInverse( this.matrixWorld );
5715
5716			if ( object.parent !== null ) {
5717
5718				object.parent.updateWorldMatrix( true, false );
5719
5720				_m1$1.multiply( object.parent.matrixWorld );
5721
5722			}
5723
5724			object.applyMatrix4( _m1$1 );
5725
5726			object.updateWorldMatrix( false, false );
5727
5728			this.add( object );
5729
5730			return this;
5731
5732		},
5733
5734		getObjectById: function ( id ) {
5735
5736			return this.getObjectByProperty( 'id', id );
5737
5738		},
5739
5740		getObjectByName: function ( name ) {
5741
5742			return this.getObjectByProperty( 'name', name );
5743
5744		},
5745
5746		getObjectByProperty: function ( name, value ) {
5747
5748			if ( this[ name ] === value ) { return this; }
5749
5750			for ( var i = 0, l = this.children.length; i < l; i ++ ) {
5751
5752				var child = this.children[ i ];
5753				var object = child.getObjectByProperty( name, value );
5754
5755				if ( object !== undefined ) {
5756
5757					return object;
5758
5759				}
5760
5761			}
5762
5763			return undefined;
5764
5765		},
5766
5767		getWorldPosition: function ( target ) {
5768
5769			if ( target === undefined ) {
5770
5771				console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' );
5772				target = new Vector3();
5773
5774			}
5775
5776			this.updateMatrixWorld( true );
5777
5778			return target.setFromMatrixPosition( this.matrixWorld );
5779
5780		},
5781
5782		getWorldQuaternion: function ( target ) {
5783
5784			if ( target === undefined ) {
5785
5786				console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
5787				target = new Quaternion();
5788
5789			}
5790
5791			this.updateMatrixWorld( true );
5792
5793			this.matrixWorld.decompose( _position, target, _scale );
5794
5795			return target;
5796
5797		},
5798
5799		getWorldScale: function ( target ) {
5800
5801			if ( target === undefined ) {
5802
5803				console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
5804				target = new Vector3();
5805
5806			}
5807
5808			this.updateMatrixWorld( true );
5809
5810			this.matrixWorld.decompose( _position, _quaternion$2, target );
5811
5812			return target;
5813
5814		},
5815
5816		getWorldDirection: function ( target ) {
5817
5818			if ( target === undefined ) {
5819
5820				console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' );
5821				target = new Vector3();
5822
5823			}
5824
5825			this.updateMatrixWorld( true );
5826
5827			var e = this.matrixWorld.elements;
5828
5829			return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
5830
5831		},
5832
5833		raycast: function () {},
5834
5835		traverse: function ( callback ) {
5836
5837			callback( this );
5838
5839			var children = this.children;
5840
5841			for ( var i = 0, l = children.length; i < l; i ++ ) {
5842
5843				children[ i ].traverse( callback );
5844
5845			}
5846
5847		},
5848
5849		traverseVisible: function ( callback ) {
5850
5851			if ( this.visible === false ) { return; }
5852
5853			callback( this );
5854
5855			var children = this.children;
5856
5857			for ( var i = 0, l = children.length; i < l; i ++ ) {
5858
5859				children[ i ].traverseVisible( callback );
5860
5861			}
5862
5863		},
5864
5865		traverseAncestors: function ( callback ) {
5866
5867			var parent = this.parent;
5868
5869			if ( parent !== null ) {
5870
5871				callback( parent );
5872
5873				parent.traverseAncestors( callback );
5874
5875			}
5876
5877		},
5878
5879		updateMatrix: function () {
5880
5881			this.matrix.compose( this.position, this.quaternion, this.scale );
5882
5883			this.matrixWorldNeedsUpdate = true;
5884
5885		},
5886
5887		updateMatrixWorld: function ( force ) {
5888
5889			if ( this.matrixAutoUpdate ) { this.updateMatrix(); }
5890
5891			if ( this.matrixWorldNeedsUpdate || force ) {
5892
5893				if ( this.parent === null ) {
5894
5895					this.matrixWorld.copy( this.matrix );
5896
5897				} else {
5898
5899					this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
5900
5901				}
5902
5903				this.matrixWorldNeedsUpdate = false;
5904
5905				force = true;
5906
5907			}
5908
5909			// update children
5910
5911			var children = this.children;
5912
5913			for ( var i = 0, l = children.length; i < l; i ++ ) {
5914
5915				children[ i ].updateMatrixWorld( force );
5916
5917			}
5918
5919		},
5920
5921		updateWorldMatrix: function ( updateParents, updateChildren ) {
5922
5923			var parent = this.parent;
5924
5925			if ( updateParents === true && parent !== null ) {
5926
5927				parent.updateWorldMatrix( true, false );
5928
5929			}
5930
5931			if ( this.matrixAutoUpdate ) { this.updateMatrix(); }
5932
5933			if ( this.parent === null ) {
5934
5935				this.matrixWorld.copy( this.matrix );
5936
5937			} else {
5938
5939				this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
5940
5941			}
5942
5943			// update children
5944
5945			if ( updateChildren === true ) {
5946
5947				var children = this.children;
5948
5949				for ( var i = 0, l = children.length; i < l; i ++ ) {
5950
5951					children[ i ].updateWorldMatrix( false, true );
5952
5953				}
5954
5955			}
5956
5957		},
5958
5959		toJSON: function ( meta ) {
5960
5961			// meta is a string when called from JSON.stringify
5962			var isRootObject = ( meta === undefined || typeof meta === 'string' );
5963
5964			var output = {};
5965
5966			// meta is a hash used to collect geometries, materials.
5967			// not providing it implies that this is the root object
5968			// being serialized.
5969			if ( isRootObject ) {
5970
5971				// initialize meta obj
5972				meta = {
5973					geometries: {},
5974					materials: {},
5975					textures: {},
5976					images: {},
5977					shapes: {}
5978				};
5979
5980				output.metadata = {
5981					version: 4.5,
5982					type: 'Object',
5983					generator: 'Object3D.toJSON'
5984				};
5985
5986			}
5987
5988			// standard Object3D serialization
5989
5990			var object = {};
5991
5992			object.uuid = this.uuid;
5993			object.type = this.type;
5994
5995			if ( this.name !== '' ) { object.name = this.name; }
5996			if ( this.castShadow === true ) { object.castShadow = true; }
5997			if ( this.receiveShadow === true ) { object.receiveShadow = true; }
5998			if ( this.visible === false ) { object.visible = false; }
5999			if ( this.frustumCulled === false ) { object.frustumCulled = false; }
6000			if ( this.renderOrder !== 0 ) { object.renderOrder = this.renderOrder; }
6001			if ( JSON.stringify( this.userData ) !== '{}' ) { object.userData = this.userData; }
6002
6003			object.layers = this.layers.mask;
6004			object.matrix = this.matrix.toArray();
6005
6006			if ( this.matrixAutoUpdate === false ) { object.matrixAutoUpdate = false; }
6007
6008			// object specific properties
6009
6010			if ( this.isInstancedMesh ) {
6011
6012				object.type = 'InstancedMesh';
6013				object.count = this.count;
6014				object.instanceMatrix = this.instanceMatrix.toJSON();
6015
6016			}
6017
6018			//
6019
6020			function serialize( library, element ) {
6021
6022				if ( library[ element.uuid ] === undefined ) {
6023
6024					library[ element.uuid ] = element.toJSON( meta );
6025
6026				}
6027
6028				return element.uuid;
6029
6030			}
6031
6032			if ( this.isMesh || this.isLine || this.isPoints ) {
6033
6034				object.geometry = serialize( meta.geometries, this.geometry );
6035
6036				var parameters = this.geometry.parameters;
6037
6038				if ( parameters !== undefined && parameters.shapes !== undefined ) {
6039
6040					var shapes = parameters.shapes;
6041
6042					if ( Array.isArray( shapes ) ) {
6043
6044						for ( var i = 0, l = shapes.length; i < l; i ++ ) {
6045
6046							var shape = shapes[ i ];
6047
6048							serialize( meta.shapes, shape );
6049
6050						}
6051
6052					} else {
6053
6054						serialize( meta.shapes, shapes );
6055
6056					}
6057
6058				}
6059
6060			}
6061
6062			if ( this.material !== undefined ) {
6063
6064				if ( Array.isArray( this.material ) ) {
6065
6066					var uuids = [];
6067
6068					for ( var i$1 = 0, l$1 = this.material.length; i$1 < l$1; i$1 ++ ) {
6069
6070						uuids.push( serialize( meta.materials, this.material[ i$1 ] ) );
6071
6072					}
6073
6074					object.material = uuids;
6075
6076				} else {
6077
6078					object.material = serialize( meta.materials, this.material );
6079
6080				}
6081
6082			}
6083
6084			//
6085
6086			if ( this.children.length > 0 ) {
6087
6088				object.children = [];
6089
6090				for ( var i$2 = 0; i$2 < this.children.length; i$2 ++ ) {
6091
6092					object.children.push( this.children[ i$2 ].toJSON( meta ).object );
6093
6094				}
6095
6096			}
6097
6098			if ( isRootObject ) {
6099
6100				var geometries = extractFromCache( meta.geometries );
6101				var materials = extractFromCache( meta.materials );
6102				var textures = extractFromCache( meta.textures );
6103				var images = extractFromCache( meta.images );
6104				var shapes$1 = extractFromCache( meta.shapes );
6105
6106				if ( geometries.length > 0 ) { output.geometries = geometries; }
6107				if ( materials.length > 0 ) { output.materials = materials; }
6108				if ( textures.length > 0 ) { output.textures = textures; }
6109				if ( images.length > 0 ) { output.images = images; }
6110				if ( shapes$1.length > 0 ) { output.shapes = shapes$1; }
6111
6112			}
6113
6114			output.object = object;
6115
6116			return output;
6117
6118			// extract data from the cache hash
6119			// remove metadata on each item
6120			// and return as array
6121			function extractFromCache( cache ) {
6122
6123				var values = [];
6124				for ( var key in cache ) {
6125
6126					var data = cache[ key ];
6127					delete data.metadata;
6128					values.push( data );
6129
6130				}
6131
6132				return values;
6133
6134			}
6135
6136		},
6137
6138		clone: function ( recursive ) {
6139
6140			return new this.constructor().copy( this, recursive );
6141
6142		},
6143
6144		copy: function ( source, recursive ) {
6145
6146			if ( recursive === undefined ) { recursive = true; }
6147
6148			this.name = source.name;
6149
6150			this.up.copy( source.up );
6151
6152			this.position.copy( source.position );
6153			this.quaternion.copy( source.quaternion );
6154			this.scale.copy( source.scale );
6155
6156			this.matrix.copy( source.matrix );
6157			this.matrixWorld.copy( source.matrixWorld );
6158
6159			this.matrixAutoUpdate = source.matrixAutoUpdate;
6160			this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
6161
6162			this.layers.mask = source.layers.mask;
6163			this.visible = source.visible;
6164
6165			this.castShadow = source.castShadow;
6166			this.receiveShadow = source.receiveShadow;
6167
6168			this.frustumCulled = source.frustumCulled;
6169			this.renderOrder = source.renderOrder;
6170
6171			this.userData = JSON.parse( JSON.stringify( source.userData ) );
6172
6173			if ( recursive === true ) {
6174
6175				for ( var i = 0; i < source.children.length; i ++ ) {
6176
6177					var child = source.children[ i ];
6178					this.add( child.clone() );
6179
6180				}
6181
6182			}
6183
6184			return this;
6185
6186		}
6187
6188	} );
6189
6190	/**
6191	 * @author mrdoob / http://mrdoob.com/
6192	 */
6193
6194	function Scene() {
6195
6196		Object3D.call( this );
6197
6198		this.type = 'Scene';
6199
6200		this.background = null;
6201		this.environment = null;
6202		this.fog = null;
6203
6204		this.overrideMaterial = null;
6205
6206		this.autoUpdate = true; // checked by the renderer
6207
6208		if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
6209
6210			__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef
6211
6212		}
6213
6214	}
6215
6216	Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
6217
6218		constructor: Scene,
6219
6220		isScene: true,
6221
6222		copy: function ( source, recursive ) {
6223
6224			Object3D.prototype.copy.call( this, source, recursive );
6225
6226			if ( source.background !== null ) { this.background = source.background.clone(); }
6227			if ( source.environment !== null ) { this.environment = source.environment.clone(); }
6228			if ( source.fog !== null ) { this.fog = source.fog.clone(); }
6229
6230			if ( source.overrideMaterial !== null ) { this.overrideMaterial = source.overrideMaterial.clone(); }
6231
6232			this.autoUpdate = source.autoUpdate;
6233			this.matrixAutoUpdate = source.matrixAutoUpdate;
6234
6235			return this;
6236
6237		},
6238
6239		toJSON: function ( meta ) {
6240
6241			var data = Object3D.prototype.toJSON.call( this, meta );
6242
6243			if ( this.background !== null ) { data.object.background = this.background.toJSON( meta ); }
6244			if ( this.environment !== null ) { data.object.environment = this.environment.toJSON( meta ); }
6245			if ( this.fog !== null ) { data.object.fog = this.fog.toJSON(); }
6246
6247			return data;
6248
6249		},
6250
6251		dispose: function () {
6252
6253			this.dispatchEvent( { type: 'dispose' } );
6254
6255		}
6256
6257	} );
6258
6259	var _points = [
6260		new Vector3(),
6261		new Vector3(),
6262		new Vector3(),
6263		new Vector3(),
6264		new Vector3(),
6265		new Vector3(),
6266		new Vector3(),
6267		new Vector3()
6268	];
6269
6270	var _vector$1 = new Vector3();
6271
6272	var _box = new Box3();
6273
6274	// triangle centered vertices
6275
6276	var _v0 = new Vector3();
6277	var _v1$2 = new Vector3();
6278	var _v2 = new Vector3();
6279
6280	// triangle edge vectors
6281
6282	var _f0 = new Vector3();
6283	var _f1 = new Vector3();
6284	var _f2 = new Vector3();
6285
6286	var _center = new Vector3();
6287	var _extents = new Vector3();
6288	var _triangleNormal = new Vector3();
6289	var _testAxis = new Vector3();
6290
6291	/**
6292	 * @author bhouston / http://clara.io
6293	 * @author WestLangley / http://github.com/WestLangley
6294	 */
6295
6296	function Box3( min, max ) {
6297
6298		this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );
6299		this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );
6300
6301	}
6302
6303
6304	Object.assign( Box3.prototype, {
6305
6306		isBox3: true,
6307
6308		set: function ( min, max ) {
6309
6310			this.min.copy( min );
6311			this.max.copy( max );
6312
6313			return this;
6314
6315		},
6316
6317		setFromArray: function ( array ) {
6318
6319			var minX = + Infinity;
6320			var minY = + Infinity;
6321			var minZ = + Infinity;
6322
6323			var maxX = - Infinity;
6324			var maxY = - Infinity;
6325			var maxZ = - Infinity;
6326
6327			for ( var i = 0, l = array.length; i < l; i += 3 ) {
6328
6329				var x = array[ i ];
6330				var y = array[ i + 1 ];
6331				var z = array[ i + 2 ];
6332
6333				if ( x < minX ) { minX = x; }
6334				if ( y < minY ) { minY = y; }
6335				if ( z < minZ ) { minZ = z; }
6336
6337				if ( x > maxX ) { maxX = x; }
6338				if ( y > maxY ) { maxY = y; }
6339				if ( z > maxZ ) { maxZ = z; }
6340
6341			}
6342
6343			this.min.set( minX, minY, minZ );
6344			this.max.set( maxX, maxY, maxZ );
6345
6346			return this;
6347
6348		},
6349
6350		setFromBufferAttribute: function ( attribute ) {
6351
6352			var minX = + Infinity;
6353			var minY = + Infinity;
6354			var minZ = + Infinity;
6355
6356			var maxX = - Infinity;
6357			var maxY = - Infinity;
6358			var maxZ = - Infinity;
6359
6360			for ( var i = 0, l = attribute.count; i < l; i ++ ) {
6361
6362				var x = attribute.getX( i );
6363				var y = attribute.getY( i );
6364				var z = attribute.getZ( i );
6365
6366				if ( x < minX ) { minX = x; }
6367				if ( y < minY ) { minY = y; }
6368				if ( z < minZ ) { minZ = z; }
6369
6370				if ( x > maxX ) { maxX = x; }
6371				if ( y > maxY ) { maxY = y; }
6372				if ( z > maxZ ) { maxZ = z; }
6373
6374			}
6375
6376			this.min.set( minX, minY, minZ );
6377			this.max.set( maxX, maxY, maxZ );
6378
6379			return this;
6380
6381		},
6382
6383		setFromPoints: function ( points ) {
6384
6385			this.makeEmpty();
6386
6387			for ( var i = 0, il = points.length; i < il; i ++ ) {
6388
6389				this.expandByPoint( points[ i ] );
6390
6391			}
6392
6393			return this;
6394
6395		},
6396
6397		setFromCenterAndSize: function ( center, size ) {
6398
6399			var halfSize = _vector$1.copy( size ).multiplyScalar( 0.5 );
6400
6401			this.min.copy( center ).sub( halfSize );
6402			this.max.copy( center ).add( halfSize );
6403
6404			return this;
6405
6406		},
6407
6408		setFromObject: function ( object ) {
6409
6410			this.makeEmpty();
6411
6412			return this.expandByObject( object );
6413
6414		},
6415
6416		clone: function () {
6417
6418			return new this.constructor().copy( this );
6419
6420		},
6421
6422		copy: function ( box ) {
6423
6424			this.min.copy( box.min );
6425			this.max.copy( box.max );
6426
6427			return this;
6428
6429		},
6430
6431		makeEmpty: function () {
6432
6433			this.min.x = this.min.y = this.min.z = + Infinity;
6434			this.max.x = this.max.y = this.max.z = - Infinity;
6435
6436			return this;
6437
6438		},
6439
6440		isEmpty: function () {
6441
6442			// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
6443
6444			return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
6445
6446		},
6447
6448		getCenter: function ( target ) {
6449
6450			if ( target === undefined ) {
6451
6452				console.warn( 'THREE.Box3: .getCenter() target is now required' );
6453				target = new Vector3();
6454
6455			}
6456
6457			return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
6458
6459		},
6460
6461		getSize: function ( target ) {
6462
6463			if ( target === undefined ) {
6464
6465				console.warn( 'THREE.Box3: .getSize() target is now required' );
6466				target = new Vector3();
6467
6468			}
6469
6470			return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min );
6471
6472		},
6473
6474		expandByPoint: function ( point ) {
6475
6476			this.min.min( point );
6477			this.max.max( point );
6478
6479			return this;
6480
6481		},
6482
6483		expandByVector: function ( vector ) {
6484
6485			this.min.sub( vector );
6486			this.max.add( vector );
6487
6488			return this;
6489
6490		},
6491
6492		expandByScalar: function ( scalar ) {
6493
6494			this.min.addScalar( - scalar );
6495			this.max.addScalar( scalar );
6496
6497			return this;
6498
6499		},
6500
6501		expandByObject: function ( object ) {
6502
6503			// Computes the world-axis-aligned bounding box of an object (including its children),
6504			// accounting for both the object's, and children's, world transforms
6505
6506			object.updateWorldMatrix( false, false );
6507
6508			var geometry = object.geometry;
6509
6510			if ( geometry !== undefined ) {
6511
6512				if ( geometry.boundingBox === null ) {
6513
6514					geometry.computeBoundingBox();
6515
6516				}
6517
6518				_box.copy( geometry.boundingBox );
6519				_box.applyMatrix4( object.matrixWorld );
6520
6521				this.union( _box );
6522
6523			}
6524
6525			var children = object.children;
6526
6527			for ( var i = 0, l = children.length; i < l; i ++ ) {
6528
6529				this.expandByObject( children[ i ] );
6530
6531			}
6532
6533			return this;
6534
6535		},
6536
6537		containsPoint: function ( point ) {
6538
6539			return point.x < this.min.x || point.x > this.max.x ||
6540				point.y < this.min.y || point.y > this.max.y ||
6541				point.z < this.min.z || point.z > this.max.z ? false : true;
6542
6543		},
6544
6545		containsBox: function ( box ) {
6546
6547			return this.min.x <= box.min.x && box.max.x <= this.max.x &&
6548				this.min.y <= box.min.y && box.max.y <= this.max.y &&
6549				this.min.z <= box.min.z && box.max.z <= this.max.z;
6550
6551		},
6552
6553		getParameter: function ( point, target ) {
6554
6555			// This can potentially have a divide by zero if the box
6556			// has a size dimension of 0.
6557
6558			if ( target === undefined ) {
6559
6560				console.warn( 'THREE.Box3: .getParameter() target is now required' );
6561				target = new Vector3();
6562
6563			}
6564
6565			return target.set(
6566				( point.x - this.min.x ) / ( this.max.x - this.min.x ),
6567				( point.y - this.min.y ) / ( this.max.y - this.min.y ),
6568				( point.z - this.min.z ) / ( this.max.z - this.min.z )
6569			);
6570
6571		},
6572
6573		intersectsBox: function ( box ) {
6574
6575			// using 6 splitting planes to rule out intersections.
6576			return box.max.x < this.min.x || box.min.x > this.max.x ||
6577				box.max.y < this.min.y || box.min.y > this.max.y ||
6578				box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
6579
6580		},
6581
6582		intersectsSphere: function ( sphere ) {
6583
6584			// Find the point on the AABB closest to the sphere center.
6585			this.clampPoint( sphere.center, _vector$1 );
6586
6587			// If that point is inside the sphere, the AABB and sphere intersect.
6588			return _vector$1.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
6589
6590		},
6591
6592		intersectsPlane: function ( plane ) {
6593
6594			// We compute the minimum and maximum dot product values. If those values
6595			// are on the same side (back or front) of the plane, then there is no intersection.
6596
6597			var min, max;
6598
6599			if ( plane.normal.x > 0 ) {
6600
6601				min = plane.normal.x * this.min.x;
6602				max = plane.normal.x * this.max.x;
6603
6604			} else {
6605
6606				min = plane.normal.x * this.max.x;
6607				max = plane.normal.x * this.min.x;
6608
6609			}
6610
6611			if ( plane.normal.y > 0 ) {
6612
6613				min += plane.normal.y * this.min.y;
6614				max += plane.normal.y * this.max.y;
6615
6616			} else {
6617
6618				min += plane.normal.y * this.max.y;
6619				max += plane.normal.y * this.min.y;
6620
6621			}
6622
6623			if ( plane.normal.z > 0 ) {
6624
6625				min += plane.normal.z * this.min.z;
6626				max += plane.normal.z * this.max.z;
6627
6628			} else {
6629
6630				min += plane.normal.z * this.max.z;
6631				max += plane.normal.z * this.min.z;
6632
6633			}
6634
6635			return ( min <= - plane.constant && max >= - plane.constant );
6636
6637		},
6638
6639		intersectsTriangle: function ( triangle ) {
6640
6641			if ( this.isEmpty() ) {
6642
6643				return false;
6644
6645			}
6646
6647			// compute box center and extents
6648			this.getCenter( _center );
6649			_extents.subVectors( this.max, _center );
6650
6651			// translate triangle to aabb origin
6652			_v0.subVectors( triangle.a, _center );
6653			_v1$2.subVectors( triangle.b, _center );
6654			_v2.subVectors( triangle.c, _center );
6655
6656			// compute edge vectors for triangle
6657			_f0.subVectors( _v1$2, _v0 );
6658			_f1.subVectors( _v2, _v1$2 );
6659			_f2.subVectors( _v0, _v2 );
6660
6661			// test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb
6662			// 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
6663			// axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned)
6664			var axes = [
6665				0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y,
6666				_f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x,
6667				- _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0
6668			];
6669			if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) {
6670
6671				return false;
6672
6673			}
6674
6675			// test 3 face normals from the aabb
6676			axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];
6677			if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) {
6678
6679				return false;
6680
6681			}
6682
6683			// finally testing the face normal of the triangle
6684			// use already existing triangle edge vectors here
6685			_triangleNormal.crossVectors( _f0, _f1 );
6686			axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ];
6687
6688			return satForAxes( axes, _v0, _v1$2, _v2, _extents );
6689
6690		},
6691
6692		clampPoint: function ( point, target ) {
6693
6694			if ( target === undefined ) {
6695
6696				console.warn( 'THREE.Box3: .clampPoint() target is now required' );
6697				target = new Vector3();
6698
6699			}
6700
6701			return target.copy( point ).clamp( this.min, this.max );
6702
6703		},
6704
6705		distanceToPoint: function ( point ) {
6706
6707			var clampedPoint = _vector$1.copy( point ).clamp( this.min, this.max );
6708
6709			return clampedPoint.sub( point ).length();
6710
6711		},
6712
6713		getBoundingSphere: function ( target ) {
6714
6715			if ( target === undefined ) {
6716
6717				console.error( 'THREE.Box3: .getBoundingSphere() target is now required' );
6718				//target = new Sphere(); // removed to avoid cyclic dependency
6719
6720			}
6721
6722			this.getCenter( target.center );
6723
6724			target.radius = this.getSize( _vector$1 ).length() * 0.5;
6725
6726			return target;
6727
6728		},
6729
6730		intersect: function ( box ) {
6731
6732			this.min.max( box.min );
6733			this.max.min( box.max );
6734
6735			// 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.
6736			if ( this.isEmpty() ) { this.makeEmpty(); }
6737
6738			return this;
6739
6740		},
6741
6742		union: function ( box ) {
6743
6744			this.min.min( box.min );
6745			this.max.max( box.max );
6746
6747			return this;
6748
6749		},
6750
6751		applyMatrix4: function ( matrix ) {
6752
6753			// transform of empty box is an empty box.
6754			if ( this.isEmpty() ) { return this; }
6755
6756			// NOTE: I am using a binary pattern to specify all 2^3 combinations below
6757			_points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000
6758			_points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001
6759			_points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010
6760			_points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011
6761			_points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100
6762			_points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101
6763			_points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110
6764			_points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111
6765
6766			this.setFromPoints( _points );
6767
6768			return this;
6769
6770		},
6771
6772		translate: function ( offset ) {
6773
6774			this.min.add( offset );
6775			this.max.add( offset );
6776
6777			return this;
6778
6779		},
6780
6781		equals: function ( box ) {
6782
6783			return box.min.equals( this.min ) && box.max.equals( this.max );
6784
6785		}
6786
6787	} );
6788
6789	function satForAxes( axes, v0, v1, v2, extents ) {
6790
6791		for ( var i = 0, j = axes.length - 3; i <= j; i += 3 ) {
6792
6793			_testAxis.fromArray( axes, i );
6794			// project the aabb onto the seperating axis
6795			var r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z );
6796			// project all 3 vertices of the triangle onto the seperating axis
6797			var p0 = v0.dot( _testAxis );
6798			var p1 = v1.dot( _testAxis );
6799			var p2 = v2.dot( _testAxis );
6800			// actual test, basically see if either of the most extreme of the triangle points intersects r
6801			if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) {
6802
6803				// points of the projected triangle are outside the projected half-length of the aabb
6804				// the axis is seperating and we can exit
6805				return false;
6806
6807			}
6808
6809		}
6810
6811		return true;
6812
6813	}
6814
6815	var _box$1 = new Box3();
6816
6817	/**
6818	 * @author bhouston / http://clara.io
6819	 * @author mrdoob / http://mrdoob.com/
6820	 */
6821
6822	function Sphere( center, radius ) {
6823
6824		this.center = ( center !== undefined ) ? center : new Vector3();
6825		this.radius = ( radius !== undefined ) ? radius : - 1;
6826
6827	}
6828
6829	Object.assign( Sphere.prototype, {
6830
6831		set: function ( center, radius ) {
6832
6833			this.center.copy( center );
6834			this.radius = radius;
6835
6836			return this;
6837
6838		},
6839
6840		setFromPoints: function ( points, optionalCenter ) {
6841
6842			var center = this.center;
6843
6844			if ( optionalCenter !== undefined ) {
6845
6846				center.copy( optionalCenter );
6847
6848			} else {
6849
6850				_box$1.setFromPoints( points ).getCenter( center );
6851
6852			}
6853
6854			var maxRadiusSq = 0;
6855
6856			for ( var i = 0, il = points.length; i < il; i ++ ) {
6857
6858				maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
6859
6860			}
6861
6862			this.radius = Math.sqrt( maxRadiusSq );
6863
6864			return this;
6865
6866		},
6867
6868		clone: function () {
6869
6870			return new this.constructor().copy( this );
6871
6872		},
6873
6874		copy: function ( sphere ) {
6875
6876			this.center.copy( sphere.center );
6877			this.radius = sphere.radius;
6878
6879			return this;
6880
6881		},
6882
6883		isEmpty: function () {
6884
6885			return ( this.radius < 0 );
6886
6887		},
6888
6889		makeEmpty: function () {
6890
6891			this.center.set( 0, 0, 0 );
6892			this.radius = - 1;
6893
6894			return this;
6895
6896		},
6897
6898		containsPoint: function ( point ) {
6899
6900			return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
6901
6902		},
6903
6904		distanceToPoint: function ( point ) {
6905
6906			return ( point.distanceTo( this.center ) - this.radius );
6907
6908		},
6909
6910		intersectsSphere: function ( sphere ) {
6911
6912			var radiusSum = this.radius + sphere.radius;
6913
6914			return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
6915
6916		},
6917
6918		intersectsBox: function ( box ) {
6919
6920			return box.intersectsSphere( this );
6921
6922		},
6923
6924		intersectsPlane: function ( plane ) {
6925
6926			return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;
6927
6928		},
6929
6930		clampPoint: function ( point, target ) {
6931
6932			var deltaLengthSq = this.center.distanceToSquared( point );
6933
6934			if ( target === undefined ) {
6935
6936				console.warn( 'THREE.Sphere: .clampPoint() target is now required' );
6937				target = new Vector3();
6938
6939			}
6940
6941			target.copy( point );
6942
6943			if ( deltaLengthSq > ( this.radius * this.radius ) ) {
6944
6945				target.sub( this.center ).normalize();
6946				target.multiplyScalar( this.radius ).add( this.center );
6947
6948			}
6949
6950			return target;
6951
6952		},
6953
6954		getBoundingBox: function ( target ) {
6955
6956			if ( target === undefined ) {
6957
6958				console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' );
6959				target = new Box3();
6960
6961			}
6962
6963			if ( this.isEmpty() ) {
6964
6965				// Empty sphere produces empty bounding box
6966				target.makeEmpty();
6967				return target;
6968
6969			}
6970
6971			target.set( this.center, this.center );
6972			target.expandByScalar( this.radius );
6973
6974			return target;
6975
6976		},
6977
6978		applyMatrix4: function ( matrix ) {
6979
6980			this.center.applyMatrix4( matrix );
6981			this.radius = this.radius * matrix.getMaxScaleOnAxis();
6982
6983			return this;
6984
6985		},
6986
6987		translate: function ( offset ) {
6988
6989			this.center.add( offset );
6990
6991			return this;
6992
6993		},
6994
6995		equals: function ( sphere ) {
6996
6997			return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
6998
6999		}
7000
7001	} );
7002
7003	var _vector$2 = new Vector3();
7004	var _segCenter = new Vector3();
7005	var _segDir = new Vector3();
7006	var _diff = new Vector3();
7007
7008	var _edge1 = new Vector3();
7009	var _edge2 = new Vector3();
7010	var _normal = new Vector3();
7011
7012	/**
7013	 * @author bhouston / http://clara.io
7014	 */
7015
7016	function Ray( origin, direction ) {
7017
7018		this.origin = ( origin !== undefined ) ? origin : new Vector3();
7019		this.direction = ( direction !== undefined ) ? direction : new Vector3( 0, 0, - 1 );
7020
7021	}
7022
7023	Object.assign( Ray.prototype, {
7024
7025		set: function ( origin, direction ) {
7026
7027			this.origin.copy( origin );
7028			this.direction.copy( direction );
7029
7030			return this;
7031
7032		},
7033
7034		clone: function () {
7035
7036			return new this.constructor().copy( this );
7037
7038		},
7039
7040		copy: function ( ray ) {
7041
7042			this.origin.copy( ray.origin );
7043			this.direction.copy( ray.direction );
7044
7045			return this;
7046
7047		},
7048
7049		at: function ( t, target ) {
7050
7051			if ( target === undefined ) {
7052
7053				console.warn( 'THREE.Ray: .at() target is now required' );
7054				target = new Vector3();
7055
7056			}
7057
7058			return target.copy( this.direction ).multiplyScalar( t ).add( this.origin );
7059
7060		},
7061
7062		lookAt: function ( v ) {
7063
7064			this.direction.copy( v ).sub( this.origin ).normalize();
7065
7066			return this;
7067
7068		},
7069
7070		recast: function ( t ) {
7071
7072			this.origin.copy( this.at( t, _vector$2 ) );
7073
7074			return this;
7075
7076		},
7077
7078		closestPointToPoint: function ( point, target ) {
7079
7080			if ( target === undefined ) {
7081
7082				console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' );
7083				target = new Vector3();
7084
7085			}
7086
7087			target.subVectors( point, this.origin );
7088
7089			var directionDistance = target.dot( this.direction );
7090
7091			if ( directionDistance < 0 ) {
7092
7093				return target.copy( this.origin );
7094
7095			}
7096
7097			return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
7098
7099		},
7100
7101		distanceToPoint: function ( point ) {
7102
7103			return Math.sqrt( this.distanceSqToPoint( point ) );
7104
7105		},
7106
7107		distanceSqToPoint: function ( point ) {
7108
7109			var directionDistance = _vector$2.subVectors( point, this.origin ).dot( this.direction );
7110
7111			// point behind the ray
7112
7113			if ( directionDistance < 0 ) {
7114
7115				return this.origin.distanceToSquared( point );
7116
7117			}
7118
7119			_vector$2.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
7120
7121			return _vector$2.distanceToSquared( point );
7122
7123		},
7124
7125		distanceSqToSegment: function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
7126
7127			// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h
7128			// It returns the min distance between the ray and the segment
7129			// defined by v0 and v1
7130			// It can also set two optional targets :
7131			// - The closest point on the ray
7132			// - The closest point on the segment
7133
7134			_segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
7135			_segDir.copy( v1 ).sub( v0 ).normalize();
7136			_diff.copy( this.origin ).sub( _segCenter );
7137
7138			var segExtent = v0.distanceTo( v1 ) * 0.5;
7139			var a01 = - this.direction.dot( _segDir );
7140			var b0 = _diff.dot( this.direction );
7141			var b1 = - _diff.dot( _segDir );
7142			var c = _diff.lengthSq();
7143			var det = Math.abs( 1 - a01 * a01 );
7144			var s0, s1, sqrDist, extDet;
7145
7146			if ( det > 0 ) {
7147
7148				// The ray and segment are not parallel.
7149
7150				s0 = a01 * b1 - b0;
7151				s1 = a01 * b0 - b1;
7152				extDet = segExtent * det;
7153
7154				if ( s0 >= 0 ) {
7155
7156					if ( s1 >= - extDet ) {
7157
7158						if ( s1 <= extDet ) {
7159
7160							// region 0
7161							// Minimum at interior points of ray and segment.
7162
7163							var invDet = 1 / det;
7164							s0 *= invDet;
7165							s1 *= invDet;
7166							sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
7167
7168						} else {
7169
7170							// region 1
7171
7172							s1 = segExtent;
7173							s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
7174							sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7175
7176						}
7177
7178					} else {
7179
7180						// region 5
7181
7182						s1 = - segExtent;
7183						s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
7184						sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7185
7186					}
7187
7188				} else {
7189
7190					if ( s1 <= - extDet ) {
7191
7192						// region 4
7193
7194						s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
7195						s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
7196						sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7197
7198					} else if ( s1 <= extDet ) {
7199
7200						// region 3
7201
7202						s0 = 0;
7203						s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
7204						sqrDist = s1 * ( s1 + 2 * b1 ) + c;
7205
7206					} else {
7207
7208						// region 2
7209
7210						s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
7211						s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
7212						sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7213
7214					}
7215
7216				}
7217
7218			} else {
7219
7220				// Ray and segment are parallel.
7221
7222				s1 = ( a01 > 0 ) ? - segExtent : segExtent;
7223				s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
7224				sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7225
7226			}
7227
7228			if ( optionalPointOnRay ) {
7229
7230				optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
7231
7232			}
7233
7234			if ( optionalPointOnSegment ) {
7235
7236				optionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter );
7237
7238			}
7239
7240			return sqrDist;
7241
7242		},
7243
7244		intersectSphere: function ( sphere, target ) {
7245
7246			_vector$2.subVectors( sphere.center, this.origin );
7247			var tca = _vector$2.dot( this.direction );
7248			var d2 = _vector$2.dot( _vector$2 ) - tca * tca;
7249			var radius2 = sphere.radius * sphere.radius;
7250
7251			if ( d2 > radius2 ) { return null; }
7252
7253			var thc = Math.sqrt( radius2 - d2 );
7254
7255			// t0 = first intersect point - entrance on front of sphere
7256			var t0 = tca - thc;
7257
7258			// t1 = second intersect point - exit point on back of sphere
7259			var t1 = tca + thc;
7260
7261			// test to see if both t0 and t1 are behind the ray - if so, return null
7262			if ( t0 < 0 && t1 < 0 ) { return null; }
7263
7264			// test to see if t0 is behind the ray:
7265			// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
7266			// in order to always return an intersect point that is in front of the ray.
7267			if ( t0 < 0 ) { return this.at( t1, target ); }
7268
7269			// else t0 is in front of the ray, so return the first collision point scaled by t0
7270			return this.at( t0, target );
7271
7272		},
7273
7274		intersectsSphere: function ( sphere ) {
7275
7276			return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius );
7277
7278		},
7279
7280		distanceToPlane: function ( plane ) {
7281
7282			var denominator = plane.normal.dot( this.direction );
7283
7284			if ( denominator === 0 ) {
7285
7286				// line is coplanar, return origin
7287				if ( plane.distanceToPoint( this.origin ) === 0 ) {
7288
7289					return 0;
7290
7291				}
7292
7293				// Null is preferable to undefined since undefined means.... it is undefined
7294
7295				return null;
7296
7297			}
7298
7299			var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;
7300
7301			// Return if the ray never intersects the plane
7302
7303			return t >= 0 ? t : null;
7304
7305		},
7306
7307		intersectPlane: function ( plane, target ) {
7308
7309			var t = this.distanceToPlane( plane );
7310
7311			if ( t === null ) {
7312
7313				return null;
7314
7315			}
7316
7317			return this.at( t, target );
7318
7319		},
7320
7321		intersectsPlane: function ( plane ) {
7322
7323			// check if the ray lies on the plane first
7324
7325			var distToPoint = plane.distanceToPoint( this.origin );
7326
7327			if ( distToPoint === 0 ) {
7328
7329				return true;
7330
7331			}
7332
7333			var denominator = plane.normal.dot( this.direction );
7334
7335			if ( denominator * distToPoint < 0 ) {
7336
7337				return true;
7338
7339			}
7340
7341			// ray origin is behind the plane (and is pointing behind it)
7342
7343			return false;
7344
7345		},
7346
7347		intersectBox: function ( box, target ) {
7348
7349			var tmin, tmax, tymin, tymax, tzmin, tzmax;
7350
7351			var invdirx = 1 / this.direction.x,
7352				invdiry = 1 / this.direction.y,
7353				invdirz = 1 / this.direction.z;
7354
7355			var origin = this.origin;
7356
7357			if ( invdirx >= 0 ) {
7358
7359				tmin = ( box.min.x - origin.x ) * invdirx;
7360				tmax = ( box.max.x - origin.x ) * invdirx;
7361
7362			} else {
7363
7364				tmin = ( box.max.x - origin.x ) * invdirx;
7365				tmax = ( box.min.x - origin.x ) * invdirx;
7366
7367			}
7368
7369			if ( invdiry >= 0 ) {
7370
7371				tymin = ( box.min.y - origin.y ) * invdiry;
7372				tymax = ( box.max.y - origin.y ) * invdiry;
7373
7374			} else {
7375
7376				tymin = ( box.max.y - origin.y ) * invdiry;
7377				tymax = ( box.min.y - origin.y ) * invdiry;
7378
7379			}
7380
7381			if ( ( tmin > tymax ) || ( tymin > tmax ) ) { return null; }
7382
7383			// These lines also handle the case where tmin or tmax is NaN
7384			// (result of 0 * Infinity). x !== x returns true if x is NaN
7385
7386			if ( tymin > tmin || tmin !== tmin ) { tmin = tymin; }
7387
7388			if ( tymax < tmax || tmax !== tmax ) { tmax = tymax; }
7389
7390			if ( invdirz >= 0 ) {
7391
7392				tzmin = ( box.min.z - origin.z ) * invdirz;
7393				tzmax = ( box.max.z - origin.z ) * invdirz;
7394
7395			} else {
7396
7397				tzmin = ( box.max.z - origin.z ) * invdirz;
7398				tzmax = ( box.min.z - origin.z ) * invdirz;
7399
7400			}
7401
7402			if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) { return null; }
7403
7404			if ( tzmin > tmin || tmin !== tmin ) { tmin = tzmin; }
7405
7406			if ( tzmax < tmax || tmax !== tmax ) { tmax = tzmax; }
7407
7408			//return point closest to the ray (positive side)
7409
7410			if ( tmax < 0 ) { return null; }
7411
7412			return this.at( tmin >= 0 ? tmin : tmax, target );
7413
7414		},
7415
7416		intersectsBox: function ( box ) {
7417
7418			return this.intersectBox( box, _vector$2 ) !== null;
7419
7420		},
7421
7422		intersectTriangle: function ( a, b, c, backfaceCulling, target ) {
7423
7424			// Compute the offset origin, edges, and normal.
7425
7426			// from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
7427
7428			_edge1.subVectors( b, a );
7429			_edge2.subVectors( c, a );
7430			_normal.crossVectors( _edge1, _edge2 );
7431
7432			// Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
7433			// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
7434			//   |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
7435			//   |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
7436			//   |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
7437			var DdN = this.direction.dot( _normal );
7438			var sign;
7439
7440			if ( DdN > 0 ) {
7441
7442				if ( backfaceCulling ) { return null; }
7443				sign = 1;
7444
7445			} else if ( DdN < 0 ) {
7446
7447				sign = - 1;
7448				DdN = - DdN;
7449
7450			} else {
7451
7452				return null;
7453
7454			}
7455
7456			_diff.subVectors( this.origin, a );
7457			var DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) );
7458
7459			// b1 < 0, no intersection
7460			if ( DdQxE2 < 0 ) {
7461
7462				return null;
7463
7464			}
7465
7466			var DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) );
7467
7468			// b2 < 0, no intersection
7469			if ( DdE1xQ < 0 ) {
7470
7471				return null;
7472
7473			}
7474
7475			// b1+b2 > 1, no intersection
7476			if ( DdQxE2 + DdE1xQ > DdN ) {
7477
7478				return null;
7479
7480			}
7481
7482			// Line intersects triangle, check if ray does.
7483			var QdN = - sign * _diff.dot( _normal );
7484
7485			// t < 0, no intersection
7486			if ( QdN < 0 ) {
7487
7488				return null;
7489
7490			}
7491
7492			// Ray intersects triangle.
7493			return this.at( QdN / DdN, target );
7494
7495		},
7496
7497		applyMatrix4: function ( matrix4 ) {
7498
7499			this.origin.applyMatrix4( matrix4 );
7500			this.direction.transformDirection( matrix4 );
7501
7502			return this;
7503
7504		},
7505
7506		equals: function ( ray ) {
7507
7508			return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );
7509
7510		}
7511
7512	} );
7513
7514	/**
7515	 * @author bhouston / http://clara.io
7516	 */
7517
7518	var _vector1 = new Vector3();
7519	var _vector2 = new Vector3();
7520	var _normalMatrix = new Matrix3();
7521
7522	function Plane( normal, constant ) {
7523
7524		// normal is assumed to be normalized
7525
7526		this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
7527		this.constant = ( constant !== undefined ) ? constant : 0;
7528
7529	}
7530
7531	Object.assign( Plane.prototype, {
7532
7533		isPlane: true,
7534
7535		set: function ( normal, constant ) {
7536
7537			this.normal.copy( normal );
7538			this.constant = constant;
7539
7540			return this;
7541
7542		},
7543
7544		setComponents: function ( x, y, z, w ) {
7545
7546			this.normal.set( x, y, z );
7547			this.constant = w;
7548
7549			return this;
7550
7551		},
7552
7553		setFromNormalAndCoplanarPoint: function ( normal, point ) {
7554
7555			this.normal.copy( normal );
7556			this.constant = - point.dot( this.normal );
7557
7558			return this;
7559
7560		},
7561
7562		setFromCoplanarPoints: function ( a, b, c ) {
7563
7564			var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize();
7565
7566			// Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
7567
7568			this.setFromNormalAndCoplanarPoint( normal, a );
7569
7570			return this;
7571
7572		},
7573
7574		clone: function () {
7575
7576			return new this.constructor().copy( this );
7577
7578		},
7579
7580		copy: function ( plane ) {
7581
7582			this.normal.copy( plane.normal );
7583			this.constant = plane.constant;
7584
7585			return this;
7586
7587		},
7588
7589		normalize: function () {
7590
7591			// Note: will lead to a divide by zero if the plane is invalid.
7592
7593			var inverseNormalLength = 1.0 / this.normal.length();
7594			this.normal.multiplyScalar( inverseNormalLength );
7595			this.constant *= inverseNormalLength;
7596
7597			return this;
7598
7599		},
7600
7601		negate: function () {
7602
7603			this.constant *= - 1;
7604			this.normal.negate();
7605
7606			return this;
7607
7608		},
7609
7610		distanceToPoint: function ( point ) {
7611
7612			return this.normal.dot( point ) + this.constant;
7613
7614		},
7615
7616		distanceToSphere: function ( sphere ) {
7617
7618			return this.distanceToPoint( sphere.center ) - sphere.radius;
7619
7620		},
7621
7622		projectPoint: function ( point, target ) {
7623
7624			if ( target === undefined ) {
7625
7626				console.warn( 'THREE.Plane: .projectPoint() target is now required' );
7627				target = new Vector3();
7628
7629			}
7630
7631			return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point );
7632
7633		},
7634
7635		intersectLine: function ( line, target ) {
7636
7637			if ( target === undefined ) {
7638
7639				console.warn( 'THREE.Plane: .intersectLine() target is now required' );
7640				target = new Vector3();
7641
7642			}
7643
7644			var direction = line.delta( _vector1 );
7645
7646			var denominator = this.normal.dot( direction );
7647
7648			if ( denominator === 0 ) {
7649
7650				// line is coplanar, return origin
7651				if ( this.distanceToPoint( line.start ) === 0 ) {
7652
7653					return target.copy( line.start );
7654
7655				}
7656
7657				// Unsure if this is the correct method to handle this case.
7658				return undefined;
7659
7660			}
7661
7662			var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
7663
7664			if ( t < 0 || t > 1 ) {
7665
7666				return undefined;
7667
7668			}
7669
7670			return target.copy( direction ).multiplyScalar( t ).add( line.start );
7671
7672		},
7673
7674		intersectsLine: function ( line ) {
7675
7676			// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
7677
7678			var startSign = this.distanceToPoint( line.start );
7679			var endSign = this.distanceToPoint( line.end );
7680
7681			return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
7682
7683		},
7684
7685		intersectsBox: function ( box ) {
7686
7687			return box.intersectsPlane( this );
7688
7689		},
7690
7691		intersectsSphere: function ( sphere ) {
7692
7693			return sphere.intersectsPlane( this );
7694
7695		},
7696
7697		coplanarPoint: function ( target ) {
7698
7699			if ( target === undefined ) {
7700
7701				console.warn( 'THREE.Plane: .coplanarPoint() target is now required' );
7702				target = new Vector3();
7703
7704			}
7705
7706			return target.copy( this.normal ).multiplyScalar( - this.constant );
7707
7708		},
7709
7710		applyMatrix4: function ( matrix, optionalNormalMatrix ) {
7711
7712			var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix );
7713
7714			var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix );
7715
7716			var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
7717
7718			this.constant = - referencePoint.dot( normal );
7719
7720			return this;
7721
7722		},
7723
7724		translate: function ( offset ) {
7725
7726			this.constant -= offset.dot( this.normal );
7727
7728			return this;
7729
7730		},
7731
7732		equals: function ( plane ) {
7733
7734			return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
7735
7736		}
7737
7738	} );
7739
7740	/**
7741	 * @author bhouston / http://clara.io
7742	 * @author mrdoob / http://mrdoob.com/
7743	 */
7744
7745	var _v0$1 = new Vector3();
7746	var _v1$3 = new Vector3();
7747	var _v2$1 = new Vector3();
7748	var _v3 = new Vector3();
7749
7750	var _vab = new Vector3();
7751	var _vac = new Vector3();
7752	var _vbc = new Vector3();
7753	var _vap = new Vector3();
7754	var _vbp = new Vector3();
7755	var _vcp = new Vector3();
7756
7757	function Triangle( a, b, c ) {
7758
7759		this.a = ( a !== undefined ) ? a : new Vector3();
7760		this.b = ( b !== undefined ) ? b : new Vector3();
7761		this.c = ( c !== undefined ) ? c : new Vector3();
7762
7763	}
7764
7765	Object.assign( Triangle, {
7766
7767		getNormal: function ( a, b, c, target ) {
7768
7769			if ( target === undefined ) {
7770
7771				console.warn( 'THREE.Triangle: .getNormal() target is now required' );
7772				target = new Vector3();
7773
7774			}
7775
7776			target.subVectors( c, b );
7777			_v0$1.subVectors( a, b );
7778			target.cross( _v0$1 );
7779
7780			var targetLengthSq = target.lengthSq();
7781			if ( targetLengthSq > 0 ) {
7782
7783				return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) );
7784
7785			}
7786
7787			return target.set( 0, 0, 0 );
7788
7789		},
7790
7791		// static/instance method to calculate barycentric coordinates
7792		// based on: http://www.blackpawn.com/texts/pointinpoly/default.html
7793		getBarycoord: function ( point, a, b, c, target ) {
7794
7795			_v0$1.subVectors( c, a );
7796			_v1$3.subVectors( b, a );
7797			_v2$1.subVectors( point, a );
7798
7799			var dot00 = _v0$1.dot( _v0$1 );
7800			var dot01 = _v0$1.dot( _v1$3 );
7801			var dot02 = _v0$1.dot( _v2$1 );
7802			var dot11 = _v1$3.dot( _v1$3 );
7803			var dot12 = _v1$3.dot( _v2$1 );
7804
7805			var denom = ( dot00 * dot11 - dot01 * dot01 );
7806
7807			if ( target === undefined ) {
7808
7809				console.warn( 'THREE.Triangle: .getBarycoord() target is now required' );
7810				target = new Vector3();
7811
7812			}
7813
7814			// collinear or singular triangle
7815			if ( denom === 0 ) {
7816
7817				// arbitrary location outside of triangle?
7818				// not sure if this is the best idea, maybe should be returning undefined
7819				return target.set( - 2, - 1, - 1 );
7820
7821			}
7822
7823			var invDenom = 1 / denom;
7824			var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
7825			var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
7826
7827			// barycentric coordinates must always sum to 1
7828			return target.set( 1 - u - v, v, u );
7829
7830		},
7831
7832		containsPoint: function ( point, a, b, c ) {
7833
7834			Triangle.getBarycoord( point, a, b, c, _v3 );
7835
7836			return ( _v3.x >= 0 ) && ( _v3.y >= 0 ) && ( ( _v3.x + _v3.y ) <= 1 );
7837
7838		},
7839
7840		getUV: function ( point, p1, p2, p3, uv1, uv2, uv3, target ) {
7841
7842			this.getBarycoord( point, p1, p2, p3, _v3 );
7843
7844			target.set( 0, 0 );
7845			target.addScaledVector( uv1, _v3.x );
7846			target.addScaledVector( uv2, _v3.y );
7847			target.addScaledVector( uv3, _v3.z );
7848
7849			return target;
7850
7851		},
7852
7853		isFrontFacing: function ( a, b, c, direction ) {
7854
7855			_v0$1.subVectors( c, b );
7856			_v1$3.subVectors( a, b );
7857
7858			// strictly front facing
7859			return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false;
7860
7861		}
7862
7863	} );
7864
7865	Object.assign( Triangle.prototype, {
7866
7867		set: function ( a, b, c ) {
7868
7869			this.a.copy( a );
7870			this.b.copy( b );
7871			this.c.copy( c );
7872
7873			return this;
7874
7875		},
7876
7877		setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
7878
7879			this.a.copy( points[ i0 ] );
7880			this.b.copy( points[ i1 ] );
7881			this.c.copy( points[ i2 ] );
7882
7883			return this;
7884
7885		},
7886
7887		clone: function () {
7888
7889			return new this.constructor().copy( this );
7890
7891		},
7892
7893		copy: function ( triangle ) {
7894
7895			this.a.copy( triangle.a );
7896			this.b.copy( triangle.b );
7897			this.c.copy( triangle.c );
7898
7899			return this;
7900
7901		},
7902
7903		getArea: function () {
7904
7905			_v0$1.subVectors( this.c, this.b );
7906			_v1$3.subVectors( this.a, this.b );
7907
7908			return _v0$1.cross( _v1$3 ).length() * 0.5;
7909
7910		},
7911
7912		getMidpoint: function ( target ) {
7913
7914			if ( target === undefined ) {
7915
7916				console.warn( 'THREE.Triangle: .getMidpoint() target is now required' );
7917				target = new Vector3();
7918
7919			}
7920
7921			return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
7922
7923		},
7924
7925		getNormal: function ( target ) {
7926
7927			return Triangle.getNormal( this.a, this.b, this.c, target );
7928
7929		},
7930
7931		getPlane: function ( target ) {
7932
7933			if ( target === undefined ) {
7934
7935				console.warn( 'THREE.Triangle: .getPlane() target is now required' );
7936				target = new Plane();
7937
7938			}
7939
7940			return target.setFromCoplanarPoints( this.a, this.b, this.c );
7941
7942		},
7943
7944		getBarycoord: function ( point, target ) {
7945
7946			return Triangle.getBarycoord( point, this.a, this.b, this.c, target );
7947
7948		},
7949
7950		getUV: function ( point, uv1, uv2, uv3, target ) {
7951
7952			return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target );
7953
7954		},
7955
7956		containsPoint: function ( point ) {
7957
7958			return Triangle.containsPoint( point, this.a, this.b, this.c );
7959
7960		},
7961
7962		isFrontFacing: function ( direction ) {
7963
7964			return Triangle.isFrontFacing( this.a, this.b, this.c, direction );
7965
7966		},
7967
7968		intersectsBox: function ( box ) {
7969
7970			return box.intersectsTriangle( this );
7971
7972		},
7973
7974		closestPointToPoint: function ( p, target ) {
7975
7976			if ( target === undefined ) {
7977
7978				console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' );
7979				target = new Vector3();
7980
7981			}
7982
7983			var a = this.a, b = this.b, c = this.c;
7984			var v, w;
7985
7986			// algorithm thanks to Real-Time Collision Detection by Christer Ericson,
7987			// published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,
7988			// under the accompanying license; see chapter 5.1.5 for detailed explanation.
7989			// basically, we're distinguishing which of the voronoi regions of the triangle
7990			// the point lies in with the minimum amount of redundant computation.
7991
7992			_vab.subVectors( b, a );
7993			_vac.subVectors( c, a );
7994			_vap.subVectors( p, a );
7995			var d1 = _vab.dot( _vap );
7996			var d2 = _vac.dot( _vap );
7997			if ( d1 <= 0 && d2 <= 0 ) {
7998
7999				// vertex region of A; barycentric coords (1, 0, 0)
8000				return target.copy( a );
8001
8002			}
8003
8004			_vbp.subVectors( p, b );
8005			var d3 = _vab.dot( _vbp );
8006			var d4 = _vac.dot( _vbp );
8007			if ( d3 >= 0 && d4 <= d3 ) {
8008
8009				// vertex region of B; barycentric coords (0, 1, 0)
8010				return target.copy( b );
8011
8012			}
8013
8014			var vc = d1 * d4 - d3 * d2;
8015			if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) {
8016
8017				v = d1 / ( d1 - d3 );
8018				// edge region of AB; barycentric coords (1-v, v, 0)
8019				return target.copy( a ).addScaledVector( _vab, v );
8020
8021			}
8022
8023			_vcp.subVectors( p, c );
8024			var d5 = _vab.dot( _vcp );
8025			var d6 = _vac.dot( _vcp );
8026			if ( d6 >= 0 && d5 <= d6 ) {
8027
8028				// vertex region of C; barycentric coords (0, 0, 1)
8029				return target.copy( c );
8030
8031			}
8032
8033			var vb = d5 * d2 - d1 * d6;
8034			if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) {
8035
8036				w = d2 / ( d2 - d6 );
8037				// edge region of AC; barycentric coords (1-w, 0, w)
8038				return target.copy( a ).addScaledVector( _vac, w );
8039
8040			}
8041
8042			var va = d3 * d6 - d5 * d4;
8043			if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) {
8044
8045				_vbc.subVectors( c, b );
8046				w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) );
8047				// edge region of BC; barycentric coords (0, 1-w, w)
8048				return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC
8049
8050			}
8051
8052			// face region
8053			var denom = 1 / ( va + vb + vc );
8054			// u = va * denom
8055			v = vb * denom;
8056			w = vc * denom;
8057
8058			return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w );
8059
8060		},
8061
8062		equals: function ( triangle ) {
8063
8064			return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
8065
8066		}
8067
8068	} );
8069
8070	/**
8071	 * @author mrdoob / http://mrdoob.com/
8072	 */
8073
8074	var _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
8075		'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
8076		'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
8077		'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
8078		'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
8079		'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
8080		'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
8081		'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
8082		'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
8083		'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
8084		'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
8085		'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
8086		'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
8087		'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
8088		'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
8089		'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
8090		'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
8091		'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
8092		'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
8093		'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
8094		'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
8095		'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
8096		'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
8097		'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
8098
8099	var _hslA = { h: 0, s: 0, l: 0 };
8100	var _hslB = { h: 0, s: 0, l: 0 };
8101
8102	function Color( r, g, b ) {
8103
8104		if ( g === undefined && b === undefined ) {
8105
8106			// r is THREE.Color, hex or string
8107			return this.set( r );
8108
8109		}
8110
8111		return this.setRGB( r, g, b );
8112
8113	}
8114
8115	function hue2rgb( p, q, t ) {
8116
8117		if ( t < 0 ) { t += 1; }
8118		if ( t > 1 ) { t -= 1; }
8119		if ( t < 1 / 6 ) { return p + ( q - p ) * 6 * t; }
8120		if ( t < 1 / 2 ) { return q; }
8121		if ( t < 2 / 3 ) { return p + ( q - p ) * 6 * ( 2 / 3 - t ); }
8122		return p;
8123
8124	}
8125
8126	function SRGBToLinear( c ) {
8127
8128		return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
8129
8130	}
8131
8132	function LinearToSRGB( c ) {
8133
8134		return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
8135
8136	}
8137
8138	Object.assign( Color.prototype, {
8139
8140		isColor: true,
8141
8142		r: 1, g: 1, b: 1,
8143
8144		set: function ( value ) {
8145
8146			if ( value && value.isColor ) {
8147
8148				this.copy( value );
8149
8150			} else if ( typeof value === 'number' ) {
8151
8152				this.setHex( value );
8153
8154			} else if ( typeof value === 'string' ) {
8155
8156				this.setStyle( value );
8157
8158			}
8159
8160			return this;
8161
8162		},
8163
8164		setScalar: function ( scalar ) {
8165
8166			this.r = scalar;
8167			this.g = scalar;
8168			this.b = scalar;
8169
8170			return this;
8171
8172		},
8173
8174		setHex: function ( hex ) {
8175
8176			hex = Math.floor( hex );
8177
8178			this.r = ( hex >> 16 & 255 ) / 255;
8179			this.g = ( hex >> 8 & 255 ) / 255;
8180			this.b = ( hex & 255 ) / 255;
8181
8182			return this;
8183
8184		},
8185
8186		setRGB: function ( r, g, b ) {
8187
8188			this.r = r;
8189			this.g = g;
8190			this.b = b;
8191
8192			return this;
8193
8194		},
8195
8196		setHSL: function ( h, s, l ) {
8197
8198			// h,s,l ranges are in 0.0 - 1.0
8199			h = MathUtils.euclideanModulo( h, 1 );
8200			s = MathUtils.clamp( s, 0, 1 );
8201			l = MathUtils.clamp( l, 0, 1 );
8202
8203			if ( s === 0 ) {
8204
8205				this.r = this.g = this.b = l;
8206
8207			} else {
8208
8209				var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
8210				var q = ( 2 * l ) - p;
8211
8212				this.r = hue2rgb( q, p, h + 1 / 3 );
8213				this.g = hue2rgb( q, p, h );
8214				this.b = hue2rgb( q, p, h - 1 / 3 );
8215
8216			}
8217
8218			return this;
8219
8220		},
8221
8222		setStyle: function ( style ) {
8223
8224			function handleAlpha( string ) {
8225
8226				if ( string === undefined ) { return; }
8227
8228				if ( parseFloat( string ) < 1 ) {
8229
8230					console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
8231
8232				}
8233
8234			}
8235
8236
8237			var m;
8238
8239			if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
8240
8241				// rgb / hsl
8242
8243				var color;
8244				var name = m[ 1 ];
8245				var components = m[ 2 ];
8246
8247				switch ( name ) {
8248
8249					case 'rgb':
8250					case 'rgba':
8251
8252						if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
8253
8254							// rgb(255,0,0) rgba(255,0,0,0.5)
8255							this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
8256							this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
8257							this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
8258
8259							handleAlpha( color[ 5 ] );
8260
8261							return this;
8262
8263						}
8264
8265						if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
8266
8267							// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
8268							this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
8269							this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
8270							this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
8271
8272							handleAlpha( color[ 5 ] );
8273
8274							return this;
8275
8276						}
8277
8278						break;
8279
8280					case 'hsl':
8281					case 'hsla':
8282
8283						if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
8284
8285							// hsl(120,50%,50%) hsla(120,50%,50%,0.5)
8286							var h = parseFloat( color[ 1 ] ) / 360;
8287							var s = parseInt( color[ 2 ], 10 ) / 100;
8288							var l = parseInt( color[ 3 ], 10 ) / 100;
8289
8290							handleAlpha( color[ 5 ] );
8291
8292							return this.setHSL( h, s, l );
8293
8294						}
8295
8296						break;
8297
8298				}
8299
8300			} else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
8301
8302				// hex color
8303
8304				var hex = m[ 1 ];
8305				var size = hex.length;
8306
8307				if ( size === 3 ) {
8308
8309					// #ff0
8310					this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;
8311					this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
8312					this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;
8313
8314					return this;
8315
8316				} else if ( size === 6 ) {
8317
8318					// #ff0000
8319					this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;
8320					this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
8321					this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;
8322
8323					return this;
8324
8325				}
8326
8327			}
8328
8329			if ( style && style.length > 0 ) {
8330
8331				return this.setColorName( style );
8332
8333			}
8334
8335			return this;
8336
8337		},
8338
8339		setColorName: function ( style ) {
8340
8341			// color keywords
8342			var hex = _colorKeywords[ style ];
8343
8344			if ( hex !== undefined ) {
8345
8346				// red
8347				this.setHex( hex );
8348
8349			} else {
8350
8351				// unknown color
8352				console.warn( 'THREE.Color: Unknown color ' + style );
8353
8354			}
8355
8356			return this;
8357
8358		},
8359
8360		clone: function () {
8361
8362			return new this.constructor( this.r, this.g, this.b );
8363
8364		},
8365
8366		copy: function ( color ) {
8367
8368			this.r = color.r;
8369			this.g = color.g;
8370			this.b = color.b;
8371
8372			return this;
8373
8374		},
8375
8376		copyGammaToLinear: function ( color, gammaFactor ) {
8377
8378			if ( gammaFactor === undefined ) { gammaFactor = 2.0; }
8379
8380			this.r = Math.pow( color.r, gammaFactor );
8381			this.g = Math.pow( color.g, gammaFactor );
8382			this.b = Math.pow( color.b, gammaFactor );
8383
8384			return this;
8385
8386		},
8387
8388		copyLinearToGamma: function ( color, gammaFactor ) {
8389
8390			if ( gammaFactor === undefined ) { gammaFactor = 2.0; }
8391
8392			var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;
8393
8394			this.r = Math.pow( color.r, safeInverse );
8395			this.g = Math.pow( color.g, safeInverse );
8396			this.b = Math.pow( color.b, safeInverse );
8397
8398			return this;
8399
8400		},
8401
8402		convertGammaToLinear: function ( gammaFactor ) {
8403
8404			this.copyGammaToLinear( this, gammaFactor );
8405
8406			return this;
8407
8408		},
8409
8410		convertLinearToGamma: function ( gammaFactor ) {
8411
8412			this.copyLinearToGamma( this, gammaFactor );
8413
8414			return this;
8415
8416		},
8417
8418		copySRGBToLinear: function ( color ) {
8419
8420			this.r = SRGBToLinear( color.r );
8421			this.g = SRGBToLinear( color.g );
8422			this.b = SRGBToLinear( color.b );
8423
8424			return this;
8425
8426		},
8427
8428		copyLinearToSRGB: function ( color ) {
8429
8430			this.r = LinearToSRGB( color.r );
8431			this.g = LinearToSRGB( color.g );
8432			this.b = LinearToSRGB( color.b );
8433
8434			return this;
8435
8436		},
8437
8438		convertSRGBToLinear: function () {
8439
8440			this.copySRGBToLinear( this );
8441
8442			return this;
8443
8444		},
8445
8446		convertLinearToSRGB: function () {
8447
8448			this.copyLinearToSRGB( this );
8449
8450			return this;
8451
8452		},
8453
8454		getHex: function () {
8455
8456			return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
8457
8458		},
8459
8460		getHexString: function () {
8461
8462			return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
8463
8464		},
8465
8466		getHSL: function ( target ) {
8467
8468			// h,s,l ranges are in 0.0 - 1.0
8469
8470			if ( target === undefined ) {
8471
8472				console.warn( 'THREE.Color: .getHSL() target is now required' );
8473				target = { h: 0, s: 0, l: 0 };
8474
8475			}
8476
8477			var r = this.r, g = this.g, b = this.b;
8478
8479			var max = Math.max( r, g, b );
8480			var min = Math.min( r, g, b );
8481
8482			var hue, saturation;
8483			var lightness = ( min + max ) / 2.0;
8484
8485			if ( min === max ) {
8486
8487				hue = 0;
8488				saturation = 0;
8489
8490			} else {
8491
8492				var delta = max - min;
8493
8494				saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
8495
8496				switch ( max ) {
8497
8498					case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
8499					case g: hue = ( b - r ) / delta + 2; break;
8500					case b: hue = ( r - g ) / delta + 4; break;
8501
8502				}
8503
8504				hue /= 6;
8505
8506			}
8507
8508			target.h = hue;
8509			target.s = saturation;
8510			target.l = lightness;
8511
8512			return target;
8513
8514		},
8515
8516		getStyle: function () {
8517
8518			return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
8519
8520		},
8521
8522		offsetHSL: function ( h, s, l ) {
8523
8524			this.getHSL( _hslA );
8525
8526			_hslA.h += h; _hslA.s += s; _hslA.l += l;
8527
8528			this.setHSL( _hslA.h, _hslA.s, _hslA.l );
8529
8530			return this;
8531
8532		},
8533
8534		add: function ( color ) {
8535
8536			this.r += color.r;
8537			this.g += color.g;
8538			this.b += color.b;
8539
8540			return this;
8541
8542		},
8543
8544		addColors: function ( color1, color2 ) {
8545
8546			this.r = color1.r + color2.r;
8547			this.g = color1.g + color2.g;
8548			this.b = color1.b + color2.b;
8549
8550			return this;
8551
8552		},
8553
8554		addScalar: function ( s ) {
8555
8556			this.r += s;
8557			this.g += s;
8558			this.b += s;
8559
8560			return this;
8561
8562		},
8563
8564		sub: function ( color ) {
8565
8566			this.r = Math.max( 0, this.r - color.r );
8567			this.g = Math.max( 0, this.g - color.g );
8568			this.b = Math.max( 0, this.b - color.b );
8569
8570			return this;
8571
8572		},
8573
8574		multiply: function ( color ) {
8575
8576			this.r *= color.r;
8577			this.g *= color.g;
8578			this.b *= color.b;
8579
8580			return this;
8581
8582		},
8583
8584		multiplyScalar: function ( s ) {
8585
8586			this.r *= s;
8587			this.g *= s;
8588			this.b *= s;
8589
8590			return this;
8591
8592		},
8593
8594		lerp: function ( color, alpha ) {
8595
8596			this.r += ( color.r - this.r ) * alpha;
8597			this.g += ( color.g - this.g ) * alpha;
8598			this.b += ( color.b - this.b ) * alpha;
8599
8600			return this;
8601
8602		},
8603
8604		lerpHSL: function ( color, alpha ) {
8605
8606			this.getHSL( _hslA );
8607			color.getHSL( _hslB );
8608
8609			var h = MathUtils.lerp( _hslA.h, _hslB.h, alpha );
8610			var s = MathUtils.lerp( _hslA.s, _hslB.s, alpha );
8611			var l = MathUtils.lerp( _hslA.l, _hslB.l, alpha );
8612
8613			this.setHSL( h, s, l );
8614
8615			return this;
8616
8617		},
8618
8619		equals: function ( c ) {
8620
8621			return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
8622
8623		},
8624
8625		fromArray: function ( array, offset ) {
8626
8627			if ( offset === undefined ) { offset = 0; }
8628
8629			this.r = array[ offset ];
8630			this.g = array[ offset + 1 ];
8631			this.b = array[ offset + 2 ];
8632
8633			return this;
8634
8635		},
8636
8637		toArray: function ( array, offset ) {
8638
8639			if ( array === undefined ) { array = []; }
8640			if ( offset === undefined ) { offset = 0; }
8641
8642			array[ offset ] = this.r;
8643			array[ offset + 1 ] = this.g;
8644			array[ offset + 2 ] = this.b;
8645
8646			return array;
8647
8648		},
8649
8650		fromBufferAttribute: function ( attribute, index ) {
8651
8652			this.r = attribute.getX( index );
8653			this.g = attribute.getY( index );
8654			this.b = attribute.getZ( index );
8655
8656			if ( attribute.normalized === true ) {
8657
8658				// assuming Uint8Array
8659
8660				this.r /= 255;
8661				this.g /= 255;
8662				this.b /= 255;
8663
8664			}
8665
8666			return this;
8667
8668		},
8669
8670		toJSON: function () {
8671
8672			return this.getHex();
8673
8674		}
8675
8676	} );
8677
8678	Color.NAMES = _colorKeywords;
8679
8680	/**
8681	 * @author mrdoob / http://mrdoob.com/
8682	 * @author alteredq / http://alteredqualia.com/
8683	 */
8684
8685	function Face3( a, b, c, normal, color, materialIndex ) {
8686
8687		this.a = a;
8688		this.b = b;
8689		this.c = c;
8690
8691		this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3();
8692		this.vertexNormals = Array.isArray( normal ) ? normal : [];
8693
8694		this.color = ( color && color.isColor ) ? color : new Color();
8695		this.vertexColors = Array.isArray( color ) ? color : [];
8696
8697		this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
8698
8699	}
8700
8701	Object.assign( Face3.prototype, {
8702
8703		clone: function () {
8704
8705			return new this.constructor().copy( this );
8706
8707		},
8708
8709		copy: function ( source ) {
8710
8711			this.a = source.a;
8712			this.b = source.b;
8713			this.c = source.c;
8714
8715			this.normal.copy( source.normal );
8716			this.color.copy( source.color );
8717
8718			this.materialIndex = source.materialIndex;
8719
8720			for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
8721
8722				this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
8723
8724			}
8725
8726			for ( var i$1 = 0, il$1 = source.vertexColors.length; i$1 < il$1; i$1 ++ ) {
8727
8728				this.vertexColors[ i$1 ] = source.vertexColors[ i$1 ].clone();
8729
8730			}
8731
8732			return this;
8733
8734		}
8735
8736	} );
8737
8738	/**
8739	 * @author mrdoob / http://mrdoob.com/
8740	 * @author alteredq / http://alteredqualia.com/
8741	 */
8742
8743	var materialId = 0;
8744
8745	function Material() {
8746
8747		Object.defineProperty( this, 'id', { value: materialId ++ } );
8748
8749		this.uuid = MathUtils.generateUUID();
8750
8751		this.name = '';
8752		this.type = 'Material';
8753
8754		this.fog = true;
8755
8756		this.blending = NormalBlending;
8757		this.side = FrontSide;
8758		this.flatShading = false;
8759		this.vertexColors = false;
8760
8761		this.opacity = 1;
8762		this.transparent = false;
8763
8764		this.blendSrc = SrcAlphaFactor;
8765		this.blendDst = OneMinusSrcAlphaFactor;
8766		this.blendEquation = AddEquation;
8767		this.blendSrcAlpha = null;
8768		this.blendDstAlpha = null;
8769		this.blendEquationAlpha = null;
8770
8771		this.depthFunc = LessEqualDepth;
8772		this.depthTest = true;
8773		this.depthWrite = true;
8774
8775		this.stencilWriteMask = 0xff;
8776		this.stencilFunc = AlwaysStencilFunc;
8777		this.stencilRef = 0;
8778		this.stencilFuncMask = 0xff;
8779		this.stencilFail = KeepStencilOp;
8780		this.stencilZFail = KeepStencilOp;
8781		this.stencilZPass = KeepStencilOp;
8782		this.stencilWrite = false;
8783
8784		this.clippingPlanes = null;
8785		this.clipIntersection = false;
8786		this.clipShadows = false;
8787
8788		this.shadowSide = null;
8789
8790		this.colorWrite = true;
8791
8792		this.precision = null; // override the renderer's default precision for this material
8793
8794		this.polygonOffset = false;
8795		this.polygonOffsetFactor = 0;
8796		this.polygonOffsetUnits = 0;
8797
8798		this.dithering = false;
8799
8800		this.alphaTest = 0;
8801		this.premultipliedAlpha = false;
8802
8803		this.visible = true;
8804
8805		this.toneMapped = true;
8806
8807		this.userData = {};
8808
8809		this.version = 0;
8810
8811	}
8812
8813	Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
8814
8815		constructor: Material,
8816
8817		isMaterial: true,
8818
8819		onBeforeCompile: function ( /* shaderobject, renderer */ ) {},
8820
8821		customProgramCacheKey: function () {
8822
8823			return this.onBeforeCompile.toString();
8824
8825		},
8826
8827		setValues: function ( values ) {
8828
8829			if ( values === undefined ) { return; }
8830
8831			for ( var key in values ) {
8832
8833				var newValue = values[ key ];
8834
8835				if ( newValue === undefined ) {
8836
8837					console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
8838					continue;
8839
8840				}
8841
8842				// for backward compatability if shading is set in the constructor
8843				if ( key === 'shading' ) {
8844
8845					console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
8846					this.flatShading = ( newValue === FlatShading ) ? true : false;
8847					continue;
8848
8849				}
8850
8851				var currentValue = this[ key ];
8852
8853				if ( currentValue === undefined ) {
8854
8855					console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
8856					continue;
8857
8858				}
8859
8860				if ( currentValue && currentValue.isColor ) {
8861
8862					currentValue.set( newValue );
8863
8864				} else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
8865
8866					currentValue.copy( newValue );
8867
8868				} else {
8869
8870					this[ key ] = newValue;
8871
8872				}
8873
8874			}
8875
8876		},
8877
8878		toJSON: function ( meta ) {
8879
8880			var isRoot = ( meta === undefined || typeof meta === 'string' );
8881
8882			if ( isRoot ) {
8883
8884				meta = {
8885					textures: {},
8886					images: {}
8887				};
8888
8889			}
8890
8891			var data = {
8892				metadata: {
8893					version: 4.5,
8894					type: 'Material',
8895					generator: 'Material.toJSON'
8896				}
8897			};
8898
8899			// standard Material serialization
8900			data.uuid = this.uuid;
8901			data.type = this.type;
8902
8903			if ( this.name !== '' ) { data.name = this.name; }
8904
8905			if ( this.color && this.color.isColor ) { data.color = this.color.getHex(); }
8906
8907			if ( this.roughness !== undefined ) { data.roughness = this.roughness; }
8908			if ( this.metalness !== undefined ) { data.metalness = this.metalness; }
8909
8910			if ( this.sheen && this.sheen.isColor ) { data.sheen = this.sheen.getHex(); }
8911			if ( this.emissive && this.emissive.isColor ) { data.emissive = this.emissive.getHex(); }
8912			if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) { data.emissiveIntensity = this.emissiveIntensity; }
8913
8914			if ( this.specular && this.specular.isColor ) { data.specular = this.specular.getHex(); }
8915			if ( this.shininess !== undefined ) { data.shininess = this.shininess; }
8916			if ( this.clearcoat !== undefined ) { data.clearcoat = this.clearcoat; }
8917			if ( this.clearcoatRoughness !== undefined ) { data.clearcoatRoughness = this.clearcoatRoughness; }
8918
8919			if ( this.clearcoatMap && this.clearcoatMap.isTexture ) {
8920
8921				data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;
8922
8923			}
8924
8925			if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {
8926
8927				data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;
8928
8929			}
8930
8931			if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {
8932
8933				data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;
8934				data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
8935
8936			}
8937
8938			if ( this.map && this.map.isTexture ) { data.map = this.map.toJSON( meta ).uuid; }
8939			if ( this.matcap && this.matcap.isTexture ) { data.matcap = this.matcap.toJSON( meta ).uuid; }
8940			if ( this.alphaMap && this.alphaMap.isTexture ) { data.alphaMap = this.alphaMap.toJSON( meta ).uuid; }
8941			if ( this.lightMap && this.lightMap.isTexture ) { data.lightMap = this.lightMap.toJSON( meta ).uuid; }
8942
8943			if ( this.aoMap && this.aoMap.isTexture ) {
8944
8945				data.aoMap = this.aoMap.toJSON( meta ).uuid;
8946				data.aoMapIntensity = this.aoMapIntensity;
8947
8948			}
8949
8950			if ( this.bumpMap && this.bumpMap.isTexture ) {
8951
8952				data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
8953				data.bumpScale = this.bumpScale;
8954
8955			}
8956
8957			if ( this.normalMap && this.normalMap.isTexture ) {
8958
8959				data.normalMap = this.normalMap.toJSON( meta ).uuid;
8960				data.normalMapType = this.normalMapType;
8961				data.normalScale = this.normalScale.toArray();
8962
8963			}
8964
8965			if ( this.displacementMap && this.displacementMap.isTexture ) {
8966
8967				data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
8968				data.displacementScale = this.displacementScale;
8969				data.displacementBias = this.displacementBias;
8970
8971			}
8972
8973			if ( this.roughnessMap && this.roughnessMap.isTexture ) { data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; }
8974			if ( this.metalnessMap && this.metalnessMap.isTexture ) { data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; }
8975
8976			if ( this.emissiveMap && this.emissiveMap.isTexture ) { data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; }
8977			if ( this.specularMap && this.specularMap.isTexture ) { data.specularMap = this.specularMap.toJSON( meta ).uuid; }
8978
8979			if ( this.envMap && this.envMap.isTexture ) {
8980
8981				data.envMap = this.envMap.toJSON( meta ).uuid;
8982				data.reflectivity = this.reflectivity; // Scale behind envMap
8983				data.refractionRatio = this.refractionRatio;
8984
8985				if ( this.combine !== undefined ) { data.combine = this.combine; }
8986				if ( this.envMapIntensity !== undefined ) { data.envMapIntensity = this.envMapIntensity; }
8987
8988			}
8989
8990			if ( this.gradientMap && this.gradientMap.isTexture ) {
8991
8992				data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
8993
8994			}
8995
8996			if ( this.size !== undefined ) { data.size = this.size; }
8997			if ( this.sizeAttenuation !== undefined ) { data.sizeAttenuation = this.sizeAttenuation; }
8998
8999			if ( this.blending !== NormalBlending ) { data.blending = this.blending; }
9000			if ( this.flatShading === true ) { data.flatShading = this.flatShading; }
9001			if ( this.side !== FrontSide ) { data.side = this.side; }
9002			if ( this.vertexColors ) { data.vertexColors = true; }
9003
9004			if ( this.opacity < 1 ) { data.opacity = this.opacity; }
9005			if ( this.transparent === true ) { data.transparent = this.transparent; }
9006
9007			data.depthFunc = this.depthFunc;
9008			data.depthTest = this.depthTest;
9009			data.depthWrite = this.depthWrite;
9010
9011			data.stencilWrite = this.stencilWrite;
9012			data.stencilWriteMask = this.stencilWriteMask;
9013			data.stencilFunc = this.stencilFunc;
9014			data.stencilRef = this.stencilRef;
9015			data.stencilFuncMask = this.stencilFuncMask;
9016			data.stencilFail = this.stencilFail;
9017			data.stencilZFail = this.stencilZFail;
9018			data.stencilZPass = this.stencilZPass;
9019
9020			// rotation (SpriteMaterial)
9021			if ( this.rotation && this.rotation !== 0 ) { data.rotation = this.rotation; }
9022
9023			if ( this.polygonOffset === true ) { data.polygonOffset = true; }
9024			if ( this.polygonOffsetFactor !== 0 ) { data.polygonOffsetFactor = this.polygonOffsetFactor; }
9025			if ( this.polygonOffsetUnits !== 0 ) { data.polygonOffsetUnits = this.polygonOffsetUnits; }
9026
9027			if ( this.linewidth && this.linewidth !== 1 ) { data.linewidth = this.linewidth; }
9028			if ( this.dashSize !== undefined ) { data.dashSize = this.dashSize; }
9029			if ( this.gapSize !== undefined ) { data.gapSize = this.gapSize; }
9030			if ( this.scale !== undefined ) { data.scale = this.scale; }
9031
9032			if ( this.dithering === true ) { data.dithering = true; }
9033
9034			if ( this.alphaTest > 0 ) { data.alphaTest = this.alphaTest; }
9035			if ( this.premultipliedAlpha === true ) { data.premultipliedAlpha = this.premultipliedAlpha; }
9036
9037			if ( this.wireframe === true ) { data.wireframe = this.wireframe; }
9038			if ( this.wireframeLinewidth > 1 ) { data.wireframeLinewidth = this.wireframeLinewidth; }
9039			if ( this.wireframeLinecap !== 'round' ) { data.wireframeLinecap = this.wireframeLinecap; }
9040			if ( this.wireframeLinejoin !== 'round' ) { data.wireframeLinejoin = this.wireframeLinejoin; }
9041
9042			if ( this.morphTargets === true ) { data.morphTargets = true; }
9043			if ( this.morphNormals === true ) { data.morphNormals = true; }
9044			if ( this.skinning === true ) { data.skinning = true; }
9045
9046			if ( this.visible === false ) { data.visible = false; }
9047
9048			if ( this.toneMapped === false ) { data.toneMapped = false; }
9049
9050			if ( JSON.stringify( this.userData ) !== '{}' ) { data.userData = this.userData; }
9051
9052			// TODO: Copied from Object3D.toJSON
9053
9054			function extractFromCache( cache ) {
9055
9056				var values = [];
9057
9058				for ( var key in cache ) {
9059
9060					var data = cache[ key ];
9061					delete data.metadata;
9062					values.push( data );
9063
9064				}
9065
9066				return values;
9067
9068			}
9069
9070			if ( isRoot ) {
9071
9072				var textures = extractFromCache( meta.textures );
9073				var images = extractFromCache( meta.images );
9074
9075				if ( textures.length > 0 ) { data.textures = textures; }
9076				if ( images.length > 0 ) { data.images = images; }
9077
9078			}
9079
9080			return data;
9081
9082		},
9083
9084		clone: function () {
9085
9086			return new this.constructor().copy( this );
9087
9088		},
9089
9090		copy: function ( source ) {
9091
9092			this.name = source.name;
9093
9094			this.fog = source.fog;
9095
9096			this.blending = source.blending;
9097			this.side = source.side;
9098			this.flatShading = source.flatShading;
9099			this.vertexColors = source.vertexColors;
9100
9101			this.opacity = source.opacity;
9102			this.transparent = source.transparent;
9103
9104			this.blendSrc = source.blendSrc;
9105			this.blendDst = source.blendDst;
9106			this.blendEquation = source.blendEquation;
9107			this.blendSrcAlpha = source.blendSrcAlpha;
9108			this.blendDstAlpha = source.blendDstAlpha;
9109			this.blendEquationAlpha = source.blendEquationAlpha;
9110
9111			this.depthFunc = source.depthFunc;
9112			this.depthTest = source.depthTest;
9113			this.depthWrite = source.depthWrite;
9114
9115			this.stencilWriteMask = source.stencilWriteMask;
9116			this.stencilFunc = source.stencilFunc;
9117			this.stencilRef = source.stencilRef;
9118			this.stencilFuncMask = source.stencilFuncMask;
9119			this.stencilFail = source.stencilFail;
9120			this.stencilZFail = source.stencilZFail;
9121			this.stencilZPass = source.stencilZPass;
9122			this.stencilWrite = source.stencilWrite;
9123
9124			var srcPlanes = source.clippingPlanes;
9125			var dstPlanes = null;
9126
9127			if ( srcPlanes !== null ) {
9128
9129				var n = srcPlanes.length;
9130				dstPlanes = new Array( n );
9131
9132				for ( var i = 0; i !== n; ++ i ) {
9133
9134					dstPlanes[ i ] = srcPlanes[ i ].clone();
9135
9136				}
9137
9138			}
9139
9140			this.clippingPlanes = dstPlanes;
9141			this.clipIntersection = source.clipIntersection;
9142			this.clipShadows = source.clipShadows;
9143
9144			this.shadowSide = source.shadowSide;
9145
9146			this.colorWrite = source.colorWrite;
9147
9148			this.precision = source.precision;
9149
9150			this.polygonOffset = source.polygonOffset;
9151			this.polygonOffsetFactor = source.polygonOffsetFactor;
9152			this.polygonOffsetUnits = source.polygonOffsetUnits;
9153
9154			this.dithering = source.dithering;
9155
9156			this.alphaTest = source.alphaTest;
9157			this.premultipliedAlpha = source.premultipliedAlpha;
9158
9159			this.visible = source.visible;
9160
9161			this.toneMapped = source.toneMapped;
9162
9163			this.userData = JSON.parse( JSON.stringify( source.userData ) );
9164
9165			return this;
9166
9167		},
9168
9169		dispose: function () {
9170
9171			this.dispatchEvent( { type: 'dispose' } );
9172
9173		}
9174
9175	} );
9176
9177	Object.defineProperty( Material.prototype, 'needsUpdate', {
9178
9179		set: function ( value ) {
9180
9181			if ( value === true ) { this.version ++; }
9182
9183		}
9184
9185	} );
9186
9187	/**
9188	 * @author mrdoob / http://mrdoob.com/
9189	 * @author alteredq / http://alteredqualia.com/
9190	 *
9191	 * parameters = {
9192	 *  color: <hex>,
9193	 *  opacity: <float>,
9194	 *  map: new THREE.Texture( <Image> ),
9195	 *
9196	 *  lightMap: new THREE.Texture( <Image> ),
9197	 *  lightMapIntensity: <float>
9198	 *
9199	 *  aoMap: new THREE.Texture( <Image> ),
9200	 *  aoMapIntensity: <float>
9201	 *
9202	 *  specularMap: new THREE.Texture( <Image> ),
9203	 *
9204	 *  alphaMap: new THREE.Texture( <Image> ),
9205	 *
9206	 *  envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
9207	 *  combine: THREE.Multiply,
9208	 *  reflectivity: <float>,
9209	 *  refractionRatio: <float>,
9210	 *
9211	 *  depthTest: <bool>,
9212	 *  depthWrite: <bool>,
9213	 *
9214	 *  wireframe: <boolean>,
9215	 *  wireframeLinewidth: <float>,
9216	 *
9217	 *  skinning: <bool>,
9218	 *  morphTargets: <bool>
9219	 * }
9220	 */
9221
9222	function MeshBasicMaterial( parameters ) {
9223
9224		Material.call( this );
9225
9226		this.type = 'MeshBasicMaterial';
9227
9228		this.color = new Color( 0xffffff ); // emissive
9229
9230		this.map = null;
9231
9232		this.lightMap = null;
9233		this.lightMapIntensity = 1.0;
9234
9235		this.aoMap = null;
9236		this.aoMapIntensity = 1.0;
9237
9238		this.specularMap = null;
9239
9240		this.alphaMap = null;
9241
9242		this.envMap = null;
9243		this.combine = MultiplyOperation;
9244		this.reflectivity = 1;
9245		this.refractionRatio = 0.98;
9246
9247		this.wireframe = false;
9248		this.wireframeLinewidth = 1;
9249		this.wireframeLinecap = 'round';
9250		this.wireframeLinejoin = 'round';
9251
9252		this.skinning = false;
9253		this.morphTargets = false;
9254
9255		this.setValues( parameters );
9256
9257	}
9258
9259	MeshBasicMaterial.prototype = Object.create( Material.prototype );
9260	MeshBasicMaterial.prototype.constructor = MeshBasicMaterial;
9261
9262	MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
9263
9264	MeshBasicMaterial.prototype.copy = function ( source ) {
9265
9266		Material.prototype.copy.call( this, source );
9267
9268		this.color.copy( source.color );
9269
9270		this.map = source.map;
9271
9272		this.lightMap = source.lightMap;
9273		this.lightMapIntensity = source.lightMapIntensity;
9274
9275		this.aoMap = source.aoMap;
9276		this.aoMapIntensity = source.aoMapIntensity;
9277
9278		this.specularMap = source.specularMap;
9279
9280		this.alphaMap = source.alphaMap;
9281
9282		this.envMap = source.envMap;
9283		this.combine = source.combine;
9284		this.reflectivity = source.reflectivity;
9285		this.refractionRatio = source.refractionRatio;
9286
9287		this.wireframe = source.wireframe;
9288		this.wireframeLinewidth = source.wireframeLinewidth;
9289		this.wireframeLinecap = source.wireframeLinecap;
9290		this.wireframeLinejoin = source.wireframeLinejoin;
9291
9292		this.skinning = source.skinning;
9293		this.morphTargets = source.morphTargets;
9294
9295		return this;
9296
9297	};
9298
9299	/**
9300	 * @author mrdoob / http://mrdoob.com/
9301	 */
9302
9303	var _vector$3 = new Vector3();
9304	var _vector2$1 = new Vector2();
9305
9306	function BufferAttribute( array, itemSize, normalized ) {
9307
9308		if ( Array.isArray( array ) ) {
9309
9310			throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
9311
9312		}
9313
9314		this.name = '';
9315
9316		this.array = array;
9317		this.itemSize = itemSize;
9318		this.count = array !== undefined ? array.length / itemSize : 0;
9319		this.normalized = normalized === true;
9320
9321		this.usage = StaticDrawUsage;
9322		this.updateRange = { offset: 0, count: - 1 };
9323
9324		this.version = 0;
9325
9326	}
9327
9328	Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', {
9329
9330		set: function ( value ) {
9331
9332			if ( value === true ) { this.version ++; }
9333
9334		}
9335
9336	} );
9337
9338	Object.assign( BufferAttribute.prototype, {
9339
9340		isBufferAttribute: true,
9341
9342		onUploadCallback: function () {},
9343
9344		setUsage: function ( value ) {
9345
9346			this.usage = value;
9347
9348			return this;
9349
9350		},
9351
9352		copy: function ( source ) {
9353
9354			this.name = source.name;
9355			this.array = new source.array.constructor( source.array );
9356			this.itemSize = source.itemSize;
9357			this.count = source.count;
9358			this.normalized = source.normalized;
9359
9360			this.usage = source.usage;
9361
9362			return this;
9363
9364		},
9365
9366		copyAt: function ( index1, attribute, index2 ) {
9367
9368			index1 *= this.itemSize;
9369			index2 *= attribute.itemSize;
9370
9371			for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
9372
9373				this.array[ index1 + i ] = attribute.array[ index2 + i ];
9374
9375			}
9376
9377			return this;
9378
9379		},
9380
9381		copyArray: function ( array ) {
9382
9383			this.array.set( array );
9384
9385			return this;
9386
9387		},
9388
9389		copyColorsArray: function ( colors ) {
9390
9391			var array = this.array;
9392			var offset = 0;
9393
9394			for ( var i = 0, l = colors.length; i < l; i ++ ) {
9395
9396				var color = colors[ i ];
9397
9398				if ( color === undefined ) {
9399
9400					console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
9401					color = new Color();
9402
9403				}
9404
9405				array[ offset ++ ] = color.r;
9406				array[ offset ++ ] = color.g;
9407				array[ offset ++ ] = color.b;
9408
9409			}
9410
9411			return this;
9412
9413		},
9414
9415		copyVector2sArray: function ( vectors ) {
9416
9417			var array = this.array;
9418			var offset = 0;
9419
9420			for ( var i = 0, l = vectors.length; i < l; i ++ ) {
9421
9422				var vector = vectors[ i ];
9423
9424				if ( vector === undefined ) {
9425
9426					console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
9427					vector = new Vector2();
9428
9429				}
9430
9431				array[ offset ++ ] = vector.x;
9432				array[ offset ++ ] = vector.y;
9433
9434			}
9435
9436			return this;
9437
9438		},
9439
9440		copyVector3sArray: function ( vectors ) {
9441
9442			var array = this.array;
9443			var offset = 0;
9444
9445			for ( var i = 0, l = vectors.length; i < l; i ++ ) {
9446
9447				var vector = vectors[ i ];
9448
9449				if ( vector === undefined ) {
9450
9451					console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
9452					vector = new Vector3();
9453
9454				}
9455
9456				array[ offset ++ ] = vector.x;
9457				array[ offset ++ ] = vector.y;
9458				array[ offset ++ ] = vector.z;
9459
9460			}
9461
9462			return this;
9463
9464		},
9465
9466		copyVector4sArray: function ( vectors ) {
9467
9468			var array = this.array;
9469			var offset = 0;
9470
9471			for ( var i = 0, l = vectors.length; i < l; i ++ ) {
9472
9473				var vector = vectors[ i ];
9474
9475				if ( vector === undefined ) {
9476
9477					console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
9478					vector = new Vector4();
9479
9480				}
9481
9482				array[ offset ++ ] = vector.x;
9483				array[ offset ++ ] = vector.y;
9484				array[ offset ++ ] = vector.z;
9485				array[ offset ++ ] = vector.w;
9486
9487			}
9488
9489			return this;
9490
9491		},
9492
9493		applyMatrix3: function ( m ) {
9494
9495			if ( this.itemSize === 2 ) {
9496
9497				for ( var i = 0, l = this.count; i < l; i ++ ) {
9498
9499					_vector2$1.fromBufferAttribute( this, i );
9500					_vector2$1.applyMatrix3( m );
9501
9502					this.setXY( i, _vector2$1.x, _vector2$1.y );
9503
9504				}
9505
9506			} else if ( this.itemSize === 3 ) {
9507
9508				for ( var i$1 = 0, l$1 = this.count; i$1 < l$1; i$1 ++ ) {
9509
9510					_vector$3.fromBufferAttribute( this, i$1 );
9511					_vector$3.applyMatrix3( m );
9512
9513					this.setXYZ( i$1, _vector$3.x, _vector$3.y, _vector$3.z );
9514
9515				}
9516
9517			}
9518
9519			return this;
9520
9521		},
9522
9523		applyMatrix4: function ( m ) {
9524
9525			for ( var i = 0, l = this.count; i < l; i ++ ) {
9526
9527				_vector$3.x = this.getX( i );
9528				_vector$3.y = this.getY( i );
9529				_vector$3.z = this.getZ( i );
9530
9531				_vector$3.applyMatrix4( m );
9532
9533				this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
9534
9535			}
9536
9537			return this;
9538
9539		},
9540
9541		applyNormalMatrix: function ( m ) {
9542
9543			for ( var i = 0, l = this.count; i < l; i ++ ) {
9544
9545				_vector$3.x = this.getX( i );
9546				_vector$3.y = this.getY( i );
9547				_vector$3.z = this.getZ( i );
9548
9549				_vector$3.applyNormalMatrix( m );
9550
9551				this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
9552
9553			}
9554
9555			return this;
9556
9557		},
9558
9559		transformDirection: function ( m ) {
9560
9561			for ( var i = 0, l = this.count; i < l; i ++ ) {
9562
9563				_vector$3.x = this.getX( i );
9564				_vector$3.y = this.getY( i );
9565				_vector$3.z = this.getZ( i );
9566
9567				_vector$3.transformDirection( m );
9568
9569				this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
9570
9571			}
9572
9573			return this;
9574
9575		},
9576
9577		set: function ( value, offset ) {
9578
9579			if ( offset === undefined ) { offset = 0; }
9580
9581			this.array.set( value, offset );
9582
9583			return this;
9584
9585		},
9586
9587		getX: function ( index ) {
9588
9589			return this.array[ index * this.itemSize ];
9590
9591		},
9592
9593		setX: function ( index, x ) {
9594
9595			this.array[ index * this.itemSize ] = x;
9596
9597			return this;
9598
9599		},
9600
9601		getY: function ( index ) {
9602
9603			return this.array[ index * this.itemSize + 1 ];
9604
9605		},
9606
9607		setY: function ( index, y ) {
9608
9609			this.array[ index * this.itemSize + 1 ] = y;
9610
9611			return this;
9612
9613		},
9614
9615		getZ: function ( index ) {
9616
9617			return this.array[ index * this.itemSize + 2 ];
9618
9619		},
9620
9621		setZ: function ( index, z ) {
9622
9623			this.array[ index * this.itemSize + 2 ] = z;
9624
9625			return this;
9626
9627		},
9628
9629		getW: function ( index ) {
9630
9631			return this.array[ index * this.itemSize + 3 ];
9632
9633		},
9634
9635		setW: function ( index, w ) {
9636
9637			this.array[ index * this.itemSize + 3 ] = w;
9638
9639			return this;
9640
9641		},
9642
9643		setXY: function ( index, x, y ) {
9644
9645			index *= this.itemSize;
9646
9647			this.array[ index + 0 ] = x;
9648			this.array[ index + 1 ] = y;
9649
9650			return this;
9651
9652		},
9653
9654		setXYZ: function ( index, x, y, z ) {
9655
9656			index *= this.itemSize;
9657
9658			this.array[ index + 0 ] = x;
9659			this.array[ index + 1 ] = y;
9660			this.array[ index + 2 ] = z;
9661
9662			return this;
9663
9664		},
9665
9666		setXYZW: function ( index, x, y, z, w ) {
9667
9668			index *= this.itemSize;
9669
9670			this.array[ index + 0 ] = x;
9671			this.array[ index + 1 ] = y;
9672			this.array[ index + 2 ] = z;
9673			this.array[ index + 3 ] = w;
9674
9675			return this;
9676
9677		},
9678
9679		onUpload: function ( callback ) {
9680
9681			this.onUploadCallback = callback;
9682
9683			return this;
9684
9685		},
9686
9687		clone: function () {
9688
9689			return new this.constructor( this.array, this.itemSize ).copy( this );
9690
9691		},
9692
9693		toJSON: function () {
9694
9695			return {
9696				itemSize: this.itemSize,
9697				type: this.array.constructor.name,
9698				array: Array.prototype.slice.call( this.array ),
9699				normalized: this.normalized
9700			};
9701
9702		}
9703
9704	} );
9705
9706	//
9707
9708	function Int8BufferAttribute( array, itemSize, normalized ) {
9709
9710		BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized );
9711
9712	}
9713
9714	Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9715	Int8BufferAttribute.prototype.constructor = Int8BufferAttribute;
9716
9717
9718	function Uint8BufferAttribute( array, itemSize, normalized ) {
9719
9720		BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized );
9721
9722	}
9723
9724	Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9725	Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
9726
9727
9728	function Uint8ClampedBufferAttribute( array, itemSize, normalized ) {
9729
9730		BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized );
9731
9732	}
9733
9734	Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9735	Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;
9736
9737
9738	function Int16BufferAttribute( array, itemSize, normalized ) {
9739
9740		BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized );
9741
9742	}
9743
9744	Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9745	Int16BufferAttribute.prototype.constructor = Int16BufferAttribute;
9746
9747
9748	function Uint16BufferAttribute( array, itemSize, normalized ) {
9749
9750		BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized );
9751
9752	}
9753
9754	Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9755	Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
9756
9757
9758	function Int32BufferAttribute( array, itemSize, normalized ) {
9759
9760		BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized );
9761
9762	}
9763
9764	Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9765	Int32BufferAttribute.prototype.constructor = Int32BufferAttribute;
9766
9767
9768	function Uint32BufferAttribute( array, itemSize, normalized ) {
9769
9770		BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized );
9771
9772	}
9773
9774	Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9775	Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
9776
9777
9778	function Float32BufferAttribute( array, itemSize, normalized ) {
9779
9780		BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized );
9781
9782	}
9783
9784	Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9785	Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
9786
9787
9788	function Float64BufferAttribute( array, itemSize, normalized ) {
9789
9790		BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized );
9791
9792	}
9793
9794	Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9795	Float64BufferAttribute.prototype.constructor = Float64BufferAttribute;
9796
9797	/**
9798	 * @author mrdoob / http://mrdoob.com/
9799	 */
9800
9801	function DirectGeometry() {
9802
9803		this.vertices = [];
9804		this.normals = [];
9805		this.colors = [];
9806		this.uvs = [];
9807		this.uvs2 = [];
9808
9809		this.groups = [];
9810
9811		this.morphTargets = {};
9812
9813		this.skinWeights = [];
9814		this.skinIndices = [];
9815
9816		// this.lineDistances = [];
9817
9818		this.boundingBox = null;
9819		this.boundingSphere = null;
9820
9821		// update flags
9822
9823		this.verticesNeedUpdate = false;
9824		this.normalsNeedUpdate = false;
9825		this.colorsNeedUpdate = false;
9826		this.uvsNeedUpdate = false;
9827		this.groupsNeedUpdate = false;
9828
9829	}
9830
9831	Object.assign( DirectGeometry.prototype, {
9832
9833		computeGroups: function ( geometry ) {
9834
9835			var groups = [];
9836
9837			var group, i;
9838			var materialIndex = undefined;
9839
9840			var faces = geometry.faces;
9841
9842			for ( i = 0; i < faces.length; i ++ ) {
9843
9844				var face = faces[ i ];
9845
9846				// materials
9847
9848				if ( face.materialIndex !== materialIndex ) {
9849
9850					materialIndex = face.materialIndex;
9851
9852					if ( group !== undefined ) {
9853
9854						group.count = ( i * 3 ) - group.start;
9855						groups.push( group );
9856
9857					}
9858
9859					group = {
9860						start: i * 3,
9861						materialIndex: materialIndex
9862					};
9863
9864				}
9865
9866			}
9867
9868			if ( group !== undefined ) {
9869
9870				group.count = ( i * 3 ) - group.start;
9871				groups.push( group );
9872
9873			}
9874
9875			this.groups = groups;
9876
9877		},
9878
9879		fromGeometry: function ( geometry ) {
9880
9881			var faces = geometry.faces;
9882			var vertices = geometry.vertices;
9883			var faceVertexUvs = geometry.faceVertexUvs;
9884
9885			var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
9886			var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
9887
9888			// morphs
9889
9890			var morphTargets = geometry.morphTargets;
9891			var morphTargetsLength = morphTargets.length;
9892
9893			var morphTargetsPosition;
9894
9895			if ( morphTargetsLength > 0 ) {
9896
9897				morphTargetsPosition = [];
9898
9899				for ( var i = 0; i < morphTargetsLength; i ++ ) {
9900
9901					morphTargetsPosition[ i ] = {
9902						name: morphTargets[ i ].name,
9903					 	data: []
9904					};
9905
9906				}
9907
9908				this.morphTargets.position = morphTargetsPosition;
9909
9910			}
9911
9912			var morphNormals = geometry.morphNormals;
9913			var morphNormalsLength = morphNormals.length;
9914
9915			var morphTargetsNormal;
9916
9917			if ( morphNormalsLength > 0 ) {
9918
9919				morphTargetsNormal = [];
9920
9921				for ( var i$1 = 0; i$1 < morphNormalsLength; i$1 ++ ) {
9922
9923					morphTargetsNormal[ i$1 ] = {
9924						name: morphNormals[ i$1 ].name,
9925					 	data: []
9926					};
9927
9928				}
9929
9930				this.morphTargets.normal = morphTargetsNormal;
9931
9932			}
9933
9934			// skins
9935
9936			var skinIndices = geometry.skinIndices;
9937			var skinWeights = geometry.skinWeights;
9938
9939			var hasSkinIndices = skinIndices.length === vertices.length;
9940			var hasSkinWeights = skinWeights.length === vertices.length;
9941
9942			//
9943
9944			if ( vertices.length > 0 && faces.length === 0 ) {
9945
9946				console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' );
9947
9948			}
9949
9950			for ( var i$2 = 0; i$2 < faces.length; i$2 ++ ) {
9951
9952				var face = faces[ i$2 ];
9953
9954				this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
9955
9956				var vertexNormals = face.vertexNormals;
9957
9958				if ( vertexNormals.length === 3 ) {
9959
9960					this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
9961
9962				} else {
9963
9964					var normal = face.normal;
9965
9966					this.normals.push( normal, normal, normal );
9967
9968				}
9969
9970				var vertexColors = face.vertexColors;
9971
9972				if ( vertexColors.length === 3 ) {
9973
9974					this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
9975
9976				} else {
9977
9978					var color = face.color;
9979
9980					this.colors.push( color, color, color );
9981
9982				}
9983
9984				if ( hasFaceVertexUv === true ) {
9985
9986					var vertexUvs = faceVertexUvs[ 0 ][ i$2 ];
9987
9988					if ( vertexUvs !== undefined ) {
9989
9990						this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
9991
9992					} else {
9993
9994						console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i$2 );
9995
9996						this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
9997
9998					}
9999
10000				}
10001
10002				if ( hasFaceVertexUv2 === true ) {
10003
10004					var vertexUvs$1 = faceVertexUvs[ 1 ][ i$2 ];
10005
10006					if ( vertexUvs$1 !== undefined ) {
10007
10008						this.uvs2.push( vertexUvs$1[ 0 ], vertexUvs$1[ 1 ], vertexUvs$1[ 2 ] );
10009
10010					} else {
10011
10012						console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i$2 );
10013
10014						this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
10015
10016					}
10017
10018				}
10019
10020				// morphs
10021
10022				for ( var j = 0; j < morphTargetsLength; j ++ ) {
10023
10024					var morphTarget = morphTargets[ j ].vertices;
10025
10026					morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
10027
10028				}
10029
10030				for ( var j$1 = 0; j$1 < morphNormalsLength; j$1 ++ ) {
10031
10032					var morphNormal = morphNormals[ j$1 ].vertexNormals[ i$2 ];
10033
10034					morphTargetsNormal[ j$1 ].data.push( morphNormal.a, morphNormal.b, morphNormal.c );
10035
10036				}
10037
10038				// skins
10039
10040				if ( hasSkinIndices ) {
10041
10042					this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
10043
10044				}
10045
10046				if ( hasSkinWeights ) {
10047
10048					this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
10049
10050				}
10051
10052			}
10053
10054			this.computeGroups( geometry );
10055
10056			this.verticesNeedUpdate = geometry.verticesNeedUpdate;
10057			this.normalsNeedUpdate = geometry.normalsNeedUpdate;
10058			this.colorsNeedUpdate = geometry.colorsNeedUpdate;
10059			this.uvsNeedUpdate = geometry.uvsNeedUpdate;
10060			this.groupsNeedUpdate = geometry.groupsNeedUpdate;
10061
10062			if ( geometry.boundingSphere !== null ) {
10063
10064				this.boundingSphere = geometry.boundingSphere.clone();
10065
10066			}
10067
10068			if ( geometry.boundingBox !== null ) {
10069
10070				this.boundingBox = geometry.boundingBox.clone();
10071
10072			}
10073
10074			return this;
10075
10076		}
10077
10078	} );
10079
10080	/**
10081	 * @author mrdoob / http://mrdoob.com/
10082	 */
10083
10084	function arrayMax( array ) {
10085
10086		if ( array.length === 0 ) { return - Infinity; }
10087
10088		var max = array[ 0 ];
10089
10090		for ( var i = 1, l = array.length; i < l; ++ i ) {
10091
10092			if ( array[ i ] > max ) { max = array[ i ]; }
10093
10094		}
10095
10096		return max;
10097
10098	}
10099
10100	/**
10101	 * @author alteredq / http://alteredqualia.com/
10102	 * @author mrdoob / http://mrdoob.com/
10103	 */
10104
10105	var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id
10106
10107	var _m1$2 = new Matrix4();
10108	var _obj = new Object3D();
10109	var _offset = new Vector3();
10110	var _box$2 = new Box3();
10111	var _boxMorphTargets = new Box3();
10112	var _vector$4 = new Vector3();
10113
10114	function BufferGeometry() {
10115
10116		Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } );
10117
10118		this.uuid = MathUtils.generateUUID();
10119
10120		this.name = '';
10121		this.type = 'BufferGeometry';
10122
10123		this.index = null;
10124		this.attributes = {};
10125
10126		this.morphAttributes = {};
10127		this.morphTargetsRelative = false;
10128
10129		this.groups = [];
10130
10131		this.boundingBox = null;
10132		this.boundingSphere = null;
10133
10134		this.drawRange = { start: 0, count: Infinity };
10135
10136		this.userData = {};
10137
10138	}
10139
10140	BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
10141
10142		constructor: BufferGeometry,
10143
10144		isBufferGeometry: true,
10145
10146		getIndex: function () {
10147
10148			return this.index;
10149
10150		},
10151
10152		setIndex: function ( index ) {
10153
10154			if ( Array.isArray( index ) ) {
10155
10156				this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );
10157
10158			} else {
10159
10160				this.index = index;
10161
10162			}
10163
10164		},
10165
10166		getAttribute: function ( name ) {
10167
10168			return this.attributes[ name ];
10169
10170		},
10171
10172		setAttribute: function ( name, attribute ) {
10173
10174			this.attributes[ name ] = attribute;
10175
10176			return this;
10177
10178		},
10179
10180		deleteAttribute: function ( name ) {
10181
10182			delete this.attributes[ name ];
10183
10184			return this;
10185
10186		},
10187
10188		addGroup: function ( start, count, materialIndex ) {
10189
10190			this.groups.push( {
10191
10192				start: start,
10193				count: count,
10194				materialIndex: materialIndex !== undefined ? materialIndex : 0
10195
10196			} );
10197
10198		},
10199
10200		clearGroups: function () {
10201
10202			this.groups = [];
10203
10204		},
10205
10206		setDrawRange: function ( start, count ) {
10207
10208			this.drawRange.start = start;
10209			this.drawRange.count = count;
10210
10211		},
10212
10213		applyMatrix4: function ( matrix ) {
10214
10215			var position = this.attributes.position;
10216
10217			if ( position !== undefined ) {
10218
10219				position.applyMatrix4( matrix );
10220
10221				position.needsUpdate = true;
10222
10223			}
10224
10225			var normal = this.attributes.normal;
10226
10227			if ( normal !== undefined ) {
10228
10229				var normalMatrix = new Matrix3().getNormalMatrix( matrix );
10230
10231				normal.applyNormalMatrix( normalMatrix );
10232
10233				normal.needsUpdate = true;
10234
10235			}
10236
10237			var tangent = this.attributes.tangent;
10238
10239			if ( tangent !== undefined ) {
10240
10241				tangent.transformDirection( matrix );
10242
10243				tangent.needsUpdate = true;
10244
10245			}
10246
10247			if ( this.boundingBox !== null ) {
10248
10249				this.computeBoundingBox();
10250
10251			}
10252
10253			if ( this.boundingSphere !== null ) {
10254
10255				this.computeBoundingSphere();
10256
10257			}
10258
10259			return this;
10260
10261		},
10262
10263		rotateX: function ( angle ) {
10264
10265			// rotate geometry around world x-axis
10266
10267			_m1$2.makeRotationX( angle );
10268
10269			this.applyMatrix4( _m1$2 );
10270
10271			return this;
10272
10273		},
10274
10275		rotateY: function ( angle ) {
10276
10277			// rotate geometry around world y-axis
10278
10279			_m1$2.makeRotationY( angle );
10280
10281			this.applyMatrix4( _m1$2 );
10282
10283			return this;
10284
10285		},
10286
10287		rotateZ: function ( angle ) {
10288
10289			// rotate geometry around world z-axis
10290
10291			_m1$2.makeRotationZ( angle );
10292
10293			this.applyMatrix4( _m1$2 );
10294
10295			return this;
10296
10297		},
10298
10299		translate: function ( x, y, z ) {
10300
10301			// translate geometry
10302
10303			_m1$2.makeTranslation( x, y, z );
10304
10305			this.applyMatrix4( _m1$2 );
10306
10307			return this;
10308
10309		},
10310
10311		scale: function ( x, y, z ) {
10312
10313			// scale geometry
10314
10315			_m1$2.makeScale( x, y, z );
10316
10317			this.applyMatrix4( _m1$2 );
10318
10319			return this;
10320
10321		},
10322
10323		lookAt: function ( vector ) {
10324
10325			_obj.lookAt( vector );
10326
10327			_obj.updateMatrix();
10328
10329			this.applyMatrix4( _obj.matrix );
10330
10331			return this;
10332
10333		},
10334
10335		center: function () {
10336
10337			this.computeBoundingBox();
10338
10339			this.boundingBox.getCenter( _offset ).negate();
10340
10341			this.translate( _offset.x, _offset.y, _offset.z );
10342
10343			return this;
10344
10345		},
10346
10347		setFromObject: function ( object ) {
10348
10349			// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
10350
10351			var geometry = object.geometry;
10352
10353			if ( object.isPoints || object.isLine ) {
10354
10355				var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
10356				var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
10357
10358				this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
10359				this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
10360
10361				if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
10362
10363					var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );
10364
10365					this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
10366
10367				}
10368
10369				if ( geometry.boundingSphere !== null ) {
10370
10371					this.boundingSphere = geometry.boundingSphere.clone();
10372
10373				}
10374
10375				if ( geometry.boundingBox !== null ) {
10376
10377					this.boundingBox = geometry.boundingBox.clone();
10378
10379				}
10380
10381			} else if ( object.isMesh ) {
10382
10383				if ( geometry && geometry.isGeometry ) {
10384
10385					this.fromGeometry( geometry );
10386
10387				}
10388
10389			}
10390
10391			return this;
10392
10393		},
10394
10395		setFromPoints: function ( points ) {
10396
10397			var position = [];
10398
10399			for ( var i = 0, l = points.length; i < l; i ++ ) {
10400
10401				var point = points[ i ];
10402				position.push( point.x, point.y, point.z || 0 );
10403
10404			}
10405
10406			this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) );
10407
10408			return this;
10409
10410		},
10411
10412		updateFromObject: function ( object ) {
10413
10414			var geometry = object.geometry;
10415
10416			if ( object.isMesh ) {
10417
10418				var direct = geometry.__directGeometry;
10419
10420				if ( geometry.elementsNeedUpdate === true ) {
10421
10422					direct = undefined;
10423					geometry.elementsNeedUpdate = false;
10424
10425				}
10426
10427				if ( direct === undefined ) {
10428
10429					return this.fromGeometry( geometry );
10430
10431				}
10432
10433				direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
10434				direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
10435				direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
10436				direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
10437				direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
10438
10439				geometry.verticesNeedUpdate = false;
10440				geometry.normalsNeedUpdate = false;
10441				geometry.colorsNeedUpdate = false;
10442				geometry.uvsNeedUpdate = false;
10443				geometry.groupsNeedUpdate = false;
10444
10445				geometry = direct;
10446
10447			}
10448
10449			if ( geometry.verticesNeedUpdate === true ) {
10450
10451				var attribute = this.attributes.position;
10452
10453				if ( attribute !== undefined ) {
10454
10455					attribute.copyVector3sArray( geometry.vertices );
10456					attribute.needsUpdate = true;
10457
10458				}
10459
10460				geometry.verticesNeedUpdate = false;
10461
10462			}
10463
10464			if ( geometry.normalsNeedUpdate === true ) {
10465
10466				var attribute$1 = this.attributes.normal;
10467
10468				if ( attribute$1 !== undefined ) {
10469
10470					attribute$1.copyVector3sArray( geometry.normals );
10471					attribute$1.needsUpdate = true;
10472
10473				}
10474
10475				geometry.normalsNeedUpdate = false;
10476
10477			}
10478
10479			if ( geometry.colorsNeedUpdate === true ) {
10480
10481				var attribute$2 = this.attributes.color;
10482
10483				if ( attribute$2 !== undefined ) {
10484
10485					attribute$2.copyColorsArray( geometry.colors );
10486					attribute$2.needsUpdate = true;
10487
10488				}
10489
10490				geometry.colorsNeedUpdate = false;
10491
10492			}
10493
10494			if ( geometry.uvsNeedUpdate ) {
10495
10496				var attribute$3 = this.attributes.uv;
10497
10498				if ( attribute$3 !== undefined ) {
10499
10500					attribute$3.copyVector2sArray( geometry.uvs );
10501					attribute$3.needsUpdate = true;
10502
10503				}
10504
10505				geometry.uvsNeedUpdate = false;
10506
10507			}
10508
10509			if ( geometry.lineDistancesNeedUpdate ) {
10510
10511				var attribute$4 = this.attributes.lineDistance;
10512
10513				if ( attribute$4 !== undefined ) {
10514
10515					attribute$4.copyArray( geometry.lineDistances );
10516					attribute$4.needsUpdate = true;
10517
10518				}
10519
10520				geometry.lineDistancesNeedUpdate = false;
10521
10522			}
10523
10524			if ( geometry.groupsNeedUpdate ) {
10525
10526				geometry.computeGroups( object.geometry );
10527				this.groups = geometry.groups;
10528
10529				geometry.groupsNeedUpdate = false;
10530
10531			}
10532
10533			return this;
10534
10535		},
10536
10537		fromGeometry: function ( geometry ) {
10538
10539			geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
10540
10541			return this.fromDirectGeometry( geometry.__directGeometry );
10542
10543		},
10544
10545		fromDirectGeometry: function ( geometry ) {
10546
10547			var positions = new Float32Array( geometry.vertices.length * 3 );
10548			this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
10549
10550			if ( geometry.normals.length > 0 ) {
10551
10552				var normals = new Float32Array( geometry.normals.length * 3 );
10553				this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
10554
10555			}
10556
10557			if ( geometry.colors.length > 0 ) {
10558
10559				var colors = new Float32Array( geometry.colors.length * 3 );
10560				this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
10561
10562			}
10563
10564			if ( geometry.uvs.length > 0 ) {
10565
10566				var uvs = new Float32Array( geometry.uvs.length * 2 );
10567				this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
10568
10569			}
10570
10571			if ( geometry.uvs2.length > 0 ) {
10572
10573				var uvs2 = new Float32Array( geometry.uvs2.length * 2 );
10574				this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
10575
10576			}
10577
10578			// groups
10579
10580			this.groups = geometry.groups;
10581
10582			// morphs
10583
10584			for ( var name in geometry.morphTargets ) {
10585
10586				var array = [];
10587				var morphTargets = geometry.morphTargets[ name ];
10588
10589				for ( var i = 0, l = morphTargets.length; i < l; i ++ ) {
10590
10591					var morphTarget = morphTargets[ i ];
10592
10593					var attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 );
10594					attribute.name = morphTarget.name;
10595
10596					array.push( attribute.copyVector3sArray( morphTarget.data ) );
10597
10598				}
10599
10600				this.morphAttributes[ name ] = array;
10601
10602			}
10603
10604			// skinning
10605
10606			if ( geometry.skinIndices.length > 0 ) {
10607
10608				var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
10609				this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
10610
10611			}
10612
10613			if ( geometry.skinWeights.length > 0 ) {
10614
10615				var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
10616				this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
10617
10618			}
10619
10620			//
10621
10622			if ( geometry.boundingSphere !== null ) {
10623
10624				this.boundingSphere = geometry.boundingSphere.clone();
10625
10626			}
10627
10628			if ( geometry.boundingBox !== null ) {
10629
10630				this.boundingBox = geometry.boundingBox.clone();
10631
10632			}
10633
10634			return this;
10635
10636		},
10637
10638		computeBoundingBox: function () {
10639
10640			if ( this.boundingBox === null ) {
10641
10642				this.boundingBox = new Box3();
10643
10644			}
10645
10646			var position = this.attributes.position;
10647			var morphAttributesPosition = this.morphAttributes.position;
10648
10649			if ( position !== undefined ) {
10650
10651				this.boundingBox.setFromBufferAttribute( position );
10652
10653				// process morph attributes if present
10654
10655				if ( morphAttributesPosition ) {
10656
10657					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
10658
10659						var morphAttribute = morphAttributesPosition[ i ];
10660						_box$2.setFromBufferAttribute( morphAttribute );
10661
10662						if ( this.morphTargetsRelative ) {
10663
10664							_vector$4.addVectors( this.boundingBox.min, _box$2.min );
10665							this.boundingBox.expandByPoint( _vector$4 );
10666
10667							_vector$4.addVectors( this.boundingBox.max, _box$2.max );
10668							this.boundingBox.expandByPoint( _vector$4 );
10669
10670						} else {
10671
10672							this.boundingBox.expandByPoint( _box$2.min );
10673							this.boundingBox.expandByPoint( _box$2.max );
10674
10675						}
10676
10677					}
10678
10679				}
10680
10681			} else {
10682
10683				this.boundingBox.makeEmpty();
10684
10685			}
10686
10687			if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
10688
10689				console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
10690
10691			}
10692
10693		},
10694
10695		computeBoundingSphere: function () {
10696
10697			if ( this.boundingSphere === null ) {
10698
10699				this.boundingSphere = new Sphere();
10700
10701			}
10702
10703			var position = this.attributes.position;
10704			var morphAttributesPosition = this.morphAttributes.position;
10705
10706			if ( position ) {
10707
10708				// first, find the center of the bounding sphere
10709
10710				var center = this.boundingSphere.center;
10711
10712				_box$2.setFromBufferAttribute( position );
10713
10714				// process morph attributes if present
10715
10716				if ( morphAttributesPosition ) {
10717
10718					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
10719
10720						var morphAttribute = morphAttributesPosition[ i ];
10721						_boxMorphTargets.setFromBufferAttribute( morphAttribute );
10722
10723						if ( this.morphTargetsRelative ) {
10724
10725							_vector$4.addVectors( _box$2.min, _boxMorphTargets.min );
10726							_box$2.expandByPoint( _vector$4 );
10727
10728							_vector$4.addVectors( _box$2.max, _boxMorphTargets.max );
10729							_box$2.expandByPoint( _vector$4 );
10730
10731						} else {
10732
10733							_box$2.expandByPoint( _boxMorphTargets.min );
10734							_box$2.expandByPoint( _boxMorphTargets.max );
10735
10736						}
10737
10738					}
10739
10740				}
10741
10742				_box$2.getCenter( center );
10743
10744				// second, try to find a boundingSphere with a radius smaller than the
10745				// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
10746
10747				var maxRadiusSq = 0;
10748
10749				for ( var i$1 = 0, il$1 = position.count; i$1 < il$1; i$1 ++ ) {
10750
10751					_vector$4.fromBufferAttribute( position, i$1 );
10752
10753					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) );
10754
10755				}
10756
10757				// process morph attributes if present
10758
10759				if ( morphAttributesPosition ) {
10760
10761					for ( var i$2 = 0, il$2 = morphAttributesPosition.length; i$2 < il$2; i$2 ++ ) {
10762
10763						var morphAttribute$1 = morphAttributesPosition[ i$2 ];
10764						var morphTargetsRelative = this.morphTargetsRelative;
10765
10766						for ( var j = 0, jl = morphAttribute$1.count; j < jl; j ++ ) {
10767
10768							_vector$4.fromBufferAttribute( morphAttribute$1, j );
10769
10770							if ( morphTargetsRelative ) {
10771
10772								_offset.fromBufferAttribute( position, j );
10773								_vector$4.add( _offset );
10774
10775							}
10776
10777							maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) );
10778
10779						}
10780
10781					}
10782
10783				}
10784
10785				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
10786
10787				if ( isNaN( this.boundingSphere.radius ) ) {
10788
10789					console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
10790
10791				}
10792
10793			}
10794
10795		},
10796
10797		computeFaceNormals: function () {
10798
10799			// backwards compatibility
10800
10801		},
10802
10803		computeVertexNormals: function () {
10804
10805			var index = this.index;
10806			var positionAttribute = this.getAttribute( 'position' );
10807
10808			if ( positionAttribute !== undefined ) {
10809
10810				var normalAttribute = this.getAttribute( 'normal' );
10811
10812				if ( normalAttribute === undefined ) {
10813
10814					normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 );
10815					this.setAttribute( 'normal', normalAttribute );
10816
10817				} else {
10818
10819					// reset existing normals to zero
10820
10821					for ( var i = 0, il = normalAttribute.count; i < il; i ++ ) {
10822
10823						normalAttribute.setXYZ( i, 0, 0, 0 );
10824
10825					}
10826
10827				}
10828
10829				var pA = new Vector3(), pB = new Vector3(), pC = new Vector3();
10830				var nA = new Vector3(), nB = new Vector3(), nC = new Vector3();
10831				var cb = new Vector3(), ab = new Vector3();
10832
10833				// indexed elements
10834
10835				if ( index ) {
10836
10837					for ( var i$1 = 0, il$1 = index.count; i$1 < il$1; i$1 += 3 ) {
10838
10839						var vA = index.getX( i$1 + 0 );
10840						var vB = index.getX( i$1 + 1 );
10841						var vC = index.getX( i$1 + 2 );
10842
10843						pA.fromBufferAttribute( positionAttribute, vA );
10844						pB.fromBufferAttribute( positionAttribute, vB );
10845						pC.fromBufferAttribute( positionAttribute, vC );
10846
10847						cb.subVectors( pC, pB );
10848						ab.subVectors( pA, pB );
10849						cb.cross( ab );
10850
10851						nA.fromBufferAttribute( normalAttribute, vA );
10852						nB.fromBufferAttribute( normalAttribute, vB );
10853						nC.fromBufferAttribute( normalAttribute, vC );
10854
10855						nA.add( cb );
10856						nB.add( cb );
10857						nC.add( cb );
10858
10859						normalAttribute.setXYZ( vA, nA.x, nA.y, nA.z );
10860						normalAttribute.setXYZ( vB, nB.x, nB.y, nB.z );
10861						normalAttribute.setXYZ( vC, nC.x, nC.y, nC.z );
10862
10863					}
10864
10865				} else {
10866
10867					// non-indexed elements (unconnected triangle soup)
10868
10869					for ( var i$2 = 0, il$2 = positionAttribute.count; i$2 < il$2; i$2 += 3 ) {
10870
10871						pA.fromBufferAttribute( positionAttribute, i$2 + 0 );
10872						pB.fromBufferAttribute( positionAttribute, i$2 + 1 );
10873						pC.fromBufferAttribute( positionAttribute, i$2 + 2 );
10874
10875						cb.subVectors( pC, pB );
10876						ab.subVectors( pA, pB );
10877						cb.cross( ab );
10878
10879						normalAttribute.setXYZ( i$2 + 0, cb.x, cb.y, cb.z );
10880						normalAttribute.setXYZ( i$2 + 1, cb.x, cb.y, cb.z );
10881						normalAttribute.setXYZ( i$2 + 2, cb.x, cb.y, cb.z );
10882
10883					}
10884
10885				}
10886
10887				this.normalizeNormals();
10888
10889				normalAttribute.needsUpdate = true;
10890
10891			}
10892
10893		},
10894
10895		merge: function ( geometry, offset ) {
10896
10897			if ( ! ( geometry && geometry.isBufferGeometry ) ) {
10898
10899				console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
10900				return;
10901
10902			}
10903
10904			if ( offset === undefined ) {
10905
10906				offset = 0;
10907
10908				console.warn(
10909					'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. '
10910					+ 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'
10911				);
10912
10913			}
10914
10915			var attributes = this.attributes;
10916
10917			for ( var key in attributes ) {
10918
10919				if ( geometry.attributes[ key ] === undefined ) { continue; }
10920
10921				var attribute1 = attributes[ key ];
10922				var attributeArray1 = attribute1.array;
10923
10924				var attribute2 = geometry.attributes[ key ];
10925				var attributeArray2 = attribute2.array;
10926
10927				var attributeOffset = attribute2.itemSize * offset;
10928				var length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset );
10929
10930				for ( var i = 0, j = attributeOffset; i < length; i ++, j ++ ) {
10931
10932					attributeArray1[ j ] = attributeArray2[ i ];
10933
10934				}
10935
10936			}
10937
10938			return this;
10939
10940		},
10941
10942		normalizeNormals: function () {
10943
10944			var normals = this.attributes.normal;
10945
10946			for ( var i = 0, il = normals.count; i < il; i ++ ) {
10947
10948				_vector$4.fromBufferAttribute( normals, i );
10949
10950				_vector$4.normalize();
10951
10952				normals.setXYZ( i, _vector$4.x, _vector$4.y, _vector$4.z );
10953
10954			}
10955
10956		},
10957
10958		toNonIndexed: function () {
10959
10960			function convertBufferAttribute( attribute, indices ) {
10961
10962				var array = attribute.array;
10963				var itemSize = attribute.itemSize;
10964				var normalized = attribute.normalized;
10965
10966				var array2 = new array.constructor( indices.length * itemSize );
10967
10968				var index = 0, index2 = 0;
10969
10970				for ( var i = 0, l = indices.length; i < l; i ++ ) {
10971
10972					index = indices[ i ] * itemSize;
10973
10974					for ( var j = 0; j < itemSize; j ++ ) {
10975
10976						array2[ index2 ++ ] = array[ index ++ ];
10977
10978					}
10979
10980				}
10981
10982				return new BufferAttribute( array2, itemSize, normalized );
10983
10984			}
10985
10986			//
10987
10988			if ( this.index === null ) {
10989
10990				console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );
10991				return this;
10992
10993			}
10994
10995			var geometry2 = new BufferGeometry();
10996
10997			var indices = this.index.array;
10998			var attributes = this.attributes;
10999
11000			// attributes
11001
11002			for ( var name in attributes ) {
11003
11004				var attribute = attributes[ name ];
11005
11006				var newAttribute = convertBufferAttribute( attribute, indices );
11007
11008				geometry2.setAttribute( name, newAttribute );
11009
11010			}
11011
11012			// morph attributes
11013
11014			var morphAttributes = this.morphAttributes;
11015
11016			for ( var name$1 in morphAttributes ) {
11017
11018				var morphArray = [];
11019				var morphAttribute = morphAttributes[ name$1 ]; // morphAttribute: array of Float32BufferAttributes
11020
11021				for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) {
11022
11023					var attribute$1 = morphAttribute[ i ];
11024
11025					var newAttribute$1 = convertBufferAttribute( attribute$1, indices );
11026
11027					morphArray.push( newAttribute$1 );
11028
11029				}
11030
11031				geometry2.morphAttributes[ name$1 ] = morphArray;
11032
11033			}
11034
11035			geometry2.morphTargetsRelative = this.morphTargetsRelative;
11036
11037			// groups
11038
11039			var groups = this.groups;
11040
11041			for ( var i$1 = 0, l = groups.length; i$1 < l; i$1 ++ ) {
11042
11043				var group = groups[ i$1 ];
11044				geometry2.addGroup( group.start, group.count, group.materialIndex );
11045
11046			}
11047
11048			return geometry2;
11049
11050		},
11051
11052		toJSON: function () {
11053
11054			var data = {
11055				metadata: {
11056					version: 4.5,
11057					type: 'BufferGeometry',
11058					generator: 'BufferGeometry.toJSON'
11059				}
11060			};
11061
11062			// standard BufferGeometry serialization
11063
11064			data.uuid = this.uuid;
11065			data.type = this.type;
11066			if ( this.name !== '' ) { data.name = this.name; }
11067			if ( Object.keys( this.userData ).length > 0 ) { data.userData = this.userData; }
11068
11069			if ( this.parameters !== undefined ) {
11070
11071				var parameters = this.parameters;
11072
11073				for ( var key in parameters ) {
11074
11075					if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; }
11076
11077				}
11078
11079				return data;
11080
11081			}
11082
11083			data.data = { attributes: {} };
11084
11085			var index = this.index;
11086
11087			if ( index !== null ) {
11088
11089				data.data.index = {
11090					type: index.array.constructor.name,
11091					array: Array.prototype.slice.call( index.array )
11092				};
11093
11094			}
11095
11096			var attributes = this.attributes;
11097
11098			for ( var key$1 in attributes ) {
11099
11100				var attribute = attributes[ key$1 ];
11101
11102				var attributeData = attribute.toJSON( data.data );
11103
11104				if ( attribute.name !== '' ) { attributeData.name = attribute.name; }
11105
11106				data.data.attributes[ key$1 ] = attributeData;
11107
11108			}
11109
11110			var morphAttributes = {};
11111			var hasMorphAttributes = false;
11112
11113			for ( var key$2 in this.morphAttributes ) {
11114
11115				var attributeArray = this.morphAttributes[ key$2 ];
11116
11117				var array = [];
11118
11119				for ( var i = 0, il = attributeArray.length; i < il; i ++ ) {
11120
11121					var attribute$1 = attributeArray[ i ];
11122
11123					var attributeData$1 = attribute$1.toJSON( data.data );
11124
11125					if ( attribute$1.name !== '' ) { attributeData$1.name = attribute$1.name; }
11126
11127					array.push( attributeData$1 );
11128
11129				}
11130
11131				if ( array.length > 0 ) {
11132
11133					morphAttributes[ key$2 ] = array;
11134
11135					hasMorphAttributes = true;
11136
11137				}
11138
11139			}
11140
11141			if ( hasMorphAttributes ) {
11142
11143				data.data.morphAttributes = morphAttributes;
11144				data.data.morphTargetsRelative = this.morphTargetsRelative;
11145
11146			}
11147
11148			var groups = this.groups;
11149
11150			if ( groups.length > 0 ) {
11151
11152				data.data.groups = JSON.parse( JSON.stringify( groups ) );
11153
11154			}
11155
11156			var boundingSphere = this.boundingSphere;
11157
11158			if ( boundingSphere !== null ) {
11159
11160				data.data.boundingSphere = {
11161					center: boundingSphere.center.toArray(),
11162					radius: boundingSphere.radius
11163				};
11164
11165			}
11166
11167			return data;
11168
11169		},
11170
11171		clone: function () {
11172
11173			/*
11174			 // Handle primitives
11175
11176			 const parameters = this.parameters;
11177
11178			 if ( parameters !== undefined ) {
11179
11180			 const values = [];
11181
11182			 for ( const key in parameters ) {
11183
11184			 values.push( parameters[ key ] );
11185
11186			 }
11187
11188			 const geometry = Object.create( this.constructor.prototype );
11189			 this.constructor.apply( geometry, values );
11190			 return geometry;
11191
11192			 }
11193
11194			 return new this.constructor().copy( this );
11195			 */
11196
11197			return new BufferGeometry().copy( this );
11198
11199		},
11200
11201		copy: function ( source ) {
11202
11203			// reset
11204
11205			this.index = null;
11206			this.attributes = {};
11207			this.morphAttributes = {};
11208			this.groups = [];
11209			this.boundingBox = null;
11210			this.boundingSphere = null;
11211
11212			// used for storing cloned, shared data
11213
11214			var data = {};
11215
11216			// name
11217
11218			this.name = source.name;
11219
11220			// index
11221
11222			var index = source.index;
11223
11224			if ( index !== null ) {
11225
11226				this.setIndex( index.clone( data ) );
11227
11228			}
11229
11230			// attributes
11231
11232			var attributes = source.attributes;
11233
11234			for ( var name in attributes ) {
11235
11236				var attribute = attributes[ name ];
11237				this.setAttribute( name, attribute.clone( data ) );
11238
11239			}
11240
11241			// morph attributes
11242
11243			var morphAttributes = source.morphAttributes;
11244
11245			for ( var name$1 in morphAttributes ) {
11246
11247				var array = [];
11248				var morphAttribute = morphAttributes[ name$1 ]; // morphAttribute: array of Float32BufferAttributes
11249
11250				for ( var i = 0, l = morphAttribute.length; i < l; i ++ ) {
11251
11252					array.push( morphAttribute[ i ].clone( data ) );
11253
11254				}
11255
11256				this.morphAttributes[ name$1 ] = array;
11257
11258			}
11259
11260			this.morphTargetsRelative = source.morphTargetsRelative;
11261
11262			// groups
11263
11264			var groups = source.groups;
11265
11266			for ( var i$1 = 0, l$1 = groups.length; i$1 < l$1; i$1 ++ ) {
11267
11268				var group = groups[ i$1 ];
11269				this.addGroup( group.start, group.count, group.materialIndex );
11270
11271			}
11272
11273			// bounding box
11274
11275			var boundingBox = source.boundingBox;
11276
11277			if ( boundingBox !== null ) {
11278
11279				this.boundingBox = boundingBox.clone();
11280
11281			}
11282
11283			// bounding sphere
11284
11285			var boundingSphere = source.boundingSphere;
11286
11287			if ( boundingSphere !== null ) {
11288
11289				this.boundingSphere = boundingSphere.clone();
11290
11291			}
11292
11293			// draw range
11294
11295			this.drawRange.start = source.drawRange.start;
11296			this.drawRange.count = source.drawRange.count;
11297
11298			// user data
11299
11300			this.userData = source.userData;
11301
11302			return this;
11303
11304		},
11305
11306		dispose: function () {
11307
11308			this.dispatchEvent( { type: 'dispose' } );
11309
11310		}
11311
11312	} );
11313
11314	/**
11315	 * @author mrdoob / http://mrdoob.com/
11316	 * @author alteredq / http://alteredqualia.com/
11317	 * @author mikael emtinger / http://gomo.se/
11318	 * @author jonobr1 / http://jonobr1.com/
11319	 */
11320
11321	var _inverseMatrix = new Matrix4();
11322	var _ray = new Ray();
11323	var _sphere = new Sphere();
11324
11325	var _vA = new Vector3();
11326	var _vB = new Vector3();
11327	var _vC = new Vector3();
11328
11329	var _tempA = new Vector3();
11330	var _tempB = new Vector3();
11331	var _tempC = new Vector3();
11332
11333	var _morphA = new Vector3();
11334	var _morphB = new Vector3();
11335	var _morphC = new Vector3();
11336
11337	var _uvA = new Vector2();
11338	var _uvB = new Vector2();
11339	var _uvC = new Vector2();
11340
11341	var _intersectionPoint = new Vector3();
11342	var _intersectionPointWorld = new Vector3();
11343
11344	function Mesh( geometry, material ) {
11345
11346		Object3D.call( this );
11347
11348		this.type = 'Mesh';
11349
11350		this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
11351		this.material = material !== undefined ? material : new MeshBasicMaterial();
11352
11353		this.updateMorphTargets();
11354
11355	}
11356
11357	Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
11358
11359		constructor: Mesh,
11360
11361		isMesh: true,
11362
11363		copy: function ( source ) {
11364
11365			Object3D.prototype.copy.call( this, source );
11366
11367			if ( source.morphTargetInfluences !== undefined ) {
11368
11369				this.morphTargetInfluences = source.morphTargetInfluences.slice();
11370
11371			}
11372
11373			if ( source.morphTargetDictionary !== undefined ) {
11374
11375				this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary );
11376
11377			}
11378
11379			this.material = source.material;
11380			this.geometry = source.geometry;
11381
11382			return this;
11383
11384		},
11385
11386		updateMorphTargets: function () {
11387
11388			var geometry = this.geometry;
11389
11390			if ( geometry.isBufferGeometry ) {
11391
11392				var morphAttributes = geometry.morphAttributes;
11393				var keys = Object.keys( morphAttributes );
11394
11395				if ( keys.length > 0 ) {
11396
11397					var morphAttribute = morphAttributes[ keys[ 0 ] ];
11398
11399					if ( morphAttribute !== undefined ) {
11400
11401						this.morphTargetInfluences = [];
11402						this.morphTargetDictionary = {};
11403
11404						for ( var m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
11405
11406							var name = morphAttribute[ m ].name || String( m );
11407
11408							this.morphTargetInfluences.push( 0 );
11409							this.morphTargetDictionary[ name ] = m;
11410
11411						}
11412
11413					}
11414
11415				}
11416
11417			} else {
11418
11419				var morphTargets = geometry.morphTargets;
11420
11421				if ( morphTargets !== undefined && morphTargets.length > 0 ) {
11422
11423					console.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
11424
11425				}
11426
11427			}
11428
11429		},
11430
11431		raycast: function ( raycaster, intersects ) {
11432
11433			var geometry = this.geometry;
11434			var material = this.material;
11435			var matrixWorld = this.matrixWorld;
11436
11437			if ( material === undefined ) { return; }
11438
11439			// Checking boundingSphere distance to ray
11440
11441			if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
11442
11443			_sphere.copy( geometry.boundingSphere );
11444			_sphere.applyMatrix4( matrixWorld );
11445
11446			if ( raycaster.ray.intersectsSphere( _sphere ) === false ) { return; }
11447
11448			//
11449
11450			_inverseMatrix.getInverse( matrixWorld );
11451			_ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
11452
11453			// Check boundingBox before continuing
11454
11455			if ( geometry.boundingBox !== null ) {
11456
11457				if ( _ray.intersectsBox( geometry.boundingBox ) === false ) { return; }
11458
11459			}
11460
11461			var intersection;
11462
11463			if ( geometry.isBufferGeometry ) {
11464
11465				var index = geometry.index;
11466				var position = geometry.attributes.position;
11467				var morphPosition = geometry.morphAttributes.position;
11468				var morphTargetsRelative = geometry.morphTargetsRelative;
11469				var uv = geometry.attributes.uv;
11470				var uv2 = geometry.attributes.uv2;
11471				var groups = geometry.groups;
11472				var drawRange = geometry.drawRange;
11473
11474				if ( index !== null ) {
11475
11476					// indexed buffer geometry
11477
11478					if ( Array.isArray( material ) ) {
11479
11480						for ( var i = 0, il = groups.length; i < il; i ++ ) {
11481
11482							var group = groups[ i ];
11483							var groupMaterial = material[ group.materialIndex ];
11484
11485							var start = Math.max( group.start, drawRange.start );
11486							var end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
11487
11488							for ( var j = start, jl = end; j < jl; j += 3 ) {
11489
11490								var a = index.getX( j );
11491								var b = index.getX( j + 1 );
11492								var c = index.getX( j + 2 );
11493
11494								intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
11495
11496								if ( intersection ) {
11497
11498									intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
11499									intersection.face.materialIndex = group.materialIndex;
11500									intersects.push( intersection );
11501
11502								}
11503
11504							}
11505
11506						}
11507
11508					} else {
11509
11510						var start$1 = Math.max( 0, drawRange.start );
11511						var end$1 = Math.min( index.count, ( drawRange.start + drawRange.count ) );
11512
11513						for ( var i$1 = start$1, il$1 = end$1; i$1 < il$1; i$1 += 3 ) {
11514
11515							var a$1 = index.getX( i$1 );
11516							var b$1 = index.getX( i$1 + 1 );
11517							var c$1 = index.getX( i$1 + 2 );
11518
11519							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a$1, b$1, c$1 );
11520
11521							if ( intersection ) {
11522
11523								intersection.faceIndex = Math.floor( i$1 / 3 ); // triangle number in indexed buffer semantics
11524								intersects.push( intersection );
11525
11526							}
11527
11528						}
11529
11530					}
11531
11532				} else if ( position !== undefined ) {
11533
11534					// non-indexed buffer geometry
11535
11536					if ( Array.isArray( material ) ) {
11537
11538						for ( var i$2 = 0, il$2 = groups.length; i$2 < il$2; i$2 ++ ) {
11539
11540							var group$1 = groups[ i$2 ];
11541							var groupMaterial$1 = material[ group$1.materialIndex ];
11542
11543							var start$2 = Math.max( group$1.start, drawRange.start );
11544							var end$2 = Math.min( ( group$1.start + group$1.count ), ( drawRange.start + drawRange.count ) );
11545
11546							for ( var j$1 = start$2, jl$1 = end$2; j$1 < jl$1; j$1 += 3 ) {
11547
11548								var a$2 = j$1;
11549								var b$2 = j$1 + 1;
11550								var c$2 = j$1 + 2;
11551
11552								intersection = checkBufferGeometryIntersection( this, groupMaterial$1, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a$2, b$2, c$2 );
11553
11554								if ( intersection ) {
11555
11556									intersection.faceIndex = Math.floor( j$1 / 3 ); // triangle number in non-indexed buffer semantics
11557									intersection.face.materialIndex = group$1.materialIndex;
11558									intersects.push( intersection );
11559
11560								}
11561
11562							}
11563
11564						}
11565
11566					} else {
11567
11568						var start$3 = Math.max( 0, drawRange.start );
11569						var end$3 = Math.min( position.count, ( drawRange.start + drawRange.count ) );
11570
11571						for ( var i$3 = start$3, il$3 = end$3; i$3 < il$3; i$3 += 3 ) {
11572
11573							var a$3 = i$3;
11574							var b$3 = i$3 + 1;
11575							var c$3 = i$3 + 2;
11576
11577							intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a$3, b$3, c$3 );
11578
11579							if ( intersection ) {
11580
11581								intersection.faceIndex = Math.floor( i$3 / 3 ); // triangle number in non-indexed buffer semantics
11582								intersects.push( intersection );
11583
11584							}
11585
11586						}
11587
11588					}
11589
11590				}
11591
11592			} else if ( geometry.isGeometry ) {
11593
11594				var isMultiMaterial = Array.isArray( material );
11595
11596				var vertices = geometry.vertices;
11597				var faces = geometry.faces;
11598				var uvs;
11599
11600				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
11601				if ( faceVertexUvs.length > 0 ) { uvs = faceVertexUvs; }
11602
11603				for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
11604
11605					var face = faces[ f ];
11606					var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
11607
11608					if ( faceMaterial === undefined ) { continue; }
11609
11610					var fvA = vertices[ face.a ];
11611					var fvB = vertices[ face.b ];
11612					var fvC = vertices[ face.c ];
11613
11614					intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
11615
11616					if ( intersection ) {
11617
11618						if ( uvs && uvs[ f ] ) {
11619
11620							var uvs_f = uvs[ f ];
11621							_uvA.copy( uvs_f[ 0 ] );
11622							_uvB.copy( uvs_f[ 1 ] );
11623							_uvC.copy( uvs_f[ 2 ] );
11624
11625							intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
11626
11627						}
11628
11629						intersection.face = face;
11630						intersection.faceIndex = f;
11631						intersects.push( intersection );
11632
11633					}
11634
11635				}
11636
11637			}
11638
11639		}
11640
11641	} );
11642
11643	function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) {
11644
11645		var intersect;
11646
11647		if ( material.side === BackSide ) {
11648
11649			intersect = ray.intersectTriangle( pC, pB, pA, true, point );
11650
11651		} else {
11652
11653			intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
11654
11655		}
11656
11657		if ( intersect === null ) { return null; }
11658
11659		_intersectionPointWorld.copy( point );
11660		_intersectionPointWorld.applyMatrix4( object.matrixWorld );
11661
11662		var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );
11663
11664		if ( distance < raycaster.near || distance > raycaster.far ) { return null; }
11665
11666		return {
11667			distance: distance,
11668			point: _intersectionPointWorld.clone(),
11669			object: object
11670		};
11671
11672	}
11673
11674	function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {
11675
11676		_vA.fromBufferAttribute( position, a );
11677		_vB.fromBufferAttribute( position, b );
11678		_vC.fromBufferAttribute( position, c );
11679
11680		var morphInfluences = object.morphTargetInfluences;
11681
11682		if ( material.morphTargets && morphPosition && morphInfluences ) {
11683
11684			_morphA.set( 0, 0, 0 );
11685			_morphB.set( 0, 0, 0 );
11686			_morphC.set( 0, 0, 0 );
11687
11688			for ( var i = 0, il = morphPosition.length; i < il; i ++ ) {
11689
11690				var influence = morphInfluences[ i ];
11691				var morphAttribute = morphPosition[ i ];
11692
11693				if ( influence === 0 ) { continue; }
11694
11695				_tempA.fromBufferAttribute( morphAttribute, a );
11696				_tempB.fromBufferAttribute( morphAttribute, b );
11697				_tempC.fromBufferAttribute( morphAttribute, c );
11698
11699				if ( morphTargetsRelative ) {
11700
11701					_morphA.addScaledVector( _tempA, influence );
11702					_morphB.addScaledVector( _tempB, influence );
11703					_morphC.addScaledVector( _tempC, influence );
11704
11705				} else {
11706
11707					_morphA.addScaledVector( _tempA.sub( _vA ), influence );
11708					_morphB.addScaledVector( _tempB.sub( _vB ), influence );
11709					_morphC.addScaledVector( _tempC.sub( _vC ), influence );
11710
11711				}
11712
11713			}
11714
11715			_vA.add( _morphA );
11716			_vB.add( _morphB );
11717			_vC.add( _morphC );
11718
11719		}
11720
11721		if ( object.isSkinnedMesh ) {
11722
11723			object.boneTransform( a, _vA );
11724			object.boneTransform( b, _vB );
11725			object.boneTransform( c, _vC );
11726
11727		}
11728
11729		var intersection = checkIntersection( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint );
11730
11731		if ( intersection ) {
11732
11733			if ( uv ) {
11734
11735				_uvA.fromBufferAttribute( uv, a );
11736				_uvB.fromBufferAttribute( uv, b );
11737				_uvC.fromBufferAttribute( uv, c );
11738
11739				intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
11740
11741			}
11742
11743			if ( uv2 ) {
11744
11745				_uvA.fromBufferAttribute( uv2, a );
11746				_uvB.fromBufferAttribute( uv2, b );
11747				_uvC.fromBufferAttribute( uv2, c );
11748
11749				intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
11750
11751			}
11752
11753			var face = new Face3( a, b, c );
11754			Triangle.getNormal( _vA, _vB, _vC, face.normal );
11755
11756			intersection.face = face;
11757
11758		}
11759
11760		return intersection;
11761
11762	}
11763
11764	/**
11765	 * @author mrdoob / http://mrdoob.com/
11766	 * @author kile / http://kile.stravaganza.org/
11767	 * @author alteredq / http://alteredqualia.com/
11768	 * @author mikael emtinger / http://gomo.se/
11769	 * @author zz85 / http://www.lab4games.net/zz85/blog
11770	 * @author bhouston / http://clara.io
11771	 */
11772
11773	var _geometryId = 0; // Geometry uses even numbers as Id
11774	var _m1$3 = new Matrix4();
11775	var _obj$1 = new Object3D();
11776	var _offset$1 = new Vector3();
11777
11778	function Geometry() {
11779
11780		Object.defineProperty( this, 'id', { value: _geometryId += 2 } );
11781
11782		this.uuid = MathUtils.generateUUID();
11783
11784		this.name = '';
11785		this.type = 'Geometry';
11786
11787		this.vertices = [];
11788		this.colors = [];
11789		this.faces = [];
11790		this.faceVertexUvs = [[]];
11791
11792		this.morphTargets = [];
11793		this.morphNormals = [];
11794
11795		this.skinWeights = [];
11796		this.skinIndices = [];
11797
11798		this.lineDistances = [];
11799
11800		this.boundingBox = null;
11801		this.boundingSphere = null;
11802
11803		// update flags
11804
11805		this.elementsNeedUpdate = false;
11806		this.verticesNeedUpdate = false;
11807		this.uvsNeedUpdate = false;
11808		this.normalsNeedUpdate = false;
11809		this.colorsNeedUpdate = false;
11810		this.lineDistancesNeedUpdate = false;
11811		this.groupsNeedUpdate = false;
11812
11813	}
11814
11815	Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
11816
11817		constructor: Geometry,
11818
11819		isGeometry: true,
11820
11821		applyMatrix4: function ( matrix ) {
11822
11823			var normalMatrix = new Matrix3().getNormalMatrix( matrix );
11824
11825			for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
11826
11827				var vertex = this.vertices[ i ];
11828				vertex.applyMatrix4( matrix );
11829
11830			}
11831
11832			for ( var i$1 = 0, il$1 = this.faces.length; i$1 < il$1; i$1 ++ ) {
11833
11834				var face = this.faces[ i$1 ];
11835				face.normal.applyMatrix3( normalMatrix ).normalize();
11836
11837				for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
11838
11839					face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
11840
11841				}
11842
11843			}
11844
11845			if ( this.boundingBox !== null ) {
11846
11847				this.computeBoundingBox();
11848
11849			}
11850
11851			if ( this.boundingSphere !== null ) {
11852
11853				this.computeBoundingSphere();
11854
11855			}
11856
11857			this.verticesNeedUpdate = true;
11858			this.normalsNeedUpdate = true;
11859
11860			return this;
11861
11862		},
11863
11864		rotateX: function ( angle ) {
11865
11866			// rotate geometry around world x-axis
11867
11868			_m1$3.makeRotationX( angle );
11869
11870			this.applyMatrix4( _m1$3 );
11871
11872			return this;
11873
11874		},
11875
11876		rotateY: function ( angle ) {
11877
11878			// rotate geometry around world y-axis
11879
11880			_m1$3.makeRotationY( angle );
11881
11882			this.applyMatrix4( _m1$3 );
11883
11884			return this;
11885
11886		},
11887
11888		rotateZ: function ( angle ) {
11889
11890			// rotate geometry around world z-axis
11891
11892			_m1$3.makeRotationZ( angle );
11893
11894			this.applyMatrix4( _m1$3 );
11895
11896			return this;
11897
11898		},
11899
11900		translate: function ( x, y, z ) {
11901
11902			// translate geometry
11903
11904			_m1$3.makeTranslation( x, y, z );
11905
11906			this.applyMatrix4( _m1$3 );
11907
11908			return this;
11909
11910		},
11911
11912		scale: function ( x, y, z ) {
11913
11914			// scale geometry
11915
11916			_m1$3.makeScale( x, y, z );
11917
11918			this.applyMatrix4( _m1$3 );
11919
11920			return this;
11921
11922		},
11923
11924		lookAt: function ( vector ) {
11925
11926			_obj$1.lookAt( vector );
11927
11928			_obj$1.updateMatrix();
11929
11930			this.applyMatrix4( _obj$1.matrix );
11931
11932			return this;
11933
11934		},
11935
11936		fromBufferGeometry: function ( geometry ) {
11937
11938			var scope = this;
11939
11940			var index = geometry.index !== null ? geometry.index : undefined;
11941			var attributes = geometry.attributes;
11942
11943			if ( attributes.position === undefined ) {
11944
11945				console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' );
11946				return this;
11947
11948			}
11949
11950			var position = attributes.position;
11951			var normal = attributes.normal;
11952			var color = attributes.color;
11953			var uv = attributes.uv;
11954			var uv2 = attributes.uv2;
11955
11956			if ( uv2 !== undefined ) { this.faceVertexUvs[ 1 ] = []; }
11957
11958			for ( var i = 0; i < position.count; i ++ ) {
11959
11960				scope.vertices.push( new Vector3().fromBufferAttribute( position, i ) );
11961
11962				if ( color !== undefined ) {
11963
11964					scope.colors.push( new Color().fromBufferAttribute( color, i ) );
11965
11966				}
11967
11968			}
11969
11970			function addFace( a, b, c, materialIndex ) {
11971
11972				var vertexColors = ( color === undefined ) ? [] : [
11973					scope.colors[ a ].clone(),
11974					scope.colors[ b ].clone(),
11975					scope.colors[ c ].clone()
11976				];
11977
11978				var vertexNormals = ( normal === undefined ) ? [] : [
11979					new Vector3().fromBufferAttribute( normal, a ),
11980					new Vector3().fromBufferAttribute( normal, b ),
11981					new Vector3().fromBufferAttribute( normal, c )
11982				];
11983
11984				var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );
11985
11986				scope.faces.push( face );
11987
11988				if ( uv !== undefined ) {
11989
11990					scope.faceVertexUvs[ 0 ].push( [
11991						new Vector2().fromBufferAttribute( uv, a ),
11992						new Vector2().fromBufferAttribute( uv, b ),
11993						new Vector2().fromBufferAttribute( uv, c )
11994					] );
11995
11996				}
11997
11998				if ( uv2 !== undefined ) {
11999
12000					scope.faceVertexUvs[ 1 ].push( [
12001						new Vector2().fromBufferAttribute( uv2, a ),
12002						new Vector2().fromBufferAttribute( uv2, b ),
12003						new Vector2().fromBufferAttribute( uv2, c )
12004					] );
12005
12006				}
12007
12008			}
12009
12010			var groups = geometry.groups;
12011
12012			if ( groups.length > 0 ) {
12013
12014				for ( var i$1 = 0; i$1 < groups.length; i$1 ++ ) {
12015
12016					var group = groups[ i$1 ];
12017
12018					var start = group.start;
12019					var count = group.count;
12020
12021					for ( var j = start, jl = start + count; j < jl; j += 3 ) {
12022
12023						if ( index !== undefined ) {
12024
12025							addFace( index.getX( j ), index.getX( j + 1 ), index.getX( j + 2 ), group.materialIndex );
12026
12027						} else {
12028
12029							addFace( j, j + 1, j + 2, group.materialIndex );
12030
12031						}
12032
12033					}
12034
12035				}
12036
12037			} else {
12038
12039				if ( index !== undefined ) {
12040
12041					for ( var i$2 = 0; i$2 < index.count; i$2 += 3 ) {
12042
12043						addFace( index.getX( i$2 ), index.getX( i$2 + 1 ), index.getX( i$2 + 2 ) );
12044
12045					}
12046
12047				} else {
12048
12049					for ( var i$3 = 0; i$3 < position.count; i$3 += 3 ) {
12050
12051						addFace( i$3, i$3 + 1, i$3 + 2 );
12052
12053					}
12054
12055				}
12056
12057			}
12058
12059			this.computeFaceNormals();
12060
12061			if ( geometry.boundingBox !== null ) {
12062
12063				this.boundingBox = geometry.boundingBox.clone();
12064
12065			}
12066
12067			if ( geometry.boundingSphere !== null ) {
12068
12069				this.boundingSphere = geometry.boundingSphere.clone();
12070
12071			}
12072
12073			return this;
12074
12075		},
12076
12077		center: function () {
12078
12079			this.computeBoundingBox();
12080
12081			this.boundingBox.getCenter( _offset$1 ).negate();
12082
12083			this.translate( _offset$1.x, _offset$1.y, _offset$1.z );
12084
12085			return this;
12086
12087		},
12088
12089		normalize: function () {
12090
12091			this.computeBoundingSphere();
12092
12093			var center = this.boundingSphere.center;
12094			var radius = this.boundingSphere.radius;
12095
12096			var s = radius === 0 ? 1 : 1.0 / radius;
12097
12098			var matrix = new Matrix4();
12099			matrix.set(
12100				s, 0, 0, - s * center.x,
12101				0, s, 0, - s * center.y,
12102				0, 0, s, - s * center.z,
12103				0, 0, 0, 1
12104			);
12105
12106			this.applyMatrix4( matrix );
12107
12108			return this;
12109
12110		},
12111
12112		computeFaceNormals: function () {
12113
12114			var cb = new Vector3(), ab = new Vector3();
12115
12116			for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
12117
12118				var face = this.faces[ f ];
12119
12120				var vA = this.vertices[ face.a ];
12121				var vB = this.vertices[ face.b ];
12122				var vC = this.vertices[ face.c ];
12123
12124				cb.subVectors( vC, vB );
12125				ab.subVectors( vA, vB );
12126				cb.cross( ab );
12127
12128				cb.normalize();
12129
12130				face.normal.copy( cb );
12131
12132			}
12133
12134		},
12135
12136		computeVertexNormals: function ( areaWeighted ) {
12137
12138			if ( areaWeighted === undefined ) { areaWeighted = true; }
12139
12140			var vertices = new Array( this.vertices.length );
12141
12142			for ( var v = 0, vl = this.vertices.length; v < vl; v ++ ) {
12143
12144				vertices[ v ] = new Vector3();
12145
12146			}
12147
12148			if ( areaWeighted ) {
12149
12150				// vertex normals weighted by triangle areas
12151				// http://www.iquilezles.org/www/articles/normals/normals.htm
12152
12153				var cb = new Vector3(), ab = new Vector3();
12154
12155				for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
12156
12157					var face = this.faces[ f ];
12158
12159					var vA = this.vertices[ face.a ];
12160					var vB = this.vertices[ face.b ];
12161					var vC = this.vertices[ face.c ];
12162
12163					cb.subVectors( vC, vB );
12164					ab.subVectors( vA, vB );
12165					cb.cross( ab );
12166
12167					vertices[ face.a ].add( cb );
12168					vertices[ face.b ].add( cb );
12169					vertices[ face.c ].add( cb );
12170
12171				}
12172
12173			} else {
12174
12175				this.computeFaceNormals();
12176
12177				for ( var f$1 = 0, fl$1 = this.faces.length; f$1 < fl$1; f$1 ++ ) {
12178
12179					var face$1 = this.faces[ f$1 ];
12180
12181					vertices[ face$1.a ].add( face$1.normal );
12182					vertices[ face$1.b ].add( face$1.normal );
12183					vertices[ face$1.c ].add( face$1.normal );
12184
12185				}
12186
12187			}
12188
12189			for ( var v$1 = 0, vl$1 = this.vertices.length; v$1 < vl$1; v$1 ++ ) {
12190
12191				vertices[ v$1 ].normalize();
12192
12193			}
12194
12195			for ( var f$2 = 0, fl$2 = this.faces.length; f$2 < fl$2; f$2 ++ ) {
12196
12197				var face$2 = this.faces[ f$2 ];
12198
12199				var vertexNormals = face$2.vertexNormals;
12200
12201				if ( vertexNormals.length === 3 ) {
12202
12203					vertexNormals[ 0 ].copy( vertices[ face$2.a ] );
12204					vertexNormals[ 1 ].copy( vertices[ face$2.b ] );
12205					vertexNormals[ 2 ].copy( vertices[ face$2.c ] );
12206
12207				} else {
12208
12209					vertexNormals[ 0 ] = vertices[ face$2.a ].clone();
12210					vertexNormals[ 1 ] = vertices[ face$2.b ].clone();
12211					vertexNormals[ 2 ] = vertices[ face$2.c ].clone();
12212
12213				}
12214
12215			}
12216
12217			if ( this.faces.length > 0 ) {
12218
12219				this.normalsNeedUpdate = true;
12220
12221			}
12222
12223		},
12224
12225		computeFlatVertexNormals: function () {
12226
12227			this.computeFaceNormals();
12228
12229			for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
12230
12231				var face = this.faces[ f ];
12232
12233				var vertexNormals = face.vertexNormals;
12234
12235				if ( vertexNormals.length === 3 ) {
12236
12237					vertexNormals[ 0 ].copy( face.normal );
12238					vertexNormals[ 1 ].copy( face.normal );
12239					vertexNormals[ 2 ].copy( face.normal );
12240
12241				} else {
12242
12243					vertexNormals[ 0 ] = face.normal.clone();
12244					vertexNormals[ 1 ] = face.normal.clone();
12245					vertexNormals[ 2 ] = face.normal.clone();
12246
12247				}
12248
12249			}
12250
12251			if ( this.faces.length > 0 ) {
12252
12253				this.normalsNeedUpdate = true;
12254
12255			}
12256
12257		},
12258
12259		computeMorphNormals: function () {
12260
12261			// save original normals
12262			// - create temp variables on first access
12263			//   otherwise just copy (for faster repeated calls)
12264
12265			for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
12266
12267				var face = this.faces[ f ];
12268
12269				if ( ! face.__originalFaceNormal ) {
12270
12271					face.__originalFaceNormal = face.normal.clone();
12272
12273				} else {
12274
12275					face.__originalFaceNormal.copy( face.normal );
12276
12277				}
12278
12279				if ( ! face.__originalVertexNormals ) { face.__originalVertexNormals = []; }
12280
12281				for ( var i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
12282
12283					if ( ! face.__originalVertexNormals[ i ] ) {
12284
12285						face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
12286
12287					} else {
12288
12289						face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
12290
12291					}
12292
12293				}
12294
12295			}
12296
12297			// use temp geometry to compute face and vertex normals for each morph
12298
12299			var tmpGeo = new Geometry();
12300			tmpGeo.faces = this.faces;
12301
12302			for ( var i$1 = 0, il$1 = this.morphTargets.length; i$1 < il$1; i$1 ++ ) {
12303
12304				// create on first access
12305
12306				if ( ! this.morphNormals[ i$1 ] ) {
12307
12308					this.morphNormals[ i$1 ] = {};
12309					this.morphNormals[ i$1 ].faceNormals = [];
12310					this.morphNormals[ i$1 ].vertexNormals = [];
12311
12312					var dstNormalsFace = this.morphNormals[ i$1 ].faceNormals;
12313					var dstNormalsVertex = this.morphNormals[ i$1 ].vertexNormals;
12314
12315					for ( var f$1 = 0, fl$1 = this.faces.length; f$1 < fl$1; f$1 ++ ) {
12316
12317						var faceNormal = new Vector3();
12318						var vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };
12319
12320						dstNormalsFace.push( faceNormal );
12321						dstNormalsVertex.push( vertexNormals );
12322
12323					}
12324
12325				}
12326
12327				var morphNormals = this.morphNormals[ i$1 ];
12328
12329				// set vertices to morph target
12330
12331				tmpGeo.vertices = this.morphTargets[ i$1 ].vertices;
12332
12333				// compute morph normals
12334
12335				tmpGeo.computeFaceNormals();
12336				tmpGeo.computeVertexNormals();
12337
12338				// store morph normals
12339
12340				for ( var f$2 = 0, fl$2 = this.faces.length; f$2 < fl$2; f$2 ++ ) {
12341
12342					var face$1 = this.faces[ f$2 ];
12343
12344					var faceNormal$1 = morphNormals.faceNormals[ f$2 ];
12345					var vertexNormals$1 = morphNormals.vertexNormals[ f$2 ];
12346
12347					faceNormal$1.copy( face$1.normal );
12348
12349					vertexNormals$1.a.copy( face$1.vertexNormals[ 0 ] );
12350					vertexNormals$1.b.copy( face$1.vertexNormals[ 1 ] );
12351					vertexNormals$1.c.copy( face$1.vertexNormals[ 2 ] );
12352
12353				}
12354
12355			}
12356
12357			// restore original normals
12358
12359			for ( var f$3 = 0, fl$3 = this.faces.length; f$3 < fl$3; f$3 ++ ) {
12360
12361				var face$2 = this.faces[ f$3 ];
12362
12363				face$2.normal = face$2.__originalFaceNormal;
12364				face$2.vertexNormals = face$2.__originalVertexNormals;
12365
12366			}
12367
12368		},
12369
12370		computeBoundingBox: function () {
12371
12372			if ( this.boundingBox === null ) {
12373
12374				this.boundingBox = new Box3();
12375
12376			}
12377
12378			this.boundingBox.setFromPoints( this.vertices );
12379
12380		},
12381
12382		computeBoundingSphere: function () {
12383
12384			if ( this.boundingSphere === null ) {
12385
12386				this.boundingSphere = new Sphere();
12387
12388			}
12389
12390			this.boundingSphere.setFromPoints( this.vertices );
12391
12392		},
12393
12394		merge: function ( geometry, matrix, materialIndexOffset ) {
12395
12396			if ( ! ( geometry && geometry.isGeometry ) ) {
12397
12398				console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
12399				return;
12400
12401			}
12402
12403			var normalMatrix,
12404				vertexOffset = this.vertices.length,
12405				vertices1 = this.vertices,
12406				vertices2 = geometry.vertices,
12407				faces1 = this.faces,
12408				faces2 = geometry.faces,
12409				colors1 = this.colors,
12410				colors2 = geometry.colors;
12411
12412			if ( materialIndexOffset === undefined ) { materialIndexOffset = 0; }
12413
12414			if ( matrix !== undefined ) {
12415
12416				normalMatrix = new Matrix3().getNormalMatrix( matrix );
12417
12418			}
12419
12420			// vertices
12421
12422			for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
12423
12424				var vertex = vertices2[ i ];
12425
12426				var vertexCopy = vertex.clone();
12427
12428				if ( matrix !== undefined ) { vertexCopy.applyMatrix4( matrix ); }
12429
12430				vertices1.push( vertexCopy );
12431
12432			}
12433
12434			// colors
12435
12436			for ( var i$1 = 0, il$1 = colors2.length; i$1 < il$1; i$1 ++ ) {
12437
12438				colors1.push( colors2[ i$1 ].clone() );
12439
12440			}
12441
12442			// faces
12443
12444			for ( var i$2 = 0, il$2 = faces2.length; i$2 < il$2; i$2 ++ ) {
12445
12446				var face = faces2[ i$2 ], faceCopy = (void 0), normal = (void 0), color = (void 0),
12447					faceVertexNormals = face.vertexNormals,
12448					faceVertexColors = face.vertexColors;
12449
12450				faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
12451				faceCopy.normal.copy( face.normal );
12452
12453				if ( normalMatrix !== undefined ) {
12454
12455					faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
12456
12457				}
12458
12459				for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
12460
12461					normal = faceVertexNormals[ j ].clone();
12462
12463					if ( normalMatrix !== undefined ) {
12464
12465						normal.applyMatrix3( normalMatrix ).normalize();
12466
12467					}
12468
12469					faceCopy.vertexNormals.push( normal );
12470
12471				}
12472
12473				faceCopy.color.copy( face.color );
12474
12475				for ( var j$1 = 0, jl$1 = faceVertexColors.length; j$1 < jl$1; j$1 ++ ) {
12476
12477					color = faceVertexColors[ j$1 ];
12478					faceCopy.vertexColors.push( color.clone() );
12479
12480				}
12481
12482				faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
12483
12484				faces1.push( faceCopy );
12485
12486			}
12487
12488			// uvs
12489
12490			for ( var i$3 = 0, il$3 = geometry.faceVertexUvs.length; i$3 < il$3; i$3 ++ ) {
12491
12492				var faceVertexUvs2 = geometry.faceVertexUvs[ i$3 ];
12493
12494				if ( this.faceVertexUvs[ i$3 ] === undefined ) { this.faceVertexUvs[ i$3 ] = []; }
12495
12496				for ( var j$2 = 0, jl$2 = faceVertexUvs2.length; j$2 < jl$2; j$2 ++ ) {
12497
12498					var uvs2 = faceVertexUvs2[ j$2 ], uvsCopy = [];
12499
12500					for ( var k = 0, kl = uvs2.length; k < kl; k ++ ) {
12501
12502						uvsCopy.push( uvs2[ k ].clone() );
12503
12504					}
12505
12506					this.faceVertexUvs[ i$3 ].push( uvsCopy );
12507
12508				}
12509
12510			}
12511
12512		},
12513
12514		mergeMesh: function ( mesh ) {
12515
12516			if ( ! ( mesh && mesh.isMesh ) ) {
12517
12518				console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
12519				return;
12520
12521			}
12522
12523			if ( mesh.matrixAutoUpdate ) { mesh.updateMatrix(); }
12524
12525			this.merge( mesh.geometry, mesh.matrix );
12526
12527		},
12528
12529		/*
12530		 * Checks for duplicate vertices with hashmap.
12531		 * Duplicated vertices are removed
12532		 * and faces' vertices are updated.
12533		 */
12534
12535		mergeVertices: function () {
12536
12537			var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)
12538			var unique = [], changes = [];
12539
12540			var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001
12541			var precision = Math.pow( 10, precisionPoints );
12542
12543			for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
12544
12545				var v = this.vertices[ i ];
12546				var key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
12547
12548				if ( verticesMap[ key ] === undefined ) {
12549
12550					verticesMap[ key ] = i;
12551					unique.push( this.vertices[ i ] );
12552					changes[ i ] = unique.length - 1;
12553
12554				} else {
12555
12556					//console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
12557					changes[ i ] = changes[ verticesMap[ key ] ];
12558
12559				}
12560
12561			}
12562
12563
12564			// if faces are completely degenerate after merging vertices, we
12565			// have to remove them from the geometry.
12566			var faceIndicesToRemove = [];
12567
12568			for ( var i$1 = 0, il$1 = this.faces.length; i$1 < il$1; i$1 ++ ) {
12569
12570				var face = this.faces[ i$1 ];
12571
12572				face.a = changes[ face.a ];
12573				face.b = changes[ face.b ];
12574				face.c = changes[ face.c ];
12575
12576				var indices = [ face.a, face.b, face.c ];
12577
12578				// if any duplicate vertices are found in a Face3
12579				// we have to remove the face as nothing can be saved
12580				for ( var n = 0; n < 3; n ++ ) {
12581
12582					if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
12583
12584						faceIndicesToRemove.push( i$1 );
12585						break;
12586
12587					}
12588
12589				}
12590
12591			}
12592
12593			for ( var i$2 = faceIndicesToRemove.length - 1; i$2 >= 0; i$2 -- ) {
12594
12595				var idx = faceIndicesToRemove[ i$2 ];
12596
12597				this.faces.splice( idx, 1 );
12598
12599				for ( var j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
12600
12601					this.faceVertexUvs[ j ].splice( idx, 1 );
12602
12603				}
12604
12605			}
12606
12607			// Use unique set of vertices
12608
12609			var diff = this.vertices.length - unique.length;
12610			this.vertices = unique;
12611			return diff;
12612
12613		},
12614
12615		setFromPoints: function ( points ) {
12616
12617			this.vertices = [];
12618
12619			for ( var i = 0, l = points.length; i < l; i ++ ) {
12620
12621				var point = points[ i ];
12622				this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
12623
12624			}
12625
12626			return this;
12627
12628		},
12629
12630		sortFacesByMaterialIndex: function () {
12631
12632			var faces = this.faces;
12633			var length = faces.length;
12634
12635			// tag faces
12636
12637			for ( var i = 0; i < length; i ++ ) {
12638
12639				faces[ i ]._id = i;
12640
12641			}
12642
12643			// sort faces
12644
12645			function materialIndexSort( a, b ) {
12646
12647				return a.materialIndex - b.materialIndex;
12648
12649			}
12650
12651			faces.sort( materialIndexSort );
12652
12653			// sort uvs
12654
12655			var uvs1 = this.faceVertexUvs[ 0 ];
12656			var uvs2 = this.faceVertexUvs[ 1 ];
12657
12658			var newUvs1, newUvs2;
12659
12660			if ( uvs1 && uvs1.length === length ) { newUvs1 = []; }
12661			if ( uvs2 && uvs2.length === length ) { newUvs2 = []; }
12662
12663			for ( var i$1 = 0; i$1 < length; i$1 ++ ) {
12664
12665				var id = faces[ i$1 ]._id;
12666
12667				if ( newUvs1 ) { newUvs1.push( uvs1[ id ] ); }
12668				if ( newUvs2 ) { newUvs2.push( uvs2[ id ] ); }
12669
12670			}
12671
12672			if ( newUvs1 ) { this.faceVertexUvs[ 0 ] = newUvs1; }
12673			if ( newUvs2 ) { this.faceVertexUvs[ 1 ] = newUvs2; }
12674
12675		},
12676
12677		toJSON: function () {
12678
12679			var data = {
12680				metadata: {
12681					version: 4.5,
12682					type: 'Geometry',
12683					generator: 'Geometry.toJSON'
12684				}
12685			};
12686
12687			// standard Geometry serialization
12688
12689			data.uuid = this.uuid;
12690			data.type = this.type;
12691			if ( this.name !== '' ) { data.name = this.name; }
12692
12693			if ( this.parameters !== undefined ) {
12694
12695				var parameters = this.parameters;
12696
12697				for ( var key in parameters ) {
12698
12699					if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; }
12700
12701				}
12702
12703				return data;
12704
12705			}
12706
12707			var vertices = [];
12708
12709			for ( var i = 0; i < this.vertices.length; i ++ ) {
12710
12711				var vertex = this.vertices[ i ];
12712				vertices.push( vertex.x, vertex.y, vertex.z );
12713
12714			}
12715
12716			var faces = [];
12717			var normals = [];
12718			var normalsHash = {};
12719			var colors = [];
12720			var colorsHash = {};
12721			var uvs = [];
12722			var uvsHash = {};
12723
12724			for ( var i$1 = 0; i$1 < this.faces.length; i$1 ++ ) {
12725
12726				var face = this.faces[ i$1 ];
12727
12728				var hasMaterial = true;
12729				var hasFaceUv = false; // deprecated
12730				var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i$1 ] !== undefined;
12731				var hasFaceNormal = face.normal.length() > 0;
12732				var hasFaceVertexNormal = face.vertexNormals.length > 0;
12733				var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
12734				var hasFaceVertexColor = face.vertexColors.length > 0;
12735
12736				var faceType = 0;
12737
12738				faceType = setBit( faceType, 0, 0 ); // isQuad
12739				faceType = setBit( faceType, 1, hasMaterial );
12740				faceType = setBit( faceType, 2, hasFaceUv );
12741				faceType = setBit( faceType, 3, hasFaceVertexUv );
12742				faceType = setBit( faceType, 4, hasFaceNormal );
12743				faceType = setBit( faceType, 5, hasFaceVertexNormal );
12744				faceType = setBit( faceType, 6, hasFaceColor );
12745				faceType = setBit( faceType, 7, hasFaceVertexColor );
12746
12747				faces.push( faceType );
12748				faces.push( face.a, face.b, face.c );
12749				faces.push( face.materialIndex );
12750
12751				if ( hasFaceVertexUv ) {
12752
12753					var faceVertexUvs = this.faceVertexUvs[ 0 ][ i$1 ];
12754
12755					faces.push(
12756						getUvIndex( faceVertexUvs[ 0 ] ),
12757						getUvIndex( faceVertexUvs[ 1 ] ),
12758						getUvIndex( faceVertexUvs[ 2 ] )
12759					);
12760
12761				}
12762
12763				if ( hasFaceNormal ) {
12764
12765					faces.push( getNormalIndex( face.normal ) );
12766
12767				}
12768
12769				if ( hasFaceVertexNormal ) {
12770
12771					var vertexNormals = face.vertexNormals;
12772
12773					faces.push(
12774						getNormalIndex( vertexNormals[ 0 ] ),
12775						getNormalIndex( vertexNormals[ 1 ] ),
12776						getNormalIndex( vertexNormals[ 2 ] )
12777					);
12778
12779				}
12780
12781				if ( hasFaceColor ) {
12782
12783					faces.push( getColorIndex( face.color ) );
12784
12785				}
12786
12787				if ( hasFaceVertexColor ) {
12788
12789					var vertexColors = face.vertexColors;
12790
12791					faces.push(
12792						getColorIndex( vertexColors[ 0 ] ),
12793						getColorIndex( vertexColors[ 1 ] ),
12794						getColorIndex( vertexColors[ 2 ] )
12795					);
12796
12797				}
12798
12799			}
12800
12801			function setBit( value, position, enabled ) {
12802
12803				return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
12804
12805			}
12806
12807			function getNormalIndex( normal ) {
12808
12809				var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
12810
12811				if ( normalsHash[ hash ] !== undefined ) {
12812
12813					return normalsHash[ hash ];
12814
12815				}
12816
12817				normalsHash[ hash ] = normals.length / 3;
12818				normals.push( normal.x, normal.y, normal.z );
12819
12820				return normalsHash[ hash ];
12821
12822			}
12823
12824			function getColorIndex( color ) {
12825
12826				var hash = color.r.toString() + color.g.toString() + color.b.toString();
12827
12828				if ( colorsHash[ hash ] !== undefined ) {
12829
12830					return colorsHash[ hash ];
12831
12832				}
12833
12834				colorsHash[ hash ] = colors.length;
12835				colors.push( color.getHex() );
12836
12837				return colorsHash[ hash ];
12838
12839			}
12840
12841			function getUvIndex( uv ) {
12842
12843				var hash = uv.x.toString() + uv.y.toString();
12844
12845				if ( uvsHash[ hash ] !== undefined ) {
12846
12847					return uvsHash[ hash ];
12848
12849				}
12850
12851				uvsHash[ hash ] = uvs.length / 2;
12852				uvs.push( uv.x, uv.y );
12853
12854				return uvsHash[ hash ];
12855
12856			}
12857
12858			data.data = {};
12859
12860			data.data.vertices = vertices;
12861			data.data.normals = normals;
12862			if ( colors.length > 0 ) { data.data.colors = colors; }
12863			if ( uvs.length > 0 ) { data.data.uvs = [ uvs ]; } // temporal backward compatibility
12864			data.data.faces = faces;
12865
12866			return data;
12867
12868		},
12869
12870		clone: function () {
12871
12872			/*
12873			 // Handle primitives
12874
12875			 const parameters = this.parameters;
12876
12877			 if ( parameters !== undefined ) {
12878
12879			 const values = [];
12880
12881			 for ( const key in parameters ) {
12882
12883			 values.push( parameters[ key ] );
12884
12885			 }
12886
12887			 const geometry = Object.create( this.constructor.prototype );
12888			 this.constructor.apply( geometry, values );
12889			 return geometry;
12890
12891			 }
12892
12893			 return new this.constructor().copy( this );
12894			 */
12895
12896			return new Geometry().copy( this );
12897
12898		},
12899
12900		copy: function ( source ) {
12901
12902			// reset
12903
12904			this.vertices = [];
12905			this.colors = [];
12906			this.faces = [];
12907			this.faceVertexUvs = [[]];
12908			this.morphTargets = [];
12909			this.morphNormals = [];
12910			this.skinWeights = [];
12911			this.skinIndices = [];
12912			this.lineDistances = [];
12913			this.boundingBox = null;
12914			this.boundingSphere = null;
12915
12916			// name
12917
12918			this.name = source.name;
12919
12920			// vertices
12921
12922			var vertices = source.vertices;
12923
12924			for ( var i = 0, il = vertices.length; i < il; i ++ ) {
12925
12926				this.vertices.push( vertices[ i ].clone() );
12927
12928			}
12929
12930			// colors
12931
12932			var colors = source.colors;
12933
12934			for ( var i$1 = 0, il$1 = colors.length; i$1 < il$1; i$1 ++ ) {
12935
12936				this.colors.push( colors[ i$1 ].clone() );
12937
12938			}
12939
12940			// faces
12941
12942			var faces = source.faces;
12943
12944			for ( var i$2 = 0, il$2 = faces.length; i$2 < il$2; i$2 ++ ) {
12945
12946				this.faces.push( faces[ i$2 ].clone() );
12947
12948			}
12949
12950			// face vertex uvs
12951
12952			for ( var i$3 = 0, il$3 = source.faceVertexUvs.length; i$3 < il$3; i$3 ++ ) {
12953
12954				var faceVertexUvs = source.faceVertexUvs[ i$3 ];
12955
12956				if ( this.faceVertexUvs[ i$3 ] === undefined ) {
12957
12958					this.faceVertexUvs[ i$3 ] = [];
12959
12960				}
12961
12962				for ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
12963
12964					var uvs = faceVertexUvs[ j ], uvsCopy = [];
12965
12966					for ( var k = 0, kl = uvs.length; k < kl; k ++ ) {
12967
12968						var uv = uvs[ k ];
12969
12970						uvsCopy.push( uv.clone() );
12971
12972					}
12973
12974					this.faceVertexUvs[ i$3 ].push( uvsCopy );
12975
12976				}
12977
12978			}
12979
12980			// morph targets
12981
12982			var morphTargets = source.morphTargets;
12983
12984			for ( var i$4 = 0, il$4 = morphTargets.length; i$4 < il$4; i$4 ++ ) {
12985
12986				var morphTarget = {};
12987				morphTarget.name = morphTargets[ i$4 ].name;
12988
12989				// vertices
12990
12991				if ( morphTargets[ i$4 ].vertices !== undefined ) {
12992
12993					morphTarget.vertices = [];
12994
12995					for ( var j$1 = 0, jl$1 = morphTargets[ i$4 ].vertices.length; j$1 < jl$1; j$1 ++ ) {
12996
12997						morphTarget.vertices.push( morphTargets[ i$4 ].vertices[ j$1 ].clone() );
12998
12999					}
13000
13001				}
13002
13003				// normals
13004
13005				if ( morphTargets[ i$4 ].normals !== undefined ) {
13006
13007					morphTarget.normals = [];
13008
13009					for ( var j$2 = 0, jl$2 = morphTargets[ i$4 ].normals.length; j$2 < jl$2; j$2 ++ ) {
13010
13011						morphTarget.normals.push( morphTargets[ i$4 ].normals[ j$2 ].clone() );
13012
13013					}
13014
13015				}
13016
13017				this.morphTargets.push( morphTarget );
13018
13019			}
13020
13021			// morph normals
13022
13023			var morphNormals = source.morphNormals;
13024
13025			for ( var i$5 = 0, il$5 = morphNormals.length; i$5 < il$5; i$5 ++ ) {
13026
13027				var morphNormal = {};
13028
13029				// vertex normals
13030
13031				if ( morphNormals[ i$5 ].vertexNormals !== undefined ) {
13032
13033					morphNormal.vertexNormals = [];
13034
13035					for ( var j$3 = 0, jl$3 = morphNormals[ i$5 ].vertexNormals.length; j$3 < jl$3; j$3 ++ ) {
13036
13037						var srcVertexNormal = morphNormals[ i$5 ].vertexNormals[ j$3 ];
13038						var destVertexNormal = {};
13039
13040						destVertexNormal.a = srcVertexNormal.a.clone();
13041						destVertexNormal.b = srcVertexNormal.b.clone();
13042						destVertexNormal.c = srcVertexNormal.c.clone();
13043
13044						morphNormal.vertexNormals.push( destVertexNormal );
13045
13046					}
13047
13048				}
13049
13050				// face normals
13051
13052				if ( morphNormals[ i$5 ].faceNormals !== undefined ) {
13053
13054					morphNormal.faceNormals = [];
13055
13056					for ( var j$4 = 0, jl$4 = morphNormals[ i$5 ].faceNormals.length; j$4 < jl$4; j$4 ++ ) {
13057
13058						morphNormal.faceNormals.push( morphNormals[ i$5 ].faceNormals[ j$4 ].clone() );
13059
13060					}
13061
13062				}
13063
13064				this.morphNormals.push( morphNormal );
13065
13066			}
13067
13068			// skin weights
13069
13070			var skinWeights = source.skinWeights;
13071
13072			for ( var i$6 = 0, il$6 = skinWeights.length; i$6 < il$6; i$6 ++ ) {
13073
13074				this.skinWeights.push( skinWeights[ i$6 ].clone() );
13075
13076			}
13077
13078			// skin indices
13079
13080			var skinIndices = source.skinIndices;
13081
13082			for ( var i$7 = 0, il$7 = skinIndices.length; i$7 < il$7; i$7 ++ ) {
13083
13084				this.skinIndices.push( skinIndices[ i$7 ].clone() );
13085
13086			}
13087
13088			// line distances
13089
13090			var lineDistances = source.lineDistances;
13091
13092			for ( var i$8 = 0, il$8 = lineDistances.length; i$8 < il$8; i$8 ++ ) {
13093
13094				this.lineDistances.push( lineDistances[ i$8 ] );
13095
13096			}
13097
13098			// bounding box
13099
13100			var boundingBox = source.boundingBox;
13101
13102			if ( boundingBox !== null ) {
13103
13104				this.boundingBox = boundingBox.clone();
13105
13106			}
13107
13108			// bounding sphere
13109
13110			var boundingSphere = source.boundingSphere;
13111
13112			if ( boundingSphere !== null ) {
13113
13114				this.boundingSphere = boundingSphere.clone();
13115
13116			}
13117
13118			// update flags
13119
13120			this.elementsNeedUpdate = source.elementsNeedUpdate;
13121			this.verticesNeedUpdate = source.verticesNeedUpdate;
13122			this.uvsNeedUpdate = source.uvsNeedUpdate;
13123			this.normalsNeedUpdate = source.normalsNeedUpdate;
13124			this.colorsNeedUpdate = source.colorsNeedUpdate;
13125			this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
13126			this.groupsNeedUpdate = source.groupsNeedUpdate;
13127
13128			return this;
13129
13130		},
13131
13132		dispose: function () {
13133
13134			this.dispatchEvent( { type: 'dispose' } );
13135
13136		}
13137
13138	} );
13139
13140	/**
13141	 * @author mrdoob / http://mrdoob.com/
13142	 * @author Mugen87 / https://github.com/Mugen87
13143	 */
13144
13145	// BoxGeometry
13146
13147	var BoxGeometry = /*@__PURE__*/(function (Geometry) {
13148		function BoxGeometry( width, height, depth, wi
13148dthSegments, heightSegments, depthSegments ) {
13149
13150			Geometry.call(this);
13151
13152			this.type = 'BoxGeometry';
13153
13154			this.parameters = {
13155				width: width,
13156				height: height,
13157				depth: depth,
13158				widthSegments: widthSegments,
13159				heightSegments: heightSegments,
13160				depthSegments: depthSegments
13161			};
13162
13163			this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
13164			this.mergeVertices();
13165
13166		}
13167
13168		if ( Geometry ) BoxGeometry.__proto__ = Geometry;
13169		BoxGeometry.prototype = Object.create( Geometry && Geometry.prototype );
13170		BoxGeometry.prototype.constructor = BoxGeometry;
13171
13172		return BoxGeometry;
13173	}(Geometry));
13174
13175	// BoxBufferGeometry
13176
13177	var BoxBufferGeometry = /*@__PURE__*/(function (BufferGeometry) {
13178		function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
13179
13180			BufferGeometry.call(this);
13181
13182			this.type = 'BoxBufferGeometry';
13183
13184			this.parameters = {
13185				width: width,
13186				height: height,
13187				depth: depth,
13188				widthSegments: widthSegments,
13189				heightSegments: heightSegments,
13190				depthSegments: depthSegments
13191			};
13192
13193			var scope = this;
13194
13195			width = width || 1;
13196			height = height || 1;
13197			depth = depth || 1;
13198
13199			// segments
13200
13201			widthSegments = Math.floor( widthSegments ) || 1;
13202			heightSegments = Math.floor( heightSegments ) || 1;
13203			depthSegments = Math.floor( depthSegments ) || 1;
13204
13205			// buffers
13206
13207			var indices = [];
13208			var vertices = [];
13209			var normals = [];
13210			var uvs = [];
13211
13212			// helper variables
13213
13214			var numberOfVertices = 0;
13215			var groupStart = 0;
13216
13217			// build each side of the box geometry
13218
13219			buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
13220			buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
13221			buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
13222			buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
13223			buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
13224			buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
13225
13226			// build geometry
13227
13228			this.setIndex( indices );
13229			this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
13230			this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
13231			this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
13232
13233			function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
13234
13235				var segmentWidth = width / gridX;
13236				var segmentHeight = height / gridY;
13237
13238				var widthHalf = width / 2;
13239				var heightHalf = height / 2;
13240				var depthHalf = depth / 2;
13241
13242				var gridX1 = gridX + 1;
13243				var gridY1 = gridY + 1;
13244
13245				var vertexCounter = 0;
13246				var groupCount = 0;
13247
13248				var vector = new Vector3();
13249
13250				// generate vertices, normals and uvs
13251
13252				for ( var iy = 0; iy < gridY1; iy ++ ) {
13253
13254					var y = iy * segmentHeight - heightHalf;
13255
13256					for ( var ix = 0; ix < gridX1; ix ++ ) {
13257
13258						var x = ix * segmentWidth - widthHalf;
13259
13260						// set values to correct vector component
13261
13262						vector[ u ] = x * udir;
13263						vector[ v ] = y * vdir;
13264						vector[ w ] = depthHalf;
13265
13266						// now apply vector to vertex buffer
13267
13268						vertices.push( vector.x, vector.y, vector.z );
13269
13270						// set values to correct vector component
13271
13272						vector[ u ] = 0;
13273						vector[ v ] = 0;
13274						vector[ w ] = depth > 0 ? 1 : - 1;
13275
13276						// now apply vector to normal buffer
13277
13278						normals.push( vector.x, vector.y, vector.z );
13279
13280						// uvs
13281
13282						uvs.push( ix / gridX );
13283						uvs.push( 1 - ( iy / gridY ) );
13284
13285						// counters
13286
13287						vertexCounter += 1;
13288
13289					}
13290
13291				}
13292
13293				// indices
13294
13295				// 1. you need three indices to draw a single face
13296				// 2. a single segment consists of two faces
13297				// 3. so we need to generate six (2*3) indices per segment
13298
13299				for ( var iy$1 = 0; iy$1 < gridY; iy$1 ++ ) {
13300
13301					for ( var ix$1 = 0; ix$1 < gridX; ix$1 ++ ) {
13302
13303						var a = numberOfVertices + ix$1 + gridX1 * iy$1;
13304						var b = numberOfVertices + ix$1 + gridX1 * ( iy$1 + 1 );
13305						var c = numberOfVertices + ( ix$1 + 1 ) + gridX1 * ( iy$1 + 1 );
13306						var d = numberOfVertices + ( ix$1 + 1 ) + gridX1 * iy$1;
13307
13308						// faces
13309
13310						indices.push( a, b, d );
13311						indices.push( b, c, d );
13312
13313						// increase counter
13314
13315						groupCount += 6;
13316
13317					}
13318
13319				}
13320
13321				// add a group to the geometry. this will ensure multi material support
13322
13323				scope.addGroup( groupStart, groupCount, materialIndex );
13324
13325				// calculate new start value for groups
13326
13327				groupStart += groupCount;
13328
13329				// update total number of vertices
13330
13331				numberOfVertices += vertexCounter;
13332
13333			}
13334
13335		}
13336
13337		if ( BufferGeometry ) BoxBufferGeometry.__proto__ = BufferGeometry;
13338		BoxBufferGeometry.prototype = Object.create( BufferGeometry && BufferGeometry.prototype );
13339		BoxBufferGeometry.prototype.constructor = BoxBufferGeometry;
13340
13341		return BoxBufferGeometry;
13342	}(BufferGeometry));
13343
13344	/**
13345	 * Uniform Utilities
13346	 */
13347
13348	function cloneUniforms( src ) {
13349
13350		var dst = {};
13351
13352		for ( var u in src ) {
13353
13354			dst[ u ] = {};
13355
13356			for ( var p in src[ u ] ) {
13357
13358				var property = src[ u ][ p ];
13359
13360				if ( property && ( property.isColor ||
13361					property.isMatrix3 || property.isMatrix4 ||
13362					property.isVector2 || property.isVector3 || property.isVector4 ||
13363					property.isTexture ) ) {
13364
13365					dst[ u ][ p ] = property.clone();
13366
13367				} else if ( Array.isArray( property ) ) {
13368
13369					dst[ u ][ p ] = property.slice();
13370
13371				} else {
13372
13373					dst[ u ][ p ] = property;
13374
13375				}
13376
13377			}
13378
13379		}
13380
13381		return dst;
13382
13383	}
13384
13385	function mergeUniforms( uniforms ) {
13386
13387		var merged = {};
13388
13389		for ( var u = 0; u < uniforms.length; u ++ ) {
13390
13391			var tmp = cloneUniforms( uniforms[ u ] );
13392
13393			for ( var p in tmp ) {
13394
13395				merged[ p ] = tmp[ p ];
13396
13397			}
13398
13399		}
13400
13401		return merged;
13402
13403	}
13404
13405	// Legacy
13406
13407	var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms };
13408
13409	var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
13410
13411	var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";
13412
13413	/**
13414	 * @author alteredq / http://alteredqualia.com/
13415	 *
13416	 * parameters = {
13417	 *  defines: { "label" : "value" },
13418	 *  uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
13419	 *
13420	 *  fragmentShader: <string>,
13421	 *  vertexShader: <string>,
13422	 *
13423	 *  wireframe: <boolean>,
13424	 *  wireframeLinewidth: <float>,
13425	 *
13426	 *  lights: <bool>,
13427	 *
13428	 *  skinning: <bool>,
13429	 *  morphTargets: <bool>,
13430	 *  morphNormals: <bool>
13431	 * }
13432	 */
13433
13434	function ShaderMaterial( parameters ) {
13435
13436		Material.call( this );
13437
13438		this.type = 'ShaderMaterial';
13439
13440		this.defines = {};
13441		this.uniforms = {};
13442
13443		this.vertexShader = default_vertex;
13444		this.fragmentShader = default_fragment;
13445
13446		this.linewidth = 1;
13447
13448		this.wireframe = false;
13449		this.wireframeLinewidth = 1;
13450
13451		this.fog = false; // set to use scene fog
13452		this.lights = false; // set to use scene lights
13453		this.clipping = false; // set to use user-defined clipping planes
13454
13455		this.skinning = false; // set to use skinning attribute streams
13456		this.morphTargets = false; // set to use morph targets
13457		this.morphNormals = false; // set to use morph normals
13458
13459		this.extensions = {
13460			derivatives: false, // set to use derivatives
13461			fragDepth: false, // set to use fragment depth values
13462			drawBuffers: false, // set to use draw buffers
13463			shaderTextureLOD: false // set to use shader texture LOD
13464		};
13465
13466		// When rendered geometry doesn't include these attributes but the material does,
13467		// use these default values in WebGL. This avoids errors when buffer data is missing.
13468		this.defaultAttributeValues = {
13469			'color': [ 1, 1, 1 ],
13470			'uv': [ 0, 0 ],
13471			'uv2': [ 0, 0 ]
13472		};
13473
13474		this.index0AttributeName = undefined;
13475		this.uniformsNeedUpdate = false;
13476
13477		if ( parameters !== undefined ) {
13478
13479			if ( parameters.attributes !== undefined ) {
13480
13481				console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
13482
13483			}
13484
13485			this.setValues( parameters );
13486
13487		}
13488
13489	}
13490
13491	ShaderMaterial.prototype = Object.create( Material.prototype );
13492	ShaderMaterial.prototype.constructor = ShaderMaterial;
13493
13494	ShaderMaterial.prototype.isShaderMaterial = true;
13495
13496	ShaderMaterial.prototype.copy = function ( source ) {
13497
13498		Material.prototype.copy.call( this, source );
13499
13500		this.fragmentShader = source.fragmentShader;
13501		this.vertexShader = source.vertexShader;
13502
13503		this.uniforms = cloneUniforms( source.uniforms );
13504
13505		this.defines = Object.assign( {}, source.defines );
13506
13507		this.wireframe = source.wireframe;
13508		this.wireframeLinewidth = source.wireframeLinewidth;
13509
13510		this.lights = source.lights;
13511		this.clipping = source.clipping;
13512
13513		this.skinning = source.skinning;
13514
13515		this.morphTargets = source.morphTargets;
13516		this.morphNormals = source.morphNormals;
13517
13518		this.extensions = Object.assign( {}, source.extensions );
13519
13520		return this;
13521
13522	};
13523
13524	ShaderMaterial.prototype.toJSON = function ( meta ) {
13525
13526		var data = Material.prototype.toJSON.call( this, meta );
13527
13528		data.uniforms = {};
13529
13530		for ( var name in this.uniforms ) {
13531
13532			var uniform = this.uniforms[ name ];
13533			var value = uniform.value;
13534
13535			if ( value && value.isTexture ) {
13536
13537				data.uniforms[ name ] = {
13538					type: 't',
13539					value: value.toJSON( meta ).uuid
13540				};
13541
13542			} else if ( value && value.isColor ) {
13543
13544				data.uniforms[ name ] = {
13545					type: 'c',
13546					value: value.getHex()
13547				};
13548
13549			} else if ( value && value.isVector2 ) {
13550
13551				data.uniforms[ name ] = {
13552					type: 'v2',
13553					value: value.toArray()
13554				};
13555
13556			} else if ( value && value.isVector3 ) {
13557
13558				data.uniforms[ name ] = {
13559					type: 'v3',
13560					value: value.toArray()
13561				};
13562
13563			} else if ( value && value.isVector4 ) {
13564
13565				data.uniforms[ name ] = {
13566					type: 'v4',
13567					value: value.toArray()
13568				};
13569
13570			} else if ( value && value.isMatrix3 ) {
13571
13572				data.uniforms[ name ] = {
13573					type: 'm3',
13574					value: value.toArray()
13575				};
13576
13577			} else if ( value && value.isMatrix4 ) {
13578
13579				data.uniforms[ name ] = {
13580					type: 'm4',
13581					value: value.toArray()
13582				};
13583
13584			} else {
13585
13586				data.uniforms[ name ] = {
13587					value: value
13588				};
13589
13590				// note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far
13591
13592			}
13593
13594		}
13595
13596		if ( Object.keys( this.defines ).length > 0 ) { data.defines = this.defines; }
13597
13598		data.vertexShader = this.vertexShader;
13599		data.fragmentShader = this.fragmentShader;
13600
13601		var extensions = {};
13602
13603		for ( var key in this.extensions ) {
13604
13605			if ( this.extensions[ key ] === true ) { extensions[ key ] = true; }
13606
13607		}
13608
13609		if ( Object.keys( extensions ).length > 0 ) { data.extensions = extensions; }
13610
13611		return data;
13612
13613	};
13614
13615	/**
13616	 * @author mrdoob / http://mrdoob.com/
13617	 * @author mikael emtinger / http://gomo.se/
13618	 * @author WestLangley / http://github.com/WestLangley
13619	*/
13620
13621	function Camera() {
13622
13623		Object3D.call( this );
13624
13625		this.type = 'Camera';
13626
13627		this.matrixWorldInverse = new Matrix4();
13628
13629		this.projectionMatrix = new Matrix4();
13630		this.projectionMatrixInverse = new Matrix4();
13631
13632	}
13633
13634	Camera.prototype = Object.assign( Object.create( Object3D.prototype ), {
13635
13636		constructor: Camera,
13637
13638		isCamera: true,
13639
13640		copy: function ( source, recursive ) {
13641
13642			Object3D.prototype.copy.call( this, source, recursive );
13643
13644			this.matrixWorldInverse.copy( source.matrixWorldInverse );
13645
13646			this.projectionMatrix.copy( source.projectionMatrix );
13647			this.projectionMatrixInverse.copy( source.projectionMatrixInverse );
13648
13649			return this;
13650
13651		},
13652
13653		getWorldDirection: function ( target ) {
13654
13655			if ( target === undefined ) {
13656
13657				console.warn( 'THREE.Camera: .getWorldDirection() target is now required' );
13658				target = new Vector3();
13659
13660			}
13661
13662			this.updateMatrixWorld( true );
13663
13664			var e = this.matrixWorld.elements;
13665
13666			return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize();
13667
13668		},
13669
13670		updateMatrixWorld: function ( force ) {
13671
13672			Object3D.prototype.updateMatrixWorld.call( this, force );
13673
13674			this.matrixWorldInverse.getInverse( this.matrixWorld );
13675
13676		},
13677
13678		updateWorldMatrix: function ( updateParents, updateChildren ) {
13679
13680			Object3D.prototype.updateWorldMatrix.call( this, updateParents, updateChildren );
13681
13682			this.matrixWorldInverse.getInverse( this.matrixWorld );
13683
13684		},
13685
13686		clone: function () {
13687
13688			return new this.constructor().copy( this );
13689
13690		}
13691
13692	} );
13693
13694	/**
13695	 * @author mrdoob / http://mrdoob.com/
13696	 * @author greggman / http://games.greggman.com/
13697	 * @author zz85 / http://www.lab4games.net/zz85/blog
13698	 * @author tschw
13699	 */
13700
13701	function PerspectiveCamera( fov, aspect, near, far ) {
13702
13703		Camera.call( this );
13704
13705		this.type = 'PerspectiveCamera';
13706
13707		this.fov = fov !== undefined ? fov : 50;
13708		this.zoom = 1;
13709
13710		this.near = near !== undefined ? near : 0.1;
13711		this.far = far !== undefined ? far : 2000;
13712		this.focus = 10;
13713
13714		this.aspect = aspect !== undefined ? aspect : 1;
13715		this.view = null;
13716
13717		this.filmGauge = 35;	// width of the film (default in millimeters)
13718		this.filmOffset = 0;	// horizontal film offset (same unit as gauge)
13719
13720		this.updateProjectionMatrix();
13721
13722	}
13723
13724	PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
13725
13726		constructor: PerspectiveCamera,
13727
13728		isPerspectiveCamera: true,
13729
13730		copy: function ( source, recursive ) {
13731
13732			Camera.prototype.copy.call( this, source, recursive );
13733
13734			this.fov = source.fov;
13735			this.zoom = source.zoom;
13736
13737			this.near = source.near;
13738			this.far = source.far;
13739			this.focus = source.focus;
13740
13741			this.aspect = source.aspect;
13742			this.view = source.view === null ? null : Object.assign( {}, source.view );
13743
13744			this.filmGauge = source.filmGauge;
13745			this.filmOffset = source.filmOffset;
13746
13747			return this;
13748
13749		},
13750
13751		/**
13752		 * Sets the FOV by focal length in respect to the current .filmGauge.
13753		 *
13754		 * The default film gauge is 35, so that the focal length can be specified for
13755		 * a 35mm (full frame) camera.
13756		 *
13757		 * Values for focal length and film gauge must have the same unit.
13758		 */
13759		setFocalLength: function ( focalLength ) {
13760
13761			// see http://www.bobatkins.com/photography/technical/field_of_view.html
13762			var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
13763
13764			this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope );
13765			this.updateProjectionMatrix();
13766
13767		},
13768
13769		/**
13770		 * Calculates the focal length from the current .fov and .filmGauge.
13771		 */
13772		getFocalLength: function () {
13773
13774			var vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov );
13775
13776			return 0.5 * this.getFilmHeight() / vExtentSlope;
13777
13778		},
13779
13780		getEffectiveFOV: function () {
13781
13782			return MathUtils.RAD2DEG * 2 * Math.atan(
13783				Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom );
13784
13785		},
13786
13787		getFilmWidth: function () {
13788
13789			// film not completely covered in portrait format (aspect < 1)
13790			return this.filmGauge * Math.min( this.aspect, 1 );
13791
13792		},
13793
13794		getFilmHeight: function () {
13795
13796			// film not completely covered in landscape format (aspect > 1)
13797			return this.filmGauge / Math.max( this.aspect, 1 );
13798
13799		},
13800
13801		/**
13802		 * Sets an offset in a larger frustum. This is useful for multi-window or
13803		 * multi-monitor/multi-machine setups.
13804		 *
13805		 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
13806		 * the monitors are in grid like this
13807		 *
13808		 *   +---+---+---+
13809		 *   | A | B | C |
13810		 *   +---+---+---+
13811		 *   | D | E | F |
13812		 *   +---+---+---+
13813		 *
13814		 * then for each monitor you would call it like this
13815		 *
13816		 *   const w = 1920;
13817		 *   const h = 1080;
13818		 *   const fullWidth = w * 3;
13819		 *   const fullHeight = h * 2;
13820		 *
13821		 *   --A--
13822		 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
13823		 *   --B--
13824		 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
13825		 *   --C--
13826		 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
13827		 *   --D--
13828		 *   camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
13829		 *   --E--
13830		 *   camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
13831		 *   --F--
13832		 *   camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
13833		 *
13834		 *   Note there is no reason monitors have to be the same size or in a grid.
13835		 */
13836		setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
13837
13838			this.aspect = fullWidth / fullHeight;
13839
13840			if ( this.view === null ) {
13841
13842				this.view = {
13843					enabled: true,
13844					fullWidth: 1,
13845					fullHeight: 1,
13846					offsetX: 0,
13847					offsetY: 0,
13848					width: 1,
13849					height: 1
13850				};
13851
13852			}
13853
13854			this.view.enabled = true;
13855			this.view.fullWidth = fullWidth;
13856			this.view.fullHeight = fullHeight;
13857			this.view.offsetX = x;
13858			this.view.offsetY = y;
13859			this.view.width = width;
13860			this.view.height = height;
13861
13862			this.updateProjectionMatrix();
13863
13864		},
13865
13866		clearViewOffset: function () {
13867
13868			if ( this.view !== null ) {
13869
13870				this.view.enabled = false;
13871
13872			}
13873
13874			this.updateProjectionMatrix();
13875
13876		},
13877
13878		updateProjectionMatrix: function () {
13879
13880			var near = this.near,
13881				top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom,
13882				height = 2 * top,
13883				width = this.aspect * height,
13884				left = - 0.5 * width,
13885				view = this.view;
13886
13887			if ( this.view !== null && this.view.enabled ) {
13888
13889				var fullWidth = view.fullWidth,
13890					fullHeight = view.fullHeight;
13891
13892				left += view.offsetX * width / fullWidth;
13893				top -= view.offsetY * height / fullHeight;
13894				width *= view.width / fullWidth;
13895				height *= view.height / fullHeight;
13896
13897			}
13898
13899			var skew = this.filmOffset;
13900			if ( skew !== 0 ) { left += near * skew / this.getFilmWidth(); }
13901
13902			this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
13903
13904			this.projectionMatrixInverse.getInverse( this.projectionMatrix );
13905
13906		},
13907
13908		toJSON: function ( meta ) {
13909
13910			var data = Object3D.prototype.toJSON.call( this, meta );
13911
13912			data.object.fov = this.fov;
13913			data.object.zoom = this.zoom;
13914
13915			data.object.near = this.near;
13916			data.object.far = this.far;
13917			data.object.focus = this.focus;
13918
13919			data.object.aspect = this.aspect;
13920
13921			if ( this.view !== null ) { data.object.view = Object.assign( {}, this.view ); }
13922
13923			data.object.filmGauge = this.filmGauge;
13924			data.object.filmOffset = this.filmOffset;
13925
13926			return data;
13927
13928		}
13929
13930	} );
13931
13932	/**
13933	 * Camera for rendering cube maps
13934	 *	- renders scene into axis-aligned cube
13935	 *
13936	 * @author alteredq / http://alteredqualia.com/
13937	 */
13938
13939	var fov = 90, aspect = 1;
13940
13941	function CubeCamera( near, far, renderTarget ) {
13942
13943		Object3D.call( this );
13944
13945		this.type = 'CubeCamera';
13946
13947		if ( renderTarget.isWebGLCubeRenderTarget !== true ) {
13948
13949			console.error( 'THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.' );
13950			return;
13951
13952		}
13953
13954		this.renderTarget = renderTarget;
13955
13956		var cameraPX = new PerspectiveCamera( fov, aspect, near, far );
13957		cameraPX.layers = this.layers;
13958		cameraPX.up.set( 0, - 1, 0 );
13959		cameraPX.lookAt( new Vector3( 1, 0, 0 ) );
13960		this.add( cameraPX );
13961
13962		var cameraNX = new PerspectiveCamera( fov, aspect, near, far );
13963		cameraNX.layers = this.layers;
13964		cameraNX.up.set( 0, - 1, 0 );
13965		cameraNX.lookAt( new Vector3( - 1, 0, 0 ) );
13966		this.add( cameraNX );
13967
13968		var cameraPY = new PerspectiveCamera( fov, aspect, near, far );
13969		cameraPY.layers = this.layers;
13970		cameraPY.up.set( 0, 0, 1 );
13971		cameraPY.lookAt( new Vector3( 0, 1, 0 ) );
13972		this.add( cameraPY );
13973
13974		var cameraNY = new PerspectiveCamera( fov, aspect, near, far );
13975		cameraNY.layers = this.layers;
13976		cameraNY.up.set( 0, 0, - 1 );
13977		cameraNY.lookAt( new Vector3( 0, - 1, 0 ) );
13978		this.add( cameraNY );
13979
13980		var cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
13981		cameraPZ.layers = this.layers;
13982		cameraPZ.up.set( 0, - 1, 0 );
13983		cameraPZ.lookAt( new Vector3( 0, 0, 1 ) );
13984		this.add( cameraPZ );
13985
13986		var cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
13987		cameraNZ.layers = this.layers;
13988		cameraNZ.up.set( 0, - 1, 0 );
13989		cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );
13990		this.add( cameraNZ );
13991
13992		this.update = function ( renderer, scene ) {
13993
13994			if ( this.parent === null ) { this.updateMatrixWorld(); }
13995
13996			var currentXrEnabled = renderer.xr.enabled;
13997			var currentRenderTarget = renderer.getRenderTarget();
13998
13999			renderer.xr.enabled = false;
14000
14001			var generateMipmaps = renderTarget.texture.generateMipmaps;
14002
14003			renderTarget.texture.generateMipmaps = false;
14004
14005			renderer.setRenderTarget( renderTarget, 0 );
14006			renderer.render( scene, cameraPX );
14007
14008			renderer.setRenderTarget( renderTarget, 1 );
14009			renderer.render( scene, cameraNX );
14010
14011			renderer.setRenderTarget( renderTarget, 2 );
14012			renderer.render( scene, cameraPY );
14013
14014			renderer.setRenderTarget( renderTarget, 3 );
14015			renderer.render( scene, cameraNY );
14016
14017			renderer.setRenderTarget( renderTarget, 4 );
14018			renderer.render( scene, cameraPZ );
14019
14020			renderTarget.texture.generateMipmaps = generateMipmaps;
14021
14022			renderer.setRenderTarget( renderTarget, 5 );
14023			renderer.render( scene, cameraNZ );
14024
14025			renderer.setRenderTarget( currentRenderTarget );
14026
14027			renderer.xr.enabled = currentXrEnabled;
14028
14029		};
14030
14031		this.clear = function ( renderer, color, depth, stencil ) {
14032
14033			var currentRenderTarget = renderer.getRenderTarget();
14034
14035			for ( var i = 0; i < 6; i ++ ) {
14036
14037				renderer.setRenderTarget( renderTarget, i );
14038
14039				renderer.clear( color, depth, stencil );
14040
14041			}
14042
14043			renderer.setRenderTarget( currentRenderTarget );
14044
14045		};
14046
14047	}
14048
14049	CubeCamera.prototype = Object.create( Object3D.prototype );
14050	CubeCamera.prototype.constructor = CubeCamera;
14051
14052	/**
14053	 * @author alteredq / http://alteredqualia.com
14054	 * @author WestLangley / http://github.com/WestLangley
14055	 */
14056
14057	function WebGLCubeRenderTarget( size, options, dummy ) {
14058
14059		if ( Number.isInteger( options ) ) {
14060
14061			console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' );
14062
14063			options = dummy;
14064
14065		}
14066
14067		WebGLRenderTarget.call( this, size, size, options );
14068
14069	}
14070
14071	WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype );
14072	WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget;
14073
14074	WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;
14075
14076	WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) {
14077
14078		this.texture.type = texture.type;
14079		this.texture.format = texture.format;
14080		this.texture.encoding = texture.encoding;
14081
14082		var scene = new Scene();
14083
14084		var shader = {
14085
14086			uniforms: {
14087				tEquirect: { value: null },
14088			},
14089
14090			vertexShader: [
14091
14092				"varying vec3 vWorldDirection;",
14093
14094				"vec3 transformDirection( in vec3 dir, in mat4 matrix ) {",
14095
14096				"	return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );",
14097
14098				"}",
14099
14100				"void main() {",
14101
14102				"	vWorldDirection = transformDirection( position, modelMatrix );",
14103
14104				"	#include <begin_vertex>",
14105				"	#include <project_vertex>",
14106
14107				"}"
14108
14109			].join( '\n' ),
14110
14111			fragmentShader: [
14112
14113				"uniform sampler2D tEquirect;",
14114
14115				"varying vec3 vWorldDirection;",
14116
14117				"#include <common>",
14118
14119				"void main() {",
14120
14121				"	vec3 direction = normalize( vWorldDirection );",
14122
14123				"	vec2 sampleUV = equirectUv( direction );",
14124
14125				"	gl_FragColor = texture2D( tEquirect, sampleUV );",
14126
14127				"}"
14128
14129			].join( '\n' ),
14130		};
14131
14132		var material = new ShaderMaterial( {
14133
14134			name: 'CubemapFromEquirect',
14135
14136			uniforms: cloneUniforms( shader.uniforms ),
14137			vertexShader: shader.vertexShader,
14138			fragmentShader: shader.fragmentShader,
14139			side: BackSide,
14140			blending: NoBlending
14141
14142		} );
14143
14144		material.uniforms.tEquirect.value = texture;
14145
14146		var mesh = new Mesh( new BoxBufferGeometry( 5, 5, 5 ), material );
14147
14148		scene.add( mesh );
14149
14150		var camera = new CubeCamera( 1, 10, this );
14151		camera.update( renderer, scene );
14152
14153		mesh.geometry.dispose();
14154		mesh.material.dispose();
14155
14156		return this;
14157
14158	};
14159
14160	/**
14161	 * @author alteredq / http://alteredqualia.com/
14162	 */
14163
14164	function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
14165
14166		Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
14167
14168		this.image = { data: data || null, width: width || 1, height: height || 1 };
14169
14170		this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
14171		this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
14172
14173		this.generateMipmaps = false;
14174		this.flipY = false;
14175		this.unpackAlignment = 1;
14176
14177		this.needsUpdate = true;
14178
14179	}
14180
14181	DataTexture.prototype = Object.create( Texture.prototype );
14182	DataTexture.prototype.constructor = DataTexture;
14183
14184	DataTexture.prototype.isDataTexture = true;
14185
14186	/**
14187	 * @author mrdoob / http://mrdoob.com/
14188	 * @author alteredq / http://alteredqualia.com/
14189	 * @author bhouston / http://clara.io
14190	 */
14191
14192	var _sphere$1 = new Sphere();
14193	var _vector$5 = new Vector3();
14194
14195	function Frustum( p0, p1, p2, p3, p4, p5 ) {
14196
14197		this.planes = [
14198
14199			( p0 !== undefined ) ? p0 : new Plane(),
14200			( p1 !== undefined ) ? p1 : new Plane(),
14201			( p2 !== undefined ) ? p2 : new Plane(),
14202			( p3 !== undefined ) ? p3 : new Plane(),
14203			( p4 !== undefined ) ? p4 : new Plane(),
14204			( p5 !== undefined ) ? p5 : new Plane()
14205
14206		];
14207
14208	}
14209
14210	Object.assign( Frustum.prototype, {
14211
14212		set: function ( p0, p1, p2, p3, p4, p5 ) {
14213
14214			var planes = this.planes;
14215
14216			planes[ 0 ].copy( p0 );
14217			planes[ 1 ].copy( p1 );
14218			planes[ 2 ].copy( p2 );
14219			planes[ 3 ].copy( p3 );
14220			planes[ 4 ].copy( p4 );
14221			planes[ 5 ].copy( p5 );
14222
14223			return this;
14224
14225		},
14226
14227		clone: function () {
14228
14229			return new this.constructor().copy( this );
14230
14231		},
14232
14233		copy: function ( frustum ) {
14234
14235			var planes = this.planes;
14236
14237			for ( var i = 0; i < 6; i ++ ) {
14238
14239				planes[ i ].copy( frustum.planes[ i ] );
14240
14241			}
14242
14243			return this;
14244
14245		},
14246
14247		setFromProjectionMatrix: function ( m ) {
14248
14249			var planes = this.planes;
14250			var me = m.elements;
14251			var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
14252			var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
14253			var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
14254			var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
14255
14256			planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
14257			planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
14258			planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
14259			planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
14260			planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
14261			planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
14262
14263			return this;
14264
14265		},
14266
14267		intersectsObject: function ( object ) {
14268
14269			var geometry = object.geometry;
14270
14271			if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
14272
14273			_sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );
14274
14275			return this.intersectsSphere( _sphere$1 );
14276
14277		},
14278
14279		intersectsSprite: function ( sprite ) {
14280
14281			_sphere$1.center.set( 0, 0, 0 );
14282			_sphere$1.radius = 0.7071067811865476;
14283			_sphere$1.applyMatrix4( sprite.matrixWorld );
14284
14285			return this.intersectsSphere( _sphere$1 );
14286
14287		},
14288
14289		intersectsSphere: function ( sphere ) {
14290
14291			var planes = this.planes;
14292			var center = sphere.center;
14293			var negRadius = - sphere.radius;
14294
14295			for ( var i = 0; i < 6; i ++ ) {
14296
14297				var distance = planes[ i ].distanceToPoint( center );
14298
14299				if ( distance < negRadius ) {
14300
14301					return false;
14302
14303				}
14304
14305			}
14306
14307			return true;
14308
14309		},
14310
14311		intersectsBox: function ( box ) {
14312
14313			var planes = this.planes;
14314
14315			for ( var i = 0; i < 6; i ++ ) {
14316
14317				var plane = planes[ i ];
14318
14319				// corner at max distance
14320
14321				_vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x;
14322				_vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y;
14323				_vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z;
14324
14325				if ( plane.distanceToPoint( _vector$5 ) < 0 ) {
14326
14327					return false;
14328
14329				}
14330
14331			}
14332
14333			return true;
14334
14335		},
14336
14337		containsPoint: function ( point ) {
14338
14339			var planes = this.planes;
14340
14341			for ( var i = 0; i < 6; i ++ ) {
14342
14343				if ( planes[ i ].distanceToPoint( point ) < 0 ) {
14344
14345					return false;
14346
14347				}
14348
14349			}
14350
14351			return true;
14352
14353		}
14354
14355	} );
14356
14357	/**
14358	 * Uniforms library for shared webgl shaders
14359	 */
14360
14361	var UniformsLib = {
14362
14363		common: {
14364
14365			diffuse: { value: new Color( 0xeeeeee ) },
14366			opacity: { value: 1.0 },
14367
14368			map: { value: null },
14369			uvTransform: { value: new Matrix3() },
14370			uv2Transform: { value: new Matrix3() },
14371
14372			alphaMap: { value: null },
14373
14374		},
14375
14376		specularmap: {
14377
14378			specularMap: { value: null },
14379
14380		},
14381
14382		envmap: {
14383
14384			envMap: { value: null },
14385			flipEnvMap: { value: - 1 },
14386			reflectivity: { value: 1.0 },
14387			refractionRatio: { value: 0.98 },
14388			maxMipLevel: { value: 0 }
14389
14390		},
14391
14392		aomap: {
14393
14394			aoMap: { value: null },
14395			aoMapIntensity: { value: 1 }
14396
14397		},
14398
14399		lightmap: {
14400
14401			lightMap: { value: null },
14402			lightMapIntensity: { value: 1 }
14403
14404		},
14405
14406		emissivemap: {
14407
14408			emissiveMap: { value: null }
14409
14410		},
14411
14412		bumpmap: {
14413
14414			bumpMap: { value: null },
14415			bumpScale: { value: 1 }
14416
14417		},
14418
14419		normalmap: {
14420
14421			normalMap: { value: null },
14422			normalScale: { value: new Vector2( 1, 1 ) }
14423
14424		},
14425
14426		displacementmap: {
14427
14428			displacementMap: { value: null },
14429			displacementScale: { value: 1 },
14430			displacementBias: { value: 0 }
14431
14432		},
14433
14434		roughnessmap: {
14435
14436			roughnessMap: { value: null }
14437
14438		},
14439
14440		metalnessmap: {
14441
14442			metalnessMap: { value: null }
14443
14444		},
14445
14446		gradientmap: {
14447
14448			gradientMap: { value: null }
14449
14450		},
14451
14452		fog: {
14453
14454			fogDensity: { value: 0.00025 },
14455			fogNear: { value: 1 },
14456			fogFar: { value: 2000 },
14457			fogColor: { value: new Color( 0xffffff ) }
14458
14459		},
14460
14461		lights: {
14462
14463			ambientLightColor: { value: [] },
14464
14465			lightProbe: { value: [] },
14466
14467			directionalLights: { value: [], properties: {
14468				direction: {},
14469				color: {}
14470			} },
14471
14472			directionalLightShadows: { value: [], properties: {
14473				shadowBias: {},
14474				shadowNormalBias: {},
14475				shadowRadius: {},
14476				shadowMapSize: {}
14477			} },
14478
14479			directionalShadowMap: { value: [] },
14480			directionalShadowMatrix: { value: [] },
14481
14482			spotLights: { value: [], properties: {
14483				color: {},
14484				position: {},
14485				direction: {},
14486				distance: {},
14487				coneCos: {},
14488				penumbraCos: {},
14489				decay: {}
14490			} },
14491
14492			spotLightShadows: { value: [], properties: {
14493				shadowBias: {},
14494				shadowNormalBias: {},
14495				shadowRadius: {},
14496				shadowMapSize: {}
14497			} },
14498
14499			spotShadowMap: { value: [] },
14500			spotShadowMatrix: { value: [] },
14501
14502			pointLights: { value: [], properties: {
14503				color: {},
14504				position: {},
14505				decay: {},
14506				distance: {}
14507			} },
14508
14509			pointLightShadows: { value: [], properties: {
14510				shadowBias: {},
14511				shadowNormalBias: {},
14512				shadowRadius: {},
14513				shadowMapSize: {},
14514				shadowCameraNear: {},
14515				shadowCameraFar: {}
14516			} },
14517
14518			pointShadowMap: { value: [] },
14519			pointShadowMatrix: { value: [] },
14520
14521			hemisphereLights: { value: [], properties: {
14522				direction: {},
14523				skyColor: {},
14524				groundColor: {}
14525			} },
14526
14527			// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
14528			rectAreaLights: { value: [], properties: {
14529				color: {},
14530				position: {},
14531				width: {},
14532				height: {}
14533			} }
14534
14535		},
14536
14537		points: {
14538
14539			diffuse: { value: new Color( 0xeeeeee ) },
14540			opacity: { value: 1.0 },
14541			size: { value: 1.0 },
14542			scale: { value: 1.0 },
14543			map: { value: null },
14544			alphaMap: { value: null },
14545			uvTransform: { value: new Matrix3() }
14546
14547		},
14548
14549		sprite: {
14550
14551			diffuse: { value: new Color( 0xeeeeee ) },
14552			opacity: { value: 1.0 },
14553			center: { value: new Vector2( 0.5, 0.5 ) },
14554			rotation: { value: 0.0 },
14555			map: { value: null },
14556			alphaMap: { value: null },
14557			uvTransform: { value: new Matrix3() }
14558
14559		}
14560
14561	};
14562
14563	/**
14564	 * @author mrdoob / http://mrdoob.com/
14565	 */
14566
14567	function WebGLAnimation() {
14568
14569		var context = null;
14570		var isAnimating = false;
14571		var animationLoop = null;
14572		var requestId = null;
14573
14574		function onAnimationFrame( time, frame ) {
14575
14576			animationLoop( time, frame );
14577
14578			requestId = context.requestAnimationFrame( onAnimationFrame );
14579
14580		}
14581
14582		return {
14583
14584			start: function () {
14585
14586				if ( isAnimating === true ) { return; }
14587				if ( animationLoop === null ) { return; }
14588
14589				requestId = context.requestAnimationFrame( onAnimationFrame );
14590
14591				isAnimating = true;
14592
14593			},
14594
14595			stop: function () {
14596
14597				context.cancelAnimationFrame( requestId );
14598
14599				isAnimating = false;
14600
14601			},
14602
14603			setAnimationLoop: function ( callback ) {
14604
14605				animationLoop = callback;
14606
14607			},
14608
14609			setContext: function ( value ) {
14610
14611				context = value;
14612
14613			}
14614
14615		};
14616
14617	}
14618
14619	/**
14620	 * @author mrdoob / http://mrdoob.com/
14621	 */
14622
14623	function WebGLAttributes( gl, capabilities ) {
14624
14625		var isWebGL2 = capabilities.isWebGL2;
14626
14627		var buffers = new WeakMap();
14628
14629		function createBuffer( attribute, bufferType ) {
14630
14631			var array = attribute.array;
14632			var usage = attribute.usage;
14633
14634			var buffer = gl.createBuffer();
14635
14636			gl.bindBuffer( bufferType, buffer );
14637			gl.bufferData( bufferType, array, usage );
14638
14639			attribute.onUploadCallback();
14640
14641			var type = 5126;
14642
14643			if ( array instanceof Float32Array ) {
14644
14645				type = 5126;
14646
14647			} else if ( array instanceof Float64Array ) {
14648
14649				console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' );
14650
14651			} else if ( array instanceof Uint16Array ) {
14652
14653				type = 5123;
14654
14655			} else if ( array instanceof Int16Array ) {
14656
14657				type = 5122;
14658
14659			} else if ( array instanceof Uint32Array ) {
14660
14661				type = 5125;
14662
14663			} else if ( array instanceof Int32Array ) {
14664
14665				type = 5124;
14666
14667			} else if ( array instanceof Int8Array ) {
14668
14669				type = 5120;
14670
14671			} else if ( array instanceof Uint8Array ) {
14672
14673				type = 5121;
14674
14675			}
14676
14677			return {
14678				buffer: buffer,
14679				type: type,
14680				bytesPerElement: array.BYTES_PER_ELEMENT,
14681				version: attribute.version
14682			};
14683
14684		}
14685
14686		function updateBuffer( buffer, attribute, bufferType ) {
14687
14688			var array = attribute.array;
14689			var updateRange = attribute.updateRange;
14690
14691			gl.bindBuffer( bufferType, buffer );
14692
14693			if ( updateRange.count === - 1 ) {
14694
14695				// Not using update ranges
14696
14697				gl.bufferSubData( bufferType, 0, array );
14698
14699			} else {
14700
14701				if ( isWebGL2 ) {
14702
14703					gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
14704						array, updateRange.offset, updateRange.count );
14705
14706				} else {
14707
14708					gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
14709						array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );
14710
14711				}
14712
14713				updateRange.count = - 1; // reset range
14714
14715			}
14716
14717		}
14718
14719		//
14720
14721		function get( attribute ) {
14722
14723			if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; }
14724
14725			return buffers.get( attribute );
14726
14727		}
14728
14729		function remove( attribute ) {
14730
14731			if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; }
14732
14733			var data = buffers.get( attribute );
14734
14735			if ( data ) {
14736
14737				gl.deleteBuffer( data.buffer );
14738
14739				buffers.delete( attribute );
14740
14741			}
14742
14743		}
14744
14745		function update( attribute, bufferType ) {
14746
14747			if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; }
14748
14749			var data = buffers.get( attribute );
14750
14751			if ( data === undefined ) {
14752
14753				buffers.set( attribute, createBuffer( attribute, bufferType ) );
14754
14755			} else if ( data.version < attribute.version ) {
14756
14757				updateBuffer( data.buffer, attribute, bufferType );
14758
14759				data.version = attribute.version;
14760
14761			}
14762
14763		}
14764
14765		return {
14766
14767			get: get,
14768			remove: remove,
14769			update: update
14770
14771		};
14772
14773	}
14774
14775	/**
14776	 * @author mrdoob / http://mrdoob.com/
14777	 * @author Mugen87 / https://github.com/Mugen87
14778	 */
14779
14780	// PlaneGeometry
14781
14782	function PlaneGeometry( width, height, widthSegments, heightSegments ) {
14783
14784		Geometry.call( this );
14785
14786		this.type = 'PlaneGeometry';
14787
14788		this.parameters = {
14789			width: width,
14790			height: height,
14791			widthSegments: widthSegments,
14792			heightSegments: heightSegments
14793		};
14794
14795		this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
14796		this.mergeVertices();
14797
14798	}
14799
14800	PlaneGeometry.prototype = Object.create( Geometry.prototype );
14801	PlaneGeometry.prototype.constructor = PlaneGeometry;
14802
14803	// PlaneBufferGeometry
14804
14805	function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {
14806
14807		BufferGeometry.call( this );
14808
14809		this.type = 'PlaneBufferGeometry';
14810
14811		this.parameters = {
14812			width: width,
14813			height: height,
14814			widthSegments: widthSegments,
14815			heightSegments: heightSegments
14816		};
14817
14818		width = width || 1;
14819		height = height || 1;
14820
14821		var width_half = width / 2;
14822		var height_half = height / 2;
14823
14824		var gridX = Math.floor( widthSegments ) || 1;
14825		var gridY = Math.floor( heightSegments ) || 1;
14826
14827		var gridX1 = gridX + 1;
14828		var gridY1 = gridY + 1;
14829
14830		var segment_width = width / gridX;
14831		var segment_height = height / gridY;
14832
14833		// buffers
14834
14835		var indices = [];
14836		var vertices = [];
14837		var normals = [];
14838		var uvs = [];
14839
14840		// generate vertices, normals and uvs
14841
14842		for ( var iy = 0; iy < gridY1; iy ++ ) {
14843
14844			var y = iy * segment_height - height_half;
14845
14846			for ( var ix = 0; ix < gridX1; ix ++ ) {
14847
14848				var x = ix * segment_width - width_half;
14849
14850				vertices.push( x, - y, 0 );
14851
14852				normals.push( 0, 0, 1 );
14853
14854				uvs.push( ix / gridX );
14855				uvs.push( 1 - ( iy / gridY ) );
14856
14857			}
14858
14859		}
14860
14861		// indices
14862
14863		for ( var iy$1 = 0; iy$1 < gridY; iy$1 ++ ) {
14864
14865			for ( var ix$1 = 0; ix$1 < gridX; ix$1 ++ ) {
14866
14867				var a = ix$1 + gridX1 * iy$1;
14868				var b = ix$1 + gridX1 * ( iy$1 + 1 );
14869				var c = ( ix$1 + 1 ) + gridX1 * ( iy$1 + 1 );
14870				var d = ( ix$1 + 1 ) + gridX1 * iy$1;
14871
14872				// faces
14873
14874				indices.push( a, b, d );
14875				indices.push( b, c, d );
14876
14877			}
14878
14879		}
14880
14881		// build geometry
14882
14883		this.setIndex( indices );
14884		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
14885		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
14886		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
14887
14888	}
14889
14890	PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
14891	PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;
14892
14893	var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif";
14894
14895	var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
14896
14897	var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif";
14898
14899	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( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif";
14900
14901	var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
14902
14903	var begin_vertex = "vec3 transformed = vec3( position );";
14904
14905	var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
14906
14907	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 vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );
14907\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( 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 >
14907 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 vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, 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}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha  = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif";
14908
14909	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}
14909\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";
14910
14911	var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif";
14912
14913	var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
14914
14915	var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";
14916
14917	var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";
14918
14919	var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";
14920
14921	var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
14922
14923	var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
14924
14925	var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif";
14926
14927	var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(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}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\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#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\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}\nbool isPerspectiveMatrix( mat4 m ) {\n  return m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}";
14928
14929	var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_maxMipLevel 8.0\n#define cubeUV_minMipLevel 4.0\n#define cubeUV_maxTileSize 256.0\n#define cubeUV_minTileSize 16.0\nfloat getFace(vec3 direction) {\n    vec3 absDirection = abs(direction);\n    float face = -1.0;\n    if (absDirection.x > absDirection.z) {\n      if (absDirection.x > absDirection.y)\n        face = direction.x > 0.0 ? 0.0 : 3.0;\n      else\n        face = direction.y > 0.0 ? 1.0 : 4.0;\n    } else {\n      if (absDirection.z > absDirection.y)\n        face = direction.z > 0.0 ? 2.0 : 5.0;\n      else\n        face = direction.y > 0.0 ? 1.0 : 4.0;\n    }\n    return face;\n}\nvec2 getUV(vec3 direction, float face) {\n    vec2 uv;\n    if (face == 0.0) {\n      uv = vec2(direction.z, direction.y) / abs(direction.x);    } else if (face == 1.0) {\n      uv = vec2(-direction.x, -direction.z) / abs(direction.y);    } else if (face == 2.0) {\n      uv = vec2(-direction.x, direction.y) / abs(direction.z);    } else if (face == 3.0) {\n      uv = vec2(-direction.z, direction.y) / abs(direction.x);    } else if (face == 4.0) {\n      uv = vec2(-direction.x, direction.z) / abs(direction.y);    } else {\n      uv = vec2(direction.x, direction.y) / abs(direction.z);    }\n    return 0.5 * (uv + 1.0);\n}\nvec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n  float face = getFace(direction);\n  float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n  mipInt = max(mipInt, cubeUV_minMipLevel);\n  float faceSize = exp2(mipInt);\n  float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n  vec2 uv = getUV(direction, face) * (faceSize - 1.0);\n  vec2 f = fract(uv);\n  uv += 0.5 - f;\n  if (face > 2.0) {\n    uv.y += faceSize;\n    face -= 3.0;\n  }\n  uv.x += face * faceSize;\n  if(mipInt < cubeUV_maxMipLevel){\n    uv.y += 2.0 * cubeUV_maxTileSize;\n  }\n  uv.y += filterInt * 2.0 * cubeUV_minTileSize;\n  uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n  uv *= texelSize;\n  vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  uv.x += texelSize;\n  vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  uv.y += texelSize;\n  vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  uv.x -= texelSize;\n  vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n  vec3 tm = mix(tl, tr, f.x);\n  vec3 bm = mix(bl, br, f.x);\n  return mix(tm, bm, f.y);\n}\n#define r0 1.0\n#define v0 0.339\n#define m0 -2.0\n#define r1 0.8\n#define v1 0.276\n#define m1 -1.0\n#define r4 0.4\n#define v4 0.046\n#define m4 2.0\n#define r5 0.305\n#define v5 0.016\n#define m5 3.0\n#define r6 0.21\n#define v6 0.0038\n#define m6 4.0\nfloat roughnessToMip(float roughness) {\
14929n  float mip = 0.0;\n  if (roughness >= r1) {\n    mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n  } else if (roughness >= r4) {\n    mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n  } else if (roughness >= r5) {\n    mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n  } else if (roughness >= r6) {\n    mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n  } else {\n    mip = -2.0 * log2(1.16 * roughness);  }\n  return mip;\n}\nvec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {\n  float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);\n  float mipF = fract(mip);\n  float mipInt = floor(mip);\n  vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);\n  if (mipF == 0.0) {\n    return vec4(color0, 1.0);\n  } else {\n    vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);\n    return vec4(mix(color0, color1, mipF), 1.0);\n  }\n}\n#endif";
14930
14931	var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
14932
14933	var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
14934
14935	var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif";
14936
14937	var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";
14938
14939	var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";
14940
14941	var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
14942
14943	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 = clamp( floor( D ) / 255.0, 0.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}
14943\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}";
14944
14945	var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\t\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t}  else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, 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_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec2 sampleUV = equirectUv( reflectVec );\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\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";
14946
14947	var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif";
14948
14949	var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif";
14950
14951	var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif";
14952
14953	var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) { \n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t}
14953 else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\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";
14954
14955	var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = -mvPosition.z;\n#endif";
14956
14957	var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif";
14958
14959	var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\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";
14960
14961	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";
14962
14963	var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}";
14964
14965	var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif";
14966
14967	var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
14968
14969	var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : 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;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif";
14970
14971	var lights_pars_begin = "uniform bool receiveShadow;\nuniform 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};\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};\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}
14971\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};\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";
14972
14973	var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\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\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 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 roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t  vec3 reflectVec = reflect( -viewDir, normal );\n\t\t  reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t  vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, 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\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV = equirectUv( reflectVec );\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#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif";
14974
14975	var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
14976
14977	var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct ToonMaterial {\n\tvec3\tdiffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)";
14978
14979	var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
14980
14981	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\tfloat dotNL = saturate( dot
14981( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\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)";
14982
14983	var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;
14983\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif";
14984
14985	var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#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#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\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#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot
14985( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\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\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}";
14986
14987	var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\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\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
14988
14989	var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * 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( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif";
14990
14991	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, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif";
14992
14993	var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif";
14994
14995	var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif";
14996
14997	var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif";
14998
14999	var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif";
15000
15001	var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif";
15002
15003	var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif";
15004
15005	var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, uv );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif";
15006
15007	var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
15008
15009	var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif";
15010
15011	var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
15012
15013	var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif";
15014
15015	var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif";
15016
15017	var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif";
15018
15019	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\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;";
15020
15021	var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );
15021\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif";
15022
15023	var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif";
15024
15025	var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif";
15026
15027	var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif";
15028
15029	var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif";
15030
15031	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}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\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}";
15032
15033	var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
15034
15035	var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;";
15036
15037	var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
15038
15039	var dithering_pars_fragment = "#ifdef 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";
15040
15041	var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif";
15042
15043	var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
15044
15045	
vendor: 9,162 bytes, line 15045
15045var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\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 dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t  texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t  f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t  texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t  f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\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 ) || defined( SHADOWMAP_TYPE_VSM )\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";
15046
15047	var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif";
15048
15049	var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\tvec4 shadowWorldPosition;\n\t#endif\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif";
15050
15051	var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}";
15052
15053	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";
15054
15055	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";
15056
15057	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";
15058
15059	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;
15059\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";
15060
15061	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";
15062
15063	var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
15064
15065	var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
15066
15067	var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\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}\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 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3(  1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108,  1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605,  1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
15068
15069	var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif";
15070
15071	var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif";
15072
15073	var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif";
15074
15075	var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
15076
15077	var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif";
15078
15079	var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif";
15080
15081	var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
15082
15083	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 <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
15084
15085	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}";
15086
15087	var cube_frag = "#include <envmap_common_pars_fragment>\nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include <envmap_fragment>\n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
15088
15089	var cube_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
15090
15091	var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}";
15092
15093	var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}";
15094
15095	var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
15096
15097	var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
15098
15099	var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
15100
15101	var equirect_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
15102
15103	var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
15104
15105	var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
15106
15107	var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
15108
15109	var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
15110
15111	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 <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\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 <lightmap_fragment>\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 <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
15112
15113	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 <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
15114
15115	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 <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\
15115n\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 <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
15116
15117	var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}";
15118
15119	var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
15120
15121	var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
15122
15123	var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
15124
15125	var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
15126
15127	var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSPARENCY\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSPARENCY\n\tuniform float transparency;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;
15127\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\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 <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\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 <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSPARENCY\n\t\tdiffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
15128
15129	var meshphysical_vert = "#define STANDARD\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 <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\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 <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
15130
15131	var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_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 <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}";
15132
15133	var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_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 <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\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 <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}";
15134
15135	var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
15136
15137	var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}";
15138
15139	var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
15140
15141	var shadow_vert = "#include <common>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
15142
15143	var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
15144
15145	var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\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 = isPerspectiveMatrix( projectionMatrix );\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 <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
15146
15147	var ShaderChunk = {
15148		alphamap_fragment: alphamap_fragment,
15149		alphamap_pars_fragment: alphamap_pars_fragment,
15150		alphatest_fragment: alphatest_fragment,
15151		aomap_fragment: aomap_fragment,
15152		aomap_pars_fragment: aomap_pars_fragment,
15153		begin_vertex: begin_vertex,
15154		beginnormal_vertex: beginnormal_vertex,
15155		bsdfs: bsdfs,
15156		bumpmap_pars_fragment: bumpmap_pars_fragment,
15157		clipping_planes_fragment: clipping_planes_fragment,
15158		clipping_planes_pars_fragment: clipping_planes_pars_fragment,
15159		clipping_planes_pars_vertex: clipping_planes_pars_vertex,
15160		clipping_planes_vertex: clipping_planes_vertex,
15161		color_fragment: color_fragment,
15162		color_pars_fragment: color_pars_fragment,
15163		color_pars_vertex: color_pars_vertex,
15164		color_vertex: color_vertex,
15165		common: common,
15166		cube_uv_reflection_fragment: cube_uv_reflection_fragment,
15167		defaultnormal_vertex: defaultnormal_vertex,
15168		displacementmap_pars_vertex: displacementmap_pars_vertex,
15169		displacementmap_vertex: displacementmap_vertex,
15170		emissivemap_fragment: emissivemap_fragment,
15171		emissivemap_pars_fragment: emissivemap_pars_fragment,
15172		encodings_fragment: encodings_fragment,
15173		encodings_pars_fragment: encodings_pars_fragment,
15174		envmap_fragment: envmap_fragment,
15175		envmap_common_pars_fragment: envmap_common_pars_fragment,
15176		envmap_pars_fragment: envmap_pars_fragment,
15177		envmap_pars_vertex: envmap_pars_vertex,
15178		envmap_physical_pars_fragment: envmap_physical_pars_fragment,
15179		envmap_vertex: envmap_vertex,
15180		fog_vertex: fog_vertex,
15181		fog_pars_vertex: fog_pars_vertex,
15182		fog_fragment: fog_fragment,
15183		fog_pars_fragment: fog_pars_fragment,
15184		gradientmap_pars_fragment: gradientmap_pars_fragment,
15185		lightmap_fragment: lightmap_fragment,
15186		lightmap_pars_fragment: lightmap_pars_fragment,
15187		lights_lambert_vertex: lights_lambert_vertex,
15188		lights_pars_begin: lights_pars_begin,
15189		lights_toon_fragment: lights_toon_fragment,
15190		lights_toon_pars_fragment: lights_toon_pars_fragment,
15191		lights_phong_fragment: lights_phong_fragment,
15192		lights_phong_pars_fragment: lights_phong_pars_fragment,
15193		lights_physical_fragment: lights_physical_fragment,
15194		lights_physical_pars_fragment: lights_physical_pars_fragment,
15195		lights_fragment_begin: lights_fragment_begin,
15196		lights_fragment_maps: lights_fragment_maps,
15197		lights_fragment_end: lights_fragment_end,
15198		logdepthbuf_fragment: logdepthbuf_fragment,
15199		logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
15200		logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
15201		logdepthbuf_vertex: logdepthbuf_vertex,
15202		map_fragment: map_fragment,
15203		map_pars_fragment: map_pars_fragment,
15204		map_particle_fragment: map_particle_fragment,
15205		map_particle_pars_fragment: map_particle_pars_fragment,
15206		metalnessmap_fragment: metalnessmap_fragment,
15207		metalnessmap_pars_fragment: metalnessmap_pars_fragment,
15208		morphnormal_vertex: morphnormal_vertex,
15209		morphtarget_pars_vertex: morphtarget_pars_vertex,
15210		morphtarget_vertex: morphtarget_vertex,
15211		normal_fragment_begin: normal_fragment_begin,
15212		normal_fragment_maps: normal_fragment_maps,
15213		normalmap_pars_fragment: normalmap_pars_fragment,
15214		clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin,
15215		clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps,
15216		clearcoat_pars_fragment: clearcoat_pars_fragment,
15217		packing: packing,
15218		premultiplied_alpha_fragment: premultiplied_alpha_fragment,
15219		project_vertex: project_vertex,
15220		dithering_fragment: dithering_fragment,
15221		dithering_pars_fragment: dithering_pars_fragment,
15222		roughnessmap_fragment: roughnessmap_fragment,
15223		roughnessmap_pars_fragment: roughnessmap_pars_fragment,
15224		shadowmap_pars_fragment: shadowmap_pars_fragment,
15225		shadowmap_pars_vertex: shadowmap_pars_vertex,
15226		shadowmap_vertex: shadowmap_vertex,
15227		shadowmask_pars_fragment: shadowmask_pars_fragment,
15228		skinbase_vertex: skinbase_vertex,
15229		skinning_pars_vertex: skinning_pars_vertex,
15230		skinning_vertex: skinning_vertex,
15231		skinnormal_vertex: skinnormal_vertex,
15232		specularmap_fragment: specularmap_fragment,
15233		specularmap_pars_fragment: specularmap_pars_fragment,
15234		tonemapping_fragment: tonemapping_fragment,
15235		tonemapping_pars_fragment: tonemapping_pars_fragment,
15236		uv_pars_fragment: uv_pars_fragment,
15237		uv_pars_vertex: uv_pars_vertex,
15238		uv_vertex: uv_vertex,
15239		uv2_pars_fragment: uv2_pars_fragment,
15240		uv2_pars_vertex: uv2_pars_vertex,
15241		uv2_vertex: uv2_vertex,
15242		worldpos_vertex: worldpos_vertex,
15243
15244		background_frag: background_frag,
15245		background_vert: background_vert,
15246		cube_frag: cube_frag,
15247		cube_vert: cube_vert,
15248		depth_frag: depth_frag,
15249		depth_vert: depth_vert,
15250		distanceRGBA_frag: distanceRGBA_frag,
15251		distanceRGBA_vert: distanceRGBA_vert,
15252		equirect_frag: equirect_frag,
15253		equirect_vert: equirect_vert,
15254		linedashed_frag: linedashed_frag,
15255		linedashed_vert: linedashed_vert,
15256		meshbasic_frag: meshbasic_frag,
15257		meshbasic_vert: meshbasic_vert,
15258		meshlambert_frag: meshlambert_frag,
15259		meshlambert_vert: meshlambert_vert,
15260		meshmatcap_frag: meshmatcap_frag,
15261		meshmatcap_vert: meshmatcap_vert,
15262		meshtoon_frag: meshtoon_frag,
15263		meshtoon_vert: meshtoon_vert,
15264		meshphong_frag: meshphong_frag,
15265		meshphong_vert: meshphong_vert,
15266		meshphysical_frag: meshphysical_frag,
15267		meshphysical_vert: meshphysical_vert,
15268		normal_frag: normal_frag,
15269		normal_vert: normal_vert,
15270		points_frag: points_frag,
15271		points_vert: points_vert,
15272		shadow_frag: shadow_frag,
15273		shadow_vert: shadow_vert,
15274		sprite_frag: sprite_frag,
15275		sprite_vert: sprite_vert
15276	};
15277
15278	/**
15279	 * @author alteredq / http://alteredqualia.com/
15280	 * @author mrdoob / http://mrdoob.com/
15281	 * @author mikael emtinger / http://gomo.se/
15282	 */
15283
15284	var ShaderLib = {
15285
15286		basic: {
15287
15288			uniforms: mergeUniforms( [
15289				UniformsLib.common,
15290				UniformsLib.specularmap,
15291				UniformsLib.envmap,
15292				UniformsLib.aomap,
15293				UniformsLib.lightmap,
15294				UniformsLib.fog
15295			] ),
15296
15297			vertexShader: ShaderChunk.meshbasic_vert,
15298			fragmentShader: ShaderChunk.meshbasic_frag
15299
15300		},
15301
15302		lambert: {
15303
15304			uniforms: mergeUniforms( [
15305				UniformsLib.common,
15306				UniformsLib.specularmap,
15307				UniformsLib.envmap,
15308				UniformsLib.aomap,
15309				UniformsLib.lightmap,
15310				UniformsLib.emi
vendor: 5,355 bytes, lines 15310-15586
15310ssivemap,
15311				UniformsLib.fog,
15312				UniformsLib.lights,
15313				{
15314					emissive: { value: new Color( 0x000000 ) }
15315				}
15316			] ),
15317
15318			vertexShader: ShaderChunk.meshlambert_vert,
15319			fragmentShader: ShaderChunk.meshlambert_frag
15320
15321		},
15322
15323		phong: {
15324
15325			uniforms: mergeUniforms( [
15326				UniformsLib.common,
15327				UniformsLib.specularmap,
15328				UniformsLib.envmap,
15329				UniformsLib.aomap,
15330				UniformsLib.lightmap,
15331				UniformsLib.emissivemap,
15332				UniformsLib.bumpmap,
15333				UniformsLib.normalmap,
15334				UniformsLib.displacementmap,
15335				UniformsLib.fog,
15336				UniformsLib.lights,
15337				{
15338					emissive: { value: new Color( 0x000000 ) },
15339					specular: { value: new Color( 0x111111 ) },
15340					shininess: { value: 30 }
15341				}
15342			] ),
15343
15344			vertexShader: ShaderChunk.meshphong_vert,
15345			fragmentShader: ShaderChunk.meshphong_frag
15346
15347		},
15348
15349		standard: {
15350
15351			uniforms: mergeUniforms( [
15352				UniformsLib.common,
15353				UniformsLib.envmap,
15354				UniformsLib.aomap,
15355				UniformsLib.lightmap,
15356				UniformsLib.emissivemap,
15357				UniformsLib.bumpmap,
15358				UniformsLib.normalmap,
15359				UniformsLib.displacementmap,
15360				UniformsLib.roughnessmap,
15361				UniformsLib.metalnessmap,
15362				UniformsLib.fog,
15363				UniformsLib.lights,
15364				{
15365					emissive: { value: new Color( 0x000000 ) },
15366					roughness: { value: 1.0 },
15367					metalness: { value: 0.0 },
15368					envMapIntensity: { value: 1 } // temporary
15369				}
15370			] ),
15371
15372			vertexShader: ShaderChunk.meshphysical_vert,
15373			fragmentShader: ShaderChunk.meshphysical_frag
15374
15375		},
15376
15377		toon: {
15378
15379			uniforms: mergeUniforms( [
15380				UniformsLib.common,
15381				UniformsLib.aomap,
15382				UniformsLib.lightmap,
15383				UniformsLib.emissivemap,
15384				UniformsLib.bumpmap,
15385				UniformsLib.normalmap,
15386				UniformsLib.displacementmap,
15387				UniformsLib.gradientmap,
15388				UniformsLib.fog,
15389				UniformsLib.lights,
15390				{
15391					emissive: { value: new Color( 0x000000 ) }
15392				}
15393			] ),
15394
15395			vertexShader: ShaderChunk.meshtoon_vert,
15396			fragmentShader: ShaderChunk.meshtoon_frag
15397
15398		},
15399
15400		matcap: {
15401
15402			uniforms: mergeUniforms( [
15403				UniformsLib.common,
15404				UniformsLib.bumpmap,
15405				UniformsLib.normalmap,
15406				UniformsLib.displacementmap,
15407				UniformsLib.fog,
15408				{
15409					matcap: { value: null }
15410				}
15411			] ),
15412
15413			vertexShader: ShaderChunk.meshmatcap_vert,
15414			fragmentShader: ShaderChunk.meshmatcap_frag
15415
15416		},
15417
15418		points: {
15419
15420			uniforms: mergeUniforms( [
15421				UniformsLib.points,
15422				UniformsLib.fog
15423			] ),
15424
15425			vertexShader: ShaderChunk.points_vert,
15426			fragmentShader: ShaderChunk.points_frag
15427
15428		},
15429
15430		dashed: {
15431
15432			uniforms: mergeUniforms( [
15433				UniformsLib.common,
15434				UniformsLib.fog,
15435				{
15436					scale: { value: 1 },
15437					dashSize: { value: 1 },
15438					totalSize: { value: 2 }
15439				}
15440			] ),
15441
15442			vertexShader: ShaderChunk.linedashed_vert,
15443			fragmentShader: ShaderChunk.linedashed_frag
15444
15445		},
15446
15447		depth: {
15448
15449			uniforms: mergeUniforms( [
15450				UniformsLib.common,
15451				UniformsLib.displacementmap
15452			] ),
15453
15454			vertexShader: ShaderChunk.depth_vert,
15455			fragmentShader: ShaderChunk.depth_frag
15456
15457		},
15458
15459		normal: {
15460
15461			uniforms: mergeUniforms( [
15462				UniformsLib.common,
15463				UniformsLib.bumpmap,
15464				UniformsLib.normalmap,
15465				UniformsLib.displacementmap,
15466				{
15467					opacity: { value: 1.0 }
15468				}
15469			] ),
15470
15471			vertexShader: ShaderChunk.normal_vert,
15472			fragmentShader: ShaderChunk.normal_frag
15473
15474		},
15475
15476		sprite: {
15477
15478			uniforms: mergeUniforms( [
15479				UniformsLib.sprite,
15480				UniformsLib.fog
15481			] ),
15482
15483			vertexShader: ShaderChunk.sprite_vert,
15484			fragmentShader: ShaderChunk.sprite_frag
15485
15486		},
15487
15488		background: {
15489
15490			uniforms: {
15491				uvTransform: { value: new Matrix3() },
15492				t2D: { value: null },
15493			},
15494
15495			vertexShader: ShaderChunk.background_vert,
15496			fragmentShader: ShaderChunk.background_frag
15497
15498		},
15499		/* -------------------------------------------------------------------------
15500		//	Cube map shader
15501		 ------------------------------------------------------------------------- */
15502
15503		cube: {
15504
15505			uniforms: mergeUniforms( [
15506				UniformsLib.envmap,
15507				{
15508					opacity: { value: 1.0 }
15509				}
15510			] ),
15511
15512			vertexShader: ShaderChunk.cube_vert,
15513			fragmentShader: ShaderChunk.cube_frag
15514
15515		},
15516
15517		equirect: {
15518
15519			uniforms: {
15520				tEquirect: { value: null },
15521			},
15522
15523			vertexShader: ShaderChunk.equirect_vert,
15524			fragmentShader: ShaderChunk.equirect_frag
15525
15526		},
15527
15528		distanceRGBA: {
15529
15530			uniforms: mergeUniforms( [
15531				UniformsLib.common,
15532				UniformsLib.displacementmap,
15533				{
15534					referencePosition: { value: new Vector3() },
15535					nearDistance: { value: 1 },
15536					farDistance: { value: 1000 }
15537				}
15538			] ),
15539
15540			vertexShader: ShaderChunk.distanceRGBA_vert,
15541			fragmentShader: ShaderChunk.distanceRGBA_frag
15542
15543		},
15544
15545		shadow: {
15546
15547			uniforms: mergeUniforms( [
15548				UniformsLib.lights,
15549				UniformsLib.fog,
15550				{
15551					color: { value: new Color( 0x00000 ) },
15552					opacity: { value: 1.0 }
15553				} ] ),
15554
15555			vertexShader: ShaderChunk.shadow_vert,
15556			fragmentShader: ShaderChunk.shadow_frag
15557
15558		}
15559
15560	};
15561
15562	ShaderLib.physical = {
15563
15564		uniforms: mergeUniforms( [
15565			ShaderLib.standard.uniforms,
15566			{
15567				clearcoat: { value: 0 },
15568				clearcoatMap: { value: null },
15569				clearcoatRoughness: { value: 0 },
15570				clearcoatRoughnessMap: { value: null },
15571				clearcoatNormalScale: { value: new Vector2( 1, 1 ) },
15572				clearcoatNormalMap: { value: null },
15573				sheen: { value: new Color( 0x000000 ) },
15574				transparency: { value: 0 },
15575			}
15576		] ),
15577
15578		vertexShader: ShaderChunk.meshphysical_vert,
15579		fragmentShader: ShaderChunk.meshphysical_frag
15580
15581	};
15582
15583	/**
15584	 * @author mrdoob / http://mrdoob.com/
15585	 */
15586
15587	function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
15588
15589		var clearColor = new Color( 0x000000 );
15590		var clearAlpha = 0;
15591
15592		var planeMesh;
15593		var boxMesh;
15594
15595		var currentBackground = null;
15596		var currentBackgroundVersion = 0;
15597		var currentTonemapping = null;
15598
15599		function render( renderList, scene, camera, forceClear ) {
15600
15601			var background = scene.isScene === true ? scene.background : null;
15602
15603			// Ignore background in AR
15604			// TODO: Reconsider this.
15605
15606			var xr = renderer.xr;
15607			var session = xr.getSession && xr.getSession();
15608
15609			if ( session && session.environmentBlendMode === 'additive' ) {
15610
15611				background = null;
15612
15613			}
15614
15615			if ( background === null ) {
15616
15617				setClear( clearColor, clearAlpha );
15618
15619			} else if ( background && background.isColor ) {
15620
15621				setClear( background, 1 );
15622				forceClear = true;
15623
15624			}
15625
15626			if ( renderer.autoClear || forceClear ) {
15627
15628				renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
15629
15630			}
15631
15632			if ( background && ( background.isCubeTexture || background.isWebGLCubeRenderTarget || background.mapping === CubeUVReflectionMapping ) ) {
15633
15634				if ( boxMesh === undefined ) {
15635
15636					boxMesh = new Mesh(
15637						new BoxBufferGeometry( 1, 1, 1 ),
15638						new ShaderMaterial( {
15639							name: 'BackgroundCubeMaterial',
15640							uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
15641							vertexShader: ShaderLib.cube.vertexShader,
15642							fragmentShader: ShaderLib.cube.fragmentShader,
15643							side: BackSide,
15644							depthTest: false,
15645							depthWrite: false,
15646							fog: false
15647						} )
15648					);
15649
15650					boxMesh.geometry.deleteAttribute( 'normal' );
15651					boxMesh.geometry.deleteAttribute( 'uv' );
15652
15653					boxMesh.onBeforeRender = function ( renderer, scene, camera ) {
15654
15655						this.matrixWorld.copyPosition( camera.matrixWorld );
15656
15657					};
15658
15659					// enable code injection for non-built-in material
15660					Object.defineProperty( boxMesh.material, 'envMap', {
15661
15662						get: function () {
15663
15664							return this.uniforms.envMap.value;
15665
15666						}
15667
15668					} );
15669
15670					objects.update( boxMesh );
15671
15672				}
15673
15674				var texture = background.isWebGLCubeRenderTarget ? background.texture : background;
15675
15676				boxMesh.material.uniforms.envMap.value = texture;
15677				boxMesh.material.uniforms.flipEnvMap.value = texture.isCubeTexture ? - 1 : 1;
15678
15679				if ( currentBackground !== background ||
15680					currentBackgroundVersion !== texture.version ||
15681					currentTonemapping !== renderer.toneMapping ) {
15682
15683					boxMesh.material.needsUpdate = true;
15684
15685					currentBackground = background;
15686					currentBackgroundVersion = texture.version;
15687					currentTonemapping = renderer.toneMapping;
15688
15689				}
15690
15691				// push to the pre-sorted opaque render list
15692				renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );
15693
15694			} else if ( background && background.isTexture ) {
15695
15696				if ( planeMesh === undefined ) {
15697
15698					planeMesh = new Mesh(
15699						new PlaneBufferGeometry( 2, 2 ),
15700						new ShaderMaterial( {
15701							name: 'BackgroundMaterial',
15702							uniforms: cloneUniforms( ShaderLib.background.uniforms ),
15703							vertexShader: ShaderLib.background.vertexShader,
15704							fragmentShader: ShaderLib.background.fragmentShader,
15705							side: FrontSide,
15706							depthTest: false,
15707							depthWrite: false,
15708							fog: false
15709						} )
15710					);
15711
15712					planeMesh.geometry.deleteAttribute( 'normal' );
15713
15714					// enable code injection for non-built-in material
15715					Object.defineProperty( planeMesh.material, 'map', {
15716
15717						get: function () {
15718
15719							return this.uniforms.t2D.value;
15720
15721						}
15722
15723					} );
15724
15725					objects.update( planeMesh );
15726
15727				}
15728
15729				planeMesh.material.uniforms.t2D.value = background;
15730
15731				if ( background.matrixAutoUpdate === true ) {
15732
15733					background.updateMatrix();
15734
15735				}
15736
15737				planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
15738
15739				if ( currentBackground !== background ||
15740					currentBackgroundVersion !== background.version ||
15741					currentTonemapping !== renderer.toneMapping ) {
15742
15743					planeMesh.material.needsUpdate = true;
15744
15745					currentBackground = background;
15746					currentBackgroundVersion = background.version;
15747					currentTonemapping = renderer.toneMapping;
15748
15749				}
15750
15751
15752				// push to the pre-sorted opaque render list
15753				renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );
15754
15755			}
15756
15757		}
15758
15759		function setClear( color, alpha ) {
15760
15761			state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );
15762
15763		}
15764
15765		return {
15766
15767			getClearColor: function () {
15768
15769				return clearColor;
15770
15771			},
15772			setClearColor: function ( color, alpha ) {
15773
15774				clearColor.set( color );
15775				clearAlpha = alpha !== undefined ? alpha : 1;
15776				setClear( clearColor, clearAlpha );
15777
15778			},
15779			getClearAlpha: function () {
15780
15781				return clearAlpha;
15782
15783			},
15784			setClearAlpha: function ( alpha ) {
15785
15786				clearAlpha = alpha;
15787				setClear( clearColor, clearAlpha );
15788
15789			},
15790			render: render
15791
15792		};
15793
15794	}
15795
15796	/**
15797	 * @author Mugen87 / https://github.com/Mugen87
15798	 * @author Takahiro / https://github.com/takahirox
15799	 */
15800
15801	function WebGLBindingStates( gl, extensions, attributes, capabilities ) {
15802
15803		var maxVertexAttributes = gl.getParameter( 34921 );
15804
15805		var extension = capabilities.isWebGL2 ? null : extensions.get( 'OES_vertex_array_object' );
15806		var vaoAvailable = capabilities.isWebGL2 || extension !== null;
15807
15808		var bindingStates = {};
15809
15810		var defaultState = createBindingState( null );
15811		var currentState = defaultState;
15812
15813		function setup( object, material, program, geometry, index ) {
15814
15815			var updateBuffers = false;
15816
15817			if ( vaoAvailable ) {
15818
15819				var state = getBindingState( geometry, program, material );
15820
15821				if ( currentState !== state ) {
15822
15823					currentState = state;
15824					bindVertexArrayObject( currentState.object );
15825
15826				}
15827
15828				updateBuffers = needsUpdate( geometry );
15829
15830				if ( updateBuffers ) { saveCache( geometry ); }
15831
15832			} else {
15833
15834				var wireframe = ( material.wireframe === true );
15835
15836				if ( currentState.geometry !== geometry.id ||
15837					currentState.program !== program.id ||
15838					currentState.wireframe !== wireframe ) {
15839
15840					currentState.geometry = geometry.id;
15841					currentState.program = program.id;
15842					currentState.wireframe = wireframe;
15843
15844					updateBuffers = true;
15845
15846				}
15847
15848			}
15849
15850			if ( object.isInstancedMesh === true ) {
15851
15852				updateBuffers = true;
15853
15854			}
15855
15856			if ( index !== null ) {
15857
15858				attributes.update( index, 34963 );
15859
15860			}
15861
15862			if ( updateBuffers ) {
15863
15864				setupVertexAttributes( object, material, program, geometry );
15865
15866				if ( index !== null ) {
15867
15868					gl.bindBuffer( 34963, attributes.get( index ).buffer );
15869
15870				}
15871
15872			}
15873
15874		}
15875
15876		function createVertexArrayObject() {
15877
15878			if ( capabilities.isWebGL2 ) { return gl.createVertexArray(); }
15879
15880			return extension.createVertexArrayOES();
15881
15882		}
15883
15884		function bindVertexArrayObject( vao ) {
15885
15886			if ( capabilities.isWebGL2 ) { return gl.bindVertexArray( vao ); }
15887
15888			return extension.bindVertexArrayOES( vao );
15889
15890		}
15891
15892		function deleteVertexArrayObject( vao ) {
15893
15894			if ( capabilities.isWebGL2 ) { return gl.deleteVertexArray( vao ); }
15895
15896			return extension.deleteVertexArrayOES( vao );
15897
15898		}
15899
15900		function getBindingState( geometry, program, material ) {
15901
15902			var wireframe = ( material.wireframe === true );
15903
15904			var programMap = bindingStates[ geometry.id ];
15905
15906			if ( programMap === undefined ) {
15907
15908				programMap = {};
15909				bindingStates[ geometry.id ] = programMap;
15910
15911			}
15912
15913			var stateMap = programMap[ program.id ];
15914
15915			if ( stateMap === undefined ) {
15916
15917				stateMap = {};
15918				programMap[ program.id ] = stateMap;
15919
15920			}
15921
15922			var state = stateMap[ wireframe ];
15923
15924			if ( state === undefined ) {
15925
15926				state = createBindingState( createVertexArrayObject() );
15927				stateMap[ wireframe ] = state;
15928
15929			}
15930
15931			return state;
15932
15933		}
15934
15935		function createBindingState( vao ) {
15936
15937			var newAttributes = [];
15938			var enabledAttributes = [];
15939			var attributeDivisors = [];
15940
15941			for ( var i = 0; i < maxVertexAttributes; i ++ ) {
15942
15943				newAttributes[ i ] = 0;
15944				enabledAttributes[ i ] = 0;
15945				attributeDivisors[ i ] = 0;
15946
15947			}
15948
15949			return {
15950
15951				// for backward compatibility on non-VAO support browser
15952				geometry: null,
15953				program: null,
15954				wireframe: false,
15955
15956				newAttributes: newAttributes,
15957				enabledAttributes: enabledAttributes,
15958				attributeDivisors: attributeDivisors,
15959				object: vao,
15960				attributes: {}
15961
15962			};
15963
15964		}
15965
15966		function needsUpdate( geometry ) {
15967
15968			var cachedAttributes = currentState.attributes;
15969			var geometryAttributes = geometry.attributes;
15970
15971			if ( Object.keys( cachedAttributes ).length !== Object.keys( geometryAttributes ).length ) { return true; }
15972
15973			for ( var key in geometryAttributes ) {
15974
15975				var cachedAttribute = cachedAttributes[ key ];
15976				var geometryAttribute = geometryAttributes[ key ];
15977
15978				if ( cachedAttribute.attribute !== geometryAttribute ) { return true; }
15979
15980				if ( cachedAttribute.data !== geometryAttribute.data ) { return true; }
15981
15982			}
15983
15984			return false;
15985
15986		}
15987
15988		function saveCache( geometry ) {
15989
15990			var cache = {};
15991			var attributes = geometry.attributes;
15992
15993			for ( var key in attributes ) {
15994
15995				var attribute = attributes[ key ];
15996
15997				var data = {};
15998				data.attribute = attribute;
15999
16000				if ( attribute.data ) {
16001
16002					data.data = attribute.data;
16003
16004				}
16005
16006				cache[ key ] = data;
16007
16008			}
16009
16010			currentState.attributes = cache;
16011
16012		}
16013
16014		function initAttributes() {
16015
16016			var newAttributes = currentState.newAttributes;
16017
16018			for ( var i = 0, il = newAttributes.length; i < il; i ++ ) {
16019
16020				newAttributes[ i ] = 0;
16021
16022			}
16023
16024		}
16025
16026		function enableAttribute( attribute ) {
16027
16028			enableAttributeAndDivisor( attribute, 0 );
16029
16030		}
16031
16032		function enableAttributeAndDivisor( attribute, meshPerAttribute ) {
16033
16034			var newAttributes = currentState.newAttributes;
16035			var enabledAttributes = currentState.enabledAttributes;
16036			var attributeDivisors = currentState.attributeDivisors;
16037
16038			newAttributes[ attribute ] = 1;
16039
16040			if ( enabledAttributes[ attribute ] === 0 ) {
16041
16042				gl.enableVertexAttribArray( attribute );
16043				enabledAttributes[ attribute ] = 1;
16044
16045			}
16046
16047			if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
16048
16049				var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_
16049instanced_arrays' );
16050
16051				extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute );
16052				attributeDivisors[ attribute ] = meshPerAttribute;
16053
16054			}
16055
16056		}
16057
16058		function disableUnusedAttributes() {
16059
16060			var newAttributes = currentState.newAttributes;
16061			var enabledAttributes = currentState.enabledAttributes;
16062
16063			for ( var i = 0, il = enabledAttributes.length; i < il; i ++ ) {
16064
16065				if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
16066
16067					gl.disableVertexAttribArray( i );
16068					enabledAttributes[ i ] = 0;
16069
16070				}
16071
16072			}
16073
16074		}
16075
16076		function vertexAttribPointer( index, size, type, normalized, stride, offset ) {
16077
16078			if ( capabilities.isWebGL2 === true && ( type === 5124 || type === 5125 ) ) {
16079
16080				gl.vertexAttribIPointer( index, size, type, normalized, stride, offset );
16081
16082			} else {
16083
16084				gl.vertexAttribPointer( index, size, type, normalized, stride, offset );
16085
16086			}
16087
16088		}
16089
16090		function setupVertexAttributes( object, material, program, geometry ) {
16091
16092			if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) {
16093
16094				if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { return; }
16095
16096			}
16097
16098			initAttributes();
16099
16100			var geometryAttributes = geometry.attributes;
16101
16102			var programAttributes = program.getAttributes();
16103
16104			var materialDefaultAttributeValues = material.defaultAttributeValues;
16105
16106			for ( var name in programAttributes ) {
16107
16108				var programAttribute = programAttributes[ name ];
16109
16110				if ( programAttribute >= 0 ) {
16111
16112					var geometryAttribute = geometryAttributes[ name ];
16113
16114					if ( geometryAttribute !== undefined ) {
16115
16116						var normalized = geometryAttribute.normalized;
16117						var size = geometryAttribute.itemSize;
16118
16119						var attribute = attributes.get( geometryAttribute );
16120
16121						// TODO Attribute may not be available on context restore
16122
16123						if ( attribute === undefined ) { continue; }
16124
16125						var buffer = attribute.buffer;
16126						var type = attribute.type;
16127						var bytesPerElement = attribute.bytesPerElement;
16128
16129						if ( geometryAttribute.isInterleavedBufferAttribute ) {
16130
16131							var data = geometryAttribute.data;
16132							var stride = data.stride;
16133							var offset = geometryAttribute.offset;
16134
16135							if ( data && data.isInstancedInterleavedBuffer ) {
16136
16137								enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
16138
16139								if ( geometry._maxInstanceCount === undefined ) {
16140
16141									geometry._maxInstanceCount = data.meshPerAttribute * data.count;
16142
16143								}
16144
16145							} else {
16146
16147								enableAttribute( programAttribute );
16148
16149							}
16150
16151							gl.bindBuffer( 34962, buffer );
16152							vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
16153
16154						} else {
16155
16156							if ( geometryAttribute.isInstancedBufferAttribute ) {
16157
16158								enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
16159
16160								if ( geometry._maxInstanceCount === undefined ) {
16161
16162									geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
16163
16164								}
16165
16166							} else {
16167
16168								enableAttribute( programAttribute );
16169
16170							}
16171
16172							gl.bindBuffer( 34962, buffer );
16173							vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
16174
16175						}
16176
16177					} else if ( name === 'instanceMatrix' ) {
16178
16179						var attribute$1 = attributes.get( object.instanceMatrix );
16180
16181						// TODO Attribute may not be available on context restore
16182
16183						if ( attribute$1 === undefined ) { continue; }
16184
16185						var buffer$1 = attribute$1.buffer;
16186						var type$1 = attribute$1.type;
16187
16188						enableAttributeAndDivisor( programAttribute + 0, 1 );
16189						enableAttributeAndDivisor( programAttribute + 1, 1 );
16190						enableAttributeAndDivisor( programAttribute + 2, 1 );
16191						enableAttributeAndDivisor( programAttribute + 3, 1 );
16192
16193						gl.bindBuffer( 34962, buffer$1 );
16194
16195						gl.vertexAttribPointer( programAttribute + 0, 4, type$1, false, 64, 0 );
16196						gl.vertexAttribPointer( programAttribute + 1, 4, type$1, false, 64, 16 );
16197						gl.vertexAttribPointer( programAttribute + 2, 4, type$1, false, 64, 32 );
16198						gl.vertexAttribPointer( programAttribute + 3, 4, type$1, false, 64, 48 );
16199
16200					} else if ( materialDefaultAttributeValues !== undefined ) {
16201
16202						var value = materialDefaultAttributeValues[ name ];
16203
16204						if ( value !== undefined ) {
16205
16206							switch ( value.length ) {
16207
16208								case 2:
16209									gl.vertexAttrib2fv( programAttribute, value );
16210									break;
16211
16212								case 3:
16213									gl.vertexAttrib3fv( programAttribute, value );
16214									break;
16215
16216								case 4:
16217									gl.vertexAttrib4fv( programAttribute, value );
16218									break;
16219
16220								default:
16221									gl.vertexAttrib1fv( programAttribute, value );
16222
16223							}
16224
16225						}
16226
16227					}
16228
16229				}
16230
16231			}
16232
16233			disableUnusedAttributes();
16234
16235		}
16236
16237		function dispose() {
16238
16239			reset();
16240
16241			for ( var geometryId in bindingStates ) {
16242
16243				var programMap = bindingStates[ geometryId ];
16244
16245				for ( var programId in programMap ) {
16246
16247					var stateMap = programMap[ programId ];
16248
16249					for ( var wireframe in stateMap ) {
16250
16251						deleteVertexArrayObject( stateMap[ wireframe ].object );
16252
16253						delete stateMap[ wireframe ];
16254
16255					}
16256
16257					delete programMap[ programId ];
16258
16259				}
16260
16261				delete bindingStates[ geometryId ];
16262
16263			}
16264
16265		}
16266
16267		function releaseStatesOfGeometry( geometry ) {
16268
16269			if ( bindingStates[ geometry.id ] === undefined ) { return; }
16270
16271			var programMap = bindingStates[ geometry.id ];
16272
16273			for ( var programId in programMap ) {
16274
16275				var stateMap = programMap[ programId ];
16276
16277				for ( var wireframe in stateMap ) {
16278
16279					deleteVertexArrayObject( stateMap[ wireframe ].object );
16280
16281					delete stateMap[ wireframe ];
16282
16283				}
16284
16285				delete programMap[ programId ];
16286
16287			}
16288
16289			delete bindingStates[ geometry.id ];
16290
16291		}
16292
16293		function releaseStatesOfProgram( program ) {
16294
16295			for ( var geometryId in bindingStates ) {
16296
16297				var programMap = bindingStates[ geometryId ];
16298
16299				if ( programMap[ program.id ] === undefined ) { continue; }
16300
16301				var stateMap = programMap[ program.id ];
16302
16303				for ( var wireframe in stateMap ) {
16304
16305					deleteVertexArrayObject( stateMap[ wireframe ].object );
16306
16307					delete stateMap[ wireframe ];
16308
16309				}
16310
16311				delete programMap[ program.id ];
16312
16313			}
16314
16315		}
16316
16317		function reset() {
16318
16319			resetDefaultState();
16320
16321			if ( currentState === defaultState ) { return; }
16322
16323			currentState = defaultState;
16324			bindVertexArrayObject( currentState.object );
16325
16326		}
16327
16328		// for backward-compatilibity
16329
16330		function resetDefaultState() {
16331
16332			defaultState.geometry = null;
16333			defaultState.program = null;
16334			defaultState.wireframe = false;
16335
16336		}
16337
16338		return {
16339
16340			setup: setup,
16341			reset: reset,
16342			resetDefaultState: resetDefaultState,
16343			dispose: dispose,
16344			releaseStatesOfGeometry: releaseStatesOfGeometry,
16345			releaseStatesOfProgram: releaseStatesOfProgram,
16346
16347			initAttributes: initAttributes,
16348			enableAttribute: enableAttribute,
16349			disableUnusedAttributes: disableUnusedAttributes
16350
16351		};
16352
16353	}
16354
16355	/**
16356	 * @author mrdoob / http://mrdoob.com/
16357	 */
16358
16359	function WebGLBufferRenderer( gl, extensions, info, capabilities ) {
16360
16361		var isWebGL2 = capabilities.isWebGL2;
16362
16363		var mode;
16364
16365		function setMode( value ) {
16366
16367			mode = value;
16368
16369		}
16370
16371		function render( start, count ) {
16372
16373			gl.drawArrays( mode, start, count );
16374
16375			info.update( count, mode );
16376
16377		}
16378
16379		function renderInstances( geometry, start, count, primcount ) {
16380
16381			if ( primcount === 0 ) { return; }
16382
16383			var extension, methodName;
16384
16385			if ( isWebGL2 ) {
16386
16387				extension = gl;
16388				methodName = 'drawArraysInstanced';
16389
16390			} else {
16391
16392				extension = extensions.get( 'ANGLE_instanced_arrays' );
16393				methodName = 'drawArraysInstancedANGLE';
16394
16395				if ( extension === null ) {
16396
16397					console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
16398					return;
16399
16400				}
16401
16402			}
16403
16404			extension[ methodName ]( mode, start, count, primcount );
16405
16406			info.update( count, mode, primcount );
16407
16408		}
16409
16410		//
16411
16412		this.setMode = setMode;
16413		this.render = render;
16414		this.renderInstances = renderInstances;
16415
16416	}
16417
16418	/**
16419	 * @author mrdoob / http://mrdoob.com/
16420	 */
16421
16422	function WebGLCapabilities( gl, extensions, parameters ) {
16423
16424		var maxAnisotropy;
16425
16426		function getMaxAnisotropy() {
16427
16428			if ( maxAnisotropy !== undefined ) { return maxAnisotropy; }
16429
16430			var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
16431
16432			if ( extension !== null ) {
16433
16434				maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
16435
16436			} else {
16437
16438				maxAnisotropy = 0;
16439
16440			}
16441
16442			return maxAnisotropy;
16443
16444		}
16445
16446		function getMaxPrecision( precision ) {
16447
16448			if ( precision === 'highp' ) {
16449
16450				if ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 &&
16451					gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) {
16452
16453					return 'highp';
16454
16455				}
16456
16457				precision = 'mediump';
16458
16459			}
16460
16461			if ( precision === 'mediump' ) {
16462
16463				if ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 &&
16464					gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) {
16465
16466					return 'mediump';
16467
16468				}
16469
16470			}
16471
16472			return 'lowp';
16473
16474		}
16475
16476		/* eslint-disable no-undef */
16477		var isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) ||
16478			( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext );
16479		/* eslint-enable no-undef */
16480
16481		var precision = parameters.precision !== undefined ? parameters.precision : 'highp';
16482		var maxPrecision = getMaxPrecision( precision );
16483
16484		if ( maxPrecision !== precision ) {
16485
16486			console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );
16487			precision = maxPrecision;
16488
16489		}
16490
16491		var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
16492
16493		var maxTextures = gl.getParameter( 34930 );
16494		var maxVertexTextures = gl.getParameter( 35660 );
16495		var maxTextureSize = gl.getParameter( 3379 );
16496		var maxCubemapSize = gl.getParameter( 34076 );
16497
16498		var maxAttributes = gl.getParameter( 34921 );
16499		var maxVertexUniforms = gl.getParameter( 36347 );
16500		var maxVaryings = gl.getParameter( 36348 );
16501		var maxFragmentUniforms = gl.getParameter( 36349 );
16502
16503		var vertexTextures = maxVertexTextures > 0;
16504		var floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' );
16505		var floatVertexTextures = vertexTextures && floatFragmentTextures;
16506
16507		var maxSamples = isWebGL2 ? gl.getParameter( 36183 ) : 0;
16508
16509		return {
16510
16511			isWebGL2: isWebGL2,
16512
16513			getMaxAnisotropy: getMaxAnisotropy,
16514			getMaxPrecision: getMaxPrecision,
16515
16516			precision: precision,
16517			logarithmicDepthBuffer: logarithmicDepthBuffer,
16518
16519			maxTextures: maxTextures,
16520			maxVertexTextures: maxVertexTextures,
16521			maxTextureSize: maxTextureSize,
16522			maxCubemapSize: maxCubemapSize,
16523
16524			maxAttributes: maxAttributes,
16525			maxVertexUniforms: maxVertexUniforms,
16526			maxVaryings: maxVaryings,
16527			maxFragmentUniforms: maxFragmentUniforms,
16528
16529			vertexTextures: vertexTextures,
16530			floatFragmentTextures: floatFragmentTextures,
16531			floatVertexTextures: floatVertexTextures,
16532
16533			maxSamples: maxSamples
16534
16535		};
16536
16537	}
16538
16539	/**
16540	 * @author tschw
16541	 */
16542
16543	function WebGLClipping() {
16544
16545		var scope = this;
16546
16547		var globalState = null,
16548			numGlobalPlanes = 0,
16549			localClippingEnabled = false,
16550			renderingShadows = false;
16551
16552		var plane = new Plane(),
16553			viewNormalMatrix = new Matrix3(),
16554
16555			uniform = { value: null, needsUpdate: false };
16556
16557		this.uniform = uniform;
16558		this.numPlanes = 0;
16559		this.numIntersection = 0;
16560
16561		this.init = function ( planes, enableLocalClipping, camera ) {
16562
16563			var enabled =
16564				planes.length !== 0 ||
16565				enableLocalClipping ||
16566				// enable state of previous frame - the clipping code has to
16567				// run another frame in order to reset the state:
16568				numGlobalPlanes !== 0 ||
16569				localClippingEnabled;
16570
16571			localClippingEnabled = enableLocalClipping;
16572
16573			globalState = projectPlanes( planes, camera, 0 );
16574			numGlobalPlanes = planes.length;
16575
16576			return enabled;
16577
16578		};
16579
16580		this.beginShadows = function () {
16581
16582			renderingShadows = true;
16583			projectPlanes( null );
16584
16585		};
16586
16587		this.endShadows = function () {
16588
16589			renderingShadows = false;
16590			resetGlobalState();
16591
16592		};
16593
16594		this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {
16595
16596			if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) {
16597
16598				// there's no local clipping
16599
16600				if ( renderingShadows ) {
16601
16602					// there's no global clipping
16603
16604					projectPlanes( null );
16605
16606				} else {
16607
16608					resetGlobalState();
16609
16610				}
16611
16612			} else {
16613
16614				var nGlobal = renderingShadows ? 0 : numGlobalPlanes,
16615					lGlobal = nGlobal * 4;
16616
16617				var dstArray = cache.clippingState || null;
16618
16619				uniform.value = dstArray; // ensure unique state
16620
16621				dstArray = projectPlanes( planes, camera, lGlobal, fromCache );
16622
16623				for ( var i = 0; i !== lGlobal; ++ i ) {
16624
16625					dstArray[ i ] = globalState[ i ];
16626
16627				}
16628
16629				cache.clippingState = dstArray;
16630				this.numIntersection = clipIntersection ? this.numPlanes : 0;
16631				this.numPlanes += nGlobal;
16632
16633			}
16634
16635
16636		};
16637
16638		function resetGlobalState() {
16639
16640			if ( uniform.value !== globalState ) {
16641
16642				uniform.value = globalState;
16643				uniform.needsUpdate = numGlobalPlanes > 0;
16644
16645			}
16646
16647			scope.numPlanes = numGlobalPlanes;
16648			scope.numIntersection = 0;
16649
16650		}
16651
16652		function projectPlanes( planes, camera, dstOffset, skipTransform ) {
16653
16654			var nPlanes = planes !== null ? planes.length : 0,
16655				dstArray = null;
16656
16657			if ( nPlanes !== 0 ) {
16658
16659				dstArray = uniform.value;
16660
16661				if ( skipTransform !== true || dstArray === null ) {
16662
16663					var flatSize = dstOffset + nPlanes * 4,
16664						viewMatrix = camera.matrixWorldInverse;
16665
16666					viewNormalMatrix.getNormalMatrix( viewMatrix );
16667
16668					if ( dstArray === null || dstArray.length < flatSize ) {
16669
16670						dstArray = new Float32Array( flatSize );
16671
16672					}
16673
16674					for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) {
16675
16676						plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix );
16677
16678						plane.normal.toArray( dstArray, i4 );
16679						dstArray[ i4 + 3 ] = plane.constant;
16680
16681					}
16682
16683				}
16684
16685				uniform.value = dstArray;
16686				uniform.needsUpdate = true;
16687
16688			}
16689
16690			scope.numPlanes = nPlanes;
16691			scope.numIntersection = 0;
16692
16693			return dstArray;
16694
16695		}
16696
16697	}
16698
16699	/**
16700	 * @author mrdoob / http://mrdoob.com/
16701	 */
16702
16703	function WebGLExtensions( gl ) {
16704
16705		var extensions = {};
16706
16707		return {
16708
16709			get: function ( name ) {
16710
16711				if ( extensions[ name ] !== undefined ) {
16712
16713					return extensions[ name ];
16714
16715				}
16716
16717				var extension;
16718
16719				switch ( name ) {
16720
16721					case 'WEBGL_depth_texture':
16722						extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
16723						break;
16724
16725					case 'EXT_texture_filter_anisotropic':
16726						extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
16727						break;
16728
16729					case 'WEBGL_compressed_texture_s3tc':
16730						extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
16731						break;
16732
16733					case 'WEBGL_compressed_texture_pvrtc':
16734						extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
16735						break;
16736
16737					default:
16738						extension = gl.getExtension( name );
16739
16740				}
16741
16742				if ( extension === null ) {
16743
16744					console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
16745
16746				}
16747
16748				extensions[ name ] = extension;
16749
16750				return extension;
16751
16752			}
16753
16754		};
16755
16756	}
16757
16758	/**
16759	 * @author mrdoob / http://mrdoob.com/
16760	 */
16761
16762	function WebGLGeometries( gl, attributes, info, bindingStates ) {
16763
16764		var geometries = new WeakMap();
16765		var wireframeAttributes = new WeakMap();
16766
16767		function onGeometryDispose( event ) {
16768
16769			var geometry = event.target;
16770			var buffergeometry = geometries.get( geometry );
16771
16772			if ( buffergeometry.index !== null ) {
16773
16774				attributes.remove( buffergeometry.index );
16775
16776			}
16777
16778			for ( var name in buffergeometry.attributes ) {
16779
16780				attributes.remove( buffergeometry.attributes[ name ] );
16781
16782			}
16783
16784			geometry.removeEventListener( 'dispose', onGeometryDispose );
16785
16786			geometries.delete( geometry );
16787
16788			var attribute = wireframeAttributes.get( buffergeometry );
16789
16790			if ( attribute ) {
16791
16792				attributes.remove( attribute );
16793				wireframeAttributes.delete( buffergeometry );
16794
16795			}
16796
16797			bindingStates.releaseStatesOfGeometry( geometry );
16798
16799			if ( geometry.isInstancedBufferGeometry === true ) {
16800
16801				delete geometry._maxInstanceCount;
16802
16803			}
16804
16805			//
16806
16807			info.memory.geometries --;
16808
16809		}
16810
16811		function get( object, geometry ) {
16812
16813			var buffergeometry = geometries.get( geometry );
16814
16815			if ( buffergeometry ) { return buffergeometry; }
16816
16817			geometry.addEventListener( 'dispose', onGeometryDispose );
16818
16819			if ( geometry.isBufferGeometry ) {
16820
16821				buffergeometry = geometry;
16822
16823			} else if ( geometry.isGeometry ) {
16824
16825				if ( geometry._bufferGeometry === undefined ) {
16826
16827					geometry._bufferGeometry = new BufferGeometry().setFromObject( object );
16828
16829				}
16830
16831				buffergeometry = geometry._bufferGeometry;
16832
16833			}
16834
16835			geometries.set( geometry, buffergeometry );
16836
16837			info.memory.geometries ++;
16838
16839			return buffergeometry;
16840
16841		}
16842
16843		function update( geometry ) {
16844
16845			var geometryAttributes = geometry.attributes;
16846
16847			// Updating index buffer in VAO now. See WebGLBindingStates.
16848
16849			for ( var name in geometryAttributes ) {
16850
16851				attributes.update( geometryAttributes[ name ], 34962 );
16852
16853			}
16854
16855			// morph targets
16856
16857			var morphAttributes = geometry.morphAttributes;
16858
16859			for ( var name$1 in morphAttributes ) {
16860
16861				var array = morphAttributes[ name$1 ];
16862
16863				for ( var i = 0, l = array.length; i < l; i ++ ) {
16864
16865					attributes.update( array[ i ], 34962 );
16866
16867				}
16868
16869			}
16870
16871		}
16872
16873		function updateWireframeAttribute( geometry ) {
16874
16875			var indices = [];
16876
16877			var geometryIndex = geometry.index;
16878			var geometryPosition = geometry.attributes.position;
16879			var version = 0;
16880
16881			if ( geometryIndex !== null ) {
16882
16883				var array = geometryIndex.array;
16884				version = geometryIndex.version;
16885
16886				for ( var i = 0, l = array.length; i < l; i += 3 ) {
16887
16888					var a = array[ i + 0 ];
16889					var b = array[ i + 1 ];
16890					var c = array[ i + 2 ];
16891
16892					indices.push( a, b, b, c, c, a );
16893
16894				}
16895
16896			} else {
16897
16898				var array$1 = geometryPosition.array;
16899				version = geometryPosition.version;
16900
16901				for ( var i$1 = 0, l$1 = ( array$1.length / 3 ) - 1; i$1 < l$1; i$1 += 3 ) {
16902
16903					var a$1 = i$1 + 0;
16904					var b$1 = i$1 + 1;
16905					var c$1 = i$1 + 2;
16906
16907					indices.push( a$1, b$1, b$1, c$1, c$1, a$1 );
16908
16909				}
16910
16911			}
16912
16913			var attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
16914			attribute.version = version;
16915
16916			// Updating index buffer in VAO now. See WebGLBindingStates
16917
16918			//
16919
16920			var previousAttribute = wireframeAttributes.get( geometry );
16921
16922			if ( previousAttribute ) { attributes.remove( previousAttribute ); }
16923
16924			//
16925
16926			wireframeAttributes.set( geometry, attribute );
16927
16928		}
16929
16930		function getWireframeAttribute( geometry ) {
16931
16932			var currentAttribute = wireframeAttributes.get( geometry );
16933
16934			if ( currentAttribute ) {
16935
16936				var geometryIndex = geometry.index;
16937
16938				if ( geometryIndex !== null ) {
16939
16940					// if the attribute is obsolete, create a new one
16941
16942					if ( currentAttribute.version < geometryIndex.version ) {
16943
16944						updateWireframeAttribute( geometry );
16945
16946					}
16947
16948				}
16949
16950			} else {
16951
16952				updateWireframeAttribute( geometry );
16953
16954			}
16955
16956			return wireframeAttributes.get( geometry );
16957
16958		}
16959
16960		return {
16961
16962			get: get,
16963			update: update,
16964
16965			getWireframeAttribute: getWireframeAttribute
16966
16967		};
16968
16969	}
16970
16971	/**
16972	 * @author mrdoob / http://mrdoob.com/
16973	 */
16974
16975	function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) {
16976
16977		var isWebGL2 = capabilities.isWebGL2;
16978
16979		var mode;
16980
16981		function setMode( value ) {
16982
16983			mode = value;
16984
16985		}
16986
16987		var type, bytesPerElement;
16988
16989		function setIndex( value ) {
16990
16991			type = value.type;
16992			bytesPerElement = value.bytesPerElement;
16993
16994		}
16995
16996		function render( start, count ) {
16997
16998			gl.drawElements( mode, count, type, start * bytesPerElement );
16999
17000			info.update( count, mode );
17001
17002		}
17003
17004		function renderInstances( geometry, start, count, primcount ) {
17005
17006			if ( primcount === 0 ) { return; }
17007
17008			var extension, methodName;
17009
17010			if ( isWebGL2 ) {
17011
17012				extension = gl;
17013				methodName = 'drawElementsInstanced';
17014
17015			} else {
17016
17017				extension = extensions.get( 'ANGLE_instanced_arrays' );
17018				methodName = 'drawElementsInstancedANGLE';
17019
17020				if ( extension === null ) {
17021
17022					console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
17023					return;
17024
17025				}
17026
17027			}
17028
17029			extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount );
17030
17031			info.update( count, mode, primcount );
17032
17033		}
17034
17035		//
17036
17037		this.setMode = setMode;
17038		this.setIndex = setIndex;
17039		this.render = render;
17040		this.renderInstances = renderInstances;
17041
17042	}
17043
17044	/**
17045	 * @author Mugen87 / https://github.com/Mugen87
17046	 */
17047
17048	function WebGLInfo( gl ) {
17049
17050		var memory = {
17051			geometries: 0,
17052			textures: 0
17053		};
17054
17055		var render = {
17056			frame: 0,
17057			calls: 0,
17058			triangles: 0,
17059			points: 0,
17060			lines: 0
17061		};
17062
17063		function update( count, mode, instanceCount ) {
17064
17065			instanceCount = instanceCount || 1;
17066
17067			render.calls ++;
17068
17069			switch ( mode ) {
17070
17071				case 4:
17072					render.triangles += instanceCount * ( count / 3 );
17073					break;
17074
17075				case 1:
17076					render.lines += instanceCount * ( count / 2 );
17077					break;
17078
17079				case 3:
17080					render.lines += instanceCount * ( count - 1 );
17081					break;
17082
17083				case 2:
17084					render.lines += instanceCount * count;
17085					break;
17086
17087				case 0:
17088					render.points += instanceCount * count;
17089					break;
17090
17091				default:
17092					console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode );
17093					break;
17094
17095			}
17096
17097		}
17098
17099		function reset() {
17100
17101			render.frame ++;
17102			render.calls = 0;
17103			render.triangles = 0;
17104			render.points = 0;
17105			render.lines = 0;
17106
17107		}
17108
17109		return {
17110			memory: memory,
17111			render: render,
17112			programs: null,
17113			autoReset: true,
17114			reset: reset,
17115			update: update
17116		};
17117
17118	}
17119
17120	/**
17121	 * @author mrdoob / http://mrdoob.com/
17122	 */
17123
17124	function numericalSort( a, b ) {
17125
17126		return a[ 0 ] - b[ 0 ];
17127
17128	}
17129
17130	function absNumericalSort( a, b ) {
17131
17132		return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] );
17133
17134	}
17135
17136	function WebGLMorphtargets( gl ) {
17137
17138		var influencesList = {};
17139		var morphInfluences = new Float32Array( 8 );
17140
17141		var workInfluences = [];
17142
17143		for ( var i = 0; i < 8; i ++ ) {
17144
17145			workInfluences[ i ] = [ i, 0 ];
17146
17147		}
17148
17149		function update( object, geometry, material, program ) {
17150
17151			var objectInfluences = object.morphTargetInfluences;
17152
17153			// When object doesn't have morph target influences defined, we treat it as a 0-length array
17154			// This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences
17155
17156			var length = objectInfluences === undefined ? 0 : objectInfluences.length;
17157
17158			var influences = influencesList[ geometry.id ];
17159
17160			if ( influences === undefined ) {
17161
17162				// initialise list
17163
17164				influences = [];
17165
17166				for ( var i = 0; i < length; i ++ ) {
17167
17168					influences[ i ] = [ i, 0 ];
17169
17170				}
17171
17172				influencesList[ geometry.id ] = influences;
17173
17174			}
17175
17176			// Collect influences
17177
17178			for ( var i$1 = 0; i$1 < length; i$1 ++ ) {
17179
17180				var influence = influences[ i$1 ];
17181
17182				influence[ 0 ] = i$1;
17183				influence[ 1 ] = objectInfluences[ i$1 ];
17184
17185			}
17186
17187			influences.sort( absNumericalSort );
17188
17189			for ( var i$2 = 0; i$2 < 8; i$2 ++ ) {
17190
17191				if ( i$2 < length && influences[ i$2 ][ 1 ] ) {
17192
17193					workInfluences[ i$2 ][ 0 ] = influences[ i$2 ][ 0 ];
17194					workInfluences[ i$2 ][ 1 ] = influences[ i$2 ][ 1 ];
17195
17196				} else {
17197
17198					workInfluences[ i$2 ][ 0 ] = Number.MAX_SAFE_INTEGER;
17199					workInfluences[ i$2 ][ 1 ] = 0;
17200
17201				}
17202
17203			}
17204
17205			workInfluences.sort( numericalSort );
17206
17207			var morphTargets = material.morphTargets && geometry.morphAttributes.position;
17208			var morphNormals = material.morphNormals && geometry.morphAttributes.normal;
17209
17210			var morphInfluencesSum = 0;
17211
17212			for ( var i$3 = 0; i$3 < 8; i$3 ++ ) {
17213
17214				var influence$1 = workInfluences[ i$3 ];
17215				var index = influence$1[ 0 ];
17216				var value = influence$1[ 1 ];
17217
17218				if ( index !== Number.MAX_SAFE_INTEGER && value ) {
17219
17220					if ( morphTargets && geometry.getAttribute( 'morphTarget' + i$3 ) !== morphTargets[ index ] ) {
17221
17222						geometry.setAttribute( 'morphTarget' + i$3, morphTargets[ index ] );
17223
17224					}
17225
17226					if ( morphNormals && geometry.getAttribute( 'morphNormal' + i$3 ) !== morphNormals[ index ] ) {
17227
17228						geometry.setAttribute( 'morphNormal' + i$3, morphNormals[ index ] );
17229
17230					}
17231
17232					morphInfluences[ i$3 ] = value;
17233					morphInfluencesSum += value;
17234
17235				} else {
17236
17237					if ( morphTargets && geometry.getAttribute( 'morphTarget' + i$3 ) !== undefined ) {
17238
17239						geometry.deleteAttribute( 'morphTarget' + i$3 );
17240
17241					}
17242
17243					if ( morphNormals && geometry.getAttribute( 'morphNormal' + i$3 ) !== undefined ) {
17244
17245						geometry.deleteAttribute( 'morphNormal' + i$3 );
17246
17247					}
17248
17249					morphInfluences[ i$3 ] = 0;
17250
17251				}
17252
17253			}
17254
17255			// GLSL shader uses formula baseinfluence * base + sum(target * influence)
17256			// This allows us to switch between absolute morphs and relative morphs without changing shader code
17257			// When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence)
17258			var morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
17259
17260			program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence );
17261			program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences );
17262
17263		}
17264
17265		return {
17266
17267			update: update
17268
17269		};
17270
17271	}
17272
17273	/**
17274	 * @author mrdoob / http://mrdoob.com/
17275	 */
17276
17277	function WebGLObjects( gl, geometries, attributes, info ) {
17278
17279		var updateMap = new WeakMap();
17280
17281		function update( object ) {
17282
17283			var frame = info.render.frame;
17284
17285			var geometry = object.geometry;
17286			var buffergeometry = geometries.get( object, geometry );
17287
17288			// Update once per frame
17289
17290			if ( updateMap.get( buffergeometry ) !== frame ) {
17291
17292				if ( geometry.isGeometry ) {
17293
17294					buffergeometry.updateFromObject( object );
17295
17296				}
17297
17298				geometries.update( buffergeometry );
17299
17300				updateMap.set( buffergeometry, frame );
17301
17302			}
17303
17304			if ( object.isInstancedMesh ) {
17305
17306				attributes.update( object.instanceMatrix, 34962 );
17307
17308			}
17309
17310			return buffergeometry;
17311
17312		}
17313
17314		function dispose() {
17315
17316			updateMap = new WeakMap();
17317
17318		}
17319
17320		return {
17321
17322			update: update,
17323			dispose: dispose
17324
17325		};
17326
17327	}
17328
17329	/**
17330	 * @author mrdoob / http://mrdoob.com/
17331	 */
17332
17333	function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
17334
17335		images = images !== undefined ? images : [];
17336		mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
17337		format = format !== undefined ? format : RGBFormat;
17338
17339		Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
17340
17341		this.flipY = false;
17342
17343	}
17344
17345	CubeTexture.prototype = Object.create( Texture.prototype );
17346	CubeTexture.prototype.constructor = CubeTexture;
17347
17348	CubeTexture.prototype.isCubeTexture = true;
17349
17350	Object.defineProperty( CubeTexture.prototype, 'images', {
17351
17352		get: function () {
17353
17354			return this.image;
17355
17356		},
17357
17358		set: function ( value ) {
17359
17360			this.image = value;
17361
17362		}
17363
17364	} );
17365
17366	/**
17367	 * @author Takahiro https://github.com/takahirox
17368	 */
17369
17370	function DataTexture2DArray( data, width, height, depth ) {
17371
17372		Texture.call( this, null );
17373
17374		this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 };
17375
17376		this.magFilter = NearestFilter;
17377		this.minFilter = NearestFilter;
17378
17379		this.wrapR = ClampToEdgeWrapping;
17380
17381		this.generateMipmaps = false;
17382		this.flipY = false;
17383
17384		this.needsUpdate = true;
17385
17386	}
17387
17388	DataTexture2DArray.prototype = Object.create( Texture.prototype );
17389	DataTexture2DArray.prototype.constructor = DataTexture2DArray;
17390	DataTexture2DArray.prototype.isDataTexture2DArray = true;
17391
17392	/**
17393	 * @author Artur Trzesiok
17394	 */
17395
17396	function DataTexture3D( data, width, height, depth ) {
17397
17398		// We're going to add .setXXX() methods for setting properties later.
17399		// Users can still set in DataTexture3D directly.
17400		//
17401		//	const texture = new THREE.DataTexture3D( data, width, height, depth );
17402		// 	texture.anisotropy = 16;
17403		//
17404		// See #14839
17405
17406		Texture.call( this, null );
17407
17408		this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 };
17409
17410		this.magFilter = NearestFilter;
17411		this.minFilter = NearestFilter;
17412
17413		this.wrapR = ClampToEdgeWrapping;
17414
17415		this.generateMipmaps = false;
17416		this.flipY = false;
17417
17418		this.needsUpdate = true;
17419
17420
17421	}
17422
17423	DataTexture3D.prototype = Object.create( Texture.prototype );
17424	DataTexture3D.prototype.constructor = DataTexture3D;
17425	DataTexture3D.prototype.isDataTexture3D = true;
17426
17427	/**
17428	 * @author tschw
17429	 * @author Mugen87 / https://github.com/Mugen87
17430	 * @author mrdoob / http://mrdoob.com/
17431	 *
17432	 * Uniforms of a program.
17433	 * Those form a tree structure with a special top-level container for the root,
17434	 * which you get by calling 'new WebGLUniforms( gl, program )'.
17435	 *
17436	 *
17437	 * Properties of inner nodes including the top-level container:
17438	 *
17439	 * .seq - array of nested uniforms
17440	 * .map - nested uniforms by name
17441	 *
17442	 *
17443	 * Methods of all nodes except the top-level container:
17444	 *
17445	 * .setValue( gl, value, [textures] )
17446	 *
17447	 * 		uploads a uniform value(s)
17448	 *  	the 'textures' parameter is needed for sampler uniforms
17449	 *
17450	 *
17451	 * Static methods of the top-level container (textures factorizations):
17452	 *
17453	 * .upload( gl, seq, values, textures )
17454	 *
17455	 * 		sets uniforms in 'seq' to 'values[id].value'
17456	 *
17457	 * .seqWithValue( seq, values ) : filteredSeq
17458	 *
17459	 * 		filters 'seq' entries with corresponding entry in values
17460	 *
17461	 *
17462	 * Methods of the top-level container (textures factorizations):
17463	 *
17464	 * .setValue( gl, name, value, textures )
17465	 *
17466	 * 		sets uniform with  name 'name' to 'value'
17467	 *
17468	 * .setOptional( gl, obj, prop )
17469	 *
17470	 * 		like .set for an optional property of the object
17471	 *
17472	 */
17473
17474	var emptyTexture = new Texture();
17475	var emptyTexture2dArray = new DataTexture2DArray();
17476	var emptyTexture3d = new DataTexture3D();
17477	var emptyCubeTexture = new CubeTexture();
17478
17479	// --- Utilities ---
17480
17481	// Array Caches (provide typed arrays for temporary by size)
17482
17483	var arrayCacheF32 = [];
17484	var arrayCacheI32 = [];
17485
17486	// Float32Array caches used for uploading Matrix uniforms
17487
17488	var mat4array = new Float32Array( 16 );
17489	var mat3array = new Float32Array( 9 );
17490	var mat2array = new Float32Array( 4 );
17491
17492	// Flattening for arrays of vectors and matrices
17493
17494	function flatten( array, nBlocks, blockSize ) {
17495
17496		var firstElem = array[ 0 ];
17497
17498		if ( firstElem <= 0 || firstElem > 0 ) { return array; }
17499		// unoptimized: ! isNaN( firstElem )
17500		// see http://jacksondunstan.com/articles/983
17501
17502		var n = nBlocks * blockSize,
17503			r = arrayCacheF32[ n ];
17504
17505		if ( r === undefined ) {
17506
17507			r = new Float32Array( n );
17508			arrayCacheF32[ n ] = r;
17509
17510		}
17511
17512		if ( nBlocks !== 0 ) {
17513
17514			firstElem.toArray( r, 0 );
17515
17516			for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {
17517
17518				offset += blockSize;
17519				array[ i ].toArray( r, offset );
17520
17521			}
17522
17523		}
17524
17525		return r;
17526
17527	}
17528
17529	function arraysEqual( a, b ) {
17530
17531		if ( a.length !== b.length ) { return false; }
17532
17533		for ( var i = 0, l = a.length; i < l; i ++ ) {
17534
17535			if ( a[ i ] !== b[ i ] ) { return false; }
17536
17537		}
17538
17539		return true;
17540
17541	}
17542
17543	function copyArray( a, b ) {
17544
17545		for ( var i = 0, l = b.length; i < l; i ++ ) {
17546
17547			a[ i ] = b[ i ];
17548
17549		}
17550
17551	}
17552
17553	// Texture unit allocation
17554
17555	function allocTexUnits( textures, n ) {
17556
17557		var r = arrayCacheI32[ n ];
17558
17559		if ( r === undefined ) {
17560
17561			r = new Int32Array( n );
17562			arrayCacheI32[ n ] = r;
17563
17564		}
17565
17566		for ( var i = 0; i !== n; ++ i ) {
17567
17568			r[ i ] = textures.allocateTextureUnit();
17569
17570		}
17571
17572		return r;
17573
17574	}
17575
17576	// --- Setters ---
17577
17578	// Note: Defining these methods externally, because they come in a bunch
17579	// and this way their names minify.
17580
17581	// Single scalar
17582
17583	function setValueV1f( gl, v ) {
17584
17585		var cache = this.cache;
17586
17587		if ( cache[ 0 ] === v ) { return; }
17588
17589		gl.uniform1f( this.addr, v );
17590
17591		cache[ 0 ] = v;
17592
17593	}
17594
17595	// Single float vector (from flat array or THREE.VectorN)
17596
17597	function setValueV2f( gl, v ) {
17598
17599		var cache = this.cache;
17600
17601		if ( v.x !== undefined ) {
17602
17603			if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) {
17604
17605				gl.uniform2f( this.addr, v.x, v.y );
17606
17607				cache[ 0 ] = v.x;
17608				cache[ 1 ] = v.y;
17609
17610			}
17611
17612		} else {
17613
17614			if ( arraysEqual( cache, v ) ) { return; }
17615
17616			gl.uniform2fv( this.addr, v );
17617
17618			copyArray( cache, v );
17619
17620		}
17621
17622	}
17623
17624	function setValueV3f( gl, v ) {
17625
17626		var cache = this.cache;
17627
17628		if ( v.x !== undefined ) {
17629
17630			if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) {
17631
17632				gl.uniform3f( this.addr, v.x, v.y, v.z );
17633
17634				cache[ 0 ] = v.x;
17635				cache[ 1 ] = v.y;
17636				cache[ 2 ] = v.z;
17637
17638			}
17639
17640		} else if ( v.r !== undefined ) {
17641
17642			if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) {
17643
17644				gl.uniform3f( this.addr, v.r, v.g, v.b );
17645
17646				cache[ 0 ] = v.r;
17647				cache[ 1 ] = v.g;
17648				cache[ 2 ] = v.b;
17649
17650			}
17651
17652		} else {
17653
17654			if ( arraysEqual( cache, v ) ) { return; }
17655
17656			gl.uniform3fv( this.addr, v );
17657
17658			copyArray( cache, v );
17659
17660		}
17661
17662	}
17663
17664	function setValueV4f( gl, v ) {
17665
17666		var cache = this.cache;
17667
17668		if ( v.x !== undefined ) {
17669
17670			if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) {
17671
17672				gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
17673
17674				cache[ 0 ] = v.x;
17675				cache[ 1 ] = v.y;
17676				cache[ 2 ] = v.z;
17677				cache[ 3 ] = v.w;
17678
17679			}
17680
17681		} else {
17682
17683			if ( arraysEqual( cache, v ) ) { return; }
17684
17685			gl.uniform4fv( this.addr, v );
17686
17687			copyArray( cache, v );
17688
17689		}
17690
17691	}
17692
17693	// Single matrix (from flat array or MatrixN)
17694
17695	function setValueM2( gl, v ) {
17696
17697		var cache = this.cache;
17698		var elements = v.elements;
17699
17700		if ( elements === undefined ) {
17701
17702			if ( arraysEqual( cache, v ) ) { return; }
17703
17704			gl.uniformMatrix2fv( this.addr, false, v );
17705
17706			copyArray( cache, v );
17707
17708		} else {
17709
17710			if ( arraysEqual( cache, elements ) ) { return; }
17711
17712			mat2array.set( elements );
17713
17714			gl.uniformMatrix2fv( this.addr, false, mat2array );
17715
17716			copyArray( cache, elements );
17717
17718		}
17719
17720	}
17721
17722	function setValueM3( gl, v ) {
17723
17724		var cache = this.cache;
17725		var elements = v.elements;
17726
17727		if ( elements === undefined ) {
17728
17729			if ( arraysEqual( cache, v ) ) { return; }
17730
17731			gl.uniformMatrix3fv( this.addr, false, v );
17732
17733			copyArray( cache, v );
17734
17735		} else {
17736
17737			if ( arraysEqual( cache, elements ) ) { return; }
17738
17739			mat3array.set( elements );
17740
17741			gl.uniformMatrix3fv( this.addr, false, mat3array );
17742
17743			copyArray( cache, elements );
17744
17745		}
17746
17747	}
17748
17749	function setValueM4( gl, v ) {
17750
17751		var cache = this.cache;
17752		var elements = v.elements;
17753
17754		if ( elements === undefined ) {
17755
17756			if ( arraysEqual( cache, v ) ) { return; }
17757
17758			gl.uniformMatrix4fv( this.addr, false, v );
17759
17760			copyArray( cache, v );
17761
17762		} else {
17763
17764			if ( arraysEqual( cache, elements ) ) { return; }
17765
17766			mat4array.set( elements );
17767
17768			gl.uniformMatrix4fv( this.addr, false, mat4array );
17769
17770			copyArray( cache, elements );
17771
17772		}
17773
17774	}
17775
17776	// Single texture (2D / Cube)
17777
17778	function setValueT1( gl, v, textures ) {
17779
17780		var cache = this.cache;
17781		var unit = textures.allocateTextureUnit();
17782
17783		if ( cache[ 0 ] !== unit ) {
17784
17785			gl.uniform1i( this.addr, unit );
17786			cache[ 0 ] = unit;
17787
17788		}
17789
17790		textures.safeSetTexture2D( v || emptyTexture, unit );
17791
17792	}
17793
17794	function setValueT2DArray1( gl, v, textures ) {
17795
17796		var cache = this.cache;
17797		var unit = textures.allocateTextureUnit();
17798
17799		if ( cache[ 0 ] !== unit ) {
17800
17801			gl.uniform1i( this.addr, unit );
17802			cache[ 0 ] = unit;
17803
17804		}
17805
17806		textures.setTexture2DArray( v || emptyTexture2dArray, unit );
17807
17808	}
17809
17810	function setValueT3D1( gl, v, textures ) {
17811
17812		var cache = this.cache;
17813		var unit = textures.allocateTextureUnit();
17814
17815		if ( cache[ 0 ] !== unit ) {
17816
17817			gl.uniform1i( this.addr, unit );
17818			cache[ 0 ] = unit;
17819
17820		}
17821
17822		textures.setTexture3D( v || emptyTexture3d, unit );
17823
17824	}
17825
17826	function setValueT6( gl, v, textures ) {
17827
17828		var cache = this.cache;
17829		var unit = textures.allocateTextureUnit();
17830
17831		if ( cache[ 0 ] !== unit ) {
17832
17833			gl.uniform1i( this.addr, unit );
17834			cache[ 0 ] = unit;
17835
17836		}
17837
17838		textures.safeSetTextureCube( v || emptyCubeTexture, unit );
17839
17840	}
17841
17842	// Integer / Boolean vectors or arrays thereof (always flat arrays)
17843
17844	function setValueV1i( gl, v ) {
17845
17846		var cache = this.cache;
17847
17848		if ( cache[ 0 ] === v ) { return; }
17849
17850		gl.uniform1i( this.addr, v );
17851
17852		cache[ 0 ] = v;
17853
17854	}
17855
17856	function setValueV2i( gl, v ) {
17857
17858		var cache = this.cache;
17859
17860		if ( arraysEqual( cache, v ) ) { return; }
17861
17862		gl.uniform2iv( this.addr, v );
17863
17864		copyArray( cache, v );
17865
17866	}
17867
17868	function setValueV3i( gl, v ) {
17869
17870		var cache = this.cache;
17871
17872		if ( arraysEqual( cache, v ) ) { return; }
17873
17874		gl.uniform3iv( this.addr, v );
17875
17876		copyArray( cache, v );
17877
17878	}
17879
17880	function setValueV4i( gl, v ) {
17881
17882		var cache = this.cache;
17883
17884		if ( arraysEqual( cache, v ) ) { return; }
17885
17886		gl.uniform4iv( this.addr, v );
17887
17888		copyArray( cache, v );
17889
17890	}
17891
17892	// uint
17893
17894	function setValueV1ui( gl, v ) {
17895
17896		var cache = this.cache;
17897
17898		if ( cache[ 0 ] === v ) { return; }
17899
17900		gl.uniform1ui( this.addr, v );
17901
17902		cache[ 0 ] = v;
17903
17904	}
17905
17906	// Helper to pick the right setter for the singular case
17907
17908	function getSingularSetter( type ) {
17909
17910		switch ( type ) {
17911
17912			case 0x1406: return setValueV1f; // FLOAT
17913			case 0x8b50: return setValueV2f; // _VEC2
17914			case 0x8b51: return setValueV3f; // _VEC3
17915			case 0x8b52: return setValueV4f; // _VEC4
17916
17917			case 0x8b5a: return setValueM2; // _MAT2
17918			case 0x8b5b: return setValueM3; // _MAT3
17919			case 0x8b5c: return setValueM4; // _MAT4
17920
17921			case 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL
17922			case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2
17923			case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3
17924			case 0x8b55: case 0x8b59: return setValueV4i; // _VEC4
17925
17926			case 0x1405: return setValueV1ui; // UINT
17927
17928			case 0x8b5e: // SAMPLER_2D
17929			case 0x8d66: // SAMPLER_EXTERNAL_OES
17930			case 0x8dca: // INT_SAMPLER_2D
17931			case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
17932			case 0x8b62: // SAMPLER_2D_SHADOW
17933				return setValueT1;
17934
17935			case 0x8b5f: // SAMPLER_3D
17936			case 0x8dcb: // INT_SAMPLER_3D
17937			case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D
17938				return setValueT3D1;
17939
17940			case 0x8b60: // SAMPLER_CUBE
17941			case 0x8dcc: // INT_SAMPLER_CUBE
17942			case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
17943			case 0x8dc5: // SAMPLER_CUBE_SHADOW
17944				return setValueT6;
17945
17946			case 0x8dc1: // SAMPLER_2D_ARRAY
17947			case 0x8dcf: // INT_SAMPLER_2D_ARRAY
17948			case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY
17949			case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW
17950				return setValueT2DArray1;
17951
17952		}
17953
17954	}
17955
17956	// Array of scalars
17957	function setValueV1fArray( gl, v ) {
17958
17959		gl.uniform1fv( this.addr, v );
17960
17961	}
17962
17963	// Integer / Boolean vectors or arrays thereof (always flat arrays)
17964	function setValueV1iArray( gl, v ) {
17965
17966		gl.uniform1iv( this.addr, v );
17967
17968	}
17969
17970	function setValueV2iArray( gl, v ) {
17971
17972		gl.uniform2iv( this.addr, v );
17973
17974	}
17975
17976	function setValueV3iArray( gl, v ) {
17977
17978		gl.uniform3iv( this.addr, v );
17979
17980	}
17981
17982	function setValueV4iArray( gl, v ) {
17983
17984		gl.uniform4iv( this.addr, v );
17985
17986	}
17987
17988
17989	// Array of vectors (flat or from THREE classes)
17990
17991	function setValueV2fArray( gl, v ) {
17992
17993		var data = flatten( v, this.size, 2 );
17994
17995		gl.uniform2fv( this.addr, data );
17996
17997	}
17998
17999	function setValueV3fArray( gl, v ) {
18000
18001		var data = flatten( v, this.size, 3 );
18002
18003		gl.uniform3fv( this.addr, data );
18004
18005	}
18006
18007	function setValueV4fArray( gl, v ) {
18008
18009		var data = flatten( v, this.size, 4 );
18010
18011		gl.uniform4fv( this.addr, data );
18012
18013	}
18014
18015	// Array of matrices (flat or from THREE clases)
18016
18017	function setValueM2Array( gl, v ) {
18018
18019		var data = flatten( v, this.size, 4 );
18020
18021		gl.uniformMatrix2fv( this.addr, false, data );
18022
18023	}
18024
18025	function setValueM3Array( gl, v ) {
18026
18027		var data = flatten( v, this.size, 9 );
18028
18029		gl.uniformMatrix3fv( this.addr, false, data );
18030
18031	}
18032
18033	function setValueM4Array( gl, v ) {
18034
18035		var data = flatten( v, this.size, 16 );
18036
18037		gl.uniformMatrix4fv( this.addr, false, data );
18038
18039	}
18040
18041	// Array of textures (2D / Cube)
18042
18043	function setValueT1Array( gl, v, textures ) {
18044
18045		var n = v.length;
18046
18047		var units = allocTexUnits( textures, n );
18048
18049		gl.uniform1iv( this.addr, units );
18050
18051		for ( var i = 0; i !== n; ++ i ) {
18052
18053			textures.safeSetTexture2D( v[ i ] || emptyTexture, units[ i ] );
18054
18055		}
18056
18057	}
18058
18059	function setValueT6Array( gl, v, textures ) {
18060
18061		var n = v.length;
18062
18063		var units = allocTexUnits( textures, n );
18064
18065		gl.uniform1iv( this.addr, units );
18066
18067		for ( var i = 0; i !== n; ++ i ) {
18068
18069			textures.safeSetTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
18070
18071		}
18072
18073	}
18074
18075	// Helper to pick the right setter for a pure (bottom-level) array
18076
18077	function getPureArraySetter( type ) {
18078
18079		switch ( type ) {
18080
18081			case 0x1406: return setValueV1fArray; // FLOAT
18082			case 0x8b50: return setValueV2fArray; // _VEC2
18083			case 0x8b51: return setValueV3fArray; // _VEC3
18084			case 0x8b52: return setValueV4fArray; // _VEC4
18085
18086			case 0x8b5a: return setValueM2Array; // _MAT2
18087			case 0x8b5b: return setValueM3Array; // _MAT3
18088			case 0x8b5c: return setValueM4Array; // _MAT4
18089
18090			case 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL
18091			case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2
18092			case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3
18093			case 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4
18094
18095			case 0x8b5e: // SAMPLER_2D
18096			case 0x8d66: // SAMPLER_EXTERNAL_OES
18097			case 0x8dca: // INT_SAMPLER_2D
18098			case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
18099			case 0x8b62: // SAMPLER_2D_SHADOW
18100				return setValueT1Array;
18101
18102			case 0x8b60: // SAMPLER_CUBE
18103			case 0x8dcc: // INT_SAMPLER_CUBE
18104			case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
18105			case 0x8dc5: // SAMPLER_CUBE_SHADOW
18106				return setValueT6Array;
18107
18108		}
18109
18110	}
18111
18112	// --- Uniform Classes ---
18113
18114	function SingleUniform( id, activeInfo, addr ) {
18115
18116		this.id = id;
18117		this.addr = addr;
18118		this.cache = [];
18119		this.setValue = getSingularSetter( activeInfo.type );
18120
18121		// this.path = activeInfo.name; // DEBUG
18122
18123	}
18124
18125	function PureArrayUniform( id, activeInfo, addr ) {
18126
18127		this.id = id;
18128		this.addr = addr;
18129		this.cache = [];
18130		this.size = activeInfo.size;
18131		this.setValue = getPureArraySetter( activeInfo.type );
18132
18133		// this.path = activeInfo.name; // DEBUG
18134
18135	}
18136
18137	PureArrayUniform.prototype.updateCache = function ( data ) {
18138
18139		var cache = this.cache;
18140
18141		if ( data instanceof Float32Array && cache.length !== data.length ) {
18142
18143			this.cache = new Float32Array( data.length );
18144
18145		}
18146
18147		copyArray( cache, data );
18148
18149	};
18150
18151	function StructuredUniform( id ) {
18152
18153		this.id = id;
18154
18155		this.seq = [];
18156		this.map = {};
18157
18158	}
18159
18160	StructuredUniform.prototype.setValue = function ( gl, value, textures ) {
18161
18162		var seq = this.seq;
18163
18164		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
18165
18166			var u = seq[ i ];
18167			u.setValue( gl, value[ u.id ], textures );
18168
18169		}
18170
18171	};
18172
18173	// --- Top-level ---
18174
18175	// Parser - builds up the property tree from the path strings
18176
18177	var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
18178
18179	// extracts
18180	// 	- the identifier (member name or array index)
18181	//  - followed by an optional right bracket (found when array index)
18182	//  - followed by an optional left bracket or dot (type of subscript)
18183	//
18184	// Note: These portions can be read in a non-overlapping fashion and
18185	// allow straightforward parsing of the hierarchy that WebGL encodes
18186	// in the uniform names.
18187
18188	function addUniform( container, uniformObject ) {
18189
18190		container.seq.push( uniformObject );
18191		container.map[ uniformObject.id ] = uniformObject;
18192
18193	}
18194
18195	function parseUniform( activeInfo, addr, container ) {
18196
18197		var path = activeInfo.name,
18198			pathLength = path.length;
18199
18200		// reset RegExp object, because of the early exit of a previous run
18201		RePathPart.lastIndex = 0;
18202
18203		while ( true ) {
18204
18205			var match = RePathPart.exec( path ),
18206				matchEnd = RePathPart.lastIndex;
18207
18208			var id = match[ 1 ],
18209				idIsIndex = match[ 2 ] === ']',
18210				subscript = match[ 3 ];
18211
18212			if ( idIsIndex ) { id = id | 0; } // convert to integer
18213
18214			if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
18215
18216				// bare name or "pure" bottom-level array "[0]" suffix
18217
18218				addUniform( container, subscript === undefined ?
18219					new SingleUniform( id, activeInfo, addr ) :
18220					new PureArrayUniform( id, activeInfo, addr ) );
18221
18222				break;
18223
18224			} else {
18225
18226				// step into inner node / create it in case it doesn't exist
18227
18228				var map = container.map;
18229				var next = map[ id ];
18230
18231				if ( next === undefined ) {
18232
18233					next = new StructuredUniform( id );
18234					addUniform( container, next );
18235
18236				}
18237
18238				container = next;
18239
18240			}
18241
18242		}
18243
18244	}
18245
18246	// Root Container
18247
18248	function WebGLUniforms( gl, program ) {
18249
18250		this.seq = [];
18251		this.map = {};
18252
18253		var n = gl.getProgramParameter( program, 35718 );
18254
18255		for ( var i = 0; i < n; ++ i ) {
18256
18257			var info = gl.getActiveUniform( program, i ),
18258				addr = gl.getUniformLocation( program, info.name );
18259
18260			parseUniform( info, addr, this );
18261
18262		}
18263
18264	}
18265
18266	WebGLUniforms.prototype.setValue = function ( gl, name, value, textures ) {
18267
18268		var u = this.map[ name ];
18269
18270		if ( u !== undefined ) { u.setValue( gl, value, textures ); }
18271
18272	};
18273
18274	WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
18275
18276		var v = object[ name ];
18277
18278		if ( v !== undefined ) { this.setValue( gl, name, v ); }
18279
18280	};
18281
18282
18283	// Static interface
18284
18285	WebGLUniforms.upload = function ( gl, seq, values, textures ) {
18286
18287		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
18288
18289			var u = seq[ i ],
18290				v = values[ u.id ];
18291
18292			if ( v.needsUpdate !== false ) {
18293
18294				// note: always updating when .needsUpdate is undefined
18295				u.setValue( gl, v.value, textures );
18296
18297			}
18298
18299		}
18300
18301	};
18302
18303	WebGLUniforms.seqWithValue = function ( seq, values ) {
18304
18305		var r = [];
18306
18307		for ( var i = 0, n = seq.length; i !== n; ++ i ) {
18308
18309			var u = seq[ i ];
18310			if ( u.id in values ) { r.push( u ); }
18311
18312		}
18313
18314		return r;
18315
18316	};
18317
18318	/**
18319	 * @author mrdoob / http://mrdoob.com/
18320	 */
18321
18322	function WebGLShader( gl, type, string ) {
18323
18324		var shader = gl.createShader( type );
18325
18326		gl.shaderSource( shader, string );
18327		gl.compileShader( shader );
18328
18329		return shader;
18330
18331	}
18332
18333	/**
18334	 * @author mrdoob / http://mrdoob.com/
18335	 */
18336
18337	var programIdCount = 0;
18338
18339	function addLineNumbers( string ) {
18340
18341		var lines = string.split( '\n' );
18342
18343		for ( var i = 0; i < lines.length; i ++ ) {
18344
18345			lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
18346
18347		}
18348
18349		return lines.join( '\n' );
18350
18351	}
18352
18353	function getEncodingComponents( encoding ) {
18354
18355		switch ( encoding ) {
18356
18357			case LinearEncoding:
18358				return [ 'Linear', '( value )' ];
18359			case sRGBEncoding:
18360				return [ 'sRGB', '( value )' ];
18361			case RGBEEncoding:
18362				return [ 'RGBE', '( value )' ];
18363			case RGBM7Encoding:
18364				return [ 'RGBM', '( value, 7.0 )' ];
18365			case RGBM16Encoding:
18366				return [ 'RGBM', '( value, 16.0 )' ];
18367			case RGBDEncoding:
18368				return [ 'RGBD', '( value, 256.0 )' ];
18369			case GammaEncoding:
18370				return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ];
18371			case LogLuvEncoding:
18372				return [ 'LogLuv', '( value )' ];
18373			default:
18374				console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding );
18375				return [ 'Linear', '( value )' ];
18376
18377		}
18378
18379	}
18380
18381	function getShaderErrors( gl, shader, type ) {
18382
18383		var status = gl.getShaderParameter( shader, 35713 );
18384		var log = gl.getShaderInfoLog( shader ).trim();
18385
18386		if ( status && log === '' ) { return ''; }
18387
18388		// --enable-privileged-webgl-extension
18389		// console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
18390
18391		var source = gl.getShaderSource( shader );
18392
18393		return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers( source );
18394
18395	}
18396
18397	function getTexelDecodingFunction( functionName, encoding ) {
18398
18399		var components = getEncodingComponents( encoding );
18400		return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }';
18401
18402	}
18403
18404	function getTexelEncodingFunction( functionName, encoding ) {
18405
18406		var components = getEncodingComponents( encoding );
18407		return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }';
18408
18409	}
18410
18411	function getToneMappingFunction( functionName, toneMapping ) {
18412
18413		var toneMappingName;
18414
18415		switch ( toneMapping ) {
18416
18417			case LinearToneMapping:
18418				toneMappingName = 'Linear';
18419				break;
18420
18421			case ReinhardToneMapping:
18422				toneMappingName = 'Reinhard';
18423				break;
18424
18425			case CineonToneMapping:
18426				toneMappingName = 'OptimizedCineon';
18427				break;
18428
18429			case ACESFilmicToneMapping:
18430				toneMappingName = 'ACESFilmic';
18431				break;
18432
18433			case CustomToneMapping:
18434				toneMappingName = 'Custom';
18435				break;
18436
18437			default:
18438				console.warn( 'THREE.WebGLProgram: Unsupported toneMapping:', toneMapping );
18439				toneMappingName = 'Linear';
18440
18441		}
18442
18443		return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';
18444
18445	}
18446
18447	function generateExtensions( parameters ) {
18448
18449		var chunks = [
18450			( parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '',
18451			( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '',
18452			( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '',
18453			( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : ''
18454		];
18455
18456		return chunks.filter( filterEmptyLine ).join( '\n' );
18457
18458	}
18459
18460	function generateDefines( defines ) {
18461
18462		var chunks = [];
18463
18464		for ( var name in defines ) {
18465
18466			var value = defines[ name ];
18467
18468			if ( value === false ) { continue; }
18469
18470			chunks.push( '#define ' + name + ' ' + value );
18471
18472		}
18473
18474		return chunks.join( '\n' );
18475
18476	}
18477
18478	function fetchAttributeLocations( gl, program ) {
18479
18480		var attributes = {};
18481
18482		var n = gl.getProgramParameter( program, 35721 );
18483
18484		for ( var i = 0; i < n; i ++ ) {
18485
18486			var info = gl.getActiveAttrib( program, i );
18487			var name = info.name;
18488
18489			// console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i );
18490
18491			attributes[ name ] = gl.getAttribLocation( program, name );
18492
18493		}
18494
18495		return attributes;
18496
18497	}
18498
18499	function filterEmptyLine( string ) {
18500
18501		return string !== '';
18502
18503	}
18504
18505	function replaceLightNums( string, parameters ) {
18506
18507		return string
18508			.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
18509			.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
18510			.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
18511			.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
18512			.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights )
18513			.replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows )
18514			.replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows )
18515			.replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows );
18516
18517	}
18518
18519	function replaceClippingPlaneNums( string, parameters ) {
18520
18521		return string
18522			.replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes )
18523			.replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) );
18524
18525	}
18526
18527	// Resolve Includes
18528
18529	var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
18530
18531	function resolveIncludes( string ) {
18532
18533		return string.replace( includePattern, includeReplacer );
18534
18535	}
18536
18537	function includeReplacer( match, include ) {
18538
18539		var string = ShaderChunk[ include ];
18540
18541		if ( string === undefined ) {
18542
18543			throw new Error( 'Can not resolve #include <' + include + '>' );
18544
18545		}
18546
18547		return resolveIncludes( string );
18548
18549	}
18550
18551	// Unroll Loops
18552
18553	var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
18554	var unrollLoopPattern = /#pragma unroll_loop_start[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g;
18555
18556	function unrollLoops( string ) {
18557
18558		return string
18559			.replace( unrollLoopPattern, loopReplacer )
18560			.replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer );
18561
18562	}
18563
18564	function deprecatedLoopReplacer( match, start, end, snippet ) {
18565
18566		console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' );
18567		return loopReplacer( match, start, end, snippet );
18568
18569	}
18570
18571	function loopReplacer( match, start, end, snippet ) {
18572
18573		var string = '';
18574
18575		for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
18576
18577			string += snippet
18578				.replace( /\[ i \]/g, '[ ' + i + ' ]' )
18579				.replace( /UNROLLED_LOOP_INDEX/g, i );
18580
18581		}
18582
18583		return string;
18584
18585	}
18586
18587	//
18588
18589	function generatePrecision( parameters ) {
18590
18591		var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;";
18592
18593		if ( parameters.precision === "highp" ) {
18594
18595			precisionstring += "\n#define HIGH_PRECISION";
18596
18597		} else if ( parameters.precision === "mediump" ) {
18598
18599			precisionstring += "\n#define MEDIUM_PRECISION";
18600
18601		} else if ( parameters.precision === "lowp" ) {
18602
18603			precisionstring += "\n#define LOW_PRECISION";
18604
18605		}
18606
18607		return precisionstring;
18608
18609	}
18610
18611	function generateShadowMapTypeDefine( parameters ) {
18612
18613		var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
18614
18615		if ( parameters.shadowMapType === PCFShadowMap ) {
18616
18617			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
18618
18619		} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
18620
18621			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
18622
18623		} else if ( parameters.shadowMapType === VSMShadowMap ) {
18624
18625			shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';
18626
18627		}
18628
18629		return shadowMapTypeDefine;
18630
18631	}
18632
18633	function generateEnvMapTypeDefine( parameters ) {
18634
18635		var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
18636
18637		if ( parameters.envMap ) {
18638
18639			switch ( parameters.envMapMode ) {
18640
18641				case CubeReflectionMapping:
18642				case CubeRefractionMapping:
18643					envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
18644					break;
18645
18646				case CubeUVReflectionMapping:
18647				case CubeUVRefractionMapping:
18648					envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
18649					break;
18650
18651				case EquirectangularReflectionMapping:
18652				case EquirectangularRefractionMapping:
18653					envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
18654					break;
18655
18656			}
18657
18658		}
18659
18660		return envMapTypeDefine;
18661
18662	}
18663
18664	function generateEnvMapModeDefine( parameters ) {
18665
18666		var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
18667
18668		if ( parameters.envMap ) {
18669
18670			switch ( parameters.envMapMode ) {
18671
18672				case CubeRefractionMapping:
18673				case EquirectangularRefractionMapping:
18674					envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
18675					break;
18676
18677			}
18678
18679		}
18680
18681		return envMapModeDefine;
18682
18683	}
18684
18685	function generateEnvMapBlendingDefine( parameters ) {
18686
18687		var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
18688
18689		if ( parameters.envMap ) {
18690
18691			switch ( parameters.combine ) {
18692
18693				case MultiplyOperation:
18694					envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
18695					break;
18696
18697				case MixOperation:
18698					envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
18699					break;
18700
18701				case AddOperation:
18702					envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
18703					break;
18704
18705			}
18706
18707		}
18708
18709		return envMapBlendingDefine;
18710
18711	}
18712
18713	function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
18714
18715		var gl = renderer.getContext();
18716
18717		var defines = parameters.defines;
18718
18719		var vertexShader = parameters.vertexShader;
18720		var fragmentShader = parameters.fragmentShader;
18721
18722		var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters );
18723		var envMapTypeDefine = generateEnvMapTypeDefine( parameters );
18724		var envMapModeDefine = generateEnvMapModeDefine( parameters );
18725		var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters );
18726
18727
18728		var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
18729
18730		var customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters );
18731
18732		var customDefines = generateDefines( defines );
18733
18734		var program = gl.createProgram();
18735
18736		var prefixVertex, prefixFragment;
18737
18738		if ( parameters.isRawShaderMaterial ) {
18739
18740			prefixVertex = [
18741
18742				customDefines
18743
18744			].filter( filterEmptyLine ).join( '\n' );
18745
18746			if ( prefixVertex.length > 0 ) {
18747
18748				prefixVertex += '\n';
18749
18750			}
18751
18752			prefixFragment = [
18753
18754				customExtensions,
18755				customDefines
18756
18757			].filter( filterEmptyLine ).join( '\n' );
18758
18759			if ( prefixFragment.length > 0 ) {
18760
18761				prefixFragment += '\n';
18762
18763			}
18764
18765		} else {
18766
18767			prefixVertex = [
18768
18769				generatePrecision( parameters ),
18770
18771				'#define SHADER_NAME ' + parameters.shaderName,
18772
18773				customDefines,
18774
18775				parameters.instancing ? '#define USE_INSTANCING' : '',
18776				parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
18777
18778				'#define GAMMA_FACTOR ' + gammaFactorDefine,
18779
18780				'#define MAX_BONES ' + parameters.maxBones,
18781				( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
18782				( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
18783
18784				parameters.map ? '#define USE_MAP' : '',
18785				parameters.envMap ? '#define USE_ENVMAP' : '',
18786				parameters.envMap ? '#define ' + envMapModeDefine : '',
18787				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
18788				parameters.aoMap ? '#define USE_AOMAP' : '',
18789				parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
18790				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
18791				parameters.normalMap ? '#define USE_NORMALMAP' : '',
18792				( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
18793				( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
18794
18795				parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
18796				parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
18797				parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
18798				parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
18799				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
18800				parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
18801				parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
18802				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
18803
18804				parameters.vertexTangents ? '#define USE_TANGENT' : '',
18805				parameters.vertexColors ? '#define USE_COLOR' : '',
18806				parameters.vertexUvs ? '#define USE_UV' : '',
18807				parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
18808
18809				parameters.flatShading ? '#define FLAT_SHADED' : '',
18810
18811				parameters.skinning ? '#define USE_SKINNING' : '',
18812				parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
18813
18814				parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
18815				parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
18816				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
18817				parameters.flipSided ? '#define FLIP_SIDED' : '',
18818
18819				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
18820				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
18821
18822				parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
18823
18824				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
18825				( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
18826
18827				'uniform mat4 modelMatrix;',
18828				'uniform mat4 modelViewMatrix;',
18829				'uniform mat4 projectionMatrix;',
18830				'uniform mat4 viewMatrix;',
18831				'uniform mat3 normalMatrix;',
18832				'uniform vec3 cameraPosition;',
18833				'uniform bool isOrthographic;',
18834
18835				'#ifdef USE_INSTANCING',
18836
18837				' attribute mat4 instanceMatrix;',
18838
18839				'#endif',
18840
18841				'attribute vec3 position;',
18842				'attribute vec3 normal;',
18843				'attribute vec2 uv;',
18844
18845				'#ifdef USE_TANGENT',
18846
18847				'	attribute vec4 tangent;',
18848
18849				'#endif',
18850
18851				'#ifdef USE_COLOR',
18852
18853				'	attribute vec3 color;',
18854
18855				'#endif',
18856
18857				'#ifdef USE_MORPHTARGETS',
18858
18859				'	attribute vec3 morphTarget0;',
18860				'	attribute vec3 morphTarget1;',
18861				'	attribute vec3 morphTarget2;',
18862				'	attribute vec3 morphTarget3;',
18863
18864				'	#ifdef USE_MORPHNORMALS',
18865
18866				'		attribute vec3 morphNormal0;',
18867				'		attribute vec3 morphNormal1;',
18868				'		attribute vec3 morphNormal2;',
18869				'		attribute vec3 morphNormal3;',
18870
18871				'	#else',
18872
18873				'		attribute vec3 morphTarget4;',
18874				'		attribute vec3 morphTarget5;',
18875				'		attribute vec3 morphTarget6;',
18876				'		attribute vec3 morphTarget7;',
18877
18878				'	#endif',
18879
18880				'#endif',
18881
18882				'#ifdef USE_SKINNING',
18883
18884				'	attribute vec4 skinIndex;',
18885				'	attribute vec4 skinWeight;',
18886
18887				'#endif',
18888
18889				'\n'
18890
18891			].filter( filterEmptyLine ).join( '\n' );
18892
18893			prefixFragment = [
18894
18895				customExtensions,
18896
18897				generatePrecision( parameters ),
18898
18899				'#define SHADER_NAME ' + parameters.shaderName,
18900
18901				customDefines,
18902
18903				parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer
18904
18905				'#define GAMMA_FACTOR ' + gammaFactorDefine,
18906
18907				( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
18908				( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
18909
18910				parameters.map ? '#define USE_MAP' : '',
18911				parameters.matcap ? '#define USE_MATCAP' : '',
18912				parameters.envMap ? '#define USE_ENVMAP' : '',
18913				parameters.envMap ? '#define ' + envMapTypeDefine : '',
18914				parameters.envMap ? '#define ' + envMapModeDefine : '',
18915				parameters.envMap ? '#define ' + envMapBlendingDefine : '',
18916				parameters.lightMap ? '#define USE_LIGHTMAP' : '',
18917				parameters.aoMap ? '#define USE_AOMAP' : '',
18918				parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
18919				parameters.bumpMap ? '#define USE_BUMPMAP' : '',
18920				parameters.normalMap ? '#define USE_NORMALMAP' : '',
18921				( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
18922				( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
18923				parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
18924				parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
18925				parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
18926				parameters.specularMap ? '#define USE_SPECULARMAP' : '',
18927				parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
18928				parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
18929				parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
18930
18931				parameters.sheen ? '#define USE_SHEEN' : '',
18932
18933				parameters.vertexTangents ? '#define USE_TANGENT' : '',
18934				parameters.vertexColors ? '#define USE_COLOR' : '',
18935				parameters.vertexUvs ? '#define USE_UV' : '',
18936				parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
18937
18938				parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
18939
18940				parameters.flatShading ? '#define FLAT_SHADED' : '',
18941
18942				parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
18943				parameters.flipSided ? '#define FLIP_SIDED' : '',
18944
18945				parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
18946				parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
18947
18948				parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '',
18949
18950				parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',
18951
18952				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
18953				( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
18954
18955				( ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ) ? '#define TEXTURE_LOD_EXT' : '',
18956
18957				'uniform mat4 viewMatrix;',
18958				'uniform vec3 cameraPosition;',
18959				'uniform bool isOrthographic;',
18960
18961				( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
18962				( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below
18963				( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
18964
18965				parameters.dithering ? '#define DITHERING' : '',
18966
18967				ShaderChunk[ 'encodings_pars_fragment' ], // this code is required here because it is used by the various encoding/decoding function defined below
18968				parameters.map ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
18969				parameters.matcap ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
18970				parameters.envMap ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
18971				parameters.emissiveMap ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
18972				parameters.lightMap ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '',
18973				getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ),
18974
18975				parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '',
18976
18977				'\n'
18978
18979			].filter( filterEmptyLine ).join( '\n' );
18980
18981		}
18982
18983		vertexShader = resolveIncludes( vertexShader );
18984		vertexShader = replaceLightNums( vertexShader, parameters );
18985		vertexShader = replaceClippingPlaneNums( vertexShader, parameters );
18986
18987		fragmentShader = resolveIncludes( fragmentShader );
18988		fragmentShader = replaceLightNums( fragmentShader, parameters );
18989		fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );
18990
18991		vertexShader = unrollLoops( vertexShader );
18992		fragmentShader = unrollLoops( fragmentShader );
18993
18994		if ( parameters.isWebGL2 && ! parameters.isRawShaderMaterial ) {
18995
18996			var isGLSL3ShaderMaterial = false;
18997
18998			var versionRegex = /^\s*#version\s+300\s+es\s*\n/;
18999
19000			if ( parameters.isShaderMaterial &&
19001				vertexShader.match( versionRegex ) !== null &&
19002				fragmentShader.match( versionRegex ) !== null ) {
19003
19004				isGLSL3ShaderMaterial = true;
19005
19006				vertexShader = vertexShader.replace( versionRegex, '' );
19007				fragmentShader = fragmentShader.replace( versionRegex, '' );
19008
19009			}
19010
19011			// GLSL 3.0 conversion
19012
19013			prefixVertex = [
19014				'#version 300 es\n',
19015				'#define attribute in',
19016				'#define varying out',
19017				'#define texture2D texture'
19018			].join( '\n' ) + '\n' + prefixVertex;
19019
19020			prefixFragment = [
19021				'#version 300 es\n',
19022				'#define varying in',
19023				isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;',
19024				isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor',
19025				'#define gl_FragDepthEXT gl_FragDepth',
19026				'#define texture2D texture',
19027				'#define textureCube texture',
19028				'#define texture2DProj textureProj',
19029				'#define texture2DLodEXT textureLod',
19030				'#define texture2DProjLodEXT textureProjLod',
19031				'#define textureCubeLodEXT textureLod',
19032				'#define texture2DGradEXT textureGrad',
19033				'#define texture2DProjGradEXT textureProjGrad',
19034				'#define textureCubeGradEXT textureGrad'
19035			].join( '\n' ) + '\n' + prefixFragment;
19036
19037		}
19038
19039		var vertexGlsl = prefixVertex + vertexShader;
19040		var fragmentGlsl = prefixFragment + fragmentShader;
19041
19042		// console.log( '*VERTEX*', vertexGlsl );
19043		// console.log( '*FRAGMENT*', fragmentGlsl );
19044
19045		var glVertexShader = WebGLShader( gl, 35633, vertexGlsl );
19046		var glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl );
19047
19048		gl.attachShader( program, glVertexShader );
19049		gl.attachShader( program, glFragmentShader );
19050
19051		// Force a particular attribute to index 0.
19052
19053		if ( parameters.index0AttributeName !== undefined ) {
19054
19055			gl.bindAttribLocation( program, 0, parameters.index0AttributeName );
19056
19057		} else if ( parameters.morphTargets === true ) {
19058
19059			// programs with morphTargets displace position out of attribute 0
19060			gl.bindAttribLocation( program, 0, 'position' );
19061
19062		}
19063
19064		gl.linkProgram( program );
19065
19066		// check for link errors
19067		if ( renderer.debug.checkShaderErrors ) {
19068
19069			var programLog = gl.getProgramInfoLog( program ).trim();
19070			var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
19071			var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
19072
19073			var runnable = true;
19074			var haveDiagnostics = true;
19075
19076			if ( gl.getProgramParameter( program, 35714 ) === false ) {
19077
19078				runnable = false;
19079
19080				var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
19081				var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
19082
19083				console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter( program, 35715 ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors );
19084
19085			} else if ( programLog !== '' ) {
19086
19087				console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
19088
19089			} else if ( vertexLog === '' || fragmentLog === '' ) {
19090
19091				haveDiagnostics = false;
19092
19093			}
19094
19095			if ( haveDiagnostics ) {
19096
19097				this.diagnostics = {
19098
19099					runnable: runnable,
19100
19101					programLog: programLog,
19102
19103					vertexShader: {
19104
19105						log: vertexLog,
19106						prefix: prefixVertex
19107
19108					},
19109
19110					fragmentShader: {
19111
19112						log: fragmentLog,
19113						prefix: prefixFragment
19114
19115					}
19116
19117				};
19118
19119			}
19120
19121		}
19122
19123		// Clean up
19124
19125		// Crashes in iOS9 and iOS10. #18402
19126		// gl.detachShader( program, glVertexShader );
19127		// gl.detachShader( program, glFragmentShader );
19128
19129		gl.deleteShader( glVertexShader );
19130		gl.deleteShader( glFragmentShader );
19131
19132		// set up caching for uniform locations
19133
19134		var cachedUniforms;
19135
19136		this.getUniforms = function () {
19137
19138			if ( cachedUniforms === undefined ) {
19139
19140				cachedUniforms = new WebGLUniforms( gl, program );
19141
19142			}
19143
19144			return cachedUniforms;
19145
19146		};
19147
19148		// set up caching for attribute locations
19149
19150		var cachedAttributes;
19151
19152		this.getAttributes = function () {
19153
19154			if ( cachedAttributes === undefined ) {
19155
19156				cachedAttributes = fetchAttributeLocations( gl, program );
19157
19158			}
19159
19160			return cachedAttributes;
19161
19162		};
19163
19164		// free resource
19165
19166		this.destroy = function () {
19167
19168			bindingStates.releaseStatesOfProgram( this );
19169
19170			gl.deleteProgram( program );
19171			this.program = undefined;
19172
19173		};
19174
19175		//
19176
19177		this.name = parameters.shaderName;
19178		this.id = programIdCount ++;
19179		this.cacheKey = cacheKey;
19180		this.usedTimes = 1;
19181		this.program = program;
19182		this.vertexShader = glVertexShader;
19183		this.fragmentShader = glFragmentShader;
19184
19185		return this;
19186
19187	}
19188
19189	/**
19190	 * @author mrdoob / http://mrdoob.com/
19191	 */
19192
19193	function WebGLPrograms( renderer, extensions, capabilities, bindingStates ) {
19194
19195		var programs = [];
19196
19197		var isWebGL2 = capabilities.isWebGL2;
19198		var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
19199		var floatVertexTextures = capabilities.floatVertexTextures;
19200		var maxVertexUniforms = capabilities.maxVertexUniforms;
19201		var vertexTextures = capabilities.vertexTextures;
19202
19203		var precision = capabilities.precision;
19204
19205		var shaderIDs = {
19206			MeshDepthMaterial: 'depth',
19207			MeshDistanceMaterial: 'distanceRGBA',
19208			MeshNormalMaterial: 'normal',
19209			MeshBasicMaterial: 'basic',
19210			MeshLambertMaterial: 'lambert',
19211			MeshPhongMaterial: 'phong',
19212			MeshToonMaterial: 'toon',
19213			MeshStandardMaterial: 'physical',
19214			MeshPhysicalMaterial: 'physical',
19215			MeshMatcapMaterial: 'matcap',
19216			LineBasicMaterial: 'basic',
19217			LineDashedMaterial: 'dashed',
19218			PointsMaterial: 'points',
19219			ShadowMaterial: 'shadow',
19220			SpriteMaterial: 'sprite'
19221		};
19222
19223		var parameterNames = [
19224			"precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing",
19225			"map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV",
19226			"lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap",
19227			"roughnessMap", "metalnessMap", "gradientMap",
19228			"alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2",
19229			"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
19230			"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
19231			"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
19232			"numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
19233			"numDirLightShadows", "numPointLightShadows", "numSpotLightShadows",
19234			"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
19235			"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering",
19236			"sheen"
19237		];
19238
19239		function getShaderObject( material, shaderID ) {
19240
19241			var shaderobject;
19242
19243			if ( shaderID ) {
19244
19245				var shader = ShaderLib[ shaderID ];
19246
19247				shaderobject = {
19248					name: material.name || material.type,
19249					uniforms: UniformsUtils.clone( shader.uniforms ),
19250					vertexShader: shader.vertexShader,
19251					fragmentShader: shader.fragmentShader
19252				};
19253
19254			} else {
19255
19256				shaderobject = {
19257					name: material.name || material.type,
19258					uniforms: material.uniforms,
19259					vertexShader: material.vertexShader,
19260					fragmentShader: material.fragmentShader
19261				};
19262
19263			}
19264
19265			return shaderobject;
19266
19267		}
19268
19269		function allocateBones( object ) {
19270
19271			var skeleton = object.skeleton;
19272			var bones = skeleton.bones;
19273
19274			if ( floatVertexTextures ) {
19275
19276				return 1024;
19277
19278			} else {
19279
19280				// default for when object is not specified
19281				// ( for example when prebuilding shader to be used with multiple objects )
19282				//
19283				//  - leave some extra space for other uniforms
19284				//  - limit here is ANGLE's 254 max uniform vectors
19285				//    (up to 54 should be safe)
19286
19287				var nVertexUniforms = maxVertexUniforms;
19288				var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
19289
19290				var maxBones = Math.min( nVertexMatrices, bones.length );
19291
19292				if ( maxBones < bones.length ) {
19293
19294					console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
19295					return 0;
19296
19297				}
19298
19299				return maxBones;
19300
19301			}
19302
19303		}
19304
19305		function getTextureEncodingFromMap( map ) {
19306
19307			var encoding;
19308
19309			if ( ! map ) {
19310
19311				encoding = LinearEncoding;
19312
19313			} else if ( map.isTexture ) {
19314
19315				encoding = map.encoding;
19316
19317			} else if ( map.isWebGLRenderTarget ) {
19318
19319				console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
19320				encoding = map.texture.encoding;
19321
19322			}
19323
19324			return encoding;
19325
19326		}
19327
19328		function getParameters( material, lights, shadows, scene, nClipPlanes, nClipIntersection, object ) {
19329
19330			var fog = scene.fog;
19331			var environment = material.isMeshStandardMaterial ? scene.environment : null;
19332
19333			var envMap = material.envMap || environment;
19334
19335			var shaderID = shaderIDs[ material.type ];
19336
19337			// heuristics to create shader parameters according to lights in the scene
19338			// (not to blow over maxLights budget)
19339
19340			var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
19341
19342			if ( material.precision !== null ) {
19343
19344				precision = capabilities.getMaxPrecision( material.precision );
19345
19346				if ( precision !== material.precision ) {
19347
19348					console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
19349
19350				}
19351
19352			}
19353
19354			var shaderobject = getShaderObject( material, shaderID );
19355			material.onBeforeCompile( shaderobject, renderer );
19356
19357			var currentRenderTarget = renderer.getRenderTarget();
19358
19359			var parameters = {
19360
19361				isWebGL2: isWebGL2,
19362
19363				shaderID: shaderID,
19364				shaderName: shaderobject.name,
19365
19366				uniforms: shaderobject.uniforms,
19367				vertexShader: shaderobject.vertexShader,
19368				fragmentShader: shaderobject.fragmentShader,
19369				defines: material.defines,
19370
19371				isRawShaderMaterial: material.isRawShaderMaterial,
19372				isShaderMaterial: material.isShaderMaterial,
19373
19374				precision: precision,
19375
19376				instancing: object.isInstancedMesh === true,
19377
19378				supportsVertexTextures: vertexTextures,
19379				outputEncoding: ( currentRenderTarget !== null ) ? getTextureEncodingFromMap( currentRenderTarget.texture ) : renderer.outputEncoding,
19380				map: !! material.map,
19381				mapEncoding: getTextureEncodingFromMap( material.map ),
19382				matcap: !! material.matcap,
19383				matcapEncoding: getTextureEncodingFromMap( material.matcap ),
19384				envMap: !! envMap,
19385				envMapMode: envMap && envMap.mapping,
19386				envMapEncoding: getTextureEncodingFromMap( envMap ),
19387				envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ),
19388				lightMap: !! material.lightMap,
19389				lightMapEncoding: getTextureEncodingFromMap( material.lightMap ),
19390				aoMap: !! material.aoMap,
19391				emissiveMap: !! material.emissiveMap,
19392				emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ),
19393				bumpMap: !! material.bumpMap,
19394				normalMap: !! material.normalMap,
19395				objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap,
19396				tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap,
19397				clearcoatMap: !! material.clearcoatMap,
19398				clearcoatRoughnessMap: !! material.clearcoatRoughnessMap,
19399				clearcoatNormalMap: !! material.clearcoatNormalMap,
19400				displacementMap: !! material.displacementMap,
19401				roughnessMap: !! material.roughnessMap,
19402				metalnessMap: !! material.metalnessMap,
19403				specularMap: !! material.specularMap,
19404				alphaMap: !! material.alphaMap,
19405
19406				gradientMap: !! material.gradientMap,
19407
19408				sheen: !! material.sheen,
19409
19410				combine: material.combine,
19411
19412				vertexTangents: ( material.normalMap && material.vertexTangents ),
19413				vertexColors: material.vertexColors,
19414				vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatMap || !! material.clearcoatRoughnessMap || !! material.clearcoatNormalMap || !! material.displacementMap,
19415				uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap ) && !! material.displacementMap,
19416
19417				fog: !! fog,
19418				useFog: material.fog,
19419				fogExp2: ( fog && fog.isFogExp2 ),
19420
19421				flatShading: material.flatShading,
19422
19423				sizeAttenuation: material.sizeAttenuation,
19424				logarithmicDepthBuffer: logarithmicDepthBuffer,
19425
19426				skinning: material.skinning && maxBones > 0,
19427				maxBones: maxBones,
19428				useVertexTexture: floatVertexTextures,
19429
19430				morphTargets: material.morphTargets,
19431				morphNormals: material.morphNormals,
19432				maxMorphTargets: renderer.maxMorphTargets,
19433				maxMorphNormals: renderer.maxMorphNormals,
19434
19435				numDirLights: lights.directional.length,
19436				numPointLights: lights.point.length,
19437				numSpotLights: lights.spot.length,
19438				numRectAreaLights: lights.rectArea.length,
19439				numHemiLights: lights.hemi.length,
19440
19441				numDirLightShadows: lights.directionalShadowMap.length,
19442				numPointLightShadows: lights.pointShadowMap.length,
19443				numSpotLightShadows: lights.spotShadowMap.length,
19444
19445				numClippingPlanes: nClipPlanes,
19446				numClipIntersection: nClipIntersection,
19447
19448				dithering: material.dithering,
19449
19450				shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
19451				shadowMapType: renderer.shadowMap.type,
19452
19453				toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
19454				physicallyCorrectLights: renderer.physicallyCorrectLights,
19455
19456				premultipliedAlpha: material.premultipliedAlpha,
19457
19458				alphaTest: material.alphaTest,
19459				doubleSided: material.side === DoubleSide,
19460				flipSided: material.side === BackSide,
19461
19462				depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false,
19463
19464				index0AttributeName: material.index0AttributeName,
19465
19466				extensionDerivatives: material.extensions && material.extensions.derivatives,
19467				extensionFragDepth: material.extensions && material.extensions.fragDepth,
19468				extensionDrawBuffers: material.extensions && material.extensions.drawBuffers,
19469				extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD,
19470
19471				rendererExtensionFragDepth: isWebGL2 || extensions.get( 'EXT_frag_depth' ) !== null,
19472				rendererExtensionDrawBuffers: isWebGL2 || extensions.get( 'WEBGL_draw_buffers' ) !== null,
19473				rendererExtensionShaderTextureLod: isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) !== null,
19474
19475				customProgramCacheKey: material.customProgramCacheKey()
19476
19477			};
19478
19479			return parameters;
19480
19481		}
19482
19483		function getProgramCacheKey( parameters ) {
19484
19485			var array = [];
19486
19487			if ( parameters.shaderID ) {
19488
19489				array.push( parameters.shaderID );
19490
19491			} else {
19492
19493				array.push( parameters.fragmentShader );
19494				array.push( parameters.vertexShader );
19495
19496			}
19497
19498			if ( parameters.defines !== undefined ) {
19499
19500				for ( var name in parameters.defines ) {
19501
19502					array.push( name );
19503					array.push( parameters.defines[ name ] );
19504
19505				}
19506
19507			}
19508
19509			if ( parameters.isRawShaderMaterial === undefined ) {
19510
19511				for ( var i = 0; i < parameterNames.length; i ++ ) {
19512
19513					array.push( parameters[ parameterNames[ i ] ] );
19514
19515				}
19516
19517				array.push( renderer.outputEncoding );
19518				array.push( renderer.gammaFactor );
19519
19520			}
19521
19522			array.push( parameters.customProgramCacheKey );
19523
19524			return array.join();
19525
19526		}
19527
19528		function acquireProgram( parameters, cacheKey ) {
19529
19530			var program;
19531
19532			// Check if code has been already compiled
19533			for ( var p = 0, pl = programs.length; p < pl; p ++ ) {
19534
19535				var preexistingProgram = programs[ p ];
19536
19537				if ( preexistingProgram.cacheKey === cacheKey ) {
19538
19539					program = preexistingProgram;
19540					++ program.usedTimes;
19541
19542					break;
19543
19544				}
19545
19546			}
19547
19548			if ( program === undefined ) {
19549
19550				program = new WebGLProgram( renderer, cacheKey, parameters, bindingStates );
19551				programs.push( program );
19552
19553			}
19554
19555			return program;
19556
19557		}
19558
19559		function releaseProgram( program ) {
19560
19561			if ( -- program.usedTimes === 0 ) {
19562
19563				// Remove from unordered set
19564				var i = programs.indexOf( program );
19565				programs[ i ] = programs[ programs.length - 1 ];
19566				programs.pop();
19567
19568				// Free WebGL resources
19569				program.destroy();
19570
19571			}
19572
19573		}
19574
19575		return {
19576			getParameters: getParameters,
19577			getProgramCacheKey: getProgramCacheKey,
19578			acquireProgram: acquireProgram,
19579			releaseProgram: releaseProgram,
19580			// Exposed for resource monitoring & error feedback via renderer.info:
19581			programs: programs
19582		};
19583
19584	}
19585
19586	/**
19587	 * @author fordacious / fordacious.github.io
19588	 */
19589
19590	function WebGLProperties() {
19591
19592		var properties = new WeakMap();
19593
19594		function get( object ) {
19595
19596			var map = properties.get( object );
19597
19598			if ( map === undefined ) {
19599
19600				map = {};
19601				properties.set( object, map );
19602
19603			}
19604
19605			return map;
19606
19607		}
19608
19609		function remove( object ) {
19610
19611			properties.delete( object );
19612
19613		}
19614
19615		function update( object, key, value ) {
19616
19617			properties.get( object )[ key ] = value;
19618
19619		}
19620
19621		function dispose() {
19622
19623			properties = new WeakMap();
19624
19625		}
19626
19627		return {
19628			get: get,
19629			remove: remove,
19630			update: update,
19631			dispose: dispose
19632		};
19633
19634	}
19635
19636	/**
19637	 * @author mrdoob / http://mrdoob.com/
19638	 */
19639
19640	function painterSortStable( a, b ) {
19641
19642		if ( a.groupOrder !== b.groupOrder ) {
19643
19644			return a.groupOrder - b.groupOrder;
19645
19646		} else if ( a.renderOrder !== b.renderOrder ) {
19647
19648			return a.renderOrder - b.renderOrder;
19649
19650		} else if ( a.program !== b.program ) {
19651
19652			return a.program.id - b.program.id;
19653
19654		} else if ( a.material.id !== b.material.id ) {
19655
19656			return a.material.id - b.material.id;
19657
19658		} else if ( a.z !== b.z ) {
19659
19660			return a.z - b.z;
19661
19662		} else {
19663
19664			return a.id - b.id;
19665
19666		}
19667
19668	}
19669
19670	function reversePainterSortStable( a, b ) {
19671
19672		if ( a.groupOrder !== b.groupOrder ) {
19673
19674			return a.groupOrder - b.groupOrder;
19675
19676		} else if ( a.renderOrder !== b.renderOrder ) {
19677
19678			return a.renderOrder - b.renderOrder;
19679
19680		} else if ( a.z !== b.z ) {
19681
19682			return b.z - a.z;
19683
19684		} else {
19685
19686			return a.id - b.id;
19687
19688		}
19689
19690	}
19691
19692
19693	function WebGLRenderList() {
19694
19695		var renderItems = [];
19696		var renderItemsIndex = 0;
19697
19698		var opaque = [];
19699		var transparent = [];
19700
19701		var defaultProgram = { id: - 1 };
19702
19703		function init() {
19704
19705			renderItemsIndex = 0;
19706
19707			opaque.length = 0;
19708			transparent.length = 0;
19709
19710		}
19711
19712		function getNextRenderItem( object, geometry, material, groupOrder, z, group ) {
19713
19714			var renderItem = renderItems[ renderItemsIndex ];
19715
19716			if ( renderItem === undefined ) {
19717
19718				renderItem = {
19719					id: object.id,
19720					object: object,
19721					geometry: geometry,
19722					material: material,
19723					program: material.program || defaultProgram,
19724					groupOrder: groupOrder,
19725					renderOrder: object.renderOrder,
19726					z: z,
19727					group: group
19728				};
19729
19730				renderItems[ renderItemsIndex ] = renderItem;
19731
19732			} else {
19733
19734				renderItem.id = object.id;
19735				renderItem.object = object;
19736				renderItem.geometry = geometry;
19737				renderItem.material = material;
19738				renderItem.program = material.program || defaultProgram;
19739				renderItem.groupOrder = groupOrder;
19740				renderItem.renderOrder = object.renderOrder;
19741				renderItem.z = z;
19742				renderItem.group = group;
19743
19744			}
19745
19746			renderItemsIndex ++;
19747
19748			return renderItem;
19749
19750		}
19751
19752		function push( object, geometry, material, groupOrder, z, group ) {
19753
19754			var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
19755
19756			( material.transparent === true ? transparent : opaque ).push( renderItem );
19757
19758		}
19759
19760		function unshift( object, geometry, material, groupOrder, z, group ) {
19761
19762			var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
19763
19764			( material.transparent === true ? transparent : opaque ).unshift( renderItem );
19765
19766		}
19767
19768		function sort( customOpaqueSort, customTransparentSort ) {
19769
19770			if ( opaque.length > 1 ) { opaque.sort( customOpaqueSort || painterSortStable ); }
19771			if ( transparent.length > 1 ) { transparent.sort( customTransparentSort || reversePainterSortStable ); }
19772
19773		}
19774
19775		function finish() {
19776
19777			// Clear references from inactive renderItems in the list
19778
19779			for ( var i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) {
19780
19781				var renderItem = renderItems[ i ];
19782
19783				if ( renderItem.id === null ) { break; }
19784
19785				renderItem.id = null;
19786				renderItem.object = null;
19787				renderItem.geometry = null;
19788				renderItem.material = null;
19789				renderItem.program = null;
19790				renderItem.group = null;
19791
19792			}
19793
19794		}
19795
19796		return {
19797			opaque: opaque,
19798			transparent: transparent,
19799
19800			init: init,
19801			push: push,
19802			unshift: unshift,
19803			finish: finish,
19804
19805			sort: sort
19806		};
19807
19808	}
19809
19810	function WebGLRenderLists() {
19811
19812		var lists = new WeakMap();
19813
19814		function onSceneDispose( event ) {
19815
19816			var scene = event.target;
19817
19818			scene.removeEventListener( 'dispose', onSceneDispose );
19819
19820			lists.delete( scene );
19821
19822		}
19823
19824		function get( scene, camera ) {
19825
19826			var cameras = lists.get( scene );
19827			var list;
19828
19829			if ( cameras === undefined ) {
19830
19831				list = new WebGLRenderList();
19832				lists.set( scene, new WeakMap() );
19833				lists.get( scene ).set( camera, list );
19834
19835				scene.addEventListener( 'dispose', onSceneDispose );
19836
19837			} else {
19838
19839				list = cameras.get( camera );
19840				if ( list === undefined ) {
19841
19842					list = new WebGLRenderList();
19843					cameras.set( camera, list );
19844
19845				}
19846
19847			}
19848
19849			return list;
19850
19851		}
19852
19853		function dispose() {
19854
19855			lists = new WeakMap();
19856
19857		}
19858
19859		return {
19860			get: get,
19861			dispose: dispose
19862		};
19863
19864	}
19865
19866	/**
19867	 * @author mrdoob / http://mrdoob.com/
19868	 */
19869
19870	function UniformsCache() {
19871
19872		var lights = {};
19873
19874		return {
19875
19876			get: function ( light ) {
19877
19878				if ( lights[ light.id ] !== undefined ) {
19879
19880					return lights[ light.id ];
19881
19882				}
19883
19884				var uniforms;
19885
19886				switch ( light.type ) {
19887
19888					case 'DirectionalLight':
19889						uniforms = {
19890							direction: new Vector3(),
19891							color: new Color()
19892						};
19893						break;
19894
19895					case 'SpotLight':
19896						uniforms = {
19897							position: new Vector3(),
19898							direction: new Vector3(),
19899							color: new Color(),
19900							distance: 0,
19901							coneCos: 0,
19902							penumbraCos: 0,
19903							decay: 0
19904						};
19905						break;
19906
19907					case 'PointLight':
19908						uniforms = {
19909							position: new Vector3(),
19910							color: new Color(),
19911							distance: 0,
19912							decay: 0
19913						};
19914						break;
19915
19916					case 'HemisphereLight':
19917						uniforms = {
19918							direction: new Vector3(),
19919							skyColor: new Color(),
19920							groundColor: new Color()
19921						};
19922						break;
19923
19924					case 'RectAreaLight':
19925						uniforms = {
19926							color: new Color(),
19927							position: new Vector3(),
19928							halfWidth: new Vector3(),
19929							halfHeight: new Vector3()
19930						};
19931						break;
19932
19933				}
19934
19935				lights[ light.id ] = uniforms;
19936
19937				return uniforms;
19938
19939			}
19940
19941		};
19942
19943	}
19944
19945	function ShadowUniformsCache() {
19946
19947		var lights = {};
19948
19949		return {
19950
19951			get: function ( light ) {
19952
19953				if ( lights[ light.id ] !== undefined ) {
19954
19955					return lights[ light.id ];
19956
19957				}
19958
19959				var uniforms;
19960
19961				switch ( light.type ) {
19962
19963					case 'DirectionalLight':
19964						uniforms = {
19965							shadowBias: 0,
19966							shadowNormalBias: 0,
19967							shadowRadius: 1,
19968							shadowMapSize: new Vector2()
19969						};
19970						break;
19971
19972					case 'SpotLight':
19973						uniforms = {
19974							shadowBias: 0,
19975							shadowNormalBias: 0,
19976							shadowRadius: 1,
19977							shadowMapSize: new Vector2()
19978						};
19979						break;
19980
19981					case 'PointLight':
19982						uniforms = {
19983							shadowBias: 0,
19984							shadowNormalBias: 0,
19985							shadowRadius: 1,
19986							shadowMapSize: new Vector2(),
19987							shadowCameraNear: 1,
19988							shadowCameraFar: 1000
19989						};
19990						break;
19991
19992					// TODO (abelnation): set RectAreaLight shadow uniforms
19993
19994				}
19995
19996				lights[ light.id ] = uniforms;
19997
19998				return uniforms;
19999
20000			}
20001
20002		};
20003
20004	}
20005
20006
20007
20008	var nextVersion = 0;
20009
20010	function shadowCastingLightsFirst( lightA, lightB ) {
20011
20012		return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 );
20013
20014	}
20015
20016	function WebGLLights() {
20017
20018		var cache = new UniformsCache();
20019
20020		var shadowCache = ShadowUniformsCache();
20021
20022		var state = {
20023
20024			version: 0,
20025
20026			hash: {
20027				directionalLength: - 1,
20028				pointLength: - 1,
20029				spotLength: - 1,
20030				rectAreaLength: - 1,
20031				hemiLength: - 1,
20032
20033				numDirectionalShadows: - 1,
20034				numPointShadows: - 1,
20035				numSpotShadows: - 1
20036			},
20037
20038			ambient: [ 0, 0, 0 ],
20039			probe: [],
20040			directional: [],
20041			directionalShadow: [],
20042			directionalShadowMap: [],
20043			directionalShadowMatrix: [],
20044			spot: [],
20045			spotShadow: [],
20046			spotShadowMap: [],
20047			spotShadowMatrix: [],
20048			rectArea: [],
20049			point: [],
20050			pointShadow: [],
20051			pointShadowMap: [],
20052			pointShadowMatrix: [],
20053			hemi: []
20054
20055		};
20056
20057		for ( var i = 0; i < 9; i ++ ) { state.probe.push( new Vector3() ); }
20058
20059		var vector3 = new Vector3();
20060		var matrix4 = new Matrix4();
20061		var matrix42 = new Matrix4();
20062
20063		function setup( lights, shadows, camera ) {
20064
20065			var r = 0, g = 0, b = 0;
20066
20067			for ( var i = 0; i < 9; i ++ ) { state.probe[ i ].set( 0, 0, 0 ); }
20068
20069			var directionalLength = 0;
20070			var pointLength = 0;
20071			var spotLength = 0;
20072			var rectAreaLength = 0;
20073			var hemiLength = 0;
20074
20075			var numDirectionalShadows = 0;
20076			var numPointShadows = 0;
20077			var numSpotShadows = 0;
20078
20079			var viewMatrix = camera.matrixWorldInverse;
20080
20081			lights.sort( shadowCastingLightsFirst );
20082
20083			for ( var i$1 = 0, l = lights.length; i$1 < l; i$1 ++ ) {
20084
20085				var light = lights[ i$1 ];
20086
20087				var color = light.color;
20088				var intensity = light.intensity;
20089				var distance = light.distance;
20090
20091				var shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
20092
20093				if ( light.isAmbientLight ) {
20094
20095					r += color.r * intensity;
20096					g += color.g * intensity;
20097					b += color.b * intensity;
20098
20099				} else if ( light.isLightProbe ) {
20100
20101					for ( var j = 0; j < 9; j ++ ) {
20102
20103						state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity );
20104
20105					}
20106
20107				} else if ( light.isDirectionalLight ) {
20108
20109					var uniforms = cache.get( light );
20110
20111					uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
20112					uniforms.direction.setFromMatrixPosition( light.matrixWorld );
20113					vector3.setFromMatrixPosition( light.target.matrixWorld );
20114					uniforms.direction.sub( vector3 );
20115					uniforms.direction.transformDirection( viewMatrix );
20116
20117					if ( light.castShadow ) {
20118
20119						var shadow = light.shadow;
20120
20121						var shadowUniforms = shadowCache.get( light );
20122
20123						shadowUniforms.shadowBias = shadow.bias;
20124						shadowUniforms.shadowNormalBias = shadow.normalBias;
20125						shadowUniforms.shadowRadius = shadow.radius;
20126						shadowUniforms.shadowMapSize = shadow.mapSize;
20127
20128						state.directionalShadow[ directionalLength ] = shadowUniforms;
20129						state.directionalShadowMap[ directionalLength ] = shadowMap;
20130						state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
20131
20132						numDirectionalShadows ++;
20133
20134					}
20135
20136					state.directional[ directionalLength ] = uniforms;
20137
20138					directionalLength ++;
20139
20140				} else if ( light.isSpotLight ) {
20141
20142					var uniforms$1 = cache.get( light );
20143
20144					uniforms$1.position.setFromMatrixPosition( light.matrixWorld );
20145					uniforms$1.position.applyMatrix4( viewMatrix );
20146
20147					uniforms$1.color.copy( color ).multiplyScalar( intensity );
20148					uniforms$1.distance = distance;
20149
20150					uniforms$1.direction.setFromMatrixPosition( light.matrixWorld );
20151					vector3.setFromMatrixPosition( light.target.matrixWorld );
20152					uniforms$1.direction.sub( vector3 );
20153					uniforms$1.direction.transformDirection( viewMatrix );
20154
20155					uniforms$1.coneCos = Math.cos( light.angle );
20156					uniforms$1.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
20157					uniforms$1.decay = light.decay;
20158
20159					if ( light.castShadow ) {
20160
20161						var shadow$1 = light.shadow;
20162
20163						var shadowUniforms$1 = shadowCache.get( light );
20164
20165						shadowUniforms$1.shadowBias = shadow$1.bias;
20166						shadowUniforms$1.shadowNormalBias = shadow$1.normalBias;
20167						shadowUniforms$1.shadowRadius = shadow$1.radius;
20168						shadowUniforms$1.shadowMapSize = shadow$1.mapSize;
20169
20170						state.spotShadow[ spotLength ] = shadowUniforms$1;
20171						state.spotShadowMap[ spotLength ] = shadowMap;
20172						state.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
20173
20174						numSpotShadows ++;
20175
20176					}
20177
20178					state.spot[ spotLength ] = uniforms$1;
20179
20180					spotLength ++;
20181
20182				} else if ( light.isRectAreaLight ) {
20183
20184					var uniforms$2 = cache.get( light );
20185
20186					// (a) intensity is the total visible light emitted
20187					//uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) );
20188
20189					// (b) intensity is the brightness of the light
20190					uniforms$2.color.copy( color ).multiplyScalar( intensity );
20191
20192					uniforms$2.position.setFromMatrixPosition( light.matrixWorld );
20193					uniforms$2.position.applyMatrix4( viewMatrix );
20194
20195					// extract local rotation of light to derive width/height half vectors
20196					matrix42.identity();
20197					matrix4.copy( light.matrixWorld );
20198					matrix4.premultiply( viewMatrix );
20199					matrix42.extractRotation( matrix4 );
20200
20201					uniforms$2.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
20202					uniforms$2.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
20203
20204					uniforms$2.halfWidth.applyMatrix4( matrix42 );
20205					uniforms$2.halfHeight.applyMatrix4( matrix42 );
20206
20207					// TODO (abelnation): RectAreaLight distance?
20208					// uniforms.distance = distance;
20209
20210					state.rectArea[ rectAreaLength ] = uniforms$2;
20211
20212					rectAreaLength ++;
20213
20214				} else if ( light.isPointLight ) {
20215
20216					var uniforms$3 = cache.get( light );
20217
20218					uniforms$3.position.setFromMatrixPosition( light.matrixWorld );
20219					uniforms$3.position.applyMatrix4( viewMatrix );
20220
20221					uniforms$3.color.copy( light.color ).multiplyScalar( light.intensity );
20222					uniforms$3.distance = light.distance;
20223					uniforms$3.decay = light.decay;
20224
20225					if ( light.castShadow ) {
20226
20227						var shadow$2 = light.shadow;
20228
20229						var shadowUniforms$2 = shadowCache.get( light );
20230
20231						shadowUniforms$2.shadowBias = shadow$2.bias;
20232						shadowUniforms$2.shadowNormalBias = shadow$2.normalBias;
20233						shadowUniforms$2.shadowRadius = shadow$2.radius;
20234						shadowUniforms$2.shadowMapSize = shadow$2.mapSize;
20235						shadowUniforms$2.shadowCameraNear = shadow$2.camera.near;
20236						shadowUniforms$2.shadowCameraFar = shadow$2.camera.far;
20237
20238						state.pointShadow[ pointLength ] = shadowUniforms$2;
20239						state.pointShadowMap[ pointLength ] = shadowMap;
20240						state.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
20241
20242						numPointShadows ++;
20243
20244					}
20245
20246					state.point[ pointLength ] = uniforms$3;
20247
20248					pointLength ++;
20249
20250				} else if ( light.isHemisphereLight ) {
20251
20252					var uniforms$4 = cache.get( light );
20253
20254					uniforms$4.direction.setFromMatrixPosition( light.matrixWorld );
20255					uniforms$4.direction.transformDirection( viewMatrix );
20256					uniforms$4.direction.normalize();
20257
20258					uniforms$4.skyColor.copy( light.color ).multiplyScalar( intensity );
20259					uniforms$4.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
20260
20261					state.hemi[ hemiLength ] = uniforms$4;
20262
20263					hemiLength ++;
20264
20265				}
20266
20267			}
20268
20269			state.ambient[ 0 ] = r;
20270			state.ambient[ 1 ] = g;
20271			state.ambient[ 2 ] = b;
20272
20273			var hash = state.hash;
20274
20275			if ( hash.directionalLength !== directionalLength ||
20276				hash.pointLength !== pointLength ||
20277				hash.spotLength !== spotLength ||
20278				hash.rectAreaLength !== rectAreaLength ||
20279				hash.hemiLength !== hemiLength ||
20280				hash.numDirectionalShadows !== numDirectionalShadows ||
20281				hash.numPointShadows !== numPointShadows ||
20282				hash.numSpotShadows !== numSpotShadows ) {
20283
20284				state.directional.length = directionalLength;
20285				state.spot.length = spotLength;
20286				state.rectArea.length = rectAreaLength;
20287				state.point.length = pointLength;
20288				state.hemi.length = hemiLength;
20289
20290				state.directionalShadow.length = numDirectionalShadows;
20291				state.directionalShadowMap.length = numDirectionalShadows;
20292				state.pointShadow.length = numPointShadows;
20293				state.pointShadowMap.length = numPointShadows;
20294				state.spotShadow.length = numSpotShadows;
20295				state.spotShadowMap.length = numSpotShadows;
20296				state.directionalShadowMatrix.length = numDirectionalShadows;
20297				state.pointShadowMatrix.length = numPointShadows;
20298				state.spotShadowMatrix.length = numSpotShadows;
20299
20300				hash.directionalLength = directionalLength;
20301				hash.pointLength = pointLength;
20302				hash.spotLength = spotLength;
20303				hash.rectAreaLength = rectAreaLength;
20304				hash.hemiLength = hemiLength;
20305
20306				hash.numDirectionalShadows = numDirectionalShadows;
20307				hash.numPointShadows = numPointShadows;
20308				hash.numSpotShadows = numSpotShadows;
20309
20310				state.version = nextVersion ++;
20311
20312			}
20313
20314		}
20315
20316		return {
20317			setup: setup,
20318			state: state
20319		};
20320
20321	}
20322
20323	/**
20324	 * @author Mugen87 / https://github.com/Mugen87
20325	 */
20326
20327	function WebGLRenderState() {
20328
20329		var lights = new WebGLLights();
20330
20331		var lightsArray = [];
20332		var shadowsArray = [];
20333
20334		function init() {
20335
20336			lightsArray.length = 0;
20337			shadowsArray.length = 0;
20338
20339		}
20340
20341		function pushLight( light ) {
20342
20343			lightsArray.push( light );
20344
20345		}
20346
20347		function pushShadow( shadowLight ) {
20348
20349			shadowsArray.push( shadowLight );
20350
20351		}
20352
20353		function setupLights( camera ) {
20354
20355			lights.setup( lightsArray, shadowsArray, camera );
20356
20357		}
20358
20359		var state = {
20360			lightsArray: lightsArray,
20361			shadowsArray: shadowsArray,
20362
20363			lights: lights
20364		};
20365
20366		return {
20367			init: init,
20368			state: state,
20369			setupLights: setupLights,
20370
20371			pushLight: pushLight,
20372			pushShadow: pushShadow
20373		};
20374
20375	}
20376
20377	function WebGLRenderStates() {
20378
20379		var renderStates = new WeakMap();
20380
20381		function onSceneDispose( event ) {
20382
20383			var scene = event.target;
20384
20385			scene.removeEventListener( 'dispose', onSceneDispose );
20386
20387			renderStates.delete( scene );
20388
20389		}
20390
20391		function get( scene, camera ) {
20392
20393			var renderState;
20394
20395			if ( renderStates.has( scene ) === false ) {
20396
20397				renderState = new WebGLRenderState();
20398				renderStates.set( scene, new WeakMap() );
20399				renderStates.get( scene ).set( camera, renderState );
20400
20401				scene.addEventListener( 'dispose', onSceneDispose );
20402
20403			} else {
20404
20405				if ( renderStates.get( scene ).has( camera ) === false ) {
20406
20407					renderState = new WebGLRenderState();
20408					renderStates.get( scene ).set( camera, renderState );
20409
20410				} else {
20411
20412					renderState = renderStates.get( scene ).get( camera );
20413
20414				}
20415
20416			}
20417
20418			return renderState;
20419
20420		}
20421
20422		function dispose() {
20423
20424			renderStates = new WeakMap();
20425
20426		}
20427
20428		return {
20429			get: get,
20430			dispose: dispose
20431		};
20432
20433	}
20434
20435	/**
20436	 * @author mrdoob / http://mrdoob.com/
20437	 * @author alteredq / http://alteredqualia.com/
20438	 * @author bhouston / https://clara.io
20439	 * @author WestLangley / http://github.com/WestLangley
20440	 *
20441	 * parameters = {
20442	 *
20443	 *  opacity: <float>,
20444	 *
20445	 *  map: new THREE.Texture( <Image> ),
20446	 *
20447	 *  alphaMap: new THREE.Texture( <Image> ),
20448	 *
20449	 *  displacementMap: new THREE.Texture( <Image> ),
20450	 *  displacementScale: <float>,
20451	 *  displacementBias: <float>,
20452	 *
20453	 *  wireframe: <boolean>,
20454	 *  wireframeLinewidth: <float>
20455	 * }
20456	 */
20457
20458	function MeshDepthMaterial( parameters ) {
20459
20460		Material.call( this );
20461
20462		this.type = 'MeshDepthMaterial';
20463
20464		this.depthPacking = BasicDepthPacking;
20465
20466		this.skinning = false;
20467		this.morphTargets = false;
20468
20469		this.map = null;
20470
20471		this.alphaMap = null;
20472
20473		this.displacementMap = null;
20474		this.displacementScale = 1;
20475		this.displacementBias = 0;
20476
20477		this.wireframe = false;
20478		this.wireframeLinewidth = 1;
20479
20480		this.fog = false;
20481
20482		this.setValues( parameters );
20483
20484	}
20485
20486	MeshDepthMaterial.prototype = Object.create( Material.prototype );
20487	MeshDepthMaterial.prototype.constructor = MeshDepthMaterial;
20488
20489	MeshDepthMaterial.prototype.isMeshDepthMaterial = true;
20490
20491	MeshDepthMaterial.prototype.copy = function ( source ) {
20492
20493		Material.prototype.copy.call( this, source );
20494
20495		this.depthPacking = source.depthPacking;
20496
20497		this.skinning = source.skinning;
20498		this.morphTargets = source.morphTargets;
20499
20500		this.map = source.map;
20501
20502		this.alphaMap = source.alphaMap;
20503
20504		this.displacementMap = source.displacementMap;
20505		this.displacementScale = source.displacementScale;
20506		this.displacementBias = source.displacementBias;
20507
20508		this.wireframe = source.wireframe;
20509		this.wireframeLinewidth = source.wireframeLinewidth;
20510
20511		return this;
20512
20513	};
20514
20515	/**
20516	 * @author WestLangley / http://github.com/WestLangley
20517	 *
20518	 * parameters = {
20519	 *
20520	 *  referencePosition: <float>,
20521	 *  nearDistance: <float>,
20522	 *  farDistance: <float>,
20523	 *
20524	 *  skinning: <bool>,
20525	 *  morphTargets: <bool>,
20526	 *
20527	 *  map: new THREE.Texture( <Image> ),
20528	 *
20529	 *  alphaMap: new THREE.Texture( <Image> ),
20530	 *
20531	 *  displacementMap: new THREE.Texture( <Image> ),
20532	 *  displacementScale: <float>,
20533	 *  displacementBias: <float>
20534	 *
20535	 * }
20536	 */
20537
20538	function MeshDistanceMaterial( parameters ) {
20539
20540		Material.call( this );
20541
20542		this.type = 'MeshDistanceMaterial';
20543
20544		this.referencePosition = new Vector3();
20545		this.nearDistance = 1;
20546		this.farDistance = 1000;
20547
20548		this.skinning = false;
20549		this.morphTargets = false;
20550
20551		this.map = null;
20552
20553		this.alphaMap = null;
20554
20555		this.displacementMap = null;
20556		this.displacementScale = 1;
20557		this.displacementBias = 0;
20558
20559		this.fog = false;
20560
20561		this.setValues( parameters );
20562
20563	}
20564
20565	MeshDistanceMaterial.prototype = Object.create( Material.prototype );
20566	MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial;
20567
20568	MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true;
20569
20570	MeshDistanceMaterial.prototype.copy = function ( source ) {
20571
20572		Material.prototype.copy.call( this, source );
20573
20574		this.referencePosition.copy( source.referencePosition );
20575		this.nearDistance = source.nearDistance;
20576		this.farDistance = source.farDistance;
20577
20578		this.skinning = source.skinning;
20579		this.morphTargets = source.morphTargets;
20580
20581		this.map = source.map;
20582
20583		this.alphaMap = source.alphaMap;
20584
20585		this.displacementMap = source.displacementMap;
20586		this.displacementScale = source.displacementScale;
20587		this.displacementBias = source.displacementBias;
20588
20589		return this;
20590
20591	};
20592
20593	var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n  float mean = 0.0;\n  float squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy  ) / resolution ) );\n  for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n    #ifdef HORIZONAL_PASS\n      vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n      mean += distribution.x;\n      squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n    #else\n      float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0,  i )  * radius ) / resolution ) );\n      mean += depth;\n      squared_mean += depth * depth;\n    #endif\n  }\n  mean = mean * HALF_SAMPLE_RATE;\n  squared_mean = squared_mean * HALF_SAMPLE_RATE;\n  float std_dev = sqrt( squared_mean - mean * mean );\n  gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
20594
20595	var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}";
20596
20597	/**
20598	 * @author alteredq / http://alteredqualia.com/
20599	 * @author mrdoob / http://mrdoob.com/
20600	 */
20601
20602	function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
20603
20604		var _frustum = new Frustum();
20605
20606		var _shadowMapSize = new Vector2(),
20607			_viewportSize = new Vector2(),
20608
20609			_viewport = new Vector4(),
20610
20611			_depthMaterials = [],
20612			_distanceMaterials = [],
20613
20614			_materialCache = {};
20615
20616		var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide };
20617
20618		var shadowMaterialVertical = new ShaderMaterial( {
20619
20620			defines: {
20621				SAMPLE_RATE: 2.0 / 8.0,
20622				HALF_SAMPLE_RATE: 1.0 / 8.0
20623			},
20624
20625			uniforms: {
20626				shadow_pass: { value: null },
20627				resolution: { value: new Vector2() },
20628				radius: { value: 4.0 }
20629			},
20630
20631			vertexShader: vsm_vert,
20632
20633			fragmentShader: vsm_frag
20634
20635		} );
20636
20637		var shadowMaterialHorizonal = shadowMaterialVertical.clone();
20638		shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1;
20639
20640		var fullScreenTri = new BufferGeometry();
20641		fullScreenTri.setAttribute(
20642			"position",
20643			new BufferAttribute(
20644				new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ),
20645				3
20646			)
20647		);
20648
20649		var fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical );
20650
20651		var scope = this;
20652
20653		this.enabled = false;
20654
20655		this.autoUpdate = true;
20656		this.needsUpdate = false;
20657
20658		this.type = PCFShadowMap;
20659
20660		this.render = function ( lights, scene, camera ) {
20661
20662			if ( scope.enabled === false ) { return; }
20663			if ( scope.autoUpdate === false && scope.needsUpdate === false ) { return; }
20664
20665			if ( lights.length === 0 ) { return; }
20666
20667			var currentRenderTarget = _renderer.getRenderTarget();
20668			var activeCubeFace = _renderer.getActiveCubeFace();
20669			var activeMipmapLevel = _renderer.getActiveMipmapLevel();
20670
20671			var _state = _renderer.state;
20672
20673			// Set GL state for depth map.
20674			_state.setBlending( NoBlending );
20675			_state.buffers.color.setClear( 1, 1, 1, 1 );
20676			_state.buffers.depth.setTest( true );
20677			_state.setScissorTest( false );
20678
20679			// render depth map
20680
20681			for ( var i = 0, il = lights.length; i < il; i ++ ) {
20682
20683				var light = lights[ i ];
20684				var shadow = light.shadow;
20685
20686				if ( shadow.autoUpdate === false && shadow.needsUpdate === false ) { continue; }
20687
20688				if ( shadow === undefined ) {
20689
20690					console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );
20691					continue;
20692
20693				}
20694
20695				_shadowMapSize.copy( shadow.mapSize );
20696
20697				var shadowFrameExtents = shadow.getFrameExtents();
20698
20699				_shadowMapSize.multiply( shadowFrameExtents );
20700
20701				_viewportSize.copy( shadow.mapSize );
20702
20703				if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) {
20704
20705					if ( _shadowMapSize.x > maxTextureSize ) {
20706
20707						_viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x );
20708						_shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
20709						shadow.mapSize.x = _viewportSize.x;
20710
20711					}
20712
20713					if ( _shadowMapSize.y > maxTextureSize ) {
20714
20715						_viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y );
20716						_shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
20717						shadow.mapSize.y = _viewportSize.y;
20718
20719					}
20720
20721				}
20722
20723				if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {
20724
20725					var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat };
20726
20727					shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
20728					shadow.map.texture.name = light.name + ".shadowMap";
20729
20730					shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
20731
20732					shadow.camera.updateProjectionMatrix();
20733
20734				}
20735
20736				if ( shadow.map === null ) {
20737
20738					var pars$1 = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat };
20739
20740					shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars$1 );
20741					shadow.map.texture.name = light.name + ".shadowMap";
20742
20743					shadow.camera.updateProjectionMatrix();
20744
20745				}
20746
20747				_renderer.setRenderTarget( shadow.map );
20748				_renderer.clear();
20749
20750				var viewportCount = shadow.getViewportCount();
20751
20752				for ( var vp = 0; vp < viewportCount; vp ++ ) {
20753
20754					var viewport = shadow.getViewport( vp );
20755
20756					_viewport.set(
20757						_viewportSize.x * viewport.x,
20758						_viewportSize.y * viewport.y,
20759						_viewportSize.x * viewport.z,
20760						_viewportSize.y * viewport.w
20761					);
20762
20763					_state.viewport( _viewport );
20764
20765					shadow.updateMatrices( light, vp );
20766
20767					_frustum = shadow.getFrustum();
20768
20769					renderObject( scene, camera, shadow.camera, light, this.type );
20770
20771				}
20772
20773				// do blur pass for VSM
20774
20775				if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {
20776
20777					VSMPass( shadow, camera );
20778
20779				}
20780
20781				shadow.needsUpdate = false;
20782
20783			}
20784
20785			scope.needsUpdate = false;
20786
20787			_renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel );
20788
20789		};
20790
20791		function VSMPass( shadow, camera ) {
20792
20793			var geometry = _objects.update( fullScreenMesh );
20794
20795			// vertical pass
20796
20797			shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;
20798			shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
20799			shadowMaterialVertical.uniforms.radius.value = shadow.radius;
20800			_renderer.setRenderTarget( shadow.mapPass );
20801			_renderer.clear();
20802			_renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null );
20803
20804			// horizonal pass
20805
20806			shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture;
20807			shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize;
20808			shadowMaterialHorizonal.uniforms.radius.value = shadow.radius;
20809			_renderer.setRenderTarget( shadow.map );
20810			_renderer.clear();
20811			_renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null );
20812
20813		}
20814
20815		function getDepthMaterialVariant( useMorphing, useSkinning, useInstancing ) {
20816
20817			var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2;
20818
20819			var material = _depthMaterials[ index ];
20820
20821			if ( material === undefined ) {
20822
20823				material = new MeshDepthMaterial( {
20824
20825					depthPacking: RGBADepthPacking,
20826
20827					morphTargets: useMorphing,
20828					skinning: useSkinning
20829
20830				} );
20831
20832				_depthMaterials[ index ] = material;
20833
20834			}
20835
20836			return material;
20837
20838		}
20839
20840		function getDistanceMaterialVariant( useMorphing, useSkinning, useInstancing ) {
20841
20842			var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2;
20843
20844			var material = _distanceMaterials[ index ];
20845
20846			if ( material === undefined ) {
20847
20848				material = new MeshDistanceMaterial( {
20849
20850					morphTargets: useMorphing,
20851					skinning: useSkinning
20852
20853				} );
20854
20855				_distanceMaterials[ index ] = material;
20856
20857			}
20858
20859			return material;
20860
20861		}
20862
20863		function getDepthMaterial( object, geometry, material, light, shadowCameraNear, shadowCameraFar, type ) {
20864
20865			var result = null;
20866
20867			var getMaterialVariant = getDepthMaterialVariant;
20868			var customMaterial = object.customDepthMaterial;
20869
20870			if ( light.isPointLight === true ) {
20871
20872				getMaterialVariant = getDistanceMaterialVariant;
20873				customMaterial = object.customDistanceMaterial;
20874
20875			}
20876
20877			if ( customMaterial === undefined ) {
20878
20879				var useMorphing = false;
20880
20881				if ( material.morphTargets === true ) {
20882
20883					useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;
20884
20885				}
20886
20887				var useSkinning = false;
20888
20889				if ( object.isSkinnedMesh === true ) {
20890
20891					if ( material.skinning === true ) {
20892
20893						useSkinning = true;
20894
20895					} else {
20896
20897						console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object );
20898
20899					}
20900
20901				}
20902
20903				var useInstancing = object.isInstancedMesh === true;
20904
20905				result = getMaterialVariant( useMorphing, useSkinning, useInstancing );
20906
20907			} else {
20908
20909				result = customMaterial;
20910
20911			}
20912
20913			if ( _renderer.localClippingEnabled &&
20914					material.clipShadows === true &&
20915					material.clippingPlanes.length !== 0 ) {
20916
20917				// in this case we need a unique material instance reflecting the
20918				// appropriate state
20919
20920				var keyA = result.uuid, keyB = material.uuid;
20921
20922				var materialsForVariant = _materialCache[ keyA ];
20923
20924				if ( materialsForVariant === undefined ) {
20925
20926					materialsForVariant = {};
20927					_materialCache[ keyA ] = materialsForVariant;
20928
20929				}
20930
20931				var cachedMaterial = materialsForVariant[ keyB ];
20932
20933				if ( cachedMaterial === undefined ) {
20934
20935					cachedMaterial = result.clone();
20936					materialsForVariant[ keyB ] = cachedMaterial;
20937
20938				}
20939
20940				result = cachedMaterial;
20941
20942			}
20943
20944			result.visible = material.visible;
20945			result.wireframe = material.wireframe;
20946
20947			if ( type === VSMShadowMap ) {
20948
20949				result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side;
20950
20951			} else {
20952
20953				result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ];
20954
20955			}
20956
20957			result.clipShadows = material.clipShadows;
20958			result.clippingPlanes = material.clippingPlanes;
20959			result.clipIntersection = material.clipIntersection;
20960
20961			result.wireframeLinewidth = material.wireframeLinewidth;
20962			result.linewidth = material.linewidth;
20963
20964			if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) {
20965
20966				result.referencePosition.setFromMatrixPosition( light.matrixWorld );
20967				result.nearDistance = shadowCameraNear;
20968				result.farDistance = shadowCameraFar;
20969
20970			}
20971
20972			return result;
20973
20974		}
20975
20976		function renderObject( object, camera, shadowCamera, light, type ) {
20977
20978			if ( object.visible === false ) { return; }
20979
20980			var visible = object.layers.test( camera.layers );
20981
20982			if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
20983
20984				if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {
20985
20986					object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
20987
20988					var geometry = _objects.update( object );
20989					var material = object.material;
20990
20991					if ( Array.isArray( material ) ) {
20992
20993						var groups = geometry.groups;
20994
20995						for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
20996
20997							var group = groups[ k ];
20998							var groupMaterial = material[ group.materialIndex ];
20999
21000							if ( groupMaterial && groupMaterial.visible ) {
21001
21002								var depthMaterial = getDepthMaterial( object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type );
21003
21004								_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
21005
21006							}
21007
21008						}
21009
21010					} else if ( material.visible ) {
21011
21012						var depthMaterial$1 = getDepthMaterial( object, geometry, material, light, shadowCamera.near, shadowCamera.far, type );
21013
21014						_renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial$1, object, null );
21015
21016					}
21017
21018				}
21019
21020			}
21021
21022			var children = object.children;
21023
21024			for ( var i = 0, l = children.length; i < l; i ++ ) {
21025
21026				renderObject( children[ i ], camera, shadowCamera, light, type );
21027
21028			}
21029
21030		}
21031
21032	}
21033
21034	/**
21035	 * @author mrdoob / http://mrdoob.com/
21036	 */
21037
21038	function WebGLState( gl, extensions, capabilities ) {
21039
21040		var isWebGL2 = capabilities.isWebGL2;
21041
21042		function ColorBuffer() {
21043
21044			var locked = false;
21045
21046			var color = new Vector4();
21047			var currentColorMask = null;
21048			var currentColorClear = new Vector4( 0, 0, 0, 0 );
21049
21050			return {
21051
21052				setMask: function ( colorMask ) {
21053
21054					if ( currentColorMask !== colorMask && ! locked ) {
21055
21056						gl.colorMask( colorMask, colorMask, colorMask, colorMask );
21057						currentColorMask = colorMask;
21058
21059					}
21060
21061				},
21062
21063				setLocked: function ( lock ) {
21064
21065					locked = lock;
21066
21067				},
21068
21069				setClear: function ( r, g, b, a, premultipliedAlpha ) {
21070
21071					if ( premultipliedAlpha === true ) {
21072
21073						r *= a; g *= a; b *= a;
21074
21075					}
21076
21077					color.set( r, g, b, a );
21078
21079					if ( currentColorClear.equals( color ) === false ) {
21080
21081						gl.clearColor( r, g, b, a );
21082						currentColorClear.copy( color );
21083
21084					}
21085
21086				},
21087
21088				reset: function () {
21089
21090					locked = false;
21091
21092					currentColorMask = null;
21093					currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state
21094
21095				}
21096
21097			};
21098
21099		}
21100
21101		function DepthBuffer() {
21102
21103			var locked = false;
21104
21105			var currentDepthMask = null;
21106			var currentDepthFunc = null;
21107			var currentDepthClear = null;
21108
21109			return {
21110
21111				setTest: function ( depthTest ) {
21112
21113					if ( depthTest ) {
21114
21115						enable( 2929 );
21116
21117					} else {
21118
21119						disable( 2929 );
21120
21121					}
21122
21123				},
21124
21125				setMask: function ( depthMask ) {
21126
21127					if ( currentDepthMask !== depthMask && ! locked ) {
21128
21129						gl.depthMask( depthMask );
21130						currentDepthMask = depthMask;
21131
21132					}
21133
21134				},
21135
21136				setFunc: function ( depthFunc ) {
21137
21138					if ( currentDepthFunc !== depthFunc ) {
21139
21140						if ( depthFunc ) {
21141
21142							switch ( depthFunc ) {
21143
21144								case NeverDepth:
21145
21146									gl.depthFunc( 512 );
21147									break;
21148
21149								case AlwaysDepth:
21150
21151									gl.depthFunc( 519 );
21152									break;
21153
21154								case LessDepth:
21155
21156									gl.depthFunc( 513 );
21157									break;
21158
21159								case LessEqualDepth:
21160
21161									gl.depthFunc( 515 );
21162									break;
21163
21164								case EqualDepth:
21165
21166									gl.depthFunc( 514 );
21167									break;
21168
21169								case GreaterEqualDepth:
21170
21171									gl.depthFunc( 518 );
21172									break;
21173
21174								case GreaterDepth:
21175
21176									gl.depthFunc( 516 );
21177									break;
21178
21179								case NotEqualDepth:
21180
21181									gl.depthFunc( 517 );
21182									break;
21183
21184								default:
21185
21186									gl.depthFunc( 515 );
21187
21188							}
21189
21190						} else {
21191
21192							gl.depthFunc( 515 );
21193
21194						}
21195
21196						currentDepthFunc = depthFunc;
21197
21198					}
21199
21200				},
21201
21202				setLocked: function ( lock ) {
21203
21204					locked = lock;
21205
21206				},
21207
21208				setClear: function ( depth ) {
21209
21210					if ( currentDepthClear !== depth ) {
21211
21212						gl.clearDepth( depth );
21213						currentDepthClear = depth;
21214
21215					}
21216
21217				},
21218
21219				reset: function () {
21220
21221					locked = false;
21222
21223					currentDepthMask = null;
21224					currentDepthFunc = null;
21225					currentDepthClear = null;
21226
21227				}
21228
21229			};
21230
21231		}
21232
21233		function StencilBuffer() {
21234
21235			var locked = false;
21236
21237			var currentStencilMask = null;
21238			var currentStencilFunc = null;
21239			var currentStencilRef = null;
21240			var currentStencilFuncMask = null;
21241			var currentStencilFail = null;
21242			var currentStencilZFail = null;
21243			var currentStencilZPass = null;
21244			var currentStencilClear = null;
21245
21246			return {
21247
21248				setTest: function ( stencilTest ) {
21249
21250					if ( ! locked ) {
21251
21252						if ( stencilTest ) {
21253
21254							enable( 2960 );
21255
21256						} else {
21257
21258							disable( 2960 );
21259
21260						}
21261
21262					}
21263
21264				},
21265
21266				setMask: function ( stencilMask ) {
21267
21268					if ( currentStencilMask !== stencilMask && ! locked ) {
21269
21270						gl.stencilMask( stencilMask );
21271						currentStencilMask = stencilMask;
21272
21273					}
21274
21275				},
21276
21277				setFunc: function ( stencilFunc, stencilRef, stencilMask ) {
21278
21279					if ( currentStencilFunc !== stencilFunc ||
21280					     currentStencilRef 	!== stencilRef 	||
21281					     currentStencilFuncMask !== stencilMask ) {
21282
21283						gl.stencilFunc( stencilFunc, stencilRef, stencilMask );
21284
21285						currentStencilFunc = stencilFunc;
21286						currentStencilRef = stencilRef;
21287						currentStencilFuncMask = stencilMask;
21288
21289					}
21290
21291				},
21292
21293				setOp: function ( stencilFail, stencilZFail, stencilZPass ) {
21294
21295					if ( currentStencilFail	 !== stencilFail 	||
21296					     currentStencilZFail !== stencilZFail ||
21297					     currentStencilZPass !== stencilZPass ) {
21298
21299						gl.stencilOp( stencilFail, stencilZFail, stencilZPass );
21300
21301						currentStencilFail = stencilFail;
21302						currentStencilZFail = stencilZFail;
21303						currentStencilZPass = stencilZPass;
21304
21305					}
21306
21307				},
21308
21309				setLocked: function ( lock ) {
21310
21311					locked = lock;
21312
21313				},
21314
21315				setClear: function ( stencil ) {
21316
21317					if ( currentStencilClear !== stencil ) {
21318
21319						gl.clearStencil( stencil );
21320						currentStencilClear = stencil;
21321
21322					}
21323
21324				},
21325
21326				reset: function () {
21327
21328					locked = false;
21329
21330					currentStencilMask = null;
21331					currentStencilFunc = null;
21332					currentStencilRef = null;
21333					currentStencilFuncMask = null;
21334					currentStencilFail = null;
21335					currentStencilZFail = null;
21336					currentStencilZPass = null;
21337					currentStencilClear = null;
21338
21339				}
21340
21341			};
21342
21343		}
21344
21345		//
21346
21347		var colorBuffer = new ColorBuffer();
21348		var depthBuffer = new DepthBuffer();
21349		var stencilBuffer = new StencilBuffer();
21350
21351		var enabledCapabilities = {};
21352
21353		var currentProgram = null;
21354
21355		var currentBlendingEnabled = null;
21356		var currentBlending = null;
21357		var currentBlendEquation = null;
21358		var currentBlendSrc = null;
21359		var currentBlendDst = null;
21360		var currentBlendEquationAlpha = null;
21361		var currentBlendSrcAlpha = null;
21362		var currentBlendDstAlpha = null;
21363		var currentPremultipledAlpha = false;
21364
21365		var currentFlipSided = null;
21366		var currentCullFace = null;
21367
21368		var currentLineWidth = null;
21369
21370		var currentPolygonOffsetFactor = null;
21371		var currentPolygonOffsetUnits = null;
21372
21373		var maxTextures = gl.getParameter( 35661 );
21374
21375		var lineWidthAvailable = false;
21376		var version = 0;
21377		var glVersion = gl.getParameter( 7938 );
21378
21379		if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) {
21380
21381			version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] );
21382			lineWidthAvailable = ( version >= 1.0 );
21383
21384		} else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) {
21385
21386			version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] );
21387			lineWidthAvailable = ( version >= 2.0 );
21388
21389		}
21390
21391		var currentTextureSlot = null;
21392		var currentBoundTextures = {};
21393
21394		var currentScissor = new Vector4();
21395		var currentViewport = new Vector4();
21396
21397		function createTexture( type, target, count ) {
21398
21399			var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.
21400			var texture = gl.createTexture();
21401
21402			gl.bindTexture( type, texture );
21403			gl.texParameteri( type, 10241, 9728 );
21404			gl.texParameteri( type, 10240, 9728 );
21405
21406			for ( var i = 0; i < count; i ++ ) {
21407
21408				gl.texImage2D( target + i, 0, 6408, 1, 1, 0, 6408, 5121, data );
21409
21410			}
21411
21412			return texture;
21413
21414		}
21415
21416		var emptyTextures = {};
21417		emptyTextures[ 3553 ] = createTexture( 3553, 3553, 1 );
21418		emptyTextures[ 34067 ] = createTexture( 34067, 34069, 6 );
21419
21420		// init
21421
21422		colorBuffer.setClear( 0, 0, 0, 1 );
21423		depthBuffer.setClear( 1 );
21424		stencilBuffer.setClear( 0 );
21425
21426		enable( 2929 );
21427		depthBuffer.setFunc( LessEqualDepth );
21428
21429		setFlipSided( false );
21430		setCullFace( CullFaceBack );
21431		enable( 2884 );
21432
21433		setBlending( NoBlending );
21434
21435		//
21436
21437		function enable( id ) {
21438
21439			if ( enabledCapabilities[ id ] !== true ) {
21440
21441				gl.enable( id );
21442				enabledCapabilities[ id ] = true;
21443
21444			}
21445
21446		}
21447
21448		function disable( id ) {
21449
21450			if ( enabledCapabilities[ id ] !== false ) {
21451
21452				gl.disable( id );
21453				enabledCapabilities[ id ] = false;
21454
21455			}
21456
21457		}
21458
21459		function useProgram( program ) {
21460
21461			if ( currentProgram !== program ) {
21462
21463				gl.useProgram( program );
21464
21465				currentProgram = program;
21466
21467				return true;
21468
21469			}
21470
21471			return false;
21472
21473		}
21474
21475		var equationToGL = {};
21476		equationToGL[ AddEquation ] = 32774;
21477		equationToGL[ SubtractEquation ] = 32778;
21478		equationToGL[ ReverseSubtractEquation ] = 32779;
21479
21480		if ( isWebGL2 ) {
21481
21482			equationToGL[ MinEquation ] = 32775;
21483			equationToGL[ MaxEquation ] = 32776;
21484
21485		} else {
21486
21487			var extension = extensions.get( 'EXT_blend_minmax' );
21488
21489			if ( extension !== null ) {
21490
21491				equationToGL[ MinEquation ] = extension.MIN_EXT;
21492				equationToGL[ MaxEquation ] = extension.MAX_EXT;
21493
21494			}
21495
21496		}
21497
21498		var factorToGL = {};
21499		factorToGL[ ZeroFactor ] = 0;
21500		factorToGL[ OneFactor ] = 1;
21501		factorToGL[ SrcColorFactor ] = 768;
21502		factorToGL[ SrcAlphaFactor ] = 770;
21503		factorToGL[ SrcAlphaSaturateFactor ] = 776;
21504		factorToGL[ DstColorFactor ] = 774;
21505		factorToGL[ DstAlphaFactor ] = 772;
21506		factorToGL[ OneMinusSrcColorFactor ] = 769;
21507		factorToGL[ OneMinusSrcAlphaFactor ] = 771;
21508		factorToGL[ OneMinusDstColorFactor ] = 775;
21509		factorToGL[ OneMinusDstAlphaFactor ] = 773;
21510
21511		function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
21512
21513			if ( blending === NoBlending ) {
21514
21515				if ( currentBlendingEnabled ) {
21516
21517					disable( 3042 );
21518					currentBlendingEnabled = false;
21519
21520				}
21521
21522				return;
21523
21524			}
21525
21526			if ( ! currentBlendingEnabled ) {
21527
21528				enable( 3042 );
21529				currentBlendingEnabled = true;
21530
21531			}
21532
21533			if ( blending !== CustomBlending ) {
21534
21535				if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {
21536
21537					if ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) {
21538
21539						gl.blendEquation( 32774 );
21540
21541						currentBlendEquation = AddEquation;
21542						currentBlendEquationAlpha = AddEquation;
21543
21544					}
21545
21546					if ( premultipliedAlpha ) {
21547
21548						switch ( blending ) {
21549
21550							case NormalBlending:
21551								gl.blendFuncSeparate( 1, 771, 1, 771 );
21552								break;
21553
21554							case AdditiveBlending:
21555								gl.blendFunc( 1, 1 );
21556								break;
21557
21558							case SubtractiveBlending:
21559								gl.blendFuncSeparate( 0, 0, 769, 771 );
21560								break;
21561
21562							case MultiplyBlending:
21563								gl.blendFuncSeparate( 0, 768, 0, 770 );
21564								break;
21565
21566							default:
21567								console.error( 'THREE.WebGLState: Invalid blending: ', blending );
21568								break;
21569
21570						}
21571
21572					} else {
21573
21574						switch ( blending ) {
21575
21576							case NormalBlending:
21577								gl.blendFuncSeparate( 770, 771, 1, 771 );
21578								break;
21579
21580							case AdditiveBlending:
21581								gl.blendFunc( 770, 1 );
21582								break;
21583
21584							case SubtractiveBlending:
21585								gl.blendFunc( 0, 769 );
21586								break;
21587
21588							case MultiplyBlending:
21589								gl.blendFunc( 0, 768 );
21590								break;
21591
21592							default:
21593								console.error( 'THREE.WebGLState: Invalid blending: ', blending );
21594								break;
21595
21596						}
21597
21598					}
21599
21600					currentBlendSrc = null;
21601					currentBlendDst = null;
21602					currentBlendSrcAlpha = null;
21603					currentBlendDstAlpha = null;
21604
21605					currentBlending = blending;
21606					currentPremultipledAlpha = premultipliedAlpha;
21607
21608				}
21609
21610				return;
21611
21612			}
21613
21614			// custom blending
21615
21616			blendEquationAlpha = blendEquationAlpha || blendEquation;
21617			blendSrcAlpha = blendSrcAlpha || blendSrc;
21618			blendDstAlpha = blendDstAlpha || blendDst;
21619
21620			if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
21621
21622				gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] );
21623
21624				currentBlendEquation = blendEquation;
21625				currentBlendEquationAlpha = blendEquationAlpha;
21626
21627			}
21628
21629			if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
21630
21631				gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] );
21632
21633				currentBlendSrc = blendSrc;
21634				currentBlendDst = blendDst;
21635				currentBlendSrcAlpha = blendSrcAlpha;
21636				currentBlendDstAlpha = blendDstAlpha;
21637
21638			}
21639
21640			currentBlending = blending;
21641			currentPremultipledAlpha = null;
21642
21643		}
21644
21645		function setMaterial( material, frontFaceCW ) {
21646
21647			material.side === DoubleSide
21648				? disable( 2884 )
21649				: enable( 2884 );
21650
21651			var flipSided = ( material.side === BackSide );
21652			if ( frontFaceCW ) { flipSided = ! flipSided; }
21653
21654			setFlipSided( flipSided );
21655
21656			( material.blending === NormalBlending && material.transparent === false )
21657				? setBlending( NoBlending )
21658				: setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
21659
21660			depthBuffer.setFunc( material.depthFunc );
21661			depthBuffer.setTest( material.depthTest );
21662			depthBuffer.setMask( material.depthWrite );
21663			colorBuffer.setMask( material.colorWrite );
21664
21665			var stencilWrite = material.stencilWrite;
21666			stencilBuffer.setTest( stencilWrite );
21667			if ( stencilWrite ) {
21668
21669				stencilBuffer.setMask( material.stencilWriteMask );
21670				stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask );
21671				stencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass );
21672
21673			}
21674
21675			setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
21676
21677		}
21678
21679		//
21680
21681		function setFlipSided( flipSided ) {
21682
21683			if ( currentFlipSided !== flipSided ) {
21684
21685				if ( flipSided ) {
21686
21687					gl.frontFace( 2304 );
21688
21689				} else {
21690
21691					gl.frontFace( 2305 );
21692
21693				}
21694
21695				currentFlipSided = flipSided;
21696
21697			}
21698
21699		}
21700
21701		function setCullFace( cullFace ) {
21702
21703			if ( cullFace !== CullFaceNone ) {
21704
21705				enable( 2884 );
21706
21707				if ( cullFace !== currentCullFace ) {
21708
21709					if ( cullFace === CullFaceBack ) {
21710
21711						gl.cullFace( 1029 );
21712
21713					} else if ( cullFace === CullFaceFront ) {
21714
21715						gl.cullFace( 1028 );
21716
21717					} else {
21718
21719						gl.cullFace( 1032 );
21720
21721					}
21722
21723				}
21724
21725			} else {
21726
21727				disable( 2884 );
21728
21729			}
21730
21731			currentCullFace = cullFace;
21732
21733		}
21734
21735		function setLineWidth( width ) {
21736
21737			if ( width !== currentLineWidth ) {
21738
21739				if ( lineWidthAvailable ) { gl.lineWidth( width ); }
21740
21741				currentLineWidth = width;
21742
21743			}
21744
21745		}
21746
21747		function setPolygonOffset( polygonOffset, factor, units ) {
21748
21749			if ( polygonOffset ) {
21750
21751				enable( 32823 );
21752
21753				if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {
21754
21755					gl.polygonOffset( factor, units );
21756
21757					currentPolygonOffsetFactor = factor;
21758					currentPolygonOffsetUnits = units;
21759
21760				}
21761
21762			} else {
21763
21764				disable( 32823 );
21765
21766			}
21767
21768		}
21769
21770		function setScissorTest( scissorTest ) {
21771
21772			if ( scissorTest ) {
21773
21774				enable( 3089 );
21775
21776			} else {
21777
21778				disable( 3089 );
21779
21780			}
21781
21782		}
21783
21784		// texture
21785
21786		function activeTexture( webglSlot ) {
21787
21788			if ( webglSlot === undefined ) { webglSlot = 33984 + maxTextures - 1; }
21789
21790			if ( currentTextureSlot !== webglSlot ) {
21791
21792				gl.activeTexture( webglSlot );
21793				currentTextureSlot = webglSlot;
21794
21795			}
21796
21797		}
21798
21799		function bindTexture( webglType, webglTexture ) {
21800
21801			if ( currentTextureSlot === null ) {
21802
21803				activeTexture();
21804
21805			}
21806
21807			var boundTexture = currentBoundTextures[ currentTextureSlot ];
21808
21809			if ( boundTexture === undefined ) {
21810
21811				boundTexture = { type: undefined, texture: undefined };
21812				currentBoundTextures[ currentTextureSlot ] = boundTexture;
21813
21814			}
21815
21816			if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
21817
21818				gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );
21819
21820				boundTexture.type = webglType;
21821				boundTexture.texture = webglTexture;
21822
21823			}
21824
21825		}
21826
21827		function unbindTexture() {
21828
21829			var boundTexture = currentBoundTextures[ currentTextureSlot ];
21830
21831			if ( boundTexture !== undefined && boundTexture.type !== undefined ) {
21832
21833				gl.bindTexture( boundTexture.type, null );
21834
21835				boundTexture.type = undefined;
21836				boundTexture.texture = undefined;
21837
21838			}
21839
21840		}
21841
21842		function compressedTexImage2D() {
21843
21844			try {
21845
21846				gl.compressedTexImage2D.apply( gl, arguments );
21847
21848			} catch ( error ) {
21849
21850				console.error( 'THREE.WebGLState:', error );
21851
21852			}
21853
21854		}
21855
21856		function texImage2D() {
21857
21858			try {
21859
21860				gl.texImage2D.apply( gl, arguments );
21861
21862			} catch ( error ) {
21863
21864				console.error( 'THREE.WebGLState:', error );
21865
21866			}
21867
21868		}
21869
21870		function texImage3D() {
21871
21872			try {
21873
21874				gl.texImage3D.apply( gl, arguments );
21875
21876			} catch ( error ) {
21877
21878				console.error( 'THREE.WebGLState:', error );
21879
21880			}
21881
21882		}
21883
21884		//
21885
21886		function scissor( scissor ) {
21887
21888			if ( currentScissor.equals( scissor ) === false ) {
21889
21890				gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );
21891				currentScissor.copy( scissor );
21892
21893			}
21894
21895		}
21896
21897		function viewport( viewport ) {
21898
21899			if ( currentViewport.equals( viewport ) === false ) {
21900
21901				gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );
21902				currentViewport.copy( viewport );
21903
21904			}
21905
21906		}
21907
21908		//
21909
21910		function reset() {
21911
21912			enabledCapabilities = {};
21913
21914			currentTextureSlot = null;
21915			currentBoundTextures = {};
21916
21917			currentProgram = null;
21918
21919			currentBlending = null;
21920
21921			currentFlipSided = null;
21922			currentCullFace = null;
21923
21924			colorBuffer.reset();
21925			depthBuffer.reset();
21926			stencilBuffer.reset();
21927
21928		}
21929
21930		return {
21931
21932			buffers: {
21933				color: colorBuffer,
21934				depth: depthBuffer,
21935				stencil: stencilBuffer
21936			},
21937
21938			enable: enable,
21939			disable: disable,
21940
21941			useProgram: useProgram,
21942
21943			setBlending: setBlending,
21944			setMaterial: setMaterial,
21945
21946			setFlipSided: setFlipSided,
21947			setCullFace: setCullFace,
21948
21949			setLineWidth: setLineWidth,
21950			setPolygonOffset: setPolygonOffset,
21951
21952			setScissorTest: setScissorTest,
21953
21954			activeTexture: activeTexture,
21955			bindTexture: bindTexture,
21956			unbindTexture: unbindTexture,
21957			compressedTexImage2D: compressedTexImage2D,
21958			texImage2D: texImage2D,
21959			texImage3D: texImage3D,
21960
21961			scissor: scissor,
21962			viewport: viewport,
21963
21964			reset: reset
21965
21966		};
21967
21968	}
21969
21970	/**
21971	 * @author mrdoob / http://mrdoob.com/
21972	 */
21973
21974	function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
21975
21976		var isWebGL2 = capabilities.isWebGL2;
21977		var maxTextures = capabilities.maxTextures;
21978		var maxCubemapSize = capabilities.maxCubemapSize;
21979		var maxTextureSize = capabilities.maxTextureSize;
21980		var maxSamples = capabilities.maxSamples;
21981
21982		var _videoTextures = new WeakMap();
21983		var _canvas;
21984
21985		// cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
21986		// also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
21987		// Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
21988
21989		var useOffscreenCanvas = false;
21990
21991		try {
21992
21993			useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'
21994				&& ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null;
21995
21996		} catch ( err ) {
21997
21998			// Ignore any errors
21999
22000		}
22001
22002		function createCanvas( width, height ) {
22003
22004			// Use OffscreenCanvas when available. Specially needed in web workers
22005
22006			return useOffscreenCanvas ?
22007				new OffscreenCanvas( width, height ) :
22008				document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
22009
22010		}
22011
22012		function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) {
22013
22014			var scale = 1;
22015
22016			// handle case if texture exceeds max size
22017
22018			if ( image.width > maxSize || image.height > maxSize ) {
22019
22020				scale = maxSize / Math.max( image.width, image.height );
22021
22022			}
22023
22024			// only perform resize if necessary
22025
22026			if ( scale < 1 || needsPowerOfTwo === true ) {
22027
22028				// only perform resize for certain image types
22029
22030				if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
22031					( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
22032					( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
22033
22034					var floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor;
22035
22036					var width = floor( scale * image.width );
22037					var height = floor( scale * image.height );
22038
22039					if ( _canvas === undefined ) { _canvas = createCanvas( width, height ); }
22040
22041					// cube textures can't reuse the same canvas
22042
22043					var canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas;
22044
22045					canvas.width = width;
22046					canvas.height = height;
22047
22048					var context = canvas.getContext( '2d' );
22049					context.drawImage( image, 0, 0, width, height );
22050
22051					console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
22052
22053					return canvas;
22054
22055				} else {
22056
22057					if ( 'data' in image ) {
22058
22059						console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
22060
22061					}
22062
22063					return image;
22064
22065				}
22066
22067			}
22068
22069			return image;
22070
22071		}
22072
22073		function isPowerOfTwo( image ) {
22074
22075			return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height );
22076
22077		}
22078
22079		function textureNeedsPowerOfTwo( texture ) {
22080
22081			if ( isWebGL2 ) { return false; }
22082
22083			return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
22084				( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
22085
22086		}
22087
22088		function textureNeedsGenerateMipmaps( texture, supportsMips ) {
22089
22090			return texture.generateMipmaps && supportsMips &&
22091				texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
22092
22093		}
22094
22095		function generateMipmap( target, texture, width, height ) {
22096
22097			_gl.generateMipmap( target );
22098
22099			var textureProperties = properties.get( texture );
22100
22101			// Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11
22102			textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E;
22103
22104		}
22105
22106		function getInternalFormat( internalFormatName, glFormat, glType ) {
22107
22108			if ( isWebGL2 === false ) { return glFormat; }
22109
22110			if ( internalFormatName !== null ) {
22111
22112				if ( _gl[ internalFormatName ] !== undefined ) { return _gl[ internalFormatName ]; }
22113
22114				console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' );
22115
22116			}
22117
22118			var internalFormat = glFormat;
22119
22120			if ( glFormat === 6403 ) {
22121
22122				if ( glType === 5126 ) { internalFormat = 33326; }
22123				if ( glType === 5131 ) { internalFormat = 33325; }
22124				if ( glType === 5121 ) { internalFormat = 33321; }
22125
22126			}
22127
22128			if ( glFormat === 6407 ) {
22129
22130				if ( glType === 5126 ) { internalFormat = 34837; }
22131				if ( glType === 5131 ) { internalFormat = 34843; }
22132				if ( glType === 5121 ) { internalFormat = 32849; }
22133
22134			}
22135
22136			if ( glFormat === 6408 ) {
22137
22138				if ( glType === 5126 ) { internalFormat = 34836; }
22139				if ( glType === 5131 ) { internalFormat = 34842; }
22140				if ( glType === 5121 ) { internalFormat = 32856; }
22141
22142			}
22143
22144			if ( internalFormat === 33325 || internalFormat === 33326 ||
22145				internalFormat === 34842 || internalFormat === 34836 ) {
22146
22147				extensions.get( 'EXT_color_buffer_float' );
22148
22149			}
22150
22151			return internalFormat;
22152
22153		}
22154
22155		// Fallback filters for non-power-of-2 textures
22156
22157		function filterFallback( f ) {
22158
22159			if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) {
22160
22161				return 9728;
22162
22163			}
22164
22165			return 9729;
22166
22167		}
22168
22169		//
22170
22171		function onTextureDispose( event ) {
22172
22173			var texture = event.target;
22174
22175			texture.removeEventListener( 'dispose', onTextureDispose );
22176
22177			deallocateTexture( texture );
22178
22179			if ( texture.isVideoTexture ) {
22180
22181				_videoTextures.delete( texture );
22182
22183			}
22184
22185			info.memory.textures --;
22186
22187		}
22188
22189		function onRenderTargetDispose( event ) {
22190
22191			var renderTarget = event.target;
22192
22193			renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
22194
22195			deallocateRenderTarget( renderTarget );
22196
22197			info.memory.textures --;
22198
22199		}
22200
22201		//
22202
22203		function deallocateTexture( texture ) {
22204
22205			var textureProperties = properties.get( texture );
22206
22207			if ( textureProperties.__webglInit === undefined ) { return; }
22208
22209			_gl.deleteTexture( textureProperties.__webglTexture );
22210
22211			properties.remove( texture );
22212
22213		}
22214
22215		function deallocateRenderTarget( renderTarget ) {
22216
22217			var renderTargetProperties = properties.get( renderTarget );
22218			var textureProperties = properties.get( renderTarget.texture );
22219
22220			if ( ! renderTarget ) { return; }
22221
22222			if ( textureProperties.__webglTexture !== undefined ) {
22223
22224				_gl.deleteTexture( textureProperties.__webglTexture );
22225
22226			}
22227
22228			if ( renderTarget.depthTexture ) {
22229
22230				renderTarget.depthTexture.dispose();
22231
22232			}
22233
22234			if ( renderTarget.isWebGLCubeRenderTarget ) {
22235
22236				for ( var i = 0; i < 6; i ++ ) {
22237
22238					_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
22239					if ( renderTargetProperties.__webglDepthbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); }
22240
22241				}
22242
22243			} else {
22244
22245				_gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
22246				if ( renderTargetProperties.__webglDepthbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); }
22247				if ( renderTargetProperties.__webglMultisampledFramebuffer ) { _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledFramebuffer ); }
22248				if ( renderTargetProperties.__webglColorRenderbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer ); }
22249				if ( renderTargetProperties.__webglDepthRenderbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthRenderbuffer ); }
22250
22251			}
22252
22253			properties.remove( renderTarget.texture );
22254			properties.remove( renderTarget );
22255
22256		}
22257
22258		//
22259
22260		var textureUnits = 0;
22261
22262		function resetTextureUnits() {
22263
22264			textureUnits = 0;
22265
22266		}
22267
22268		function allocateTextureUnit() {
22269
22270			var textureUnit = textureUnits;
22271
22272			if ( textureUnit >= maxTextures ) {
22273
22274				console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures );
22275
22276			}
22277
22278			textureUnits += 1;
22279
22280			return textureUnit;
22281
22282		}
22283
22284		//
22285
22286		function setTexture2D( texture, slot ) {
22287
22288			var textureProperties = properties.get( texture );
22289
22290			if ( texture.isVideoTexture ) { updateVideoTexture( texture ); }
22291
22292			if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
22293
22294				var image = texture.image;
22295
22296				if ( image === undefined ) {
22297
22298					console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' );
22299
22300				} else if ( image.complete === false ) {
22301
22302					console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' );
22303
22304				} else {
22305
22306					uploadTexture( textureProperties, texture, slot );
22307					return;
22308
22309				}
22310
22311			}
22312
22313			state.activeTexture( 33984 + slot );
22314			state.bindTexture( 3553, textureProperties.__webglTexture );
22315
22316		}
22317
22318		function setTexture2DArray( texture, slot ) {
22319
22320			var textureProperties = properties.get( texture );
22321
22322			if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
22323
22324				uploadTexture( textureProperties, texture, slot );
22325				return;
22326
22327			}
22328
22329			state.activeTexture( 33984 + slot );
22330			state.bindTexture( 35866, textureProperties.__webglTexture );
22331
22332		}
22333
22334		function setTexture3D( texture, slot ) {
22335
22336			var textureProperties = properties.get( texture );
22337
22338			if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
22339
22340				uploadTexture( textureProperties, texture, slot );
22341				return;
22342
22343			}
22344
22345			state.activeTexture( 33984 + slot );
22346			state.bindTexture( 32879, textureProperties.__webglTexture );
22347
22348		}
22349
22350		function setTextureCube( texture, slot ) {
22351
22352			if ( texture.image.length !== 6 ) { return; }
22353
22354			var textureProperties = properties.get( texture );
22355
22356			if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
22357
22358				initTexture( textureProperties, texture );
22359
22360				state.activeTexture( 33984 + slot );
22361				state.bindTexture( 34067, textureProperties.__webglTexture );
22362
22363				_gl.pixelStorei( 37440, texture.flipY );
22364
22365				var isCompressed = ( texture && ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ) );
22366				var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
22367
22368				var cubeImage = [];
22369
22370				for ( var i = 0; i < 6; i ++ ) {
22371
22372					if ( ! isCompressed && ! isDataTexture ) {
22373
22374						cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize );
22375
22376					} else {
22377
22378						cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
22379
22380					}
22381
22382				}
22383
22384				var image = cubeImage[ 0 ],
22385					supportsMips = isPowerOfTwo( image ) || isWebGL2,
22386					glFormat = utils.convert( texture.format ),
22387					glType = utils.convert( texture.type ),
22388					glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
22389
22390				setTextureParameters( 34067, texture, supportsMips );
22391
22392				var mipmaps;
22393
22394				if ( isCompressed ) {
22395
22396					for ( var i$1 = 0; i$1 < 6; i$1 ++ ) {
22397
22398						mipmaps = cubeImage[ i$1 ].mipmaps;
22399
22400						for ( var j = 0; j < mipmaps.length; j ++ ) {
22401
22402							var mipmap = mipmaps[ j ];
22403
22404							if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
22405
22406								if ( glFormat !== null ) {
22407
22408									state.compressedTexImage2D( 34069 + i$1, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
22409
22410								} else {
22411
22412									console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' );
22413
22414								}
22415
22416							} else {
22417
22418								state.texImage2D( 34069 + i$1, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
22419
22420							}
22421
22422						}
22423
22424					}
22425
22426					textureProperties.__maxMipLevel = mipmaps.length - 1;
22427
22428				} else {
22429
22430					mipmaps = texture.mipmaps;
22431
22432					for ( var i$2 = 0; i$2 < 6; i$2 ++ ) {
22433
22434						if ( isDataTexture ) {
22435
22436							state.texImage2D( 34069 + i$2, 0, glInternalFormat, cubeImage[ i$2 ].width, cubeImage[ i$2 ].height, 0, glFormat, glType, cubeImage[ i$2 ].data );
22437
22438							for ( var j$1 = 0; j$1 < mipmaps.length; j$1 ++ ) {
22439
22440								var mipmap$1 = mipmaps[ j$1 ];
22441								var mipmapImage = mipmap$1.image[ i$2 ].image;
22442
22443								state.texImage2D( 34069 + i$2, j$1 + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data );
22444
22445							}
22446
22447						} else {
22448
22449							state.texImage2D( 34069 + i$2, 0, glInternalFormat, glFormat, glType, cubeImage[ i$2 ] );
22450
22451							for ( var j$2 = 0; j$2 < mipmaps.length; j$2 ++ ) {
22452
22453								var mipmap$2 = mipmaps[ j$2 ];
22454
22455								state.texImage2D( 34069 + i$2, j$2 + 1, glInternalFormat, glFormat, glType, mipmap$2.image[ i$2 ] );
22456
22457							}
22458
22459						}
22460
22461					}
22462
22463					textureProperties.__maxMipLevel = mipmaps.length;
22464
22465				}
22466
22467				if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
22468
22469					// We assume images for cube map have the same size.
22470					generateMipmap( 34067, texture, image.width, image.height );
22471
22472				}
22473
22474				textureProperties.__version = texture.version;
22475
22476				if ( texture.onUpdate ) { texture.onUpdate( texture ); }
22477
22478			} else {
22479
22480				state.activeTexture( 33984 + slot );
22481				state.bindTexture( 34067, textureProperties.__webglTexture );
22482
22483			}
22484
22485		}
22486
22487		function setTextureCubeDynamic( texture, slot ) {
22488
22489			state.activeTexture( 33984 + slot );
22490			state.bindTexture( 34067, properties.get( texture ).__webglTexture );
22491
22492		}
22493
22494		var wrappingToGL = {};
22495		wrappingToGL[ RepeatWrapping ] = 10497;
22496		wrappingToGL[ ClampToEdgeWrapping ] = 33071;
22497		wrappingToGL[ MirroredRepeatWrapping ] = 33648;
22498
22499		var filterToGL = {};
22500		filterToGL[ NearestFilter ] = 9728;
22501		filterToGL[ NearestMipmapNearestFilter ] = 9984;
22502		filterToGL[ NearestMipmapLinearFilter ] = 9986;
22503		filterToGL[ LinearFilter ] = 9729;
22504		filterToGL[ LinearMipmapNearestFilter ] = 9985;
22505		filterToGL[ LinearMipmapLinearFilter ] = 9987;
22506
22507		function setTextureParameters( textureType, texture, supportsMips ) {
22508
22509			if ( supportsMips ) {
22510
22511				_gl.texParameteri( textureType, 10242, wrappingToGL[ texture.wrapS ] );
22512				_gl.texParameteri( textureType, 10243, wrappingToGL[ texture.wrapT ] );
22513
22514				if ( textureType === 32879 || textureType === 35866 ) {
22515
22516					_gl.texParameteri( textureType, 32882, wrappingToGL[ texture.wrapR ] );
22517
22518				}
22519
22520				_gl.texParameteri( textureType, 10240, filterToGL[ texture.magFilter ] );
22521				_gl.texParameteri( textureType, 10241, filterToGL[ texture.minFilter ] );
22522
22523			} else {
22524
22525				_gl.texParameteri( textureType, 10242, 33071 );
22526				_gl.texParameteri( textureType, 10243, 33071 );
22527
22528				if ( textureType === 32879 || textureType === 35866 ) {
22529
22530					_gl.texParameteri( textureType, 32882, 33071 );
22531
22532				}
22533
22534				if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {
22535
22536					console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' );
22537
22538				}
22539
22540				_gl.texParameteri( textureType, 10240, filterFallback( texture.magFilter ) );
22541				_gl.texParameteri( textureType, 10241, filterFallback( texture.minFilter ) );
22542
22543				if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {
22544
22545					console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' );
22546
22547				}
22548
22549			}
22550
22551			var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
22552
22553			if ( extension ) {
22554
22555				if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) { return; }
22556				if ( texture.type === HalfFloatType && ( isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) { return; }
22557
22558				if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
22559
22560					_gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );
22561					properties.get( texture ).__currentAnisotropy = texture.anisotropy;
22562
22563				}
22564
22565			}
22566
22567		}
22568
22569		function initTexture( textureProperties, texture ) {
22570
22571			if ( textureProperties.__webglInit === undefined ) {
22572
22573				textureProperties.__webglInit = true;
22574
22575				texture.addEventListener( 'dispose', onTextureDispose );
22576
22577				textureProperties.__webglTexture = _gl.createTexture();
22578
22579				info.memory.textures ++;
22580
22581			}
22582
22583		}
22584
22585		function uploadTexture( textureProperties, texture, slot ) {
22586
22587			var textureType = 3553;
22588
22589			if ( texture.isDataTexture2DArray ) { textureType = 35866; }
22590			if ( texture.isDataTexture3D ) { textureType = 32879; }
22591
22592			initTexture( textureProperties, texture );
22593
22594			state.activeTexture( 33984 + slot );
22595			state.bindTexture( textureType, textureProperties.__webglTexture );
22596
22597			_gl.pixelStorei( 37440, texture.flipY );
22598			_gl.pixelStorei( 37441, texture.premultiplyAlpha );
22599			_gl.pixelStorei( 3317, texture.unpackAlignment );
22600
22601			var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;
22602			var image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize );
22603
22604			var supportsMips = isPowerOfTwo( image ) || isWebGL2,
22605				glFormat = utils.convert( texture.format );
22606
22607			var glType = utils.convert( texture.type ),
22608				glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
22609
22610			setTextureParameters( textureType, texture, supportsMips );
22611
22612			var mipmap;
22613			var mipmaps = texture.mipmaps;
22614
22615			if ( texture.isDepthTexture ) {
22616
22617				// populate depth texture with dummy data
22618
22619				glInternalFormat = 6402;
22620
22621				if ( isWebGL2 ) {
22622
22623					if ( texture.type === FloatType ) {
22624
22625						glInternalFormat = 36012;
22626
22627					} else if ( texture.type === UnsignedIntType ) {
22628
22629						glInternalFormat = 33190;
22630
22631					} else if ( texture.type === UnsignedInt248Type ) {
22632
22633						glInternalFormat = 35056;
22634
22635					} else {
22636
22637						glInternalFormat = 33189; // WebGL2 requires sized internalformat for glTexImage2D
22638
22639					}
22640
22641				} else {
22642
22643					if ( texture.type === FloatType ) {
22644
22645						console.error( 'WebGLRenderer: Floating point depth texture requires WebGL2.' );
22646
22647					}
22648
22649				}
22650
22651				// validation checks for WebGL 1
22652
22653				if ( texture.format === DepthFormat && glInternalFormat === 6402 ) {
22654
22655					// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
22656					// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
22657					// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
22658					if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {
22659
22660						console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );
22661
22662						texture.type = UnsignedShortType;
22663						glType = utils.convert( texture.type );
22664
22665					}
22666
22667				}
22668
22669				if ( texture.format === DepthStencilFormat && glInternalFormat === 6402 ) {
22670
22671					// Depth stencil textures need the DEPTH_STENCIL internal format
22672					// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
22673					glInternalFormat = 34041;
22674
22675					// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
22676					// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
22677					// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
22678					if ( texture.type !== UnsignedInt248Type ) {
22679
22680						console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );
22681
22682						texture.type = UnsignedInt248Type;
22683						glType = utils.convert( texture.type );
22684
22685					}
22686
22687				}
22688
22689				//
22690
22691				state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null );
22692
22693			} else if ( texture.isDataTexture ) {
22694
22695				// use manually created mipmaps if available
22696				// if there are no manual mipmaps
22697				// set 0 level mipmap and then use GL to generate other mipmap levels
22698
22699				if ( mipmaps.length > 0 && supportsMips ) {
22700
22701					for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
22702
22703						mipmap = mipmaps[ i ];
22704						state.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
22705
22706					}
22707
22708					texture.generateMipmaps = false;
22709					textureProperties.__maxMipLevel = mipmaps.length - 1;
22710
22711				} else {
22712
22713					state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data );
22714					textureProperties.__maxMipLevel = 0;
22715
22716				}
22717
22718			} else if ( texture.isCompressedTexture ) {
22719
22720				for ( var i$1 = 0, il$1 = mipmaps.length; i$1 < il$1; i$1 ++ ) {
22721
22722					mipmap = mipmaps[ i$1 ];
22723
22724					if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
22725
22726						if ( glFormat !== null ) {
22727
22728							state.compressedTexImage2D( 3553, i$1, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
22729
22730						} else {
22731
22732							console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );
22733
22734						}
22735
22736					} else {
22737
22738						state.texImage2D( 3553, i$1, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
22739
22740					}
22741
22742				}
22743
22744				textureProperties.__maxMipLevel = mipmaps.length - 1;
22745
22746			} else if ( texture.isDataTexture2DArray ) {
22747
22748				state.texImage3D( 35866, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
22749				textureProperties.__maxMipLevel = 0;
22750
22751			} else if ( texture.isDataTexture3D ) {
22752
22753				state.texImage3D( 32879, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
22754				textureProperties.__maxMipLevel = 0;
22755
22756			} else {
22757
22758				// regular Texture (image, video, canvas)
22759
22760				// use manually created mipmaps if available
22761				// if there are no manual mipmaps
22762				// set 0 level mipmap and then use GL to generate other mipmap levels
22763
22764				if ( mipmaps.length > 0 && supportsMips ) {
22765
22766					for ( var i$2 = 0, il$2 = mipmaps.length; i$2 < il$2; i$2 ++ ) {
22767
22768						mipmap = mipmaps[ i$2 ];
22769						state.texImage2D( 3553, i$2, glInternalFormat, glFormat, glType, mipmap );
22770
22771					}
22772
22773					texture.generateMipmaps = false;
22774					textureProperties.__maxMipLevel = mipmaps.length - 1;
22775
22776				} else {
22777
22778					state.texImage2D( 3553, 0, glInternalFormat, glFormat, glType, image );
22779					textureProperties.__maxMipLevel = 0;
22780
22781				}
22782
22783			}
22784
22785			if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
22786
22787				generateMipmap( textureType, texture, image.width, image.height );
22788
22789			}
22790
22791			textureProperties.__version = texture.version;
22792
22793			if ( texture.onUpdate ) { texture.onUpdate( texture ); }
22794
22795		}
22796
22797		// Render targets
22798
22799		// Setup storage for target texture and bind it to correct framebuffer
22800		function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {
22801
22802			var glFormat = utils.convert( renderTarget.texture.format );
22803			var glType = utils.convert( renderTarget.texture.type );
22804			var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
22805			state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
22806			_gl.bindFramebuffer( 36160, framebuffer );
22807			_gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
22808			_gl.bindFramebuffer( 36160, null );
22809
22810		}
22811
22812		// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
22813		function setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) {
22814
22815			_gl.bindRenderbuffer( 36161, renderbuffer );
22816
22817			if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
22818
22819				var glInternalFormat = 33189;
22820
22821				if ( isMultisample ) {
22822
22823					var depthTexture = renderTarget.depthTexture;
22824
22825					if ( depthTexture && depthTexture.isDepthTexture ) {
22826
22827						if ( depthTexture.type === FloatType ) {
22828
22829							glInternalFormat = 36012;
22830
22831						} else if ( depthTexture.type === UnsignedIntType ) {
22832
22833							glInternalFormat = 33190;
22834
22835						}
22836
22837					}
22838
22839					var samples = getRenderTargetSamples( renderTarget );
22840
22841					_gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
22842
22843				} else {
22844
22845					_gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height );
22846
22847				}
22848
22849				_gl.framebufferRenderbuffer( 36160, 36096, 36161, renderbuffer );
22850
22851			} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
22852
22853				if ( isMultisample ) {
22854
22855					var samples$1 = getRenderTargetSamples( renderTarget );
22856
22857					_gl.renderbufferStorageMultisample( 36161, samples$1, 35056, renderTarget.width, renderTarget.height );
22858
22859				} else {
22860
22861					_gl.renderbufferStorage( 36161, 34041, renderTarget.width, renderTarget.height );
22862
22863				}
22864
22865
22866				_gl.framebufferRenderbuffer( 36160, 33306, 36161, renderbuffer );
22867
22868			} else {
22869
22870				var glFormat = utils.convert( renderTarget.texture.format );
22871				var glType = utils.convert( renderTarget.texture.type );
22872				var glInternalFormat$1 = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
22873
22874				if ( isMultisample ) {
22875
22876					var samples$2 = getRenderTargetSamples( renderTarget );
22877
22878					_gl.renderbufferStorageMultisample( 36161, samples$2, glInternalFormat$1, renderTarget.width, renderTarget.height );
22879
22880				} else {
22881
22882					_gl.renderbufferStorage( 36161, glInternalFormat$1, renderTarget.width, renderTarget.height );
22883
22884				}
22885
22886			}
22887
22888			_gl.bindRenderbuffer( 36161, null );
22889
22890		}
22891
22892		// Setup resources for a Depth Texture for a FBO (needs an extension)
22893		function setupDepthTexture( framebuffer, renderTarget ) {
22894
22895			var isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget );
22896			if ( isCube ) { throw new Error( 'Depth Texture with cube render targets is not supported' ); }
22897
22898			_gl.bindFramebuffer( 36160, framebuffer );
22899
22900			if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
22901
22902				throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' );
22903
22904			}
22905
22906			// upload an empty depth texture with framebuffer size
22907			if ( ! properties.get( renderTarget.depthTexture ).__webglTexture ||
22908					renderTarget.depthTexture.image.width !== renderTarget.width ||
22909					renderTarget.depthTexture.image.height !== renderTarget.height ) {
22910
22911				renderTarget.depthTexture.image.width = renderTarget.width;
22912				renderTarget.depthTexture.image.height = renderTarget.height;
22913				renderTarget.depthTexture.needsUpdate = true;
22914
22915			}
22916
22917			setTexture2D( renderTarget.depthTexture, 0 );
22918
22919			var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
22920
22921			if ( renderTarget.depthTexture.format === DepthFormat ) {
22922
22923				_gl.framebufferTexture2D( 36160, 36096, 3553, webglDepthTexture, 0 );
22924
22925			} else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
22926
22927				_gl.framebufferTexture2D( 36160, 33306, 3553, webglDepthTexture, 0 );
22928
22929			} else {
22930
22931				throw new Error( 'Unknown depthTexture format' );
22932
22933			}
22934
22935		}
22936
22937		// Setup GL resources for a non-texture depth buffer
22938		function setupDepthRenderbuffer( renderTarget ) {
22939
22940			var renderTargetProperties = properties.get( renderTarget );
22941
22942			var isCube = ( renderTarget.isWebGLCubeRenderTarget === true );
22943
22944			if ( renderTarget.depthTexture ) {
22945
22946				if ( isCube ) { throw new Error( 'target.depthTexture not supported in Cube render targets' ); }
22947
22948				setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );
22949
22950			} else {
22951
22952				if ( isCube ) {
22953
22954					renderTargetProperties.__webglDepthbuffer = [];
22955
22956					for ( var i = 0; i < 6; i ++ ) {
22957
22958						_gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer[ i ] );
22959						renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
22960						setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false );
22961
22962					}
22963
22964				} else {
22965
22966					_gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );
22967					renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
22968					setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false );
22969
22970				}
22971
22972			}
22973
22974			_gl.bindFramebuffer( 36160, null );
22975
22976		}
22977
22978		// Set up GL resources for the render target
22979		function setupRenderTarget( renderTarget ) {
22980
22981			var renderTargetProperties = properties.get( renderTarget );
22982			var textureProperties = properties.get( renderTarget.texture );
22983
22984			renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
22985
22986			textureProperties.__webglTexture = _gl.createTexture();
22987
22988			info.memory.textures ++;
22989
22990			var isCube = ( renderTarget.isWebGLCubeRenderTarget === true );
22991			var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true );
22992			var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2;
22993
22994			// Handles WebGL2 RGBFormat fallback - #18858
22995
22996			if ( isWebGL2 && renderTarget.texture.format === RGBFormat && ( renderTarget.texture.type === FloatType || renderTarget.texture.type === HalfFloatType ) ) {
22997
22998				renderTarget.texture.format = RGBAFormat;
22999
23000				console.warn( 'THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead.' );
23001
23002			}
23003
23004			// Setup framebuffer
23005
23006			if ( isCube ) {
23007
23008				renderTargetProperties.__webglFramebuffer = [];
23009
23010				for ( var i = 0; i < 6; i ++ ) {
23011
23012					renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
23013
23014				}
23015
23016			} else {
23017
23018				renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
23019
23020				if ( isMultisample ) {
23021
23022					if ( isWebGL2 ) {
23023
23024						renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();
23025						renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer();
23026
23027						_gl.bindRenderbuffer( 36161, renderTargetProperties.__webglColorRen
23027derbuffer );
23028
23029						var glFormat = utils.convert( renderTarget.texture.format );
23030						var glType = utils.convert( renderTarget.texture.type );
23031						var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
23032						var samples = getRenderTargetSamples( renderTarget );
23033						_gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
23034
23035						_gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );
23036						_gl.framebufferRenderbuffer( 36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer );
23037						_gl.bindRenderbuffer( 36161, null );
23038
23039						if ( renderTarget.depthBuffer ) {
23040
23041							renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();
23042							setupRenderBufferStorage( renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true );
23043
23044						}
23045
23046						_gl.bindFramebuffer( 36160, null );
23047
23048
23049					} else {
23050
23051						console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );
23052
23053					}
23054
23055				}
23056
23057			}
23058
23059			// Setup color buffer
23060
23061			if ( isCube ) {
23062
23063				state.bindTexture( 34067, textureProperties.__webglTexture );
23064				setTextureParameters( 34067, renderTarget.texture, supportsMips );
23065
23066				for ( var i$1 = 0; i$1 < 6; i$1 ++ ) {
23067
23068					setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i$1 ], renderTarget, 36064, 34069 + i$1 );
23069
23070				}
23071
23072				if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
23073
23074					generateMipmap( 34067, renderTarget.texture, renderTarget.width, renderTarget.height );
23075
23076				}
23077
23078				state.bindTexture( 34067, null );
23079
23080			} else {
23081
23082				state.bindTexture( 3553, textureProperties.__webglTexture );
23083				setTextureParameters( 3553, renderTarget.texture, supportsMips );
23084				setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, 36064, 3553 );
23085
23086				if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
23087
23088					generateMipmap( 3553, renderTarget.texture, renderTarget.width, renderTarget.height );
23089
23090				}
23091
23092				state.bindTexture( 3553, null );
23093
23094			}
23095
23096			// Setup depth and stencil buffers
23097
23098			if ( renderTarget.depthBuffer ) {
23099
23100				setupDepthRenderbuffer( renderTarget );
23101
23102			}
23103
23104		}
23105
23106		function updateRenderTargetMipmap( renderTarget ) {
23107
23108			var texture = renderTarget.texture;
23109			var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2;
23110
23111			if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
23112
23113				var target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553;
23114				var webglTexture = properties.get( texture ).__webglTexture;
23115
23116				state.bindTexture( target, webglTexture );
23117				generateMipmap( target, texture, renderTarget.width, renderTarget.height );
23118				state.bindTexture( target, null );
23119
23120			}
23121
23122		}
23123
23124		function updateMultisampleRenderTarget( renderTarget ) {
23125
23126			if ( renderTarget.isWebGLMultisampleRenderTarget ) {
23127
23128				if ( isWebGL2 ) {
23129
23130					var renderTargetProperties = properties.get( renderTarget );
23131
23132					_gl.bindFramebuffer( 36008, renderTargetProperties.__webglMultisampledFramebuffer );
23133					_gl.bindFramebuffer( 36009, renderTargetProperties.__webglFramebuffer );
23134
23135					var width = renderTarget.width;
23136					var height = renderTarget.height;
23137					var mask = 16384;
23138
23139					if ( renderTarget.depthBuffer ) { mask |= 256; }
23140					if ( renderTarget.stencilBuffer ) { mask |= 1024; }
23141
23142					_gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, 9728 );
23143
23144					_gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer ); // see #18905
23145
23146				} else {
23147
23148					console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );
23149
23150				}
23151
23152			}
23153
23154		}
23155
23156		function getRenderTargetSamples( renderTarget ) {
23157
23158			return ( isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ?
23159				Math.min( maxSamples, renderTarget.samples ) : 0;
23160
23161		}
23162
23163		function updateVideoTexture( texture ) {
23164
23165			var frame = info.render.frame;
23166
23167			// Check the last frame we updated the VideoTexture
23168
23169			if ( _videoTextures.get( texture ) !== frame ) {
23170
23171				_videoTextures.set( texture, frame );
23172				texture.update();
23173
23174			}
23175
23176		}
23177
23178		// backwards compatibility
23179
23180		var warnedTexture2D = false;
23181		var warnedTextureCube = false;
23182
23183		function safeSetTexture2D( texture, slot ) {
23184
23185			if ( texture && texture.isWebGLRenderTarget ) {
23186
23187				if ( warnedTexture2D === false ) {
23188
23189					console.warn( "THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead." );
23190					warnedTexture2D = true;
23191
23192				}
23193
23194				texture = texture.texture;
23195
23196			}
23197
23198			setTexture2D( texture, slot );
23199
23200		}
23201
23202		function safeSetTextureCube( texture, slot ) {
23203
23204			if ( texture && texture.isWebGLCubeRenderTarget ) {
23205
23206				if ( warnedTextureCube === false ) {
23207
23208					console.warn( "THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
23209					warnedTextureCube = true;
23210
23211				}
23212
23213				texture = texture.texture;
23214
23215			}
23216
23217			// currently relying on the fact that WebGLCubeRenderTarget.texture is a Texture and NOT a CubeTexture
23218			// TODO: unify these code paths
23219			if ( ( texture && texture.isCubeTexture ) ||
23220				( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
23221
23222				// CompressedTexture can have Array in image :/
23223
23224				// this function alone should take care of cube textures
23225				setTextureCube( texture, slot );
23226
23227			} else {
23228
23229				// assumed: texture property of THREE.WebGLCubeRenderTarget
23230				setTextureCubeDynamic( texture, slot );
23231
23232			}
23233
23234		}
23235
23236		//
23237
23238		this.allocateTextureUnit = allocateTextureUnit;
23239		this.resetTextureUnits = resetTextureUnits;
23240
23241		this.setTexture2D = setTexture2D;
23242		this.setTexture2DArray = setTexture2DArray;
23243		this.setTexture3D = setTexture3D;
23244		this.setTextureCube = setTextureCube;
23245		this.setTextureCubeDynamic = setTextureCubeDynamic;
23246		this.setupRenderTarget = setupRenderTarget;
23247		this.updateRenderTargetMipmap = updateRenderTargetMipmap;
23248		this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
23249
23250		this.safeSetTexture2D = safeSetTexture2D;
23251		this.safeSetTextureCube = safeSetTextureCube;
23252
23253	}
23254
23255	/**
23256	 * @author thespite / http://www.twitter.com/thespite
23257	 */
23258
23259	function WebGLUtils( gl, extensions, capabilities ) {
23260
23261		var isWebGL2 = capabilities.isWebGL2;
23262
23263		function convert( p ) {
23264
23265			var extension;
23266
23267			if ( p === UnsignedByteType ) { return 5121; }
23268			if ( p === UnsignedShort4444Type ) { return 32819; }
23269			if ( p === UnsignedShort5551Type ) { return 32820; }
23270			if ( p === UnsignedShort565Type ) { return 33635; }
23271
23272			if ( p === ByteType ) { return 5120; }
23273			if ( p === ShortType ) { return 5122; }
23274			if ( p === UnsignedShortType ) { return 5123; }
23275			if ( p === IntType ) { return 5124; }
23276			if ( p === UnsignedIntType ) { return 5125; }
23277			if ( p === FloatType ) { return 5126; }
23278
23279			if ( p === HalfFloatType ) {
23280
23281				if ( isWebGL2 ) { return 5131; }
23282
23283				extension = extensions.get( 'OES_texture_half_float' );
23284
23285				if ( extension !== null ) {
23286
23287					return extension.HALF_FLOAT_OES;
23288
23289				} else {
23290
23291					return null;
23292
23293				}
23294
23295			}
23296
23297			if ( p === AlphaFormat ) { return 6406; }
23298			if ( p === RGBFormat ) { return 6407; }
23299			if ( p === RGBAFormat ) { return 6408; }
23300			if ( p === LuminanceFormat ) { return 6409; }
23301			if ( p === LuminanceAlphaFormat ) { return 6410; }
23302			if ( p === DepthFormat ) { return 6402; }
23303			if ( p === DepthStencilFormat ) { return 34041; }
23304			if ( p === RedFormat ) { return 6403; }
23305
23306			// WebGL2 formats.
23307
23308			if ( p === RedIntegerFormat ) { return 36244; }
23309			if ( p === RGFormat ) { return 33319; }
23310			if ( p === RGIntegerFormat ) { return 33320; }
23311			if ( p === RGBIntegerFormat ) { return 36248; }
23312			if ( p === RGBAIntegerFormat ) { return 36249; }
23313
23314			if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
23315				p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
23316
23317				extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
23318
23319				if ( extension !== null ) {
23320
23321					if ( p === RGB_S3TC_DXT1_Format ) { return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; }
23322					if ( p === RGBA_S3TC_DXT1_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; }
23323					if ( p === RGBA_S3TC_DXT3_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; }
23324					if ( p === RGBA_S3TC_DXT5_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; }
23325
23326				} else {
23327
23328					return null;
23329
23330				}
23331
23332			}
23333
23334			if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
23335				p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
23336
23337				extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
23338
23339				if ( extension !== null ) {
23340
23341					if ( p === RGB_PVRTC_4BPPV1_Format ) { return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; }
23342					if ( p === RGB_PVRTC_2BPPV1_Format ) { return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; }
23343					if ( p === RGBA_PVRTC_4BPPV1_Format ) { return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; }
23344					if ( p === RGBA_PVRTC_2BPPV1_Format ) { return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; }
23345
23346				} else {
23347
23348					return null;
23349
23350				}
23351
23352			}
23353
23354			if ( p === RGB_ETC1_Format ) {
23355
23356				extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
23357
23358				if ( extension !== null ) {
23359
23360					return extension.COMPRESSED_RGB_ETC1_WEBGL;
23361
23362				} else {
23363
23364					return null;
23365
23366				}
23367
23368			}
23369
23370			if ( p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) {
23371
23372				extension = extensions.get( 'WEBGL_compressed_texture_etc' );
23373
23374				if ( extension !== null ) {
23375
23376					if ( p === RGB_ETC2_Format ) { return extension.COMPRESSED_RGB8_ETC2; }
23377					if ( p === RGBA_ETC2_EAC_Format ) { return extension.COMPRESSED_RGBA8_ETC2_EAC; }
23378
23379				}
23380
23381			}
23382
23383			if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format ||
23384				p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format ||
23385				p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format ||
23386				p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format ||
23387				p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ||
23388				p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format ||
23389				p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format ||
23390				p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format ||
23391				p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format ||
23392				p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format ) {
23393
23394				extension = extensions.get( 'WEBGL_compressed_texture_astc' );
23395
23396				if ( extension !== null ) {
23397
23398					// TODO Complete?
23399
23400					return p;
23401
23402				} else {
23403
23404					return null;
23405
23406				}
23407
23408			}
23409
23410			if ( p === RGBA_BPTC_Format ) {
23411
23412				extension = extensions.get( 'EXT_texture_compression_bptc' );
23413
23414				if ( extension !== null ) {
23415
23416					// TODO Complete?
23417
23418					return p;
23419
23420				} else {
23421
23422					return null;
23423
23424				}
23425
23426			}
23427
23428			if ( p === UnsignedInt248Type ) {
23429
23430				if ( isWebGL2 ) { return 34042; }
23431
23432				extension = extensions.get( 'WEBGL_depth_texture' );
23433
23434				if ( extension !== null ) {
23435
23436					return extension.UNSIGNED_INT_24_8_WEBGL;
23437
23438				} else {
23439
23440					return null;
23441
23442				}
23443
23444			}
23445
23446		}
23447
23448		return { convert: convert };
23449
23450	}
23451
23452	/**
23453	 * @author mrdoob / http://mrdoob.com/
23454	 */
23455
23456	function ArrayCamera( array ) {
23457
23458		PerspectiveCamera.call( this );
23459
23460		this.cameras = array || [];
23461
23462	}
23463
23464	ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), {
23465
23466		constructor: ArrayCamera,
23467
23468		isArrayCamera: true
23469
23470	} );
23471
23472	/**
23473	 * @author mrdoob / http://mrdoob.com/
23474	 */
23475
23476	function Group() {
23477
23478		Object3D.call( this );
23479
23480		this.type = 'Group';
23481
23482	}
23483
23484	Group.prototype = Object.assign( Object.create( Object3D.prototype ), {
23485
23486		constructor: Group,
23487
23488		isGroup: true
23489
23490	} );
23491
23492	/**
23493	 * @author Mugen87 / https://github.com/Mugen87
23494	 */
23495
23496	function WebXRController() {
23497
23498		this._targetRay = null;
23499		this._grip = null;
23500
23501	}
23502
23503	Object.assign( WebXRController.prototype, {
23504
23505		constructor: WebXRController,
23506
23507		getTargetRaySpace: function () {
23508
23509			if ( this._targetRay === null ) {
23510
23511				this._targetRay = new Group();
23512				this._targetRay.matrixAutoUpdate = false;
23513				this._targetRay.visible = false;
23514
23515			}
23516
23517			return this._targetRay;
23518
23519		},
23520
23521		getGripSpace: function () {
23522
23523			if ( this._grip === null ) {
23524
23525				this._grip = new Group();
23526				this._grip.matrixAutoUpdate = false;
23527				this._grip.visible = false;
23528
23529			}
23530
23531			return this._grip;
23532
23533		},
23534
23535		dispatchEvent: function ( event ) {
23536
23537			if ( this._targetRay !== null ) {
23538
23539				this._targetRay.dispatchEvent( event );
23540
23541			}
23542
23543			if ( this._grip !== null ) {
23544
23545				this._grip.dispatchEvent( event );
23546
23547			}
23548
23549			return this;
23550
23551		},
23552
23553		disconnect: function ( inputSource ) {
23554
23555			this.dispatchEvent( { type: 'disconnected', data: inputSource } );
23556
23557			if ( this._targetRay !== null ) {
23558
23559				this._targetRay.visible = false;
23560
23561			}
23562
23563			if ( this._grip !== null ) {
23564
23565				this._grip.visible = false;
23566
23567			}
23568
23569			return this;
23570
23571		},
23572
23573		update: function ( inputSource, frame, referenceSpace ) {
23574
23575			var inputPose = null;
23576			var gripPose = null;
23577
23578			var targetRay = this._targetRay;
23579			var grip = this._grip;
23580
23581			if ( inputSource ) {
23582
23583				if ( targetRay !== null ) {
23584
23585					inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace );
23586
23587					if ( inputPose !== null ) {
23588
23589						targetRay.matrix.fromArray( inputPose.transform.matrix );
23590						targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale );
23591
23592					}
23593
23594				}
23595
23596				if ( grip !== null && inputSource.gripSpace ) {
23597
23598					gripPose = frame.getPose( inputSource.gripSpace, referenceSpace );
23599
23600					if ( gripPose !== null ) {
23601
23602						grip.matrix.fromArray( gripPose.transform.matrix );
23603						grip.matrix.decompose( grip.position, grip.rotation, grip.scale );
23604
23605					}
23606
23607				}
23608
23609			}
23610
23611			if ( targetRay !== null ) {
23612
23613				targetRay.visible = ( inputPose !== null );
23614
23615			}
23616
23617			if ( grip !== null ) {
23618
23619				grip.visible = ( gripPose !== null );
23620
23621			}
23622
23623			return this;
23624
23625		}
23626
23627	} );
23628
23629	/**
23630	 * @author mrdoob / http://mrdoob.com/
23631	 */
23632
23633	function WebXRManager( renderer, gl ) {
23634
23635		var scope = this;
23636
23637		var session = null;
23638
23639		var framebufferScaleFactor = 1.0;
23640
23641		var referenceSpace = null;
23642		var referenceSpaceType = 'local-floor';
23643
23644		var pose = null;
23645
23646		var controllers = [];
23647		var inputSourcesMap = new Map();
23648
23649		//
23650
23651		var cameraL = new PerspectiveCamera();
23652		cameraL.layers.enable( 1 );
23653		cameraL.viewport = new Vector4();
23654
23655		var cameraR = new PerspectiveCamera();
23656		cameraR.layers.enable( 2 );
23657		cameraR.viewport = new Vector4();
23658
23659		var cameras = [ cameraL, cameraR ];
23660
23661		var cameraVR = new ArrayCamera();
23662		cameraVR.layers.enable( 1 );
23663		cameraVR.layers.enable( 2 );
23664
23665		var _currentDepthNear = null;
23666		var _currentDepthFar = null;
23667
23668		//
23669
23670		this.enabled = false;
23671
23672		this.isPresenting = false;
23673
23674		this.getController = function ( index ) {
23675
23676			var controller = controllers[ index ];
23677
23678			if ( controller === undefined ) {
23679
23680				controller = new WebXRController();
23681				controllers[ index ] = controller;
23682
23683			}
23684
23685			return controller.getTargetRaySpace();
23686
23687		};
23688
23689		this.getControllerGrip = function ( index ) {
23690
23691			var controller = controllers[ index ];
23692
23693			if ( controller === undefined ) {
23694
23695				controller = new WebXRController();
23696				controllers[ index ] = controller;
23697
23698			}
23699
23700			return controller.getGripSpace();
23701
23702		};
23703
23704		//
23705
23706		function onSessionEvent( event ) {
23707
23708			var controller = inputSourcesMap.get( event.inputSource );
23709
23710			if ( controller ) {
23711
23712				controller.dispatchEvent( { type: event.type } );
23713
23714			}
23715
23716		}
23717
23718		function onSessionEnd() {
23719
23720			inputSourcesMap.forEach( function ( controller, inputSource ) {
23721
23722				controller.disconnect( inputSource );
23723
23724			} );
23725
23726			inputSourcesMap.clear();
23727
23728			//
23729
23730			renderer.setFramebuffer( null );
23731			renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
23732			animation.stop();
23733
23734			scope.isPresenting = false;
23735
23736			scope.dispatchEvent( { type: 'sessionend' } );
23737
23738		}
23739
23740		function onRequestReferenceSpace( value ) {
23741
23742			referenceSpace = value;
23743
23744			animation.setContext( session );
23745			animation.start();
23746
23747			scope.isPresenting = true;
23748
23749			scope.dispatchEvent( { type: 'sessionstart' } );
23750
23751		}
23752
23753		this.setFramebufferScaleFactor = function ( value ) {
23754
23755			framebufferScaleFactor = value;
23756
23757			if ( scope.isPresenting === true ) {
23758
23759				console.warn( 'THREE.WebXRManager: Cannot change framebuffer scale while presenting.' );
23760
23761			}
23762
23763		};
23764
23765		this.setReferenceSpaceType = function ( value ) {
23766
23767			referenceSpaceType = value;
23768
23769			if ( scope.isPresenting === true ) {
23770
23771				console.warn( 'THREE.WebXRManager: Cannot change reference space type while presenting.' );
23772
23773			}
23774
23775		};
23776
23777		this.getReferenceSpace = function () {
23778
23779			return referenceSpace;
23780
23781		};
23782
23783		this.getSession = function () {
23784
23785			return session;
23786
23787		};
23788
23789		this.setSession = function ( value ) {
23790
23791			session = value;
23792
23793			if ( session !== null ) {
23794
23795				session.addEventListener( 'select', onSessionEvent );
23796				session.addEventListener( 'selectstart', onSessionEvent );
23797				session.addEventListener( 'selectend', onSessionEvent );
23798				session.addEventListener( 'squeeze', onSessionEvent );
23799				session.addEventListener( 'squeezestart', onSessionEvent );
23800				session.addEventListener( 'squeezeend', onSessionEvent );
23801				session.addEventListener( 'end', onSessionEnd );
23802
23803				var attributes = gl.getContextAttributes();
23804
23805				if ( attributes.xrCompatible !== true ) {
23806
23807					gl.makeXRCompatible();
23808
23809				}
23810
23811				var layerInit = {
23812					antialias: attributes.antialias,
23813					alpha: attributes.alpha,
23814					depth: attributes.depth,
23815					stencil: attributes.stencil,
23816					framebufferScaleFactor: framebufferScaleFactor
23817				};
23818
23819				// eslint-disable-next-line no-undef
23820				var baseLayer = new XRWebGLLayer( session, gl, layerInit );
23821
23822				session.updateRenderState( { baseLayer: baseLayer } );
23823
23824				session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace );
23825
23826				//
23827
23828				session.addEventListener( 'inputsourceschange', updateInputSources );
23829
23830			}
23831
23832		};
23833
23834		function updateInputSources( event ) {
23835
23836			var inputSources = session.inputSources;
23837
23838			// Assign inputSources to available controllers
23839
23840			for ( var i = 0; i < controllers.length; i ++ ) {
23841
23842				inputSourcesMap.set( inputSources[ i ], controllers[ i ] );
23843
23844			}
23845
23846			// Notify disconnected
23847
23848			for ( var i$1 = 0; i$1 < event.removed.length; i$1 ++ ) {
23849
23850				var inputSource = event.removed[ i$1 ];
23851				var controller = inputSourcesMap.get( inputSource );
23852
23853				if ( controller ) {
23854
23855					controller.dispatchEvent( { type: 'disconnected', data: inputSource } );
23856					inputSourcesMap.delete( inputSource );
23857
23858				}
23859
23860			}
23861
23862			// Notify connected
23863
23864			for ( var i$2 = 0; i$2 < event.added.length; i$2 ++ ) {
23865
23866				var inputSource$1 = event.added[ i$2 ];
23867				var controller$1 = inputSourcesMap.get( inputSource$1 );
23868
23869				if ( controller$1 ) {
23870
23871					controller$1.dispatchEvent( { type: 'connected', data: inputSource$1 } );
23872
23873				}
23874
23875			}
23876
23877		}
23878
23879		//
23880
23881		var cameraLPos = new Vector3();
23882		var cameraRPos = new Vector3();
23883
23884		/**
23885		 * @author jsantell / https://www.jsantell.com/
23886		 *
23887		 * Assumes 2 cameras that are parallel and share an X-axis, and that
23888		 * the cameras' projection and world matrices have already been set.
23889		 * And that near and far planes are identical for both cameras.
23890		 * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
23891		 */
23892		function setProjectionFromUnion( camera, cameraL, cameraR ) {
23893
23894			cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
23895			cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
23896
23897			var ipd = cameraLPos.distanceTo( cameraRPos );
23898
23899			var projL = cameraL.projectionMatrix.elements;
23900			var projR = cameraR.projectionMatrix.elements;
23901
23902			// VR systems will have identical far and near planes, and
23903			// most likely identical top and bottom frustum extents.
23904			// Use the left camera for these values.
23905			var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
23906			var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
23907			var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];
23908			var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];
23909
23910			var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
23911			var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
23912			var left = near * leftFov;
23913			var right = near * rightFov;
23914
23915			// Calculate the new camera's position offset from the
23916			// left camera. xOffset should be roughly half `ipd`.
23917			var zOffset = ipd / ( - leftFov + rightFov );
23918			var xOffset = zOffset * - leftFov;
23919
23920			// TODO: Better way to apply this offset?
23921			cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
23922			camera.translateX( xOffset );
23923			camera.translateZ( zOffset );
23924			camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale );
23925			camera.matrixWorldInverse.getInverse( camera.matrixWorld );
23926
23927			// Find the union of the frustum values of the cameras and scale
23928			// the values so that the near plane's position does not change in world space,
23929			// although must now be relative to the new union camera.
23930			var near2 = near + zOffset;
23931			var far2 = far + zOffset;
23932			var left2 = left - xOffset;
23933			var right2 = right + ( ipd - xOffset );
23934			var top2 = topFov * far / far2 * near2;
23935			var bottom2 = bottomFov * far / far2 * near2;
23936
23937			camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
23938
23939		}
23940
23941		function updateCamera( camera, parent ) {
23942
23943			if ( parent === null ) {
23944
23945				camera.matrixWorld.copy( camera.matrix );
23946
23947			} else {
23948
23949				camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );
23950
23951			}
23952
23953			camera.matrixWorldInverse.getInverse( camera.matrixWorld );
23954
23955		}
23956
23957		this.getCamera = function ( camera ) {
23958
23959			cameraVR.near = cameraR.near = cameraL.near = camera.near;
23960			cameraVR.far = cameraR.far = cameraL.far = camera.far;
23961
23962			if ( _currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far ) {
23963
23964				// Note that the new renderState won't apply until the next frame. See #18320
23965
23966				session.updateRenderState( {
23967					depthNear: cameraVR.near,
23968					depthFar: cameraVR.far
23969				} );
23970
23971				_currentDepthNear = cameraVR.near;
23972				_currentDepthFar = cameraVR.far;
23973
23974			}
23975
23976			var parent = camera.parent;
23977			var cameras = cameraVR.cameras;
23978
23979			updateCamera( cameraVR, parent );
23980
23981			for ( var i = 0; i < cameras.length; i ++ ) {
23982
23983				updateCamera( cameras[ i ], parent );
23984
23985			}
23986
23987			// update camera and its children
23988
23989			camera.matrixWorld.copy( cameraVR.matrixWorld );
23990
23991			var children = camera.children;
23992
23993			for ( var i$1 = 0, l = children.length; i$1 < l; i$1 ++ ) {
23994
23995				children[ i$1 ].updateMatrixWorld( true );
23996
23997			}
23998
23999			// update projection matrix for proper view frustum culling
24000
24001			if ( cameras.length === 2 ) {
24002
24003				setProjectionFromUnion( cameraVR, cameraL, cameraR );
24004
24005			} else {
24006
24007				// assume single camera setup (AR)
24008
24009				cameraVR.projectionMatrix.copy( cameraL.projectionMatrix );
24010
24011			}
24012
24013			return cameraVR;
24014
24015		};
24016
24017		// Animation Loop
24018
24019		var onAnimationFrameCallback = null;
24020
24021		function onAnimationFrame( time, frame ) {
24022
24023			pose = frame.getViewerPose( referenceSpace );
24024
24025			if ( pose !== null ) {
24026
24027				var views = pose.views;
24028				var baseLayer = session.renderState.baseLayer;
24029
24030				renderer.setFramebuffer( baseLayer.framebuffer );
24031
24032				var cameraVRNeedsUpdate = false;
24033
24034				// check if it's necessary to rebuild cameraVR's camera list
24035
24036				if ( views.length !== cameraVR.cameras.length ) {
24037
24038					cameraVR.cameras.length = 0;
24039					cameraVRNeedsUpdate = true;
24040
24041				}
24042
24043				for ( var i = 0; i < views.length; i ++ ) {
24044
24045					var view = views[ i ];
24046					var viewport = baseLayer.getViewport( view );
24047
24048					var camera = cameras[ i ];
24049					camera.matrix.fromArray( view.transform.matrix );
24050					camera.projectionMatrix.fromArray( view.projectionMatrix );
24051					camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
24052
24053					if ( i === 0 ) {
24054
24055						cameraVR.matrix.copy( camera.matrix );
24056
24057					}
24058
24059					if ( cameraVRNeedsUpdate === true ) {
24060
24061						cameraVR.cameras.push( camera );
24062
24063					}
24064
24065				}
24066
24067			}
24068
24069			//
24070
24071			var inputSources = session.inputSources;
24072
24073			for ( var i$1 = 0; i$1 < controllers.length; i$1 ++ ) {
24074
24075				var controller = controllers[ i$1 ];
24076				var inputSource = inputSources[ i$1 ];
24077
24078				controller.update( inputSource, frame, referenceSpace );
24079
24080			}
24081
24082			if ( onAnimationFrameCallback ) { onAnimationFrameCallback( time, frame ); }
24083
24084		}
24085
24086		var animation = new WebGLAnimation();
24087		animation.setAnimationLoop( onAnimationFrame );
24088
24089		this.setAnimationLoop = function ( callback ) {
24090
24091			onAnimationFrameCallback = callback;
24092
24093		};
24094
24095		this.dispose = function () {};
24096
24097	}
24098
24099	Object.assign( WebXRManager.prototype, EventDispatcher.prototype );
24100
24101	/**
24102	 * @author mrdoob / http://mrdoob.com/
24103	 */
24104
24105	function WebGLMaterials( properties ) {
24106
24107		function refreshFogUniforms( uniforms, fog ) {
24108
24109			uniforms.fogColor.value.copy( fog.color );
24110
24111			if ( fog.isFog ) {
24112
24113				uniforms.fogNear.value = fog.near;
24114				uniforms.fogFar.value = fog.far;
24115
24116			} else if ( fog.isFogExp2 ) {
24117
24118				uniforms.fogDensity.value = fog.density;
24119
24120			}
24121
24122		}
24123
24124		function refreshMaterialUniforms( uniforms, material, environment, pixelRatio, height ) {
24125
24126			if ( material.isMeshBasicMaterial ) {
24127
24128				refreshUniformsCommon( uniforms, material );
24129
24130			} else if ( material.isMeshLambertMaterial ) {
24131
24132				refreshUniformsCommon( uniforms, material );
24133				refreshUniformsLambert( uniforms, material );
24134
24135			} else if ( material.isMeshToonMaterial ) {
24136
24137				refreshUniformsCommon( uniforms, material );
24138				refreshUniformsToon( uniforms, material );
24139
24140			} else if ( material.isMeshPhongMaterial ) {
24141
24142				refreshUniformsCommon( uniforms, material );
24143				refreshUniformsPhong( uniforms, material );
24144
24145			} else if ( material.isMeshStandardMaterial ) {
24146
24147				refreshUniformsCommon( uniforms, material, environment );
24148
24149				if ( material.isMeshPhysicalMaterial ) {
24150
24151					refreshUniformsPhysical( uniforms, material, environment );
24152
24153				} else {
24154
24155					refreshUniformsStandard( uniforms, material, environment );
24156
24157				}
24158
24159			}
vendor: 13,266 bytes, lines 24159-24767
24159 else if ( material.isMeshMatcapMaterial ) {
24160
24161				refreshUniformsCommon( uniforms, material );
24162				refreshUniformsMatcap( uniforms, material );
24163
24164			} else if ( material.isMeshDepthMaterial ) {
24165
24166				refreshUniformsCommon( uniforms, material );
24167				refreshUniformsDepth( uniforms, material );
24168
24169			} else if ( material.isMeshDistanceMaterial ) {
24170
24171				refreshUniformsCommon( uniforms, material );
24172				refreshUniformsDistance( uniforms, material );
24173
24174			} else if ( material.isMeshNormalMaterial ) {
24175
24176				refreshUniformsCommon( uniforms, material );
24177				refreshUniformsNormal( uniforms, material );
24178
24179			} else if ( material.isLineBasicMaterial ) {
24180
24181				refreshUniformsLine( uniforms, material );
24182
24183				if ( material.isLineDashedMaterial ) {
24184
24185					refreshUniformsDash( uniforms, material );
24186
24187				}
24188
24189			} else if ( material.isPointsMaterial ) {
24190
24191				refreshUniformsPoints( uniforms, material, pixelRatio, height );
24192
24193			} else if ( material.isSpriteMaterial ) {
24194
24195				refreshUniformsSprites( uniforms, material );
24196
24197			} else if ( material.isShadowMaterial ) {
24198
24199				uniforms.color.value.copy( material.color );
24200				uniforms.opacity.value = material.opacity;
24201
24202			} else if ( material.isShaderMaterial ) {
24203
24204				material.uniformsNeedUpdate = false; // #15581
24205
24206			}
24207
24208		}
24209
24210		function refreshUniformsCommon( uniforms, material, environment ) {
24211
24212			uniforms.opacity.value = material.opacity;
24213
24214			if ( material.color ) {
24215
24216				uniforms.diffuse.value.copy( material.color );
24217
24218			}
24219
24220			if ( material.emissive ) {
24221
24222				uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
24223
24224			}
24225
24226			if ( material.map ) {
24227
24228				uniforms.map.value = material.map;
24229
24230			}
24231
24232			if ( material.alphaMap ) {
24233
24234				uniforms.alphaMap.value = material.alphaMap;
24235
24236			}
24237
24238			if ( material.specularMap ) {
24239
24240				uniforms.specularMap.value = material.specularMap;
24241
24242			}
24243
24244			var envMap = material.envMap || environment;
24245
24246			if ( envMap ) {
24247
24248				uniforms.envMap.value = envMap;
24249
24250				uniforms.flipEnvMap.value = envMap.isCubeTexture ? - 1 : 1;
24251
24252				uniforms.reflectivity.value = material.reflectivity;
24253				uniforms.refractionRatio.value = material.refractionRatio;
24254
24255				uniforms.maxMipLevel.value = properties.get( envMap ).__maxMipLevel;
24256
24257			}
24258
24259			if ( material.lightMap ) {
24260
24261				uniforms.lightMap.value = material.lightMap;
24262				uniforms.lightMapIntensity.value = material.lightMapIntensity;
24263
24264			}
24265
24266			if ( material.aoMap ) {
24267
24268				uniforms.aoMap.value = material.aoMap;
24269				uniforms.aoMapIntensity.value = material.aoMapIntensity;
24270
24271			}
24272
24273			// uv repeat and offset setting priorities
24274			// 1. color map
24275			// 2. specular map
24276			// 3. normal map
24277			// 4. bump map
24278			// 5. alpha map
24279			// 6. emissive map
24280
24281			var uvScaleMap;
24282
24283			if ( material.map ) {
24284
24285				uvScaleMap = material.map;
24286
24287			} else if ( material.specularMap ) {
24288
24289				uvScaleMap = material.specularMap;
24290
24291			} else if ( material.displacementMap ) {
24292
24293				uvScaleMap = material.displacementMap;
24294
24295			} else if ( material.normalMap ) {
24296
24297				uvScaleMap = material.normalMap;
24298
24299			} else if ( material.bumpMap ) {
24300
24301				uvScaleMap = material.bumpMap;
24302
24303			} else if ( material.roughnessMap ) {
24304
24305				uvScaleMap = material.roughnessMap;
24306
24307			} else if ( material.metalnessMap ) {
24308
24309				uvScaleMap = material.metalnessMap;
24310
24311			} else if ( material.alphaMap ) {
24312
24313				uvScaleMap = material.alphaMap;
24314
24315			} else if ( material.emissiveMap ) {
24316
24317				uvScaleMap = material.emissiveMap;
24318
24319			}
24320
24321			if ( uvScaleMap !== undefined ) {
24322
24323				// backwards compatibility
24324				if ( uvScaleMap.isWebGLRenderTarget ) {
24325
24326					uvScaleMap = uvScaleMap.texture;
24327
24328				}
24329
24330				if ( uvScaleMap.matrixAutoUpdate === true ) {
24331
24332					uvScaleMap.updateMatrix();
24333
24334				}
24335
24336				uniforms.uvTransform.value.copy( uvScaleMap.matrix );
24337
24338			}
24339
24340			// uv repeat and offset setting priorities for uv2
24341			// 1. ao map
24342			// 2. light map
24343
24344			var uv2ScaleMap;
24345
24346			if ( material.aoMap ) {
24347
24348				uv2ScaleMap = material.aoMap;
24349
24350			} else if ( material.lightMap ) {
24351
24352				uv2ScaleMap = material.lightMap;
24353
24354			}
24355
24356			if ( uv2ScaleMap !== undefined ) {
24357
24358				// backwards compatibility
24359				if ( uv2ScaleMap.isWebGLRenderTarget ) {
24360
24361					uv2ScaleMap = uv2ScaleMap.texture;
24362
24363				}
24364
24365				if ( uv2ScaleMap.matrixAutoUpdate === true ) {
24366
24367					uv2ScaleMap.updateMatrix();
24368
24369				}
24370
24371				uniforms.uv2Transform.value.copy( uv2ScaleMap.matrix );
24372
24373			}
24374
24375		}
24376
24377		function refreshUniformsLine( uniforms, material ) {
24378
24379			uniforms.diffuse.value.copy( material.color );
24380			uniforms.opacity.value = material.opacity;
24381
24382		}
24383
24384		function refreshUniformsDash( uniforms, material ) {
24385
24386			uniforms.dashSize.value = material.dashSize;
24387			uniforms.totalSize.value = material.dashSize + material.gapSize;
24388			uniforms.scale.value = material.scale;
24389
24390		}
24391
24392		function refreshUniformsPoints( uniforms, material, pixelRatio, height ) {
24393
24394			uniforms.diffuse.value.copy( material.color );
24395			uniforms.opacity.value = material.opacity;
24396			uniforms.size.value = material.size * pixelRatio;
24397			uniforms.scale.value = height * 0.5;
24398
24399			if ( material.map ) {
24400
24401				uniforms.map.value = material.map;
24402
24403			}
24404
24405			if ( material.alphaMap ) {
24406
24407				uniforms.alphaMap.value = material.alphaMap;
24408
24409			}
24410
24411			// uv repeat and offset setting priorities
24412			// 1. color map
24413			// 2. alpha map
24414
24415			var uvScaleMap;
24416
24417			if ( material.map ) {
24418
24419				uvScaleMap = material.map;
24420
24421			} else if ( material.alphaMap ) {
24422
24423				uvScaleMap = material.alphaMap;
24424
24425			}
24426
24427			if ( uvScaleMap !== undefined ) {
24428
24429				if ( uvScaleMap.matrixAutoUpdate === true ) {
24430
24431					uvScaleMap.updateMatrix();
24432
24433				}
24434
24435				uniforms.uvTransform.value.copy( uvScaleMap.matrix );
24436
24437			}
24438
24439		}
24440
24441		function refreshUniformsSprites( uniforms, material ) {
24442
24443			uniforms.diffuse.value.copy( material.color );
24444			uniforms.opacity.value = material.opacity;
24445			uniforms.rotation.value = material.rotation;
24446
24447			if ( material.map ) {
24448
24449				uniforms.map.value = material.map;
24450
24451			}
24452
24453			if ( material.alphaMap ) {
24454
24455				uniforms.alphaMap.value = material.alphaMap;
24456
24457			}
24458
24459			// uv repeat and offset setting priorities
24460			// 1. color map
24461			// 2. alpha map
24462
24463			var uvScaleMap;
24464
24465			if ( material.map ) {
24466
24467				uvScaleMap = material.map;
24468
24469			} else if ( material.alphaMap ) {
24470
24471				uvScaleMap = material.alphaMap;
24472
24473			}
24474
24475			if ( uvScaleMap !== undefined ) {
24476
24477				if ( uvScaleMap.matrixAutoUpdate === true ) {
24478
24479					uvScaleMap.updateMatrix();
24480
24481				}
24482
24483				uniforms.uvTransform.value.copy( uvScaleMap.matrix );
24484
24485			}
24486
24487		}
24488
24489		function refreshUniformsLambert( uniforms, material ) {
24490
24491			if ( material.emissiveMap ) {
24492
24493				uniforms.emissiveMap.value = material.emissiveMap;
24494
24495			}
24496
24497		}
24498
24499		function refreshUniformsPhong( uniforms, material ) {
24500
24501			uniforms.specular.value.copy( material.specular );
24502			uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
24503
24504			if ( material.emissiveMap ) {
24505
24506				uniforms.emissiveMap.value = material.emissiveMap;
24507
24508			}
24509
24510			if ( material.bumpMap ) {
24511
24512				uniforms.bumpMap.value = material.bumpMap;
24513				uniforms.bumpScale.value = material.bumpScale;
24514				if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24515
24516			}
24517
24518			if ( material.normalMap ) {
24519
24520				uniforms.normalMap.value = material.normalMap;
24521				uniforms.normalScale.value.copy( material.normalScale );
24522				if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24523
24524			}
24525
24526			if ( material.displacementMap ) {
24527
24528				uniforms.displacementMap.value = material.displacementMap;
24529				uniforms.displacementScale.value = material.displacementScale;
24530				uniforms.displacementBias.value = material.displacementBias;
24531
24532			}
24533
24534		}
24535
24536		function refreshUniformsToon( uniforms, material ) {
24537
24538			if ( material.gradientMap ) {
24539
24540				uniforms.gradientMap.value = material.gradientMap;
24541
24542			}
24543
24544			if ( material.emissiveMap ) {
24545
24546				uniforms.emissiveMap.value = material.emissiveMap;
24547
24548			}
24549
24550			if ( material.bumpMap ) {
24551
24552				uniforms.bumpMap.value = material.bumpMap;
24553				uniforms.bumpScale.value = material.bumpScale;
24554				if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24555
24556			}
24557
24558			if ( material.normalMap ) {
24559
24560				uniforms.normalMap.value = material.normalMap;
24561				uniforms.normalScale.value.copy( material.normalScale );
24562				if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24563
24564			}
24565
24566			if ( material.displacementMap ) {
24567
24568				uniforms.displacementMap.value = material.displacementMap;
24569				uniforms.displacementScale.value = material.displacementScale;
24570				uniforms.displacementBias.value = material.displacementBias;
24571
24572			}
24573
24574		}
24575
24576		function refreshUniformsStandard( uniforms, material, environment ) {
24577
24578			uniforms.roughness.value = material.roughness;
24579			uniforms.metalness.value = material.metalness;
24580
24581			if ( material.roughnessMap ) {
24582
24583				uniforms.roughnessMap.value = material.roughnessMap;
24584
24585			}
24586
24587			if ( material.metalnessMap ) {
24588
24589				uniforms.metalnessMap.value = material.metalnessMap;
24590
24591			}
24592
24593			if ( material.emissiveMap ) {
24594
24595				uniforms.emissiveMap.value = material.emissiveMap;
24596
24597			}
24598
24599			if ( material.bumpMap ) {
24600
24601				uniforms.bumpMap.value = material.bumpMap;
24602				uniforms.bumpScale.value = material.bumpScale;
24603				if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24604
24605			}
24606
24607			if ( material.normalMap ) {
24608
24609				uniforms.normalMap.value = material.normalMap;
24610				uniforms.normalScale.value.copy( material.normalScale );
24611				if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24612
24613			}
24614
24615			if ( material.displacementMap ) {
24616
24617				uniforms.displacementMap.value = material.displacementMap;
24618				uniforms.displacementScale.value = material.displacementScale;
24619				uniforms.displacementBias.value = material.displacementBias;
24620
24621			}
24622
24623			if ( material.envMap || environment ) {
24624
24625				//uniforms.envMap.value = material.envMap; // part of uniforms common
24626				uniforms.envMapIntensity.value = material.envMapIntensity;
24627
24628			}
24629
24630		}
24631
24632		function refreshUniformsPhysical( uniforms, material, environment ) {
24633
24634			refreshUniformsStandard( uniforms, material, environment );
24635
24636			uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common
24637
24638			uniforms.clearcoat.value = material.clearcoat;
24639			uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
24640			if ( material.sheen ) { uniforms.sheen.value.copy( material.sheen ); }
24641
24642			if ( material.clearcoatMap ) {
24643
24644				uniforms.clearcoatMap.value = material.clearcoatMap;
24645
24646			}
24647
24648			if ( material.clearcoatRoughnessMap ) {
24649
24650				uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;
24651
24652			}
24653
24654			if ( material.clearcoatNormalMap ) {
24655
24656				uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale );
24657				uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
24658
24659				if ( material.side === BackSide ) {
24660
24661					uniforms.clearcoatNormalScale.value.negate();
24662
24663				}
24664
24665			}
24666
24667			uniforms.transparency.value = material.transparency;
24668
24669		}
24670
24671		function refreshUniformsMatcap( uniforms, material ) {
24672
24673			if ( material.matcap ) {
24674
24675				uniforms.matcap.value = material.matcap;
24676
24677			}
24678
24679			if ( material.bumpMap ) {
24680
24681				uniforms.bumpMap.value = material.bumpMap;
24682				uniforms.bumpScale.value = material.bumpScale;
24683				if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24684
24685			}
24686
24687			if ( material.normalMap ) {
24688
24689				uniforms.normalMap.value = material.normalMap;
24690				uniforms.normalScale.value.copy( material.normalScale );
24691				if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24692
24693			}
24694
24695			if ( material.displacementMap ) {
24696
24697				uniforms.displacementMap.value = material.displacementMap;
24698				uniforms.displacementScale.value = material.displacementScale;
24699				uniforms.displacementBias.value = material.displacementBias;
24700
24701			}
24702
24703		}
24704
24705		function refreshUniformsDepth( uniforms, material ) {
24706
24707			if ( material.displacementMap ) {
24708
24709				uniforms.displacementMap.value = material.displacementMap;
24710				uniforms.displacementScale.value = material.displacementScale;
24711				uniforms.displacementBias.value = material.displacementBias;
24712
24713			}
24714
24715		}
24716
24717		function refreshUniformsDistance( uniforms, material ) {
24718
24719			if ( material.displacementMap ) {
24720
24721				uniforms.displacementMap.value = material.displacementMap;
24722				uniforms.displacementScale.value = material.displacementScale;
24723				uniforms.displacementBias.value = material.displacementBias;
24724
24725			}
24726
24727			uniforms.referencePosition.value.copy( material.referencePosition );
24728			uniforms.nearDistance.value = material.nearDistance;
24729			uniforms.farDistance.value = material.farDistance;
24730
24731		}
24732
24733		function refreshUniformsNormal( uniforms, material ) {
24734
24735			if ( material.bumpMap ) {
24736
24737				uniforms.bumpMap.value = material.bumpMap;
24738				uniforms.bumpScale.value = material.bumpScale;
24739				if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24740
24741			}
24742
24743			if ( material.normalMap ) {
24744
24745				uniforms.normalMap.value = material.normalMap;
24746				uniforms.normalScale.value.copy( material.normalScale );
24747				if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24748
24749			}
24750
24751			if ( material.displacementMap ) {
24752
24753				uniforms.displacementMap.value = material.displacementMap;
24754				uniforms.displacementScale.value = material.displacementScale;
24755				uniforms.displacementBias.value = material.displacementBias;
24756
24757			}
24758
24759		}
24760
24761		return {
24762			refreshFogUniforms: refreshFogUniforms,
24763			refreshMaterialUniforms: refreshMaterialUniforms
24764		};
24765
24766	}
24767
24768	/**
24769	 * @author supereggbert / http://www.paulbrunt.co.uk/
24770	 * @author mrdoob / http://mrdoob.com/
24771	 * @author alteredq / http://alteredqualia.com/
24772	 * @author szimek / https://github.com/szimek/
24773	 * @author tschw
24774	 */
24775
24776	function WebGLRenderer( parameters ) {
24777
24778		parameters = parameters || {};
24779
24780		var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
24781			_context = parameters.context !== undefined ? parameters.context : null,
24782
24783			_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
24784			_depth = parameters.depth !== undefined ? parameters.depth : true,
24785			_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
24786			_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
24787			_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
24788			_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
24789			_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',
24790			_failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;
24791
24792		var currentRenderList = null;
24793		var currentRenderState = null;
24794
24795		// public properties
24796
24797		this.domElement = _canvas;
24798
24799		// Debug configuration container
24800		this.debug = {
24801
24802			/**
24803			 * Enables error checking and reporting when shader programs are being compiled
24804			 * @type {boolean}
24805			 */
24806			checkShaderErrors: true
24807		};
24808
24809		// clearing
24810
24811		this.autoClear = true;
24812		this.autoClearColor = true;
24813		this.autoClearDepth = true;
24814		this.autoClearStencil = true;
24815
24816		// scene graph
24817
24818		this.sortObjects = true;
24819
24820		// user-defined clipping
24821
24822		this.clippingPlanes = [];
24823		this.localClippingEnabled = false;
24824
24825		// physically based shading
24826
24827		this.gammaFactor = 2.0;	// for backwards compatibility
24828		this.outputEncoding = LinearEncoding;
24829
24830		// physical lights
24831
24832		this.physicallyCorrectLights = false;
24833
24834		// tone mapping
24835
24836		this.toneMapping = NoToneMapping;
24837		this.toneMappingExposure = 1.0;
24838
24839		// morphs
24840
24841		this.maxMorphTargets = 8;
24842		this.maxMorphNormals = 4;
24843
24844		// internal properties
24845
24846		var _this = this;
24847
24848		var _isContextLost = false;
24849
24850		// internal state cache
24851
24852		var _framebuffer = null;
24853
24854		var _currentActiveCubeFace = 0;
24855		var _currentActiveMipmapLevel = 0;
24856		var _currentRenderTarget = null;
24857		var _currentFramebuffer = null;
24858		var _currentMaterialId = - 1;
24859
24860		var _currentCamera = null;
24861		var _currentArrayCamera = null;
24862
24863		var _currentViewport = new Vector4();
24864		var _currentScissor = new Vector4();
24865		var _currentScissorTest = null;
24866
24867		//
24868
24869		var _width = _canvas.width;
24870		var _height = _canvas.height;
24871
24872		var _pixelRatio = 1;
24873		var _opaqueSort = null;
24874		var _transparentSort = null;
24875
24876		var _viewport = new Vector4( 0, 0, _width, _height );
24877		var _scissor = new Vector4( 0, 0, _width, _height );
24878		var _scissorTest = false;
24879
24880		// frustum
24881
24882		var _frustum = new Frustum();
24883
24884		// clipping
24885
24886		var _clipping = new WebGLClipping();
24887		var _clippingEnabled = false;
24888		var _localClippingEnabled = false;
24889
24890		// camera matrices cache
24891
24892		var _projScreenMatrix = new Matrix4();
24893
24894		var _vector3 = new Vector3();
24895
24896		var _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true };
24897
24898		function getTargetPixelRatio() {
24899
24900			return _currentRenderTarget === null ? _pixelRatio : 1;
24901
24902		}
24903
24904		// initialize
24905
24906		var _gl = _context;
24907
24908		function getContext( contextNames, contextAttributes ) {
24909
24910			for ( var i = 0; i < contextNames.length; i ++ ) {
24911
24912				var contextName = contextNames[ i ];
24913				var context = _canvas.getContext( contextName, contextAttributes );
24914				if ( context !== null ) { return context; }
24915
24916			}
24917
24918			return null;
24919
24920		}
24921
24922		try {
24923
24924			var contextAttributes = {
24925				alpha: _alpha,
24926				depth: _depth,
24927				stencil: _stencil,
24928				antialias: _antialias,
24929				premultipliedAlpha: _premultipliedAlpha,
24930				preserveDrawingBuffer: _preserveDrawingBuffer,
24931				powerPreference: _powerPreference,
24932				failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat
24933			};
24934
24935			// event listeners must be registered before WebGL context is created, see #12753
24936
24937			_canvas.addEventListener( 'webglcontextlost', onContextLost, false );
24938			_canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
24939
24940			if ( _gl === null ) {
24941
24942				var contextNames = [ 'webgl2', 'webgl', 'experimental-webgl' ];
24943
24944				if ( _this.isWebGL1Renderer === true ) {
24945
24946					contextNames.shift();
24947
24948				}
24949
24950				_gl = getContext( contextNames, contextAttributes );
24951
24952				if ( _gl === null ) {
24953
24954					if ( getContext( contextNames ) ) {
24955
24956						throw new Error( 'Error creating WebGL context with your selected attributes.' );
24957
24958					} else {
24959
24960						throw new Error( 'Error creating WebGL context.' );
24961
24962					}
24963
24964				}
24965
24966			}
24967
24968			// Some experimental-webgl implementations do not have getShaderPrecisionFormat
24969
24970			if ( _gl.getShaderPrecisionFormat === undefined ) {
24971
24972				_gl.getShaderPrecisionFormat = function () {
24973
24974					return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };
24975
24976				};
24977
24978			}
24979
24980		} catch ( error ) {
24981
24982			console.error( 'THREE.WebGLRenderer: ' + error.message );
24983			throw error;
24984
24985		}
24986
24987		var extensions, capabilities, state, info;
24988		var properties, textures, attributes, geometries, objects;
24989		var programCache, materials, renderLists, renderStates;
24990
24991		var background, morphtargets, bufferRenderer, indexedBufferRenderer;
24992
24993		var utils, bindingStates;
24994
24995		function initGLContext() {
24996
24997			extensions = new WebGLExtensions( _gl );
24998
24999			capabilities = new WebGLCapabilities( _gl, extensions, parameters );
25000
25001			if ( capabilities.isWebGL2 === false ) {
25002
25003				extensions.get( 'WEBGL_depth_texture' );
25004				extensions.get( 'OES_texture_float' );
25005				extensions.get( 'OES_texture_half_float' );
25006				extensions.get( 'OES_texture_half_float_linear' );
25007				extensions.get( 'OES_standard_derivatives' );
25008				extensions.get( 'OES_element_index_uint' );
25009				extensions.get( 'OES_vertex_array_object' );
25010				extensions.get( 'ANGLE_instanced_arrays' );
25011
25012			}
25013
25014			extensions.get( 'OES_texture_float_linear' );
25015
25016			utils = new WebGLUtils( _gl, extensions, capabilities );
25017
25018			state = new WebGLState( _gl, extensions, capabilities );
25019			state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
25020			state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
25021
25022			info = new WebGLInfo( _gl );
25023			properties = new WebGLProperties();
25024			textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
25025			attributes = new WebGLAttributes( _gl, capabilities );
25026			bindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities );
25027			geometries = new WebGLGeometries( _gl, attributes, info, bindingStates );
25028			objects = new WebGLObjects( _gl, geometries, attributes, info );
25029			morphtargets = new WebGLMorphtargets( _gl );
25030			programCache = new WebGLPrograms( _this, extensions, capabilities, bindingStates );
25031			materials = new WebGLMaterials( properties );
25032			renderLists = new WebGLRenderLists();
25033			renderStates = new WebGLRenderStates();
25034
25035			background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
25036
25037			bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );
25038			indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );
25039
25040			info.programs = programCache.programs;
25041
25042			_this.capabilities = capabilities;
25043			_this.extensions = extensions;
25044			_this.properties = properties;
25045			_this.renderLists = renderLists;
25046			_this.state = state;
25047			_this.info = info;
25048
25049		}
25050
25051		initGLContext();
25052
25053		// xr
25054
25055		var xr = new WebXRManager( _this, _gl );
25056
25057		this.xr = xr;
25058
25059		// shadow map
25060
25061		var shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize );
25062
25063		this.shadowMap = shadowMap;
25064
25065		// API
25066
25067		this.getContext = function () {
25068
25069			return _gl;
25070
25071		};
25072
25073		this.getContextAttributes = function () {
25074
25075			return _gl.getContextAttributes();
25076
25077		};
25078
25079		this.forceContextLoss = function () {
25080
25081			var extension = extensions.get( 'WEBGL_lose_context' );
25082			if ( extension ) { extension.loseContext(); }
25083
25084		};
25085
25086		this.forceContextRestore = function () {
25087
25088			var extension = extensions.get( 'WEBGL_lose_context' );
25089			if ( extension ) { extension.restoreContext(); }
25090
25091		};
25092
25093		this.getPixelRatio = function () {
25094
25095			return _pixelRatio;
25096
25097		};
25098
25099		this.setPixelRatio = function ( value ) {
25100
25101			if ( value === undefined ) { return; }
25102
25103			_pixelRatio = value;
25104
25105			this.setSize( _width, _height, false );
25106
25107		};
25108
25109		this.getSize = function ( target ) {
25110
25111			if ( target === undefined ) {
25112
25113				console.warn( 'WebGLRenderer: .getsize() now requires a Vector2 as an argument' );
25114
25115				target = new Vector2();
25116
25117			}
25118
25119			return target.set( _width, _height );
25120
25121		};
25122
25123		this.setSize = function ( width, height, updateStyle ) {
25124
25125			if ( xr.isPresenting ) {
25126
25127				console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' );
25128				return;
25129
25130			}
25131
25132			_width = width;
25133			_height = height;
25134
25135			_canvas.width = Math.floor( width * _pixelRatio );
25136			_canvas.height = Math.floor( height * _pixelRatio );
25137
25138			if ( updateStyle !== false ) {
25139
25140				_canvas.style.width = width + 'px';
25141				_canvas.style.height = height + 'px';
25142
25143			}
25144
25145			this.setViewport( 0, 0, width, height );
25146
25147		};
25148
25149		this.getDrawingBufferSize = function ( target ) {
25150
25151			if ( target === undefined ) {
25152
25153				console.warn( 'WebGLRenderer: .getdrawingBufferSize() now requires a Vector2 as an argument' );
25154
25155				target = new Vector2();
25156
25157			}
25158
25159			return target.set( _width * _pixelRatio, _height * _pixelRatio ).floor();
25160
25161		};
25162
25163		this.setDrawingBufferSize = function ( width, height, pixelRatio ) {
25164
25165			_width = width;
25166			_height = height;
25167
25168			_pixelRatio = pixelRatio;
25169
25170			_canvas.width = Math.floor( width * pixelRatio );
25171			_canvas.height = Math.floor( height * pixelRatio );
25172
25173			this.setViewport( 0, 0, width, height );
25174
25175		};
25176
25177		this.getCurrentViewport = function ( target ) {
25178
25179			if ( target === undefined ) {
25180
25181				console.warn( 'WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument' );
25182
25183				target = new Vector4();
25184
25185			}
25186
25187			return target.copy( _currentViewport );
25188
25189		};
25190
25191		this.getViewport = function ( target ) {
25192
25193			return target.copy( _viewport );
25194
25195		};
25196
25197		this.setViewport = function ( x, y, width, height ) {
25198
25199			if ( x.isVector4 ) {
25200
25201				_viewport.set( x.x, x.y, x.z, x.w );
25202
25203			} else {
25204
25205				_viewport.set( x, y, width, height );
25206
25207			}
25208
25209			state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
25210
25211		};
25212
25213		this.getScissor = function ( target ) {
25214
25215			return target.copy( _scissor );
25216
25217		};
25218
25219		this.setScissor = function ( x, y, width, height ) {
25220
25221			if ( x.isVector4 ) {
25222
25223				_scissor.set( x.x, x.y, x.z, x.w );
25224
25225			} else {
25226
25227				_scissor.set( x, y, width, height );
25228
25229			}
25230
25231			state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
25232
25233		};
25234
25235		this.getScissorTest = function () {
25236
25237			return _scissorTest;
25238
25239		};
25240
25241		this.setScissorTest = function ( boolean ) {
25242
25243			state.setScissorTest( _scissorTest = boolean );
25244
25245		};
25246
25247		this.setOpaqueSort = function ( method ) {
25248
25249			_opaqueSort = method;
25250
25251		};
25252
25253		this.setTransparentSort = function ( method ) {
25254
25255			_transparentSort = method;
25256
25257		};
25258
25259		// Clearing
25260
25261		this.getClearColor = function () {
25262
25263			return background.getClearColor();
25264
25265		};
25266
25267		this.setClearColor = function () {
25268
25269			background.setClearColor.apply( background, arguments );
25270
25271		};
25272
25273		this.getClearAlpha = function () {
25274
25275			return background.getClearAlpha();
25276
25277		};
25278
25279		this.setClearAlpha = function () {
25280
25281			background.setClearAlpha.apply( background, arguments );
25282
25283		};
25284
25285		this.clear = function ( color, depth, stencil ) {
25286
25287			var bits = 0;
25288
25289			if ( color === undefined || color ) { bits |= 16384; }
25290			if ( depth === undefined || depth ) { bits |= 256; }
25291			if ( stencil === undefined || stencil ) { bits |= 1024; }
25292
25293			_gl.clear( bits );
25294
25295		};
25296
25297		this.clearColor = function () {
25298
25299			this.clear( true, false, false );
25300
25301		};
25302
25303		this.clearDepth = function () {
25304
25305			this.clear( false, true, false );
25306
25307		};
25308
25309		this.clearStencil = function () {
25310
25311			this.clear( false, false, true );
25312
25313		};
25314
25315		//
25316
25317		this.dispose = function () {
25318
25319			_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
25320			_canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false );
25321
25322			renderLists.dispose();
25323			renderStates.dispose();
25324			properties.dispose();
25325			objects.dispose();
25326			bindingStates.dispose();
25327
25328			xr.dispose();
25329
25330			animation.stop();
25331
25332		};
25333
25334		// Events
25335
25336		function onContextLost( event ) {
25337
25338			event.preventDefault();
25339
25340			console.log( 'THREE.WebGLRenderer: Context Lost.' );
25341
25342			_isContextLost = true;
25343
25344		}
25345
25346		function onContextRestore( /* event */ ) {
25347
25348			console.log( 'THREE.WebGLRenderer: Context Restored.' );
25349
25350			_isContextLost = false;
25351
25352			initGLContext();
25353
25354		}
25355
25356		function onMaterialDispose( event ) {
25357
25358			var material = event.target;
25359
25360			material.removeEventListener( 'dispose', onMaterialDispose );
25361
25362			deallocateMaterial( material );
25363
25364		}
25365
25366		// Buffer deallocation
25367
25368		function deallocateMaterial( material ) {
25369
25370			releaseMaterialProgramReference( material );
25371
25372			properties.remove( material );
25373
25374		}
25375
25376
25377		function releaseMaterialProgramReference( material ) {
25378
25379			var programInfo = properties.get( material ).program;
25380
25381			material.program = undefined;
25382
25383			if ( programInfo !== undefined ) {
25384
25385				programCache.releaseProgram( programInfo );
25386
25387			}
25388
25389		}
25390
25391		// Buffer rendering
25392
25393		function renderObjectImmediate( object, program ) {
25394
25395			object.render( function ( object ) {
25396
25397				_this.renderBufferImmediate( object, program );
25398
25399			} );
25400
25401		}
25402
25403		this.renderBufferImmediate = function ( object, program ) {
25404
25405			bindingStates.initAttributes();
25406
25407			var buffers = properties.get( object );
25408
25409			if ( object.hasPositions && ! buffers.position ) { buffers.position = _gl.createBuffer(); }
25410			if ( object.hasNormals && ! buffers.normal ) { buffers.normal = _gl.createBuffer(); }
25411			if ( object.hasUvs && ! buffers.uv ) { buffers.uv = _gl.createBuffer(); }
25412			if ( object.hasColors && ! buffers.color ) { buffers.color = _gl.createBuffer(); }
25413
25414			var programAttributes = program.getAttributes();
25415
25416			if ( object.hasPositions ) {
25417
25418				_gl.bindBuffer( 34962, buffers.position );
25419				_gl.bufferData( 34962, object.positionArray, 35048 );
25420
25421				bindingStates.enableAttribute( programAttributes.position );
25422				_gl.vertexAttribPointer( programAttributes.position, 3, 5126, false, 0, 0 );
25423
25424			}
25425
25426			if ( object.hasNormals ) {
25427
25428				_gl.bindBuffer( 34962, buffers.normal );
25429				_gl.bufferData( 34962, object.normalArray, 35048 );
25430
25431				bindingStates.enableAttribute( programAttributes.normal );
25432				_gl.vertexAttribPointer( programAttributes.normal, 3, 5126, false, 0, 0 );
25433
25434			}
25435
25436			if ( object.hasUvs ) {
25437
25438				_gl.bindBuffer( 34962, buffers.uv );
25439				_gl.bufferData( 34962, object.uvArray, 35048 );
25440
25441				bindingStates.enableAttribute( programAttributes.uv );
25442				_gl.vertexAttribPointer( programAttributes.uv, 2, 5126, false, 0, 0 );
25443
25444			}
25445
25446			if ( object.hasColors ) {
25447
25448				_gl.bindBuffer( 34962, buffers.color );
25449				_gl.bufferData( 34962, object.colorArray, 35048 );
25450
25451				bindingStates.enableAttribute( programAttributes.color );
25452				_gl.vertexAttribPointer( programAttributes.color, 3, 5126, false, 0, 0 );
25453
25454			}
25455
25456			bindingStates.disableUnusedAttributes();
25457
25458			_gl.drawArrays( 4, 0, object.count );
25459
25460			object.count = 0;
25461
25462		};
25463
25464		this.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) {
25465
25466			if ( scene === null ) { scene = _emptyScene; } // renderBufferDirect second parameter used to be fog (could be null)
25467
25468			var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
25469
25470			var program = setProgram( camera, scene, material, object );
25471
25472			state.setMaterial( material, frontFaceCW );
25473
25474			//
25475
25476			var index = geometry.index;
25477			var position = geometry.attributes.position;
25478
25479			//
25480
25481			if ( index === null ) {
25482
25483				if ( position === undefined || position.count === 0 ) { return; }
25484
25485			} else if ( index.count === 0 ) {
25486
25487				return;
25488
25489			}
25490
25491			//
25492
25493			var rangeFactor = 1;
25494
25495			if ( material.wireframe === true ) {
25496
25497				index = geometries.getWireframeAttribute( geometry );
25498				rangeFactor = 2;
25499
25500			}
25501
25502			if ( material.morphTargets || material.morphNormals ) {
25503
25504				morphtargets.update( object, geometry, material, program );
25505
25506			}
25507
25508			bindingStates.setup( object, material, program, geometry, index );
25509
25510			var attribute;
25511			var renderer = bufferRenderer;
25512
25513			if ( index !== null ) {
25514
25515				attribute = attributes.get( index );
25516
25517				renderer = indexedBufferRenderer;
25518				renderer.setIndex( attribute );
25519
25520			}
25521
25522			//
25523
25524			var dataCount = ( index !== null ) ? index.count : position.count;
25525
25526			var rangeStart = geometry.drawRange.start * rangeFactor;
25527			var rangeCount = geometry.drawRange.count * rangeFactor;
25528
25529			var groupStart = group !== null ? group.start * rangeFactor : 0;
25530			var groupCount = group !== null ? group.count * rangeFactor : Infinity;
25531
25532			var drawStart = Math.max( rangeStart, groupStart );
25533			var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
25534
25535			var drawCount = Math.max( 0, drawEnd - drawStart + 1 );
25536
25537			if ( drawCount === 0 ) { return; }
25538
25539			//
25540
25541			if ( object.isMesh ) {
25542
25543				if ( material.wireframe === true ) {
25544
25545					state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
25546					renderer.setMode( 1 );
25547
25548				} else {
25549
25550					renderer.setMode( 4 );
25551
25552				}
25553
25554			} else if ( object.isLine ) {
25555
25556				var lineWidth = material.linewidth;
25557
25558				if ( lineWidth === undefined ) { lineWidth = 1; } // Not using Line*Material
25559
25560				state.setLineWidth( lineWidth * getTargetPixelRatio() );
25561
25562				if ( object.isLineSegments ) {
25563
25564					renderer.setMode( 1 );
25565
25566				} else if ( object.isLineLoop ) {
25567
25568					renderer.setMode( 2 );
25569
25570				} else {
25571
25572					renderer.setMode( 3 );
25573
25574				}
25575
25576			} else if ( object.isPoints ) {
25577
25578				renderer.setMode( 0 );
25579
25580			} else if ( object.isSprite ) {
25581
25582				renderer.setMode( 4 );
25583
25584			}
25585
25586			if ( object.isInstancedMesh ) {
25587
25588				renderer.renderInstances( geometry, drawStart, drawCount, object.count );
25589
25590			} else if ( geometry.isInstancedBufferGeometry ) {
25591
25592				var instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount );
25593
25594				renderer.renderInstances( geometry, drawStart, drawCount, instanceCount );
25595
25596			} else {
25597
25598				renderer.render( drawStart, drawCount );
25599
25600			}
25601
25602		};
25603
25604		// Compile
25605
25606		this.compile = function ( scene, camera ) {
25607
25608			currentRenderState = renderStates.get( scene, camera );
25609			currentRenderState.init();
25610
25611			scene.traverse( function ( object ) {
25612
25613				if ( object.isLight ) {
25614
25615					currentRenderState.pushLight( object );
25616
25617					if ( object.castShadow ) {
25618
25619						currentRenderState.pushShadow( object );
25620
25621					}
25622
25623				}
25624
25625			} );
25626
25627			currentRenderState.setupLights( camera );
25628
25629			var compiled = new WeakMap();
25630
25631			scene.traverse( function ( object ) {
25632
25633				var material = object.material;
25634
25635				if ( material ) {
25636
25637					if ( Array.isArray( material ) ) {
25638
25639						for ( var i = 0; i < material.length; i ++ ) {
25640
25641							var material2 = material[ i ];
25642
25643							if ( compiled.has( material2 ) === false ) {
25644
25645								initMaterial( material2, scene, object );
25646								compiled.set( material2 );
25647
25648							}
25649
25650						}
25651
25652					} else if ( compiled.has( material ) === false ) {
25653
25654						initMaterial( material, scene, object );
25655						compiled.set( material );
25656
25657					}
25658
25659				}
25660
25661			} );
25662
25663		};
25664
25665		// Animation Loop
25666
25667		var onAnimationFrameCallback = null;
25668
25669		function onAnimationFrame( time ) {
25670
25671			if ( xr.isPresenting ) { return; }
25672			if ( onAnimationFrameCallback ) { onAnimationFrameCallback( time ); }
25673
25674		}
25675
25676		var animation = new WebGLAnimation();
25677		animation.setAnimationLoop( onAnimationFrame );
25678
25679		if ( typeof window !== 'undefined' ) { animation.setContext( window ); }
25680
25681		this.setAnimationLoop = function ( callback ) {
25682
25683			onAnimationFrameCallback = callback;
25684			xr.setAnimationLoop( callback );
25685
25686			( callback === null ) ? animation.stop() : animation.start();
25687
25688		};
25689
25690		// Rendering
25691
25692		this.render = function ( scene, camera ) {
25693
25694			var renderTarget, forceClear;
25695
25696			if ( arguments[ 2 ] !== undefined ) {
25697
25698				console.warn( 'THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' );
25699				renderTarget = arguments[ 2 ];
25700
25701			}
25702
25703			if ( arguments[ 3 ] !== undefined ) {
25704
25705				console.warn( 'THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.' );
25706				forceClear = arguments[ 3 ];
25707
25708			}
25709
25710			if ( camera !== undefined && camera.isCamera !== true ) {
25711
25712				console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
25713				return;
25714
25715			}
25716
25717			if ( _isContextLost === true ) { return; }
25718
25719			// reset caching for this frame
25720
25721			bindingStates.resetDefaultState();
25722			_currentMaterialId = - 1;
25723			_currentCamera = null;
25724
25725			// update scene graph
25726
25727			if ( scene.autoUpdate === true ) { scene.updateMatrixWorld(); }
25728
25729			// update camera matrices and frustum
25730
25731			if ( camera.parent === null ) { camera.updateMatrixWorld(); }
25732
25733			if ( xr.enabled === true && xr.isPresenting === true ) {
25734
25735				camera = xr.getCamera( camera );
25736
25737			}
25738
25739			//
25740			if ( scene.isScene === true ) { scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget ); }
25741
25742			currentRenderState = renderStates.get( scene, camera );
25743			currentRenderState.init();
25744
25745			_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
25746			_frustum.setFromProjectionMatrix( _projScreenMatrix );
25747
25748			_localClippingEnabled = this.localClippingEnabled;
25749			_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
25750
25751			currentRenderList = renderLists.get( scene, camera );
25752			currentRenderList.init();
25753
25754			projectObject( scene, camera, 0, _this.sortObjects );
25755
25756			currentRenderList.finish();
25757
25758			if ( _this.sortObjects === true ) {
25759
25760				currentRenderList.sort( _opaqueSort, _transparentSort );
25761
25762			}
25763
25764			//
25765
25766			if ( _clippingEnabled === true ) { _clipping.beginShadows(); }
25767
25768			var shadowsArray = currentRenderState.state.shadowsArray;
25769
25770			shadowMap.render( shadowsArray, scene, camera );
25771
25772			currentRenderState.setupLights( camera );
25773
25774			if ( _clippingEnabled === true ) { _clipping.endShadows(); }
25775
25776			//
25777
25778			if ( this.info.autoReset === true ) { this.info.reset(); }
25779
25780			if ( renderTarget !== undefined ) {
25781
25782				this.setRenderTarget( renderTarget );
25783
25784			}
25785
25786			//
25787
25788			background.render( currentRenderList, scene, camera, forceClear );
25789
25790			// render scene
25791
25792			var opaqueObjects = currentRenderList.opaque;
25793			var transparentObjects = currentRenderList.transparent;
25794
25795			if ( opaqueObjects.length > 0 ) { renderObjects( opaqueObjects, scene, camera ); }
25796			if ( transparentObjects.length > 0 ) { renderObjects( transparentObjects, scene, camera ); }
25797
25798			//
25799
25800			if ( scene.isScene === true ) { scene.onAfterRender( _this, scene, camera ); }
25801
25802			//
25803
25804			if ( _currentRenderTarget !== null ) {
25805
25806				// Generate mipmap if we're using any kind of mipmap filtering
25807
25808				textures.updateRenderTargetMipmap( _currentRenderTarget );
25809
25810				// resolve multisample renderbuffers to a single-sample texture if necessary
25811
25812				textures.updateMultisampleRenderTarget( _currentRenderTarget );
25813
25814			}
25815
25816			// Ensure depth buffer writing is enabled so it can be cleared on next render
25817
25818			state.buffers.depth.setTest( true );
25819			state.buffers.depth.setMask( true );
25820			state.buffers.color.setMask( true );
25821
25822			state.setPolygonOffset( false );
25823
25824			// _gl.finish();
25825
25826			currentRenderList = null;
25827			currentRenderState = null;
25828
25829		};
25830
25831		function projectObject( object, camera, groupOrder, sortObjects ) {
25832
25833			if ( object.visible === false ) { return; }
25834
25835			var visible = object.layers.test( camera.layers );
25836
25837			if ( visible ) {
25838
25839				if ( object.isGroup ) {
25840
25841					groupOrder = object.renderOrder;
25842
25843				} else if ( object.isLOD ) {
25844
25845					if ( object.autoUpdate === true ) { object.update( camera ); }
25846
25847				} else if ( object.isLight ) {
25848
25849					currentRenderState.pushLight( object );
25850
25851					if ( object.castShadow ) {
25852
25853						currentRenderState.pushShadow( object );
25854
25855					}
25856
25857				} else if ( object.isSprite ) {
25858
25859					if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
25860
25861						if ( sortObjects ) {
25862
25863							_vector3.setFromMatrixPosition( object.matrixWorld )
25864								.applyMatrix4( _projScreenMatrix );
25865
25866						}
25867
25868						var geometry = objects.update( object );
25869						var material = object.material;
25870
25871						if ( material.visible ) {
25872
25873							currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );
25874
25875						}
25876
25877					}
25878
25879				} else if ( object.isImmediateRenderObject ) {
25880
25881					if ( sortObjects ) {
25882
25883						_vector3.setFromMatrixPosition( object.matrixWorld )
25884							.applyMatrix4( _projScreenMatrix );
25885
25886					}
25887
25888					currentRenderList.push( object, null, object.material, groupOrder, _vector3.z, null );
25889
25890				} else if ( object.isMesh || object.isLine || object.isPoints ) {
25891
25892					if ( object.isSkinnedMesh ) {
25893
25894						// update skeleton only once in a frame
25895
25896						if ( object.skeleton.frame !== info.render.frame ) {
25897
25898							object.skeleton.update();
25899							object.skeleton.frame = info.render.frame;
25900
25901						}
25902
25903					}
25904
25905					if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
25906
25907						if ( sortObjects ) {
25908
25909							_vector3.setFromMatrixPosition( object.matrixWorld )
25910								.applyMatrix4( _projScreenMatrix );
25911
25912						}
25913
25914						var geometry$1 = objects.update( object );
25915						var material$1 = object.material;
25916
25917						if ( Array.isArray( material$1 ) ) {
25918
25919							var groups = geometry$1.groups;
25920
25921							for ( var i = 0, l = groups.length; i < l; i ++ ) {
25922
25923								var group = groups[ i ];
25924								var groupMaterial = material$1[ group.materialIndex ];
25925
25926								if ( groupMaterial && groupMaterial.visible ) {
25927
25928									currentRenderList.push( object, geometry$1, groupMaterial, groupOrder, _vector3.z, group );
25929
25930								}
25931
25932							}
25933
25934						} else if ( material$1.visible ) {
25935
25936							currentRenderList.push( object, geometry$1, material$1, groupOrder, _vector3.z, null );
25937
25938						}
25939
25940					}
25941
25942				}
25943
25944			}
25945
25946			var children = object.children;
25947
25948			for ( var i$1 = 0, l$1 = children.length; i$1 < l$1; i$1 ++ ) {
25949
25950				projectObject( children[ i$1 ], camera, groupOrder, sortObjects );
25951
25952			}
25953
25954		}
25955
25956		function renderObjects( renderList, scene, camera ) {
25957
25958			var overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
25959
25960			for ( var i = 0, l = renderList.length; i < l; i ++ ) {
25961
25962				var renderItem = renderList[ i ];
25963
25964				var object = renderItem.object;
25965				var geometry = renderItem.geometry;
25966				var material = overrideMaterial === null ? renderItem.material : overrideMaterial;
25967				var group = renderItem.group;
25968
25969				if ( camera.isArrayCamera ) {
25970
25971					_currentArrayCamera = camera;
25972
25973					var cameras = camera.cameras;
25974
25975					for ( var j = 0, jl = cameras.length; j < jl; j ++ ) {
25976
25977						var camera2 = cameras[ j ];
25978
25979						if ( object.layers.test( camera2.layers ) ) {
25980
25981							state.viewport( _currentViewport.copy( camera2.viewport ) );
25982
25983							currentRenderState.setupLights( camera2 );
25984
25985							renderObject( object, scene, camera2, geometry, material, group );
25986
25987						}
25988
25989					}
25990
25991				} else {
25992
25993					_currentArrayCamera = null;
25994
25995					renderObject( object, scene, camera, geometry, material, group );
25996
25997				}
25998
25999			}
26000
26001		}
26002
26003		function renderObject( object, scene, camera, geometry, material, group ) {
26004
26005			object.onBeforeRender( _this, scene, camera, geometry, material, group );
26006			currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
26007
26008			object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
26009			object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
26010
26011			if ( object.isImmediateRenderObject ) {
26012
26013				var program = setProgram( camera, scene, material, object );
26014
26015				state.setMaterial( material );
26016
26017				bindingStates.reset();
26018
26019				renderObjectImmediate( object, program );
26020
26021			} else {
26022
26023				_this.renderBufferDirect( camera, scene, geometry, material, object, group );
26024
26025			}
26026
26027			object.onAfterRender( _this, scene, camera, geometry, material, group );
26028			currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
26029
26030		}
26031
26032		function initMaterial( material, scene, object ) {
26033
26034			if ( scene.isScene !== true ) { scene = _emptyScene; } // scene could be a Mesh, Line, Points, ...
26035
26036			var materialProperties = properties.get( material );
26037
26038			var lights = currentRenderState.state.lights;
26039			var shadowsArray = currentRenderState.state.shadowsArray;
26040
26041			var lightsStateVersion = lights.state.version;
26042
26043			var parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, _clipping.numPlanes, _clipping.numIntersection, object );
26044			var programCacheKey = programCache.getProgramCacheKey( parameters );
26045
26046			var program = materialProperties.program;
26047			var programChange = true;
26048
26049			if ( program === undefined ) {
26050
26051				// new material
26052				material.addEventListener( 'dispose', onMaterialDispose );
26053
26054			} else if ( program.cacheKey !== programCacheKey ) {
26055
26056				// changed glsl or parameters
26057				releaseMaterialProgramReference( material );
26058
26059			} else if ( materialProperties.lightsStateVersion !== lightsStateVersion ) {
26060
26061				materialProperties.lightsStateVersion = lightsStateVersion;
26062
26063				programChange = false;
26064
26065			} else if ( parameters.shaderID !== undefined ) {
26066
26067				// same glsl and uniform list
26068				return;
26069
26070			} else {
26071
26072				// only rebuild uniform list
26073				programChange = false;
26074
26075			}
26076
26077			if ( programChange ) {
26078
26079				program = programCache.acquireProgram( parameters, programCacheKey );
26080
26081				materialProperties.program = program;
26082				materialProperties.uniforms = parameters.uniforms;
26083				materialProperties.outputEncoding = parameters.outputEncoding;
26084				material.program = program;
26085
26086			}
26087
26088			var programAttributes = program.getAttributes();
26089
26090			if ( material.morphTargets ) {
26091
26092				material.numSupportedMorphTargets = 0;
26093
26094				for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
26095
26096					if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
26097
26098						material.numSupportedMorphTargets ++;
26099
26100					}
26101
26102				}
26103
26104			}
26105
26106			if ( material.morphNormals ) {
26107
26108				material.numSupportedMorphNormals = 0;
26109
26110				for ( var i$1 = 0; i$1 < _this.maxMorphNormals; i$1 ++ ) {
26111
26112					if ( programAttributes[ 'morphNormal' + i$1 ] >= 0 ) {
26113
26114						material.numSupportedMorphNormals ++;
26115
26116					}
26117
26118				}
26119
26120			}
26121
26122			var uniforms = materialProperties.uniforms;
26123
26124			if ( ! material.isShaderMaterial &&
26125				! material.isRawShaderMaterial ||
26126				material.clipping === true ) {
26127
26128				materialProperties.numClippingPlanes = _clipping.numPlanes;
26129				materialProperties.numIntersection = _clipping.numIntersection;
26130				uniforms.clippingPlanes = _clipping.uniform;
26131
26132			}
26133
26134			materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
26135			materialProperties.fog = scene.fog;
26136
26137			// store the light setup it was created for
26138
26139			materialProperties.needsLights = materialNeedsLights( material );
26140			materialProperties.lightsStateVersion = lightsStateVersion;
26141
26142			if ( materialProperties.needsLights ) {
26143
26144				// wire up the material to this renderer's lighting state
26145
26146				uniforms.ambientLightColor.value = lights.state.ambient;
26147				uniforms.lightProbe.value = lights.state.probe;
26148				uniforms.directionalLights.value = lights.state.directional;
26149				uniforms.directionalLightShadows.value = lights.state.directionalShadow;
26150				uniforms.spotLights.value = lights.state.spot;
26151				uniforms.spotLightShadows.value = lights.state.spotShadow;
26152				uniforms.rectAreaLights.value = lights.state.rectArea;
26153				uniforms.pointLights.value = lights.state.point;
26154				uniforms.pointLightShadows.value = lights.state.pointShadow;
26155				uniforms.hemisphereLights.value = lights.state.hemi;
26156
26157				uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
26158				uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
26159				uniforms.spotShadowMap.value = lights.state.spotShadowMap;
26160				uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix;
26161				uniforms.pointShadowMap.value = lights.state.pointShadowMap;
26162				uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix;
26163				// TODO (abelnation): add area lights shadow info to uniforms
26164
26165			}
26166
26167			var progUniforms = materialProperties.program.getUniforms(),
26168				uniformsList =
26169					WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
26170
26171			materialProperties.uniformsList = uniformsList;
26172
26173		}
26174
26175		function setProgram( camera, scene, material, object ) {
26176
26177			if ( scene.isScene !== true ) { scene = _emptyScene; } // scene could be a Mesh, Line, Points, ...
26178
26179			textures.resetTextureUnits();
26180
26181			var fog = scene.fog;
26182			var environment = material.isMeshStandardMaterial ? scene.environment : null;
26183			var encoding = ( _currentRenderTarget === null ) ? _this.outputEncoding : _currentRenderTarget.texture.encoding;
26184
26185			var materialProperties = properties.get( material );
26186			var lights = currentRenderState.state.lights;
26187
26188			if ( _clippingEnabled === true ) {
26189
26190				if ( _localClippingEnabled === true || camera !== _currentCamera ) {
26191
26192					var useCache =
26193						camera === _currentCamera &&
26194						material.id === _currentMaterialId;
26195
26196					// we might want to call this function with some ClippingGroup
26197					// object instead of the material, once it becomes feasible
26198					// (#8465, #8379)
26199					_clipping.setState(
26200						material.clippingPlanes, material.clipIntersection, material.clipShadows,
26201						camera, materialProperties, useCache );
26202
26203				}
26204
26205			}
26206
26207			if ( material.version === materialProperties.__version ) {
26208
26209				if ( materialProperties.program === undefined ) {
26210
26211					initMaterial( material, scene, object );
26212
26213				} else if ( material.fog && materialProperties.fog !== fog ) {
26214
26215					initMaterial( material, scene, object );
26216
26217				} else if ( materialProperties.environment !== environment ) {
26218
26219					initMaterial( material, scene, object );
26220
26221				} else if ( materialProperties.needsLights && ( materialProperties.lightsStateVersion !== lights.state.version ) ) {
26222
26223					initMaterial( material, scene, object );
26224
26225				} else if ( materialProperties.numClippingPlanes !== undefined &&
26226					( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
26227					materialProperties.numIntersection !== _clipping.numIntersection ) ) {
26228
26229					initMaterial( material, scene, object );
26230
26231				} else if ( materialProperties.outputEncoding !== encoding ) {
26232
26233					initMaterial( material, scene, object );
26234
26235				}
26236
26237			} else {
26238
26239				initMaterial( material, scene, object );
26240				materialProperties.__version = material.version;
26241
26242			}
26243
26244			var refreshProgram = false;
26245			var refreshMaterial = false;
26246			var refreshLights = false;
26247
26248			var program = materialProperties.program,
26249				p_uniforms = program.getUniforms(),
26250				m_uniforms = materialProperties.uniforms;
26251
26252			if ( state.useProgram( program.program ) ) {
26253
26254				refreshProgram = true;
26255				refreshMaterial = true;
26256				refreshLights = true;
26257
26258			}
26259
26260			if ( material.id !== _currentMaterialId ) {
26261
26262				_currentMaterialId = material.id;
26263
26264				refreshMaterial = true;
26265
26266			}
26267
26268			if ( refreshProgram || _currentCamera !== camera ) {
26269
26270				p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
26271
26272				if ( capabilities.logarithmicDepthBuffer ) {
26273
26274					p_uniforms.setValue( _gl, 'logDepthBufFC',
26275						2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
26276
26277				}
26278
26279				if ( _currentCamera !== camera ) {
26280
26281					_currentCamera = camera;
26282
26283					// lighting uniforms depend on the camera so enforce an update
26284					// now, in case this material supports lights - or later, when
26285					// the next material that does gets activated:
26286
26287					refreshMaterial = true;		// set to true on material change
26288					refreshLights = true;		// remains set until update done
26289
26290				}
26291
26292				// load material specific uniforms
26293				// (shader material also gets them for the sake of genericity)
26294
26295				if ( material.isShaderMaterial ||
26296					material.isMeshPhongMaterial ||
26297					material.isMeshToonMaterial ||
26298					material.isMeshStandardMaterial ||
26299					material.envMap ) {
26300
26301					var uCamPos = p_uniforms.map.cameraPosition;
26302
26303					if ( uCamPos !== undefined ) {
26304
26305						uCamPos.setValue( _gl,
26306							_vector3.setFromMatrixPosition( camera.matrixWorld ) );
26307
26308					}
26309
26310				}
26311
26312				if ( material.isMeshPhongMaterial ||
26313					material.isMeshToonMaterial ||
26314					material.isMeshLambertMaterial ||
26315					material.isMeshBasicMaterial ||
26316					material.isMeshStandardMaterial ||
26317					material.isShaderMaterial ) {
26318
26319					p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true );
26320
26321				}
26322
26323				if ( material.isMeshPhongMaterial ||
26324					material.isMeshToonMaterial ||
26325					material.isMeshLambertMaterial ||
26326					material.isMeshBasicMaterial ||
26327					material.isMeshStandardMaterial ||
26328					material.isShaderMaterial ||
26329					material.isShadowMaterial ||
26330					material.skinning ) {
26331
26332					p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
26333
26334				}
26335
26336			}
26337
26338			// skinning uniforms must be set even if material didn't change
26339			// auto-setting of texture unit for bone texture must go before other textures
26340			// otherwise textures used for skinning can take over texture units reserved for other material textures
26341
26342			if ( material.skinning ) {
26343
26344				p_uniforms.setOptional( _gl, object, 'bindMatrix' );
26345				p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
26346
26347				var skeleton = object.skeleton;
26348
26349				if ( skeleton ) {
26350
26351					var bones = skeleton.bones;
26352
26353					if ( capabilities.floatVertexTextures ) {
26354
26355						if ( skeleton.boneTexture === undefined ) {
26356
26357							// layout (1 matrix = 4 pixels)
26358							//      RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
26359							//  with  8x8  pixel texture max   16 bones * 4 pixels =  (8 * 8)
26360							//       16x16 pixel texture max   64 bones * 4 pixels = (16 * 16)
26361							//       32x32 pixel texture max  256 bones * 4 pixels = (32 * 32)
26362							//       64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
26363
26364
26365							var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix
26366							size = MathUtils.ceilPowerOfTwo( size );
26367							size = Math.max( size, 4 );
26368
26369							var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
26370							boneMatrices.set( skeleton.boneMatrices ); // copy current values
26371
26372							var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );
26373
26374							skeleton.boneMatrices = boneMatrices;
26375							skeleton.boneTexture = boneTexture;
26376							skeleton.boneTextureSize = size;
26377
26378						}
26379
26380						p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );
26381						p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
26382
26383					} else {
26384
26385						p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
26386
26387					}
26388
26389				}
26390
26391			}
26392
26393			if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) {
26394
26395				materialProperties.receiveShadow = object.receiveShadow;
26396				p_uniforms.setValue( _gl, 'receiveShadow', object.receiveShadow );
26397
26398			}
26399
26400			if ( refreshMaterial ) {
26401
26402				p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
26403
26404				if ( materialProperties.needsLights ) {
26405
26406					// the current material requires lighting info
26407
26408					// note: all lighting uniforms are always set correctly
26409					// they simply reference the renderer's state for their
26410					// values
26411					//
26412					// use the current material's .needsUpdate flags to set
26413					// the GL state when required
26414
26415					markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
26416
26417				}
26418
26419				// refresh uniforms common to several materials
26420
26421				if ( fog && material.fog ) {
26422
26423					materials.refreshFogUniforms( m_uniforms, fog );
26424
26425				}
26426
26427				materials.refreshMaterialUniforms( m_uniforms, material, environment, _pixelRatio, _height );
26428
26429				// RectAreaLight Texture
26430				// TODO (mrdoob): Find a nicer implementation
26431
26432				if ( m_uniforms.ltc_1 !== undefined ) { m_uniforms.ltc_1.value = UniformsLib.LTC_1; }
26433				if ( m_uniforms.ltc_2 !== undefined ) { m_uniforms.ltc_2.value = UniformsLib.LTC_2; }
26434
26435				WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
26436
26437			}
26438
26439			if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {
26440
26441				WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
26442				material.uniformsNeedUpdate = false;
26443
26444			}
26445
26446			if ( material.isSpriteMaterial ) {
26447
26448				p_uniforms.setValue( _gl, 'center', object.center );
26449
26450			}
26451
26452			// common matrices
26453
26454			p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
26455			p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
26456			p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
26457
26458			return program;
26459
26460		}
26461
26462		// If uniforms are marked as clean, they don't need to be loaded to the GPU.
26463
26464		function markUniformsLightsNeedsUpdate( uniforms, value ) {
26465
26466			uniforms.ambientLightColor.needsUpdate = value;
26467			uniforms.lightProbe.needsUpdate = value;
26468
26469			uniforms.directionalLights.needsUpdate = value;
26470			uniforms.directionalLightShadows.needsUpdate = value;
26471			uniforms.pointLights.needsUpdate = value;
26472			uniforms.pointLightShadows.needsUpdate = value;
26473			uniforms.spotLights.needsUpdate = value;
26474			uniforms.spotLightShadows.needsUpdate = value;
26475			uniforms.rectAreaLights.needsUpdate = value;
26476			uniforms.hemisphereLights.needsUpdate = value;
26477
26478		}
26479
26480		function materialNeedsLights( material ) {
26481
26482			return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial ||
26483				material.isMeshStandardMaterial || material.isShadowMaterial ||
26484				( material.isShaderMaterial && material.lights === true );
26485
26486		}
26487
26488		//
26489		this.setFramebuffer = function ( value ) {
26490
26491			if ( _framebuffer !== value && _currentRenderTarget === null ) { _gl.bindFramebuffer( 36160, value ); }
26492
26493			_framebuffer = value;
26494
26495		};
26496
26497		this.getActiveCubeFace = function () {
26498
26499			return _currentActiveCubeFace;
26500
26501		};
26502
26503		this.getActiveMipmapLevel = function () {
26504
26505			return _currentActiveMipmapLevel;
26506
26507		};
26508
26509		this.getRenderTarget = function () {
26510
26511			return _currentRenderTarget;
26512
26513		};
26514
26515		this.setRenderTarget = function ( renderTarget, activeCubeFace, activeMipmapLevel ) {
26516
26517			_currentRenderTarget = renderTarget;
26518			_currentActiveCubeFace = activeCubeFace;
26519			_currentActiveMipmapLevel = activeMipmapLevel;
26520
26521			if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
26522
26523				textures.setupRenderTarget( renderTarget );
26524
26525			}
26526
26527			var framebuffer = _framebuffer;
26528			var isCube = false;
26529
26530			if ( renderTarget ) {
26531
26532				var _webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer;
26533
26534				if ( renderTarget.isWebGLCubeRenderTarget ) {
26535
26536					framebuffer = _webglFramebuffer[ activeCubeFace || 0 ];
26537					isCube = true;
26538
26539				} else if ( renderTarget.isWebGLMultisampleRenderTarget ) {
26540
26541					framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;
26542
26543				} else {
26544
26545					framebuffer = _webglFramebuffer;
26546
26547				}
26548
26549				_currentViewport.copy( renderTarget.viewport );
26550				_currentScissor.copy( renderTarget.scissor );
26551				_currentScissorTest = renderTarget.scissorTest;
26552
26553			} else {
26554
26555				_currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor();
26556				_currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor();
26557				_currentScissorTest = _scissorTest;
26558
26559			}
26560
26561			if ( _currentFramebuffer !== framebuffer ) {
26562
26563				_gl.bindFramebuffer( 36160, framebuffer );
26564				_currentFramebuffer = framebuffer;
26565
26566			}
26567
26568			state.viewport( _currentViewport );
26569			state.scissor( _currentScissor );
26570			state.setScissorTest( _currentScissorTest );
26571
26572			if ( isCube ) {
26573
26574				var textureProperties = properties.get( renderTarget.texture );
26575				_gl.framebufferTexture2D( 36160, 36064, 34069 + ( activeCubeFace || 0 ), textureProperties.__webglTexture, activeMipmapLevel || 0 );
26576
26577			}
26578
26579		};
26580
26581		this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) {
26582
26583			if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
26584
26585				console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
26586				return;
26587
26588			}
26589
26590			var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
26591
26592			if ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) {
26593
26594				framebuffer = framebuffer[ activeCubeFaceIndex ];
26595
26596			}
26597
26598			if ( framebuffer ) {
26599
26600				var restore = false;
26601
26602				if ( framebuffer !== _currentFramebuffer ) {
26603
26604					_gl.bindFramebuffer( 36160, framebuffer );
26605
26606					restore = true;
26607
26608				}
26609
26610				try {
26611
26612					var texture = renderTarget.texture;
26613					var textureFormat = texture.format;
26614					var textureType = texture.type;
26615
26616					if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( 35739 ) ) {
26617
26618						console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
26619						return;
26620
26621					}
26622
26623					if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( 35738 ) && // IE11, Edge and Chrome Mac < 52 (#9513)
26624						! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
26625						! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
26626
26627						console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
26628						return;
26629
26630					}
26631
26632					if ( _gl.checkFramebufferStatus( 36160 ) === 36053 ) {
26633
26634						// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
26635
26636						if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
26637
26638							_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
26639
26640						}
26641
26642					} else {
26643
26644						console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
26645
26646					}
26647
26648				} finally {
26649
26650					if ( restore ) {
26651
26652						_gl.bindFramebuffer( 36160, _currentFramebuffer );
26653
26654					}
26655
26656				}
26657
26658			}
26659
26660		};
26661
26662		this.copyFramebufferToTexture = function ( position, texture, level ) {
26663
26664			if ( level === undefined ) { level = 0; }
26665
26666			var levelScale = Math.pow( 2, - level );
26667			var width = Math.floor( texture.image.width * levelScale );
26668			var height = Math.floor( texture.image.height * levelScale );
26669			var glFormat = utils.convert( texture.format );
26670
26671			textures.setTexture2D( texture, 0 );
26672
26673			_gl.copyTexImage2D( 3553, level, glFormat, position.x, position.y, width, height, 0 );
26674
26675			state.unbindTexture();
26676
26677		};
26678
26679		this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) {
26680
26681			if ( level === undefined ) { level = 0; }
26682
26683			var width = srcTexture.image.width;
26684			var height = srcTexture.image.height;
26685			var glFormat = utils.convert( dstTexture.format );
26686			var glType = utils.convert( dstTexture.type );
26687
26688			textures.setTexture2D( dstTexture, 0 );
26689
26690			// As another texture upload may have changed pixelStorei
26691			// parameters, make sure they are correct for the dstTexture
26692			_gl.pixelStorei( 37440, dstTexture.flipY );
26693			_gl.pixelStorei( 37441, dstTexture.premultiplyAlpha );
26694			_gl.pixelStorei( 3317, dstTexture.unpackAlignment );
26695
26696			if ( srcTexture.isDataTexture ) {
26697
26698				_gl.texSubImage2D( 3553, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
26699
26700			} else {
26701
26702				if ( srcTexture.isCompressedTexture ) {
26703
26704					_gl.compressedTexSubImage2D( 3553, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
26705
26706				} else {
26707
26708					_gl.texSubImage2D( 3553, level, position.x, position.y, glFormat, glType, srcTexture.image );
26709
26710				}
26711
26712			}
26713
26714			// Generate mipmaps only when copying level 0
26715			if ( level === 0 && dstTexture.generateMipmaps ) { _gl.generateMipmap( 3553 ); }
26716
26717			state.unbindTexture();
26718
26719		};
26720
26721		this.initTexture = function ( texture ) {
26722
26723			textures.setTexture2D( texture, 0 );
26724
26725			state.unbindTexture();
26726
26727		};
26728
26729		if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
26730
26731			__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef
26732
26733		}
26734
26735	}
26736
26737	/**
26738	 * @author Mugen87 / https://github.com/Mugen87
26739	 */
26740
26741	function WebGL1Renderer( parameters ) {
26742
26743		WebGLRenderer.call( this, parameters );
26744
26745	}
26746
26747	WebGL1Renderer.prototype = Object.assign( Object.create( WebGLRenderer.prototype ), {
26748
26749		constructor: WebGL1Renderer,
26750
26751		isWebGL1Renderer: true
26752
26753	} );
26754
26755	/**
26756	 * @author mrdoob / http://mrdoob.com/
26757	 * @author alteredq / http://alteredqualia.com/
26758	 */
26759
26760	function FogExp2( color, density ) {
26761
26762		this.name = '';
26763
26764		this.color = new Color( color );
26765		this.density = ( density !== undefined ) ? density : 0.00025;
26766
26767	}
26768
26769	Object.assign( FogExp2.prototype, {
26770
26771		isFogExp2: true,
26772
26773		clone: function () {
26774
26775			return new FogExp2( this.color, this.density );
26776
26777		},
26778
26779		toJSON: function ( /* meta */ ) {
26780
26781			return {
26782				type: 'FogExp2',
26783				color: this.color.getHex(),
26784				density: this.density
26785			};
26786
26787		}
26788
26789	} );
26790
26791	/**
26792	 * @author mrdoob / http://mrdoob.com/
26793	 * @author alteredq / http://alteredqualia.com/
26794	 */
26795
26796	function Fog( color, near, far ) {
26797
26798		this.name = '';
26799
26800		this.color = new Color( color );
26801
26802		this.near = ( near !== undefined ) ? near : 1;
26803		this.far = ( far !== undefined ) ? far : 1000;
26804
26805	}
26806
26807	Object.assign( Fog.prototype, {
26808
26809		isFog: true,
26810
26811		clone: function () {
26812
26813			return new Fog( this.color, this.near, this.far );
26814
26815		},
26816
26817		toJSON: function ( /* meta */ ) {
26818
26819			return {
26820				type: 'Fog',
26821				color: this.color.getHex(),
26822				near: this.near,
26823				far: this.far
26824			};
26825
26826		}
26827
26828	} );
26829
26830	/**
26831	 * @author benaadams / https://twitter.com/ben_a_adams
26832	 */
26833
26834	function InterleavedBuffer( array, stride ) {
26835
26836		this.array = array;
26837		this.stride = stride;
26838		this.count = array !== undefined ? array.length / stride : 0;
26839
26840		this.usage = StaticDrawUsage;
26841		this.updateRange = { offset: 0, count: - 1 };
26842
26843		this.version = 0;
26844
26845		this.uuid = MathUtils.generateUUID();
26846
26847	}
26848
26849	Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', {
26850
26851		set: function ( value ) {
26852
26853			if ( value === true ) { this.version ++; }
26854
26855		}
26856
26857	} );
26858
26859	Object.assign( InterleavedBuffer.prototype, {
26860
26861		isInterleavedBuffer: true,
26862
26863		onUploadCallback: function () {},
26864
26865		setUsage: function ( value ) {
26866
26867			this.usage = value;
26868
26869			return this;
26870
26871		},
26872
26873		copy: function ( source ) {
26874
26875			this.array = new source.array.constructor( source.array );
26876			this.count = source.count;
26877			this.stride = source.stride;
26878			this.usage = source.usage;
26879
26880			return this;
26881
26882		},
26883
26884		copyAt: function ( index1, attribute, index2 ) {
26885
26886			index1 *= this.stride;
26887			index2 *= attribute.stride;
26888
26889			for ( var i = 0, l = this.stride; i < l; i ++ ) {
26890
26891				this.array[ index1 + i ] = attribute.array[ index2 + i ];
26892
26893			}
26894
26895			return this;
26896
26897		},
26898
26899		set: function ( value, offset ) {
26900
26901			if ( offset === undefined ) { offset = 0; }
26902
26903			this.array.set( value, offset );
26904
26905			return this;
26906
26907		},
26908
26909		clone: function ( data ) {
26910
26911			if ( data.arrayBuffers === undefined ) {
26912
26913				data.arrayBuffers = {};
26914
26915			}
26916
26917			if ( this.array.buffer._uuid === undefined ) {
26918
26919				this.array.buffer._uuid = MathUtils.generateUUID();
26920
26921			}
26922
26923			if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
26924
26925				data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer;
26926
26927			}
26928
26929			var array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] );
26930
26931			var ib = new InterleavedBuffer( array, this.stride );
26932			ib.setUsage( this.usage );
26933
26934			return ib;
26935
26936		},
26937
26938		onUpload: function ( callback ) {
26939
26940			this.onUploadCallback = callback;
26941
26942			return this;
26943
26944		},
26945
26946		toJSON: function ( data ) {
26947
26948			if ( data.arrayBuffers === undefined ) {
26949
26950				data.arrayBuffers = {};
26951
26952			}
26953
26954			// generate UUID for array buffer if necessary
26955
26956			if ( this.array.buffer._uuid === undefined ) {
26957
26958				this.array.buffer._uuid = MathUtils.generateUUID();
26959
26960			}
26961
26962			if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
26963
26964				data.arrayBuffers[ this.array.buffer._uuid ] = Array.prototype.slice.call( new Uint32Array( this.array.buffer ) );
26965
26966			}
26967
26968			//
26969
26970			return {
26971				uuid: this.uuid,
26972				buffer: this.array.buffer._uuid,
26973				type: this.array.constructor.name,
26974				stride: this.stride
26975			};
26976
26977		}
26978
26979	} );
26980
26981	/**
26982	 * @author benaadams / https://twitter.com/ben_a_adams
26983	 */
26984
26985	var _vector$6 = new Vector3();
26986
26987	function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {
26988
26989		this.name = '';
26990
26991		this.data = interleavedBuffer;
26992		this.itemSize = itemSize;
26993		this.offset = offset;
26994
26995		this.normalized = normalized === true;
26996
26997	}
26998
26999	Object.defineProperties( InterleavedBufferAttribute.prototype, {
27000
27001		count: {
27002
27003			get: function () {
27004
27005				return this.data.count;
27006
27007			}
27008
27009		},
27010
27011		array: {
27012
27013			get: function () {
27014
27015				return this.data.array;
27016
27017			}
27018
27019		}
27020
27021	} );
27022
27023	Object.assign( InterleavedBufferAttribute.prototype, {
27024
27025		isInterleavedBufferAttribute: true,
27026
27027		applyMatrix4: function ( m ) {
27028
27029			for ( var i = 0, l = this.data.count; i < l; i ++ ) {
27030
27031				_vector$6.x = this.getX( i );
27032				_vector$6.y = this.getY( i );
27033				_vector$6.z = this.getZ( i );
27034
27035				_vector$6.applyMatrix4( m );
27036
27037				this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );
27038
27039			}
27040
27041			return this;
27042
27043		},
27044
27045		setX: function ( index, x ) {
27046
27047			this.data.array[ index * this.data.stride + this.offset ] = x;
27048
27049			return this;
27050
27051		},
27052
27053		setY: function ( index, y ) {
27054
27055			this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
27056
27057			return this;
27058
27059		},
27060
27061		setZ: function ( index, z ) {
27062
27063			this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
27064
27065			return this;
27066
27067		},
27068
27069		setW: function ( index, w ) {
27070
27071			this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
27072
27073			return this;
27074
27075		},
27076
27077		getX: function ( index ) {
27078
27079			return this.data.array[ index * this.data.stride + this.offset ];
27080
27081		},
27082
27083		getY: function ( index ) {
27084
27085			return this.data.array[ index * this.data.stride + this.offset + 1 ];
27086
27087		},
27088
27089		getZ: function ( index ) {
27090
27091			return this.data.array[ index * this.data.stride + this.offset + 2 ];
27092
27093		},
27094
27095		getW: function ( index ) {
27096
27097			return this.data.array[ index * this.data.stride + this.offset + 3 ];
27098
27099		},
27100
27101		setXY: function ( index, x, y ) {
27102
27103			index = index * this.data.stride + this.offset;
27104
27105			this.data.array[ index + 0 ] = x;
27106			this.data.array[ index + 1 ] = y;
27107
27108			return this;
27109
27110		},
27111
27112		setXYZ: function ( index, x, y, z ) {
27113
27114			index = index * this.data.stride + this.offset;
27115
27116			this.data.array[ index + 0 ] = x;
27117			this.data.array[ index + 1 ] = y;
27118			this.data.array[ index + 2 ] = z;
27119
27120			return this;
27121
27122		},
27123
27124		setXYZW: function ( index, x, y, z, w ) {
27125
27126			index = index * this.data.stride + this.offset;
27127
27128			this.data.array[ index + 0 ] = x;
27129			this.data.array[ index + 1 ] = y;
27130			this.data.array[ index + 2 ] = z;
27131			this.data.array[ index + 3 ] = w;
27132
27133			return this;
27134
27135		},
27136
27137		clone: function ( data ) {
27138
27139			if ( data === undefined ) {
27140
27141				console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.' );
27142
27143				var array = [];
27144
27145				for ( var i = 0; i < this.count; i ++ ) {
27146
27147					var index = i * this.data.stride + this.offset;
27148
27149					for ( var j = 0; j < this.itemSize; j ++ ) {
27150
27151						array.push( this.data.array[ index + j ] );
27152
27153					}
27154
27155				}
27156
27157				return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );
27158
27159			} else {
27160
27161				if ( data.interleavedBuffers === undefined ) {
27162
27163					data.interleavedBuffers = {};
27164
27165				}
27166
27167				if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
27168
27169					data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data );
27170
27171				}
27172
27173				return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized );
27174
27175			}
27176
27177		},
27178
27179		toJSON: function ( data ) {
27180
27181			if ( data === undefined ) {
27182
27183				console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.' );
27184
27185				var array = [];
27186
27187				for ( var i = 0; i < this.count; i ++ ) {
27188
27189					var index = i * this.data.stride + this.offset;
27190
27191					for ( var j = 0; j < this.itemSize; j ++ ) {
27192
27193						array.push( this.data.array[ index + j ] );
27194
27195					}
27196
27197				}
27198
27199				// deinterleave data and save it as an ordinary buffer attribute for now
27200
27201				return {
27202					itemSize: this.itemSize,
27203					type: this.array.constructor.name,
27204					array: array,
27205					normalized: this.normalized
27206				};
27207
27208			} else {
27209
27210				// save as true interlaved attribtue
27211
27212				if ( data.interleavedBuffers === undefined ) {
27213
27214					data.interleavedBuffers = {};
27215
27216				}
27217
27218				if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
27219
27220					data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data );
27221
27222				}
27223
27224				return {
27225					isInterleavedBufferAttribute: true,
27226					itemSize: this.itemSize,
27227					data: this.data.uuid,
27228					offset: this.offset,
27229					normalized: this.normalized
27230				};
27231
27232			}
27233
27234		}
27235
27236	} );
27237
27238	/**
27239	 * @author alteredq / http://alteredqualia.com/
27240	 *
27241	 * parameters = {
27242	 *  color: <hex>,
27243	 *  map: new THREE.Texture( <Image> ),
27244	 *  alphaMap: new THREE.Texture( <Image> ),
27245	 *  rotation: <float>,
27246	 *  sizeAttenuation: <bool>
27247	 * }
27248	 */
27249
27250	function SpriteMaterial( parameters ) {
27251
27252		Material.call( this );
27253
27254		this.type = 'SpriteMaterial';
27255
27256		this.color = new Color( 0xffffff );
27257
27258		this.map = null;
27259
27260		this.alphaMap = null;
27261
27262		this.rotation = 0;
27263
27264		this.sizeAttenuation = true;
27265
27266		this.transparent = true;
27267
27268		this.setValues( parameters );
27269
27270	}
27271
27272	SpriteMaterial.prototype = Object.create( Material.prototype );
27273	SpriteMaterial.prototype.constructor = SpriteMaterial;
27274	SpriteMaterial.prototype.isSpriteMaterial = true;
27275
27276	SpriteMaterial.prototype.copy = function ( source ) {
27277
27278		Material.prototype.copy.call( this, source );
27279
27280		this.color.copy( source.color );
27281
27282		this.map = source.map;
27283
27284		this.alphaMap = source.alphaMap;
27285
27286		this.rotation = source.rotation;
27287
27288		this.sizeAttenuation = source.sizeAttenuation;
27289
27290		return this;
27291
27292	};
27293
27294	/**
27295	 * @author mikael emtinger / http://gomo.se/
27296	 * @author alteredq / http://alteredqualia.com/
27297	 */
27298
27299	var _geometry;
27300
27301	var _intersectPoint = new Vector3();
27302	var _worldScale = new Vector3();
27303	var _mvPosition = new Vector3();
27304
27305	var _alignedPosition = new Vector2();
27306	var _rotatedPosition = new Vector2();
27307	var _viewWorldMatrix = new Matrix4();
27308
27309	var _vA$1 = new Vector3();
27310	var _vB$1 = new Vector3();
27311	var _vC$1 = new Vector3();
27312
27313	var _uvA$1 = new Vector2();
27314	var _uvB$1 = new Vector2();
27315	var _uvC$1 = new Vector2();
27316
27317	function Sprite( material ) {
27318
27319		Object3D.call( this );
27320
27321		this.type = 'Sprite';
27322
27323		if ( _geometry === undefined ) {
27324
27325			_geometry = new BufferGeometry();
27326
27327			var float32Array = new Float32Array( [
27328				- 0.5, - 0.5, 0, 0, 0,
27329				0.5, - 0.5, 0, 1, 0,
27330				0.5, 0.5, 0, 1, 1,
27331				- 0.5, 0.5, 0, 0, 1
27332			] );
27333
27334			var interleavedBuffer = new InterleavedBuffer( float32Array, 5 );
27335
27336			_geometry.setIndex( [ 0, 1, 2,	0, 2, 3 ] );
27337			_geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );
27338			_geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );
27339
27340		}
27341
27342		this.geometry = _geometry;
27343		this.material = ( material !== undefined ) ? material : new SpriteMaterial();
27344
27345		this.center = new Vector2( 0.5, 0.5 );
27346
27347	}
27348
27349	Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
27350
27351		constructor: Sprite,
27352
27353		isSprite: true,
27354
27355		raycast: function ( raycaster, intersects ) {
27356
27357			if ( raycaster.camera === null ) {
27358
27359				console.error( 'THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' );
27360
27361			}
27362
27363			_worldScale.setFromMatrixScale( this.matrixWorld );
27364
27365			_viewWorldMatrix.copy( raycaster.camera.matrixWorld );
27366			this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld );
27367
27368			_mvPosition.setFromMatrixPosition( this.modelViewMatrix );
27369
27370			if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) {
27371
27372				_worldScale.multiplyScalar( - _mvPosition.z );
27373
27374			}
27375
27376			var rotation = this.material.rotation;
27377			var sin, cos;
27378
27379			if ( rotation !== 0 ) {
27380
27381				cos = Math.cos( rotation );
27382				sin = Math.sin( rotation );
27383
27384			}
27385
27386			var center = this.center;
27387
27388			transformVertex( _vA$1.set( - 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27389			transformVertex( _vB$1.set( 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27390			transformVertex( _vC$1.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27391
27392			_uvA$1.set( 0, 0 );
27393			_uvB$1.set( 1, 0 );
27394			_uvC$1.set( 1, 1 );
27395
27396			// check first triangle
27397			var intersect = raycaster.ray.intersectTriangle( _vA$1, _vB$1, _vC$1, false, _intersectPoint );
27398
27399			if ( intersect === null ) {
27400
27401				// check second triangle
27402				transformVertex( _vB$1.set( - 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27403				_uvB$1.set( 0, 1 );
27404
27405				intersect = raycaster.ray.intersectTriangle( _vA$1, _vC$1, _vB$1, false, _intersectPoint );
27406				if ( intersect === null ) {
27407
27408					return;
27409
27410				}
27411
27412			}
27413
27414			var distance = raycaster.ray.origin.distanceTo( _intersectPoint );
27415
27416			if ( distance < raycaster.near || distance > raycaster.far ) { return; }
27417
27418			intersects.push( {
27419
27420				distance: distance,
27421				point: _intersectPoint.clone(),
27422				uv: Triangle.getUV( _intersectPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ),
27423				face: null,
27424				object: this
27425
27426			} );
27427
27428		},
27429
27430		copy: function ( source ) {
27431
27432			Object3D.prototype.copy.call( this, source );
27433
27434			if ( source.center !== undefined ) { this.center.copy( source.center ); }
27435
27436			this.material = source.material;
27437
27438			return this;
27439
27440		}
27441
27442	} );
27443
27444	function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
27445
27446		// compute position in camera space
27447		_alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
27448
27449		// to check if rotation is not zero
27450		if ( sin !== undefined ) {
27451
27452			_rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y );
27453			_rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y );
27454
27455		} else {
27456
27457			_rotatedPosition.copy( _alignedPosition );
27458
27459		}
27460
27461
27462		vertexPosition.copy( mvPosition );
27463		vertexPosition.x += _rotatedPosition.x;
27464		vertexPosition.y += _rotatedPosition.y;
27465
27466		// transform to world space
27467		vertexPosition.applyMatrix4( _viewWorldMatrix );
27468
27469	}
27470
27471	/**
27472	 * @author mikael emtinger / http://gomo.se/
27473	 * @author alteredq / http://alteredqualia.com/
27474	 * @author mrdoob / http://mrdoob.com/
27475	 */
27476
27477	var _v1$4 = new Vector3();
27478	var _v2$2 = new Vector3();
27479
27480	function LOD() {
27481
27482		Object3D.call( this );
27483
27484		this._currentLevel = 0;
27485
27486		this.type = 'LOD';
27487
27488		Object.defineProperties( this, {
27489			levels: {
27490				enumerable: true,
27491				value: []
27492			}
27493		} );
27494
27495		this.autoUpdate = true;
27496
27497	}
27498
27499	LOD.prototype = Object.assign( Object.create( Object3D.prototype ), {
27500
27501		constructor: LOD,
27502
27503		isLOD: true,
27504
27505		copy: function ( source ) {
27506
27507			Object3D.prototype.copy.call( this, source, false );
27508
27509			var levels = source.levels;
27510
27511			for ( var i = 0, l = levels.length; i < l; i ++ ) {
27512
27513				var level = levels[ i ];
27514
27515				this.addLevel( level.object.clone(), level.distance );
27516
27517			}
27518
27519			this.autoUpdate = source.autoUpdate;
27520
27521			return this;
27522
27523		},
27524
27525		addLevel: function ( object, distance ) {
27526
27527			if ( distance === undefined ) { distance = 0; }
27528
27529			distance = Math.abs( distance );
27530
27531			var levels = this.levels;
27532
27533			var l;
27534
27535			for ( l = 0; l < levels.length; l ++ ) {
27536
27537				if ( distance < levels[ l ].distance ) {
27538
27539					break;
27540
27541				}
27542
27543			}
27544
27545			levels.splice( l, 0, { distance: distance, object: object } );
27546
27547			this.add( object );
27548
27549			return this;
27550
27551		},
27552
27553		getCurrentLevel: function () {
27554
27555			return this._currentLevel;
27556
27557		},
27558
27559		getObjectForDistance: function ( distance ) {
27560
27561			var levels = this.levels;
27562
27563			if ( levels.length > 0 ) {
27564
27565				var i, l;
27566
27567				for ( i = 1, l = levels.length; i < l; i ++ ) {
27568
27569					if ( distance < levels[ i ].distance ) {
27570
27571						break;
27572
27573					}
27574
27575				}
27576
27577				return levels[ i - 1 ].object;
27578
27579			}
27580
27581			return null;
27582
27583		},
27584
27585		raycast: function ( raycaster, intersects ) {
27586
27587			var levels = this.levels;
27588
27589			if ( levels.length > 0 ) {
27590
27591				_v1$4.setFromMatrixPosition( this.matrixWorld );
27592
27593				var distance = raycaster.ray.origin.distanceTo( _v1$4 );
27594
27595				this.getObjectForDistance( distance ).raycast( raycaster, intersects );
27596
27597			}
27598
27599		},
27600
27601		update: function ( camera ) {
27602
27603			var levels = this.levels;
27604
27605			if ( levels.length > 1 ) {
27606
27607				_v1$4.setFromMatrixPosition( camera.matrixWorld );
27608				_v2$2.setFromMatrixPosition( this.matrixWorld );
27609
27610				var distance = _v1$4.distanceTo( _v2$2 ) / camera.zoom;
27611
27612				levels[ 0 ].object.visible = true;
27613
27614				var i, l;
27615
27616				for ( i = 1, l = levels.length; i < l; i ++ ) {
27617
27618					if ( distance >= levels[ i ].distance ) {
27619
27620						levels[ i - 1 ].object.visible = false;
27621						levels[ i ].object.visible = true;
27622
27623					} else {
27624
27625						break;
27626
27627					}
27628
27629				}
27630
27631				this._currentLevel = i - 1;
27632
27633				for ( ; i < l; i ++ ) {
27634
27635					levels[ i ].object.visible = false;
27636
27637				}
27638
27639			}
27640
27641		},
27642
27643		toJSON: function ( meta ) {
27644
27645			var data = Object3D.prototype.toJSON.call( this, meta );
27646
27647			if ( this.autoUpdate === false ) { data.object.autoUpdate = false; }
27648
27649			data.object.levels = [];
27650
27651			var levels = this.levels;
27652
27653			for ( var i = 0, l = levels.length; i < l; i ++ ) {
27654
27655				var level = levels[ i ];
27656
27657				data.object.levels.push( {
27658					object: level.object.uuid,
27659					distance: level.distance
27660				} );
27661
27662			}
27663
27664			return data;
27665
27666		}
27667
27668	} );
27669
27670	/**
27671	 * @author mikael emtinger / http://gomo.se/
27672	 * @author alteredq / http://alteredqualia.com/
27673	 * @author ikerr / http://verold.com
27674	 */
27675
27676	function SkinnedMesh( geometry, material ) {
27677
27678		if ( geometry && geometry.isGeometry ) {
27679
27680			console.error( 'THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
27681
27682		}
27683
27684		Mesh.call( this, geometry, material );
27685
27686		this.type = 'SkinnedMesh';
27687
27688		this.bindMode = 'attached';
27689		this.bindMatrix = new Matrix4();
27690		this.bindMatrixInverse = new Matrix4();
27691
27692	}
27693
27694	SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
27695
27696		constructor: SkinnedMesh,
27697
27698		isSkinnedMesh: true,
27699
27700		copy: function ( source ) {
27701
27702			Mesh.prototype.copy.call( this, source );
27703
27704			this.bindMode = source.bindMode;
27705			this.bindMatrix.copy( source.bindMatrix );
27706			this.bindMatrixInverse.copy( source.bindMatrixInverse );
27707
27708			this.skeleton = source.skeleton;
27709
27710			return this;
27711
27712		},
27713
27714		bind: function ( skeleton, bindMatrix ) {
27715
27716			this.skeleton = skeleton;
27717
27718			if ( bindMatrix === undefined ) {
27719
27720				this.updateMatrixWorld( true );
27721
27722				this.skeleton.calculateInverses();
27723
27724				bindMatrix = this.matrixWorld;
27725
27726			}
27727
27728			this.bindMatrix.copy( bindMatrix );
27729			this.bindMatrixInverse.getInverse( bindMatrix );
27730
27731		},
27732
27733		pose: function () {
27734
27735			this.skeleton.pose();
27736
27737		},
27738
27739		normalizeSkinWeights: function () {
27740
27741			var vector = new Vector4();
27742
27743			var skinWeight = this.geometry.attributes.skinWeight;
27744
27745			for ( var i = 0, l = skinWeight.count; i < l; i ++ ) {
27746
27747				vector.x = skinWeight.getX( i );
27748				vector.y = skinWeight.getY( i );
27749				vector.z = skinWeight.getZ( i );
27750				vector.w = skinWeight.getW( i );
27751
27752				var scale = 1.0 / vector.manhattanLength();
27753
27754				if ( scale !== Infinity ) {
27755
27756					vector.multiplyScalar( scale );
27757
27758				} else {
27759
27760					vector.set( 1, 0, 0, 0 );
27760 // do something reasonable
27761
27762				}
27763
27764				skinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w );
27765
27766			}
27767
27768		},
27769
27770		updateMatrixWorld: function ( force ) {
27771
27772			Mesh.prototype.updateMatrixWorld.call( this, force );
27773
27774			if ( this.bindMode === 'attached' ) {
27775
27776				this.bindMatrixInverse.getInverse( this.matrixWorld );
27777
27778			} else if ( this.bindMode === 'detached' ) {
27779
27780				this.bindMatrixInverse.getInverse( this.bindMatrix );
27781
27782			} else {
27783
27784				console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );
27785
27786			}
27787
27788		},
27789
27790		boneTransform: ( function () {
27791
27792			var basePosition = new Vector3();
27793
27794			var skinIndex = new Vector4();
27795			var skinWeight = new Vector4();
27796
27797			var vector = new Vector3();
27798			var matrix = new Matrix4();
27799
27800			return function ( index, target ) {
27801
27802				var skeleton = this.skeleton;
27803				var geometry = this.geometry;
27804
27805				skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
27806				skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
27807
27808				basePosition.fromBufferAttribute( geometry.attributes.position, index ).applyMatrix4( this.bindMatrix );
27809
27810				target.set( 0, 0, 0 );
27811
27812				for ( var i = 0; i < 4; i ++ ) {
27813
27814					var weight = skinWeight.getComponent( i );
27815
27816					if ( weight !== 0 ) {
27817
27818						var boneIndex = skinIndex.getComponent( i );
27819
27820						matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
27821
27822						target.addScaledVector( vector.copy( basePosition ).applyMatrix4( matrix ), weight );
27823
27824					}
27825
27826				}
27827
27828				return target.applyMatrix4( this.bindMatrixInverse );
27829
27830			};
27831
27832		}() )
27833
27834	} );
27835
27836	/**
27837	 * @author mikael emtinger / http://gomo.se/
27838	 * @author alteredq / http://alteredqualia.com/
27839	 * @author michael guerrero / http://realitymeltdown.com
27840	 * @author ikerr / http://verold.com
27841	 */
27842
27843	var _offsetMatrix = new Matrix4();
27844	var _identityMatrix = new Matrix4();
27845
27846	function Skeleton( bones, boneInverses ) {
27847
27848		// copy the bone array
27849
27850		bones = bones || [];
27851
27852		this.bones = bones.slice( 0 );
27853		this.boneMatrices = new Float32Array( this.bones.length * 16 );
27854
27855		this.frame = - 1;
27856
27857		// use the supplied bone inverses or calculate the inverses
27858
27859		if ( boneInverses === undefined ) {
27860
27861			this.calculateInverses();
27862
27863		} else {
27864
27865			if ( this.bones.length === boneInverses.length ) {
27866
27867				this.boneInverses = boneInverses.slice( 0 );
27868
27869			} else {
27870
27871				console.warn( 'THREE.Skeleton boneInverses is the wrong length.' );
27872
27873				this.boneInverses = [];
27874
27875				for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27876
27877					this.boneInverses.push( new Matrix4() );
27878
27879				}
27880
27881			}
27882
27883		}
27884
27885	}
27886
27887	Object.assign( Skeleton.prototype, {
27888
27889		calculateInverses: function () {
27890
27891			this.boneInverses = [];
27892
27893			for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27894
27895				var inverse = new Matrix4();
27896
27897				if ( this.bones[ i ] ) {
27898
27899					inverse.getInverse( this.bones[ i ].matrixWorld );
27900
27901				}
27902
27903				this.boneInverses.push( inverse );
27904
27905			}
27906
27907		},
27908
27909		pose: function () {
27910
27911			// recover the bind-time world matrices
27912
27913			for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27914
27915				var bone = this.bones[ i ];
27916
27917				if ( bone ) {
27918
27919					bone.matrixWorld.getInverse( this.boneInverses[ i ] );
27920
27921				}
27922
27923			}
27924
27925			// compute the local matrices, positions, rotations and scales
27926
27927			for ( var i$1 = 0, il$1 = this.bones.length; i$1 < il$1; i$1 ++ ) {
27928
27929				var bone$1 = this.bones[ i$1 ];
27930
27931				if ( bone$1 ) {
27932
27933					if ( bone$1.parent && bone$1.parent.isBone ) {
27934
27935						bone$1.matrix.getInverse( bone$1.parent.matrixWorld );
27936						bone$1.matrix.multiply( bone$1.matrixWorld );
27937
27938					} else {
27939
27940						bone$1.matrix.copy( bone$1.matrixWorld );
27941
27942					}
27943
27944					bone$1.matrix.decompose( bone$1.position, bone$1.quaternion, bone$1.scale );
27945
27946				}
27947
27948			}
27949
27950		},
27951
27952		update: function () {
27953
27954			var bones = this.bones;
27955			var boneInverses = this.boneInverses;
27956			var boneMatrices = this.boneMatrices;
27957			var boneTexture = this.boneTexture;
27958
27959			// flatten bone matrices to array
27960
27961			for ( var i = 0, il = bones.length; i < il; i ++ ) {
27962
27963				// compute the offset between the current and the original transform
27964
27965				var matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix;
27966
27967				_offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] );
27968				_offsetMatrix.toArray( boneMatrices, i * 16 );
27969
27970			}
27971
27972			if ( boneTexture !== undefined ) {
27973
27974				boneTexture.needsUpdate = true;
27975
27976			}
27977
27978		},
27979
27980		clone: function () {
27981
27982			return new Skeleton( this.bones, this.boneInverses );
27983
27984		},
27985
27986		getBoneByName: function ( name ) {
27987
27988			for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27989
27990				var bone = this.bones[ i ];
27991
27992				if ( bone.name === name ) {
27993
27994					return bone;
27995
27996				}
27997
27998			}
27999
28000			return undefined;
28001
28002		},
28003
28004		dispose: function ( ) {
28005
28006			if ( this.boneTexture ) {
28007
28008				this.boneTexture.dispose();
28009
28010				this.boneTexture = undefined;
28011
28012			}
28013
28014		}
28015
28016	} );
28017
28018	/**
28019	 * @author mikael emtinger / http://gomo.se/
28020	 * @author alteredq / http://alteredqualia.com/
28021	 * @author ikerr / http://verold.com
28022	 */
28023
28024	function Bone() {
28025
28026		Object3D.call( this );
28027
28028		this.type = 'Bone';
28029
28030	}
28031
28032	Bone.prototype = Object.assign( Object.create( Object3D.prototype ), {
28033
28034		constructor: Bone,
28035
28036		isBone: true
28037
28038	} );
28039
28040	/**
28041	 * @author mrdoob / http://mrdoob.com/
28042	 */
28043
28044	var _instanceLocalMatrix = new Matrix4();
28045	var _instanceWorldMatrix = new Matrix4();
28046
28047	var _instanceIntersects = [];
28048
28049	var _mesh = new Mesh();
28050
28051	function InstancedMesh( geometry, material, count ) {
28052
28053		Mesh.call( this, geometry, material );
28054
28055		this.instanceMatrix = new BufferAttribute( new Float32Array( count * 16 ), 16 );
28056
28057		this.count = count;
28058
28059		this.frustumCulled = false;
28060
28061	}
28062
28063	InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
28064
28065		constructor: InstancedMesh,
28066
28067		isInstancedMesh: true,
28068
28069		copy: function ( source ) {
28070
28071			Mesh.prototype.copy.call( this, source );
28072
28073			this.instanceMatrix.copy( source.instanceMatrix );
28074			this.count = source.count;
28075
28076			return this;
28077
28078		},
28079
28080		getMatrixAt: function ( index, matrix ) {
28081
28082			matrix.fromArray( this.instanceMatrix.array, index * 16 );
28083
28084		},
28085
28086		raycast: function ( raycaster, intersects ) {
28087
28088			var matrixWorld = this.matrixWorld;
28089			var raycastTimes = this.count;
28090
28091			_mesh.geometry = this.geometry;
28092			_mesh.material = this.material;
28093
28094			if ( _mesh.material === undefined ) { return; }
28095
28096			for ( var instanceId = 0; instanceId < raycastTimes; instanceId ++ ) {
28097
28098				// calculate the world matrix for each instance
28099
28100				this.getMatrixAt( instanceId, _instanceLocalMatrix );
28101
28102				_instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix );
28103
28104				// the mesh represents this single instance
28105
28106				_mesh.matrixWorld = _instanceWorldMatrix;
28107
28108				_mesh.raycast( raycaster, _instanceIntersects );
28109
28110				// process the result of raycast
28111
28112				for ( var i = 0, l = _instanceIntersects.length; i < l; i ++ ) {
28113
28114					var intersect = _instanceIntersects[ i ];
28115					intersect.instanceId = instanceId;
28116					intersect.object = this;
28117					intersects.push( intersect );
28118
28119				}
28120
28121				_instanceIntersects.length = 0;
28122
28123			}
28124
28125		},
28126
28127		setMatrixAt: function ( index, matrix ) {
28128
28129			matrix.toArray( this.instanceMatrix.array, index * 16 );
28130
28131		},
28132
28133		updateMorphTargets: function () {
28134
28135		}
28136
28137	} );
28138
28139	/**
28140	 * @author mrdoob / http://mrdoob.com/
28141	 * @author alteredq / http://alteredqualia.com/
28142	 *
28143	 * parameters = {
28144	 *  color: <hex>,
28145	 *  opacity: <float>,
28146	 *
28147	 *  linewidth: <float>,
28148	 *  linecap: "round",
28149	 *  linejoin: "round"
28150	 * }
28151	 */
28152
28153	function LineBasicMaterial( parameters ) {
28154
28155		Material.call( this );
28156
28157		this.type = 'LineBasicMaterial';
28158
28159		this.color = new Color( 0xffffff );
28160
28161		this.linewidth = 1;
28162		this.linecap = 'round';
28163		this.linejoin = 'round';
28164
28165		this.morphTargets = false;
28166
28167		this.setValues( parameters );
28168
28169	}
28170
28171	LineBasicMaterial.prototype = Object.create( Material.prototype );
28172	LineBasicMaterial.prototype.constructor = LineBasicMaterial;
28173
28174	LineBasicMaterial.prototype.isLineBasicMaterial = true;
28175
28176	LineBasicMaterial.prototype.copy = function ( source ) {
28177
28178		Material.prototype.copy.call( this, source );
28179
28180		this.color.copy( source.color );
28181
28182		this.linewidth = source.linewidth;
28183		this.linecap = source.linecap;
28184		this.linejoin = source.linejoin;
28185
28186		this.morphTargets = source.morphTargets;
28187
28188		return this;
28189
28190	};
28191
28192	/**
28193	 * @author mrdoob / http://mrdoob.com/
28194	 */
28195
28196	var _start = new Vector3();
28197	var _end = new Vector3();
28198	var _inverseMatrix$1 = new Matrix4();
28199	var _ray$1 = new Ray();
28200	var _sphere$2 = new Sphere();
28201
28202	function Line( geometry, material, mode ) {
28203
28204		if ( mode === 1 ) {
28205
28206			console.error( 'THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.' );
28207
28208		}
28209
28210		Object3D.call( this );
28211
28212		this.type = 'Line';
28213
28214		this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
28215		this.material = material !== undefined ? material : new LineBasicMaterial();
28216
28217		this.updateMorphTargets();
28218
28219	}
28220
28221	Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
28222
28223		constructor: Line,
28224
28225		isLine: true,
28226
28227		copy: function ( source ) {
28228
28229			Object3D.prototype.copy.call( this, source );
28230
28231			this.material = source.material;
28232			this.geometry = source.geometry;
28233
28234			return this;
28235
28236		},
28237
28238		computeLineDistances: function () {
28239
28240			var geometry = this.geometry;
28241
28242			if ( geometry.isBufferGeometry ) {
28243
28244				// we assume non-indexed geometry
28245
28246				if ( geometry.index === null ) {
28247
28248					var positionAttribute = geometry.attributes.position;
28249					var lineDistances = [ 0 ];
28250
28251					for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) {
28252
28253						_start.fromBufferAttribute( positionAttribute, i - 1 );
28254						_end.fromBufferAttribute( positionAttribute, i );
28255
28256						lineDistances[ i ] = lineDistances[ i - 1 ];
28257						lineDistances[ i ] += _start.distanceTo( _end );
28258
28259					}
28260
28261					geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
28262
28263				} else {
28264
28265					console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
28266
28267				}
28268
28269			} else if ( geometry.isGeometry ) {
28270
28271				var vertices = geometry.vertices;
28272				var lineDistances$1 = geometry.lineDistances;
28273
28274				lineDistances$1[ 0 ] = 0;
28275
28276				for ( var i$1 = 1, l$1 = vertices.length; i$1 < l$1; i$1 ++ ) {
28277
28278					lineDistances$1[ i$1 ] = lineDistances$1[ i$1 - 1 ];
28279					lineDistances$1[ i$1 ] += vertices[ i$1 - 1 ].distanceTo( vertices[ i$1 ] );
28280
28281				}
28282
28283			}
28284
28285			return this;
28286
28287		},
28288
28289		raycast: function ( raycaster, intersects ) {
28290
28291			var geometry = this.geometry;
28292			var matrixWorld = this.matrixWorld;
28293			var threshold = raycaster.params.Line.threshold;
28294
28295			// Checking boundingSphere distance to ray
28296
28297			if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
28298
28299			_sphere$2.copy( geometry.boundingSphere );
28300			_sphere$2.applyMatrix4( matrixWorld );
28301			_sphere$2.radius += threshold;
28302
28303			if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) { return; }
28304
28305			//
28306
28307			_inverseMatrix$1.getInverse( matrixWorld );
28308			_ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );
28309
28310			var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
28311			var localThresholdSq = localThreshold * localThreshold;
28312
28313			var vStart = new Vector3();
28314			var vEnd = new Vector3();
28315			var interSegment = new Vector3();
28316			var interRay = new Vector3();
28317			var step = ( this && this.isLineSegments ) ? 2 : 1;
28318
28319			if ( geometry.isBufferGeometry ) {
28320
28321				var index = geometry.index;
28322				var attributes = geometry.attributes;
28323				var positions = attributes.position.array;
28324
28325				if ( index !== null ) {
28326
28327					var indices = index.array;
28328
28329					for ( var i = 0, l = indices.length - 1; i < l; i += step ) {
28330
28331						var a = indices[ i ];
28332						var b = indices[ i + 1 ];
28333
28334						vStart.fromArray( positions, a * 3 );
28335						vEnd.fromArray( positions, b * 3 );
28336
28337						var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
28338
28339						if ( distSq > localThresholdSq ) { continue; }
28340
28341						interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
28342
28343						var distance = raycaster.ray.origin.distanceTo( interRay );
28344
28345						if ( distance < raycaster.near || distance > raycaster.far ) { continue; }
28346
28347						intersects.push( {
28348
28349							distance: distance,
28350							// What do we want? intersection point on the ray or on the segment??
28351							// point: raycaster.ray.at( distance ),
28352							point: interSegment.clone().applyMatrix4( this.matrixWorld ),
28353							index: i,
28354							face: null,
28355							faceIndex: null,
28356							object: this
28357
28358						} );
28359
28360					}
28361
28362				} else {
28363
28364					for ( var i$1 = 0, l$1 = positions.length / 3 - 1; i$1 < l$1; i$1 += step ) {
28365
28366						vStart.fromArray( positions, 3 * i$1 );
28367						vEnd.fromArray( positions, 3 * i$1 + 3 );
28368
28369						var distSq$1 = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
28370
28371						if ( distSq$1 > localThresholdSq ) { continue; }
28372
28373						interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
28374
28375						var distance$1 = raycaster.ray.origin.distanceTo( interRay );
28376
28377						if ( distance$1 < raycaster.near || distance$1 > raycaster.far ) { continue; }
28378
28379						intersects.push( {
28380
28381							distance: distance$1,
28382							// What do we want? intersection point on the ray or on the segment??
28383							// point: raycaster.ray.at( distance ),
28384							point: interSegment.clone().applyMatrix4( this.matrixWorld ),
28385							index: i$1,
28386							face: null,
28387							faceIndex: null,
28388							object: this
28389
28390						} );
28391
28392					}
28393
28394				}
28395
28396			} else if ( geometry.isGeometry ) {
28397
28398				var vertices = geometry.vertices;
28399				var nbVertices = vertices.length;
28400
28401				for ( var i$2 = 0; i$2 < nbVertices - 1; i$2 += step ) {
28402
28403					var distSq$2 = _ray$1.distanceSqToSegment( vertices[ i$2 ], vertices[ i$2 + 1 ], interRay, interSegment );
28404
28405					if ( distSq$2 > localThresholdSq ) { continue; }
28406
28407					interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
28408
28409					var distance$2 = raycaster.ray.origin.distanceTo( interRay );
28410
28411					if ( distance$2 < raycaster.near || distance$2 > raycaster.far ) { continue; }
28412
28413					intersects.push( {
28414
28415						distance: distance$2,
28416						// What do we want? intersection point on the ray or on the segment??
28417						// point: raycaster.ray.at( distance ),
28418						point: interSegment.clone().applyMatrix4( this.matrixWorld ),
28419						index: i$2,
28420						face: null,
28421						faceIndex: null,
28422						object: this
28423
28424					} );
28425
28426				}
28427
28428			}
28429
28430		},
28431
28432		updateMorphTargets: function () {
28433
28434			var geometry = this.geometry;
28435
28436			if ( geometry.isBufferGeometry ) {
28437
28438				var morphAttributes = geometry.morphAttributes;
28439				var keys = Object.keys( morphAttributes );
28440
28441				if ( keys.length > 0 ) {
28442
28443					var morphAttribute = morphAttributes[ keys[ 0 ] ];
28444
28445					if ( morphAttribute !== undefined ) {
28446
28447						this.morphTargetInfluences = [];
28448						this.morphTargetDictionary = {};
28449
28450						for ( var m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
28451
28452							var name = morphAttribute[ m ].name || String( m );
28453
28454							this.morphTargetInfluences.push( 0 );
28455							this.morphTargetDictionary[ name ] = m;
28456
28457						}
28458
28459					}
28460
28461				}
28462
28463			} else {
28464
28465				var morphTargets = geometry.morphTargets;
28466
28467				if ( morphTargets !== undefined && morphTargets.length > 0 ) {
28468
28469					console.error( 'THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
28470
28471				}
28472
28473			}
28474
28475		}
28476
28477	} );
28478
28479	/**
28480	 * @author mrdoob / http://mrdoob.com/
28481	 */
28482
28483	var _start$1 = new Vector3();
28484	var _end$1 = new Vector3();
28485
28486	function LineSegments( geometry, material ) {
28487
28488		Line.call( this, geometry, material );
28489
28490		this.type = 'LineSegments';
28491
28492	}
28493
28494	LineSegments.prototype = Object.assign( Object.create( Line.prototype ), {
28495
28496		constructor: LineSegments,
28497
28498		isLineSegments: true,
28499
28500		computeLineDistances: function () {
28501
28502			var geometry = this.geometry;
28503
28504			if ( geometry.isBufferGeometry ) {
28505
28506				// we assume non-indexed geometry
28507
28508				if ( geometry.index === null ) {
28509
28510					var positionAttribute = geometry.attributes.position;
28511					var lineDistances = [];
28512
28513					for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) {
28514
28515						_start$1.fromBufferAttribute( positionAttribute, i );
28516						_end$1.fromBufferAttribute( positionAttribute, i + 1 );
28517
28518						lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
28519						lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
28520
28521					}
28522
28523					geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
28524
28525				} else {
28526
28527					console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
28528
28529				}
28530
28531			} else if ( geometry.isGeometry ) {
28532
28533				var vertices = geometry.vertices;
28534				var lineDistances$1 = geometry.lineDistances;
28535
28536				for ( var i$1 = 0, l$1 = vertices.length; i$1 < l$1; i$1 += 2 ) {
28537
28538					_start$1.copy( vertices[ i$1 ] );
28539					_end$1.copy( vertices[ i$1 + 1 ] );
28540
28541					lineDistances$1[ i$1 ] = ( i$1 === 0 ) ? 0 : lineDistances$1[ i$1 - 1 ];
28542					lineDistances$1[ i$1 + 1 ] = lineDistances$1[ i$1 ] + _start$1.distanceTo( _end$1 );
28543
28544				}
28545
28546			}
28547
28548			return this;
28549
28550		}
28551
28552	} );
28553
28554	/**
28555	 * @author mgreter / http://github.com/mgreter
28556	 */
28557
28558	function LineLoop( geometry, material ) {
28559
28560		Line.call( this, geometry, material );
28561
28562		this.type = 'LineLoop';
28563
28564	}
28565
28566	LineLoop.prototype = Object.assign( Object.create( Line.prototype ), {
28567
28568		constructor: LineLoop,
28569
28570		isLineLoop: true,
28571
28572	} );
28573
28574	/**
28575	 * @author mrdoob / http://mrdoob.com/
28576	 * @author alteredq / http://alteredqualia.com/
28577	 *
28578	 * parameters = {
28579	 *  color: <hex>,
28580	 *  opacity: <float>,
28581	 *  map: new THREE.Texture( <Image> ),
28582	 *  alphaMap: new THREE.Texture( <Image> ),
28583	 *
28584	 *  size: <float>,
28585	 *  sizeAttenuation: <bool>
28586	 *
28587	 *  morphTargets: <bool>
28588	 * }
28589	 */
28590
28591	function PointsMaterial( parameters ) {
28592
28593		Material.call( this );
28594
28595		this.type = 'PointsMaterial';
28596
28597		this.color = new Color( 0xffffff );
28598
28599		this.map = null;
28600
28601		this.alphaMap = null;
28602
28603		this.size = 1;
28604		this.sizeAttenuation = true;
28605
28606		this.morphTargets = false;
28607
28608		this.setValues( parameters );
28609
28610	}
28611
28612	PointsMaterial.prototype = Object.create( Material.prototype );
28613	PointsMaterial.prototype.constructor = PointsMaterial;
28614
28615	PointsMaterial.prototype.isPointsMaterial = true;
28616
28617	PointsMaterial.prototype.copy = function ( source ) {
28618
28619		Material.prototype.copy.call( this, source );
28620
28621		this.color.copy( source.color );
28622
28623		this.map = source.map;
28624
28625		this.alphaMap = source.alphaMap;
28626
28627		this.size = source.size;
28628		this.sizeAttenuation = source.sizeAttenuation;
28629
28630		this.morphTargets = source.morphTargets;
28631
28632		return this;
28633
28634	};
28635
28636	/**
28637	 * @author alteredq / http://alteredqualia.com/
28638	 */
28639
28640	var _inverseMatrix$2 = new Matrix4();
28641	var _ray$2 = new Ray();
28642	var _sphere$3 = new Sphere();
28643	var _position$1 = new Vector3();
28644
28645	function Points( geometry, material ) {
28646
28647		Object3D.call( this );
28648
28649		this.type = 'Points';
28650
28651		this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
28652		this.material = material !== undefined ? material : new PointsMaterial();
28653
28654		this.updateMorphTargets();
28655
28656	}
28657
28658	Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
28659
28660		constructor: Points,
28661
28662		isPoints: true,
28663
28664		copy: function ( source ) {
28665
28666			Object3D.prototype.copy.call( this, source );
28667
28668			this.material = source.material;
28669			this.geometry = source.geometry;
28670
28671			return this;
28672
28673		},
28674
28675		raycast: function ( raycaster, intersects ) {
28676
28677			var geometry = this.geometry;
28678			var matrixWorld = this.matrixWorld;
28679			var threshold = raycaster.params.Points.threshold;
28680
28681			// Checking boundingSphere distance to ray
28682
28683			if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
28684
28685			_sphere$3.copy( geometry.boundingSphere );
28686			_sphere$3.applyMatrix4( matrixWorld );
28687			_sphere$3.radius += threshold;
28688
28689			if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) { return; }
28690
28691			//
28692
28693			_inverseMatrix$2.getInverse( matrixWorld );
28694			_ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
28695
28696			var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
28697			var localThresholdSq = localThreshold * localThreshold;
28698
28699			if ( geometry.isBufferGeometry ) {
28700
28701				var index = geometry.index;
28702				var attributes = geometry.attributes;
28703				var positions = attributes.position.array;
28704
28705				if ( index !== null ) {
28706
28707					var indices = index.array;
28708
28709					for ( var i = 0, il = indices.length; i < il; i ++ ) {
28710
28711						var a = indices[ i ];
28712
28713						_position$1.fromArray( positions, a * 3 );
28714
28715						testPoint( _position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this );
28716
28717					}
28718
28719				} else {
28720
28721					for ( var i$1 = 0, l = positions.length / 3; i$1 < l; i$1 ++ ) {
28722
28723						_position$1.fromArray( positions, i$1 * 3 );
28724
28725						testPoint( _position$1, i$1, localThresholdSq, matrixWorld, raycaster, intersects, this );
28726
28727					}
28728
28729				}
28730
28731			} else {
28732
28733				var vertices = geometry.vertices;
28734
28735				for ( var i$2 = 0, l$1 = vertices.length; i$2 < l$1; i$2 ++ ) {
28736
28737					testPoint( vertices[ i$2 ], i$2, localThresholdSq, matrixWorld, raycaster, intersects, this );
28738
28739				}
28740
28741			}
28742
28743		},
28744
28745		updateMorphTargets: function () {
28746
28747			var geometry = this.geometry;
28748
28749			if ( geometry.isBufferGeometry ) {
28750
28751				var morphAttributes = geometry.morphAttributes;
28752				var keys = Object.keys( morphAttributes );
28753
28754				if ( keys.length > 0 ) {
28755
28756					var morphAttribute = morphAttributes[ keys[ 0 ] ];
28757
28758					if ( morphAttribute !== undefined ) {
28759
28760						this.morphTargetInfluences = [];
28761						this.morphTargetDictionary = {};
28762
28763						for ( var m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
28764
28765							var name = morphAttribute[ m ].name || String( m );
28766
28767							this.morphTargetInfluences.push( 0 );
28768							this.morphTargetDictionary[ name ] = m;
28769
28770						}
28771
28772					}
28773
28774				}
28775
28776			} else {
28777
28778				var morphTargets = geometry.morphTargets;
28779
28780				if ( morphTargets !== undefined && morphTargets.length > 0 ) {
28781
28782					console.error( 'THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
28783
28784				}
28785
28786			}
28787
28788		}
28789
28790	} );
28791
28792	function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
28793
28794		var rayPointDistanceSq = _ray$2.distanceSqToPoint( point );
28795
28796		if ( rayPointDistanceSq < localThresholdSq ) {
28797
28798			var intersectPoint = new Vector3();
28799
28800			_ray$2.closestPointToPoint( point, intersectPoint );
28801			intersectPoint.applyMatrix4( matrixWorld );
28802
28803			var distance = raycaster.ray.origin.distanceTo( intersectPoint );
28804
28805			if ( distance < raycaster.near || distance > raycaster.far ) { return; }
28806
28807			intersects.push( {
28808
28809				distance: distance,
28810				distanceToRay: Math.sqrt( rayPointDistanceSq ),
28811				point: intersectPoint,
28812				index: index,
28813				face: null,
28814				object: object
28815
28816			} );
28817
28818		}
28819
28820	}
28821
28822	/**
28823	 * @author mrdoob / http://mrdoob.com/
28824	 */
28825
28826	function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
28827
28828		Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
28829
28830		this.format = format !== undefined ? format : RGBFormat;
28831
28832		this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
28833		this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
28834
28835		this.generateMipmaps = false;
28836
28837	}
28838
28839	VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), {
28840
28841		constructor: VideoTexture,
28842
28843		isVideoTexture: true,
28844
28845		update: function () {
28846
28847			var video = this.image;
28848
28849			if ( video.readyState >= video.HAVE_CURRENT_DATA ) {
28850
28851				this.needsUpdate = true;
28852
28853			}
28854
28855		}
28856
28857	} );
28858
28859	/**
28860	 * @author alteredq / http://alteredqualia.com/
28861	 */
28862
28863	function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
28864
28865		Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
28866
28867		this.image = { width: width, height: height };
28868		this.mipmaps = mipmaps;
28869
28870		// no flipping for cube textures
28871		// (also flipping doesn't work for compressed textures )
28872
28873		this.flipY = false;
28874
28875		// can't generate mipmaps for compressed textures
28876		// mips must be embedded in DDS files
28877
28878		this.generateMipmaps = false;
28879
28880	}
28881
28882	CompressedTexture.prototype = Object.create( Texture.prototype );
28883	CompressedTexture.prototype.constructor = CompressedTexture;
28884
28885	CompressedTexture.prototype.isCompressedTexture = true;
28886
28887	/**
28888	 * @author mrdoob / http://mrdoob.com/
28889	 */
28890
28891	function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
28892
28893		Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
28894
28895		this.needsUpdate = true;
28896
28897	}
28898
28899	CanvasTexture.prototype = Object.create( Texture.prototype );
28900	CanvasTexture.prototype.constructor = CanvasTexture;
28901	CanvasTexture.prototype.isCanvasTexture = true;
28902
28903	/**
28904	 * @author Matt DesLauriers / @mattdesl
28905	 * @author atix / arthursilber.de
28906	 */
28907
28908	function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
28909
28910		format = format !== undefined ? format : DepthFormat;
28911
28912		if ( format !== DepthFormat && format !== DepthStencilFormat ) {
28913
28914			throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
28915
28916		}
28917
28918		if ( type === undefined && format === DepthFormat ) { type = UnsignedShortType; }
28919		if ( type === undefined && format === DepthStencilFormat ) { type = UnsignedInt248Type; }
28920
28921		Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
28922
28923		this.image = { width: width, height: height };
28924
28925		this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
28926		this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
28927
28928		this.flipY = false;
28929		this.generateMipmaps	= false;
28930
28931	}
28932
28933	DepthTexture.prototype = Object.create( Texture.prototype );
28934	DepthTexture.prototype.constructor = DepthTexture;
28935	DepthTexture.prototype.isDepthTexture = true;
28936
28937	/**
28938	 * @author mrdoob / http://mrdoob.com/
28939	 * @author Mugen87 / https://github.com/Mugen87
28940	 */
28941
28942	function WireframeGeometry( geometry ) {
28943
28944		BufferGeometry.call( this );
28945
28946		this.type = 'WireframeGeometry';
28947
28948		// buffer
28949
28950		var vertices = [];
28951
28952		// helper variables
28953
28954		var edge = [ 0, 0 ], edges = {};
28955		var keys = [ 'a', 'b', 'c' ];
28956
28957		// different logic for Geometry and BufferGeometry
28958
28959		if ( geometry && geometry.isGeometry ) {
28960
28961			// create a data structure that contains all edges without duplicates
28962
28963			var faces = geometry.faces;
28964
28965			for ( var i = 0, l = faces.length; i < l; i ++ ) {
28966
28967				var face = faces[ i ];
28968
28969				for ( var j = 0; j < 3; j ++ ) {
28970
28971					var edge1 = face[ keys[ j ] ];
28972					var edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
28973					edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
28974					edge[ 1 ] = Math.max( edge1, edge2 );
28975
28976					var key = edge[ 0 ] + ',' + edge[ 1 ];
28977
28978					if ( edges[ key ] === undefined ) {
28979
28980						edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
28981
28982					}
28983
28984				}
28985
28986			}
28987
28988			// generate vertices
28989
28990			for ( var key$1 in edges ) {
28991
28992				var e = edges[ key$1 ];
28993
28994				var vertex = geometry.vertices[ e.index1 ];
28995				vertices.push( vertex.x, vertex.y, vertex.z );
28996
28997				vertex = geometry.vertices[ e.index2 ];
28998				vertices.push( vertex.x, vertex.y, vertex.z );
28999
29000			}
29001
29002		} else if ( geometry && geometry.isBufferGeometry ) {
29003
29004			var vertex$1 = new Vector3();
29005
29006			if ( geometry.index !== null ) {
29007
29008				// indexed BufferGeometry
29009
29010				var position = geometry.attributes.position;
29011				var indices = geometry.index;
29012				var groups = geometry.groups;
29013
29014				if ( groups.length === 0 ) {
29015
29016					groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
29017
29018				}
29019
29020				// create a data structure that contains all eges without duplicates
29021
29022				for ( var o = 0, ol = groups.length; o < ol; ++ o ) {
29023
29024					var group = groups[ o ];
29025
29026					var start = group.start;
29027					var count = group.count;
29028
29029					for ( var i$1 = start, l$1 = ( start + count ); i$1 < l$1; i$1 += 3 ) {
29030
29031						for ( var j$1 = 0; j$1 < 3; j$1 ++ ) {
29032
29033							var edge1$1 = indices.getX( i$1 + j$1 );
29034							var edge2$1 = indices.getX( i$1 + ( j$1 + 1 ) % 3 );
29035							edge[ 0 ] = Math.min( edge1$1, edge2$1 ); // sorting prevents duplicates
29036							edge[ 1 ] = Math.max( edge1$1, edge2$1 );
29037
29038							var key$2 = edge[ 0 ] + ',' + edge[ 1 ];
29039
29040							if ( edges[ key$2 ] === undefined ) {
29041
29042								edges[ key$2 ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
29043
29044							}
29045
29046						}
29047
29048					}
29049
29050				}
29051
29052				// generate vertices
29053
29054				for ( var key$3 in edges ) {
29055
29056					var e$1 = edges[ key$3 ];
29057
29058					vertex$1.fromBufferAttribute( position, e$1.index1 );
29059					vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
29060
29061					vertex$1.fromBufferAttribute( position, e$1.index2 );
29062					vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
29063
29064				}
29065
29066			} else {
29067
29068				// non-indexed BufferGeometry
29069
29070				var position$1 = geometry.attributes.position;
29071
29072				for ( var i$2 = 0, l$2 = ( position$1.count / 3 ); i$2 < l$2; i$2 ++ ) {
29073
29074					for ( var j$2 = 0; j$2 < 3; j$2 ++ ) {
29075
29076						// three edges per triangle, an edge is represented as (index1, index2)
29077						// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
29078
29079						var index1 = 3 * i$2 + j$2;
29080						vertex$1.fromBufferAttribute( position$1, index1 );
29081						vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
29082
29083						var index2 = 3 * i$2 + ( ( j$2 + 1 ) % 3 );
29084						vertex$1.fromBufferAttribute( position$1, index2 );
29085						vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
29086
29087					}
29088
29089				}
29090
29091			}
29092
29093		}
29094
29095		// build geometry
29096
29097		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
29098
29099	}
29100
29101	WireframeGeometry.prototype = Object.create( BufferGeometry.prototype );
29102	WireframeGeometry.prototype.constructor = WireframeGeometry;
29103
29104	/**
29105	 * @author zz85 / https://github.com/zz85
29106	 * @author Mugen87 / https://github.com/Mugen87
29107	 *
29108	 * Parametric Surfaces Geometry
29109	 * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html
29110	 */
29111
29112	// ParametricGeometry
29113
29114	function ParametricGeometry( func, slices, stacks ) {
29115
29116		Geometry.call( this );
29117
29118		this.type = 'ParametricGeometry';
29119
29120		this.parameters = {
29121			func: func,
29122			slices: slices,
29123			stacks: stacks
29124		};
29125
29126		this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );
29127		this.mergeVertices();
29128
29129	}
29130
29131	ParametricGeometry.prototype = Object.create( Geometry.prototype );
29132	ParametricGeometry.prototype.constructor = ParametricGeometry;
29133
29134	// ParametricBufferGeometry
29135
29136	function ParametricBufferGeometry( func, slices, stacks ) {
29137
29138		BufferGeometry.call( this );
29139
29140		this.type = 'ParametricBufferGeometry';
29141
29142		this.parameters = {
29143			func: func,
29144			slices: slices,
29145			stacks: stacks
29146		};
29147
29148		// buffers
29149
29150		var indices = [];
29151		var vertices = [];
29152		var normals = [];
29153		var uvs = [];
29154
29155		var EPS = 0.00001;
29156
29157		var normal = new Vector3();
29158
29159		var p0 = new Vector3(), p1 = new Vector3();
29160		var pu = new Vector3(), pv = new Vector3();
29161
29162		if ( func.length < 3 ) {
29163
29164			console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' );
29165
29166		}
29167
29168		// generate vertices, normals and uvs
29169
29170		var sliceCount = slices + 1;
29171
29172		for ( var i = 0; i <= stacks; i ++ ) {
29173
29174			var v = i / stacks;
29175
29176			for ( var j = 0; j <= slices; j ++ ) {
29177
29178				var u = j / slices;
29179
29180				// vertex
29181
29182				func( u, v, p0 );
29183				vertices.push( p0.x, p0.y, p0.z );
29184
29185				// normal
29186
29187				// approximate tangent vectors via finite differences
29188
29189				if ( u - EPS >= 0 ) {
29190
29191					func( u - EPS, v, p1 );
29192					pu.subVectors( p0, p1 );
29193
29194				} else {
29195
29196					func( u + EPS, v, p1 );
29197					pu.subVectors( p1, p0 );
29198
29199				}
29200
29201				if ( v - EPS >= 0 ) {
29202
29203					func( u, v - EPS, p1 );
29204					pv.subVectors( p0, p1 );
29205
29206				} else {
29207
29208					func( u, v + EPS, p1 );
29209					pv.subVectors( p1, p0 );
29210
29211				}
29212
29213				// cross product of tangent vectors returns surface normal
29214
29215				normal.crossVectors( pu, pv ).normalize();
29216				normals.push( normal.x, normal.y, normal.z );
29217
29218				// uv
29219
29220				uvs.push( u, v );
29221
29222			}
29223
29224		}
29225
29226		// generate indices
29227
29228		for ( var i$1 = 0; i$1 < stacks; i$1 ++ ) {
29229
29230			for ( var j$1 = 0; j$1 < slices; j$1 ++ ) {
29231
29232				var a = i$1 * sliceCount + j$1;
29233				var b = i$1 * sliceCount + j$1 + 1;
29234				var c = ( i$1 + 1 ) * sliceCount + j$1 + 1;
29235				var d = ( i$1 + 1 ) * sliceCount + j$1;
29236
29237				// faces one and two
29238
29239				indices.push( a, b, d );
29240				indices.push( b, c, d );
29241
29242			}
29243
29244		}
29245
29246		// build geometry
29247
29248		this.setIndex( indices );
29249		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
29250		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
29251		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
29252
29253	}
29254
29255	ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
29256	ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;
29257
29258	/**
29259	 * @author clockworkgeek / https://github.com/clockworkgeek
29260	 * @author timothypratley / https://github.com/timothypratley
29261	 * @author WestLangley / http://github.com/WestLangley
29262	 * @author Mugen87 / https://github.com/Mugen87
29263	 */
29264
29265	// PolyhedronGeometry
29266
29267	function PolyhedronGeometry( vertices, indices, radius, detail ) {
29268
29269		Geometry.call( this );
29270
29271		this.type = 'PolyhedronGeometry';
29272
29273		this.parameters = {
29274			vertices: vertices,
29275			indices: indices,
29276			radius: radius,
29277			detail: detail
29278		};
29279
29280		this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );
29281		this.mergeVertices();
29282
29283	}
29284
29285	PolyhedronGeometry.prototype = Object.create( Geometry.prototype );
29286	PolyhedronGeometry.prototype.constructor = PolyhedronGeometry;
29287
29288	// PolyhedronBufferGeometry
29289
29290	function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
29291
29292		BufferGeometry.call( this );
29293
29294		this.type = 'PolyhedronBufferGeometry';
29295
29296		this.parameters = {
29297			vertices: vertices,
29298			indices: indices,
29299			radius: radius,
29300			detail: detail
29301		};
29302
29303		radius = radius || 1;
29304		detail = detail || 0;
29305
29306		// default buffer data
29307
29308		var vertexBuffer = [];
29309		var uvBuffer = [];
29310
29311		// the subdivision creates the vertex buffer data
29312
29313		subdivide( detail );
29314
29315		// all vertices should lie on a conceptual sphere with a given radius
29316
29317		applyRadius( radius );
29318
29319		// finally, create the uv data
29320
29321		generateUVs();
29322
29323		// build non-indexed geometry
29324
29325		this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );
29326		this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );
29327		this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );
29328
29329		if ( detail === 0 ) {
29330
29331			this.computeVertexNormals(); // flat normals
29332
29333		} else {
29334
29335			this.normalizeNormals(); // smooth normals
29336
29337		}
29338
29339		// helper functions
29340
29341		function subdivide( detail ) {
29342
29343			var a = new Vector3();
29344			var b = new Vector3();
29345			var c = new Vector3();
29346
29347			// iterate over all faces and apply a subdivison with the given detail value
29348
29349			for ( var i = 0; i < indices.length; i += 3 ) {
29350
29351				// get the vertices of the face
29352
29353				getVertexByIndex( indices[ i + 0 ], a );
29354				getVertexByIndex( indices[ i + 1 ], b );
29355				getVertexByIndex( indices[ i + 2 ], c );
29356
29357				// perform subdivision
29358
29359				subdivideFace( a, b, c, detail );
29360
29361			}
29362
29363		}
29364
29365		function subdivideFace( a, b, c, detail ) {
29366
29367			var cols = Math.pow( 2, detail );
29368
29369			// we use this multidimensional array as a data structure for creating the subdivision
29370
29371			var v = [];
29372
29373			// construct all of the vertices for this subdivision
29374
29375			for ( var i = 0; i <= cols; i ++ ) {
29376
29377				v[ i ] = [];
29378
29379				var aj = a.clone().lerp( c, i / cols );
29380				var bj = b.clone().lerp( c, i / cols );
29381
29382				var rows = cols - i;
29383
29384				for ( var j = 0; j <= rows; j ++ ) {
29385
29386					if ( j === 0 && i === cols ) {
29387
29388						v[ i ][ j ] = aj;
29389
29390					} else {
29391
29392						v[ i ][ j ] = aj.clone().lerp( bj, j / rows );
29393
29394					}
29395
29396				}
29397
29398			}
29399
29400			// construct all of the faces
29401
29402			for ( var i$1 = 0; i$1 < cols; i$1 ++ ) {
29403
29404				for ( var j$1 = 0; j$1 < 2 * ( cols - i$1 ) - 1; j$1 ++ ) {
29405
29406					var k = Math.floor( j$1 / 2 );
29407
29408					if ( j$1 % 2 === 0 ) {
29409
29410						pushVertex( v[ i$1 ][ k + 1 ] );
29411						pushVertex( v[ i$1 + 1 ][ k ] );
29412						pushVertex( v[ i$1 ][ k ] );
29413
29414					} else {
29415
29416						pushVertex( v[ i$1 ][ k + 1 ] );
29417						pushVertex( v[ i$1 + 1 ][ k + 1 ] );
29418						pushVertex( v[ i$1 + 1 ][ k ] );
29419
29420					}
29421
29422				}
29423
29424			}
29425
29426		}
29427
29428		function applyRadius( radius ) {
29429
29430			var vertex = new Vector3();
29431
29432			// iterate over the entire buffer and apply the radius to each vertex
29433
29434			for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
29435
29436				vertex.x = vertexBuffer[ i + 0 ];
29437				vertex.y = vertexBuffer[ i + 1 ];
29438				vertex.z = vertexBuffer[ i + 2 ];
29439
29440				vertex.normalize().multiplyScalar( radius );
29441
29442				vertexBuffer[ i + 0 ] = vertex.x;
29443				vertexBuffer[ i + 1 ] = vertex.y;
29444				vertexBuffer[ i + 2 ] = vertex.z;
29445
29446			}
29447
29448		}
29449
29450		function generateUVs() {
29451
29452			var vertex = new Vector3();
29453
29454			for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
29455
29456				vertex.x = vertexBuffer[ i + 0 ];
29457				vertex.y = vertexBuffer[ i + 1 ];
29458				vertex.z = vertexBuffer[ i + 2 ];
29459
29460				var u = azimuth( vertex ) / 2 / Math.PI + 0.5;
29461				var v = inclination( vertex ) / Math.PI + 0.5;
29462				uvBuffer.push( u, 1 - v );
29463
29464			}
29465
29466			correctUVs();
29467
29468			correctSeam();
29469
29470		}
29471
29472		function correctSeam() {
29473
29474			// handle case when face straddles the seam, see #3269
29475
29476			for ( var i = 0; i < uvBuffer.length; i += 6 ) {
29477
29478				// uv data of a single face
29479
29480				var x0 = uvBuffer[ i + 0 ];
29481				var x1 = uvBuffer[ i + 2 ];
29482				var x2 = uvBuffer[ i + 4 ];
29483
29484				var max = Math.max( x0, x1, x2 );
29485				var min = Math.min( x0, x1, x2 );
29486
29487				// 0.9 is somewhat arbitrary
29488
29489				if ( max > 0.9 && min < 0.1 ) {
29490
29491					if ( x0 < 0.2 ) { uvBuffer[ i + 0 ] += 1; }
29492					if ( x1 < 0.2 ) { uvBuffer[ i + 2 ] += 1; }
29493					if ( x2 < 0.2 ) { uvBuffer[ i + 4 ] += 1; }
29494
29495				}
29496
29497			}
29498
29499		}
29500
29501		function pushVertex( vertex ) {
29502
29503			vertexBuffer.push( vertex.x, vertex.y, vertex.z );
29504
29505		}
29506
29507		function getVertexByIndex( index, vertex ) {
29508
29509			var stride = index * 3;
29510
29511			vertex.x = vertices[ stride + 0 ];
29512			vertex.y = vertices[ stride + 1 ];
29513			vertex.z = vertices[ stride + 2 ];
29514
29515		}
29516
29517		function correctUVs() {
29518
29519			var a = new Vector3();
29520			var b = new Vector3();
29521			var c = new Vector3();
29522
29523			var centroid = new Vector3();
29524
29525			var uvA = new Vector2();
29526			var uvB = new Vector2();
29527			var uvC = new Vector2();
29528
29529			for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {
29530
29531				a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );
29532				b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );
29533				c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );
29534
29535				uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );
29536				uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );
29537				uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );
29538
29539				centroid.copy( a ).add( b ).add( c ).divideScalar( 3 );
29540
29541				var azi = azimuth( centroid );
29542
29543				correctUV( uvA, j + 0, a, azi );
29544				correctUV( uvB, j + 2, b, azi );
29545				correctUV( uvC, j + 4, c, azi );
29546
29547			}
29548
29549		}
29550
29551		function correctUV( uv, stride, vector, azimuth ) {
29552
29553			if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {
29554
29555				uvBuffer[ stride ] = uv.x - 1;
29556
29557			}
29558
29559			if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {
29560
29561				uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;
29562
29563			}
29564
29565		}
29566
29567		// Angle around the Y axis, counter-clockwise when looking from above.
29568
29569		function azimuth( vector ) {
29570
29571			return Math.atan2( vector.z, - vector.x );
29572
29573		}
29574
29575
29576		// Angle above the XZ plane.
29577
29578		function inclination( vector ) {
29579
29580			return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
29581
29582		}
29583
29584	}
29585
29586	PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
29587	PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;
29588
29589	/**
29590	 * @author timothypratley / https://github.com/timothypratley
29591	 * @author Mugen87 / https://github.com/Mugen87
29592	 */
29593
29594	// TetrahedronGeometry
29595
29596	function TetrahedronGeometry( radius, detail ) {
29597
29598		Geometry.call( this );
29599
29600		this.type = 'TetrahedronGeometry';
29601
29602		this.parameters = {
29603			radius: radius,
29604			detail: detail
29605		};
29606
29607		this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
29608		this.mergeVertices();
29609
29610	}
29611
29612	TetrahedronGeometry.prototype = Object.create( Geometry.prototype );
29613	TetrahedronGeometry.prototype.constructor = TetrahedronGeometry;
29614
29615	// TetrahedronBufferGeometry
29616
29617	function TetrahedronBufferGeometry( radius, detail ) {
29618
29619		var vertices = [
29620			1, 1, 1, 	- 1, - 1, 1, 	- 1, 1, - 1, 	1, - 1, - 1
29621		];
29622
29623		var indices = [
29624			2, 1, 0, 	0, 3, 2,	1, 3, 0,	2, 3, 1
29625		];
29626
29627		PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29628
29629		this.type = 'TetrahedronBufferGeometry';
29630
29631		this.parameters = {
29632			radius: radius,
29633			detail: detail
29634		};
29635
29636	}
29637
29638	TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29639	TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;
29640
29641	/**
29642	 * @author timothypratley / https://github.com/timothypratley
29643	 * @author Mugen87 / https://github.com/Mugen87
29644	 */
29645
29646	// OctahedronGeometry
29647
29648	function OctahedronGeometry( radius, detail ) {
29649
29650		Geometry.call( this );
29651
29652		this.type = 'OctahedronGeometry';
29653
29654		this.parameters = {
29655			radius: radius,
29656			detail: detail
29657		};
29658
29659		this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );
29660		this.mergeVertices();
29661
29662	}
29663
29664	OctahedronGeometry.prototype = Object.create( Geometry.prototype );
29665	OctahedronGeometry.prototype.constructor = OctahedronGeometry;
29666
29667	// OctahedronBufferGeometry
29668
29669	function OctahedronBufferGeometry( radius, detail ) {
29670
29671		var vertices = [
29672			1, 0, 0, 	- 1, 0, 0,	0, 1, 0,
29673			0, - 1, 0, 	0, 0, 1,	0, 0, - 1
29674		];
29675
29676		var indices = [
29677			0, 2, 4,	0, 4, 3,	0, 3, 5,
29678			0, 5, 2,	1, 2, 5,	1, 5, 3,
29679			1, 3, 4,	1, 4, 2
29680		];
29681
29682		PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29683
29684		this.type = 'OctahedronBufferGeometry';
29685
29686		this.parameters = {
29687			radius: radius,
29688			detail: detail
29689		};
29690
29691	}
29692
29693	OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29694	OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;
29695
29696	/**
29697	 * @author timothypratley / https://github.com/timothypratley
29698	 * @author Mugen87 / https://github.com/Mugen87
29699	 */
29700
29701	// IcosahedronGeometry
29702
29703	function IcosahedronGeometry( radius, detail ) {
29704
29705		Geometry.call( this );
29706
29707		this.type = 'IcosahedronGeometry';
29708
29709		this.parameters = {
29710			radius: radius,
29711			detail: detail
29712		};
29713
29714		this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );
29715		this.mergeVertices();
29716
29717	}
29718
29719	IcosahedronGeometry.prototype = Object.create( Geometry.prototype );
29720	IcosahedronGeometry.prototype.constructor = IcosahedronGeometry;
29721
29722	// IcosahedronBufferGeometry
29723
29724	function IcosahedronBufferGeometry( radius, detail ) {
29725
29726		var t = ( 1 + Math.sqrt( 5 ) ) / 2;
29727
29728		var vertices = [
29729			- 1, t, 0, 	1, t, 0, 	- 1, - t, 0, 	1, - t, 0,
29730			 0, - 1, t, 	0, 1, t,	0, - 1, - t, 	0, 1, - t,
29731			 t, 0, - 1, 	t, 0, 1, 	- t, 0, - 1, 	- t, 0, 1
29732		];
29733
29734		var indices = [
29735			 0, 11, 5, 	0, 5, 1, 	0, 1, 7, 	0, 7, 10, 	0, 10, 11,
29736			 1, 5, 9, 	5, 11, 4,	11, 10, 2,	10, 7, 6,	7, 1, 8,
29737			 3, 9, 4, 	3, 4, 2,	3, 2, 6,	3, 6, 8,	3, 8, 9,
29738			 4, 9, 5, 	2, 4, 11,	6, 2, 10,	8, 6, 7,	9, 8, 1
29739		];
29740
29741		PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29742
29743		this.type = 'IcosahedronBufferGeometry';
29744
29745		this.parameters = {
29746			radius: radius,
29747			detail: detail
29748		};
29749
29750	}
29751
29752	IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29753	IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;
29754
29755	/**
29756	 * @author Abe Pazos / https://hamoid.com
29757	 * @author Mugen87 / https://github.com/Mugen87
29758	 */
29759
29760	// DodecahedronGeometry
29761
29762	function DodecahedronGeometry( radius, detail ) {
29763
29764		Geometry.call( this );
29765
29766		this.type = 'DodecahedronGeometry';
29767
29768		this.parameters = {
29769			radius: radius,
29770			detail: detail
29771		};
29772
29773		this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );
29774		this.mergeVertices();
29775
29776	}
29777
29778	DodecahedronGeometry.prototype = Object.create( Geometry.prototype );
29779	DodecahedronGeometry.prototype.constructor = DodecahedronGeometry;
29780
29781	// DodecahedronBufferGeometry
29782
29783	function DodecahedronBufferGeometry( radius, detail ) {
29784
29785		var t = ( 1 + Math.sqrt( 5 ) ) / 2;
29786		var r = 1 / t;
29787
29788		var vertices = [
29789
29790			// (±1, ±1, ±1)
29791			- 1, - 1, - 1,	- 1, - 1, 1,
29792			- 1, 1, - 1, - 1, 1, 1,
29793			1, - 1, - 1, 1, - 1, 1,
29794			1, 1, - 1, 1, 1, 1,
29795
29796			// (0, ±1/φ, ±φ)
29797			 0, - r, - t, 0, - r, t,
29798			 0, r, - t, 0, r, t,
29799
29800			// (±1/φ, ±φ, 0)
29801			- r, - t, 0, - r, t, 0,
29802			 r, - t, 0, r, t, 0,
29803
29804			// (±φ, 0, ±1/φ)
29805			- t, 0, - r, t, 0, - r,
29806			- t, 0, r, t, 0, r
29807		];
29808
29809		var indices = [
29810			3, 11, 7, 	3, 7, 15, 	3, 15, 13,
29811			7, 19, 17, 	7, 17, 6, 	7, 6, 15,
29812			17, 4, 8, 	17, 8, 10, 	17, 10, 6,
29813			8, 0, 16, 	8, 16, 2, 	8, 2, 10,
29814			0, 12, 1, 	0, 1, 18, 	0, 18, 16,
29815			6, 10, 2, 	6, 2, 13, 	6, 13, 15,
29816			2, 16, 18, 	2, 18, 3, 	2, 3, 13,
29817			18, 1, 9, 	18, 9, 11, 	18, 11, 3,
29818			4, 14, 12, 	4, 12, 0, 	4, 0, 8,
29819			11, 9, 5, 	11, 5, 19, 	11, 19, 7,
29820			19, 5, 14, 	19, 14, 4, 	19, 4, 17,
29821			1, 12, 14, 	1, 14, 5, 	1, 5, 9
29822		];
29823
29824		PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29825
29826		this.type = 'DodecahedronBufferGeometry';
29827
29828		this.parameters = {
29829			radius: radius,
29830			detail: detail
29831		};
29832
29833	}
29834
29835	DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29836	DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;
29837
29838	/**
29839	 * @author oosmoxiecode / https://github.com/oosmoxiecode
29840	 * @author WestLangley / https://github.com/WestLangley
29841	 * @author zz85 / https://github.com/zz85
29842	 * @author miningold / https://github.com/miningold
29843	 * @author jonobr1 / https://github.com/jonobr1
29844	 * @author Mugen87 / https://github.com/Mugen87
29845	 *
29846	 */
29847
29848	// TubeGeometry
29849
29850	function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {
29851
29852		Geometry.call( this );
29853
29854		this.type = 'TubeGeometry';
29855
29856		this.parameters = {
29857			path: path,
29858			tubularSegments: tubularSegments,
29859			radius: radius,
29860			radialSegments: radialSegments,
29861			closed: closed
29862		};
29863
29864		if ( taper !== undefined ) { console.warn( 'THREE.TubeGeometry: taper has been removed.' ); }
29865
29866		var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );
29867
29868		// expose internals
29869
29870		this.tangents = bufferGeometry.tangents;
29871		this.normals = bufferGeometry.normals;
29872		this.binormals = bufferGeometry.binormals;
29873
29874		// create geometry
29875
29876		this.fromBufferGeometry( bufferGeometry );
29877		this.mergeVertices();
29878
29879	}
29880
29881	TubeGeometry.prototype = Object.create( Geometry.prototype );
29882	TubeGeometry.prototype.constructor = TubeGeometry;
29883
29884	// TubeBufferGeometry
29885
29886	function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {
29887
29888		BufferGeometry.call( this );
29889
29890		this.type = 'TubeBufferGeometry';
29891
29892		this.parameters = {
29893			path: path,
29894			tubularSegments: tubularSegments,
29895			radius: radius,
29896			radialSegments: radialSegments,
29897			closed: closed
29898		};
29899
29900		tubularSegments = tubularSegments || 64;
29901		radius = radius || 1;
29902		radialSegments = radialSegments || 8;
29903		closed = closed || false;
29904
29905		var frames = path.computeFrenetFrames( tubularSegments, closed );
29906
29907		// expose internals
29908
29909		this.tangents = frames.tangents;
29910		this.normals = frames.normals;
29911		this.binormals = frames.binormals;
29912
29913		// helper variables
29914
29915		var vertex = new Vector3();
29916		var normal = new Vector3();
29917		var uv = new Vector2();
29918		var P = new Vector3();
29919
29920		// buffer
29921
29922		var vertices = [];
29923		var normals = [];
29924		var uvs = [];
29925		var indices = [];
29926
29927		// create buffer data
29928
29929		generateBufferData();
29930
29931		// build geometry
29932
29933		this.setIndex( indices );
29934		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
29935		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
29936		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
29937
29938		// functions
29939
29940		function generateBufferData() {
29941
29942			for ( var i = 0; i < tubularSegments; i ++ ) {
29943
29944				generateSegment( i );
29945
29946			}
29947
29948			// if the geometry is not closed, generate the last row of vertices and normals
29949			// at the regular position on the given path
29950			//
29951			// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
29952
29953			generateSegment( ( closed === false ) ? tubularSegments : 0 );
29954
29955			// uvs are generated in a separate function.
29956			// this makes it easy compute correct values for closed geometries
29957
29958			generateUVs();
29959
29960			// finally create faces
29961
29962			generateIndices();
29963
29964		}
29965
29966		function generateSegment( i ) {
29967
29968			// we use getPointAt to sample evenly distributed points from the given path
29969
29970			P = path.getPointAt( i / tubularSegments, P );
29971
29972			// retrieve corresponding normal and binormal
29973
29974			var N = frames.normals[ i ];
29975			var B = frames.binormals[ i ];
29976
29977			// generate normals and vertices for the current segment
29978
29979			for ( var j = 0; j <= radialSegments; j ++ ) {
29980
29981				var v = j / radialSegments * Math.PI * 2;
29982
29983				var sin = Math.sin( v );
29984				var cos = - Math.cos( v );
29985
29986				// normal
29987
29988				normal.x = ( cos * N.x + sin * B.x );
29989				normal.y = ( cos * N.y + sin * B.y );
29990				normal.z = ( cos * N.z + sin * B.z );
29991				normal.normalize();
29992
29993				normals.push( normal.x, normal.y, normal.z );
29994
29995				// vertex
29996
29997				vertex.x = P.x + radius * normal.x;
29998				vertex.y = P.y + radius * normal.y;
29999				vertex.z = P.z + radius * normal.z;
30000
30001				vertices.push( vertex.x, vertex.y, vertex.z );
30002
30003			}
30004
30005		}
30006
30007		function generateIndices() {
30008
30009			for ( var j = 1; j <= tubularSegments; j ++ ) {
30010
30011				for ( var i = 1; i <= radialSegments; i ++ ) {
30012
30013					var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
30014					var b = ( radialSegments + 1 ) * j + ( i - 1 );
30015					var c = ( radialSegments + 1 ) * j + i;
30016					var d = ( radialSegments + 1 ) * ( j - 1 ) + i;
30017
30018					// faces
30019
30020					indices.push( a, b, d );
30021					indices.push( b, c, d );
30022
30023				}
30024
30025			}
30026
30027		}
30028
30029		function generateUVs() {
30030
30031			for ( var i = 0; i <= tubularSegments; i ++ ) {
30032
30033				for ( var j = 0; j <= radialSegments; j ++ ) {
30034
30035					uv.x = i / tubularSegments;
30036					uv.y = j / radialSegments;
30037
30038					uvs.push( uv.x, uv.y );
30039
30040				}
30041
30042			}
30043
30044		}
30045
30046	}
30047
30048	TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
30049	TubeBufferGeometry.prototype.constructor = TubeBufferGeometry;
30050
30051	TubeBufferGeometry.prototype.toJSON = function () {
30052
30053		var data = BufferGeometry.prototype.toJSON.call( this );
30054
30055		data.path = this.parameters.path.toJSON();
30056
30057		return data;
30058
30059	};
30060
30061	/**
30062	 * @author oosmoxiecode
30063	 * @author Mugen87 / https://github.com/Mugen87
30064	 *
30065	 * based on http://www.blackpawn.com/texts/pqtorus/
30066	 */
30067
30068	// TorusKnotGeometry
30069
30070	function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {
30071
30072		Geometry.call( this );
30073
30074		this.type = 'TorusKnotGeometry';
30075
30076		this.parameters = {
30077			radius: radius,
30078			tube: tube,
30079			tubularSegments: tubularSegments,
30080			radialSegments: radialSegments,
30081			p: p,
30082			q: q
30083		};
30084
30085		if ( heightScale !== undefined ) { console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); }
30086
30087		this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );
30088		this.mergeVertices();
30089
30090	}
30091
30092	TorusKnotGeometry.prototype = Object.create( Geometry.prototype );
30093	TorusKnotGeometry.prototype.constructor = TorusKnotGeometry;
30094
30095	// TorusKnotBufferGeometry
30096
30097	function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {
30098
30099		BufferGeometry.call( this );
30100
30101		this.type = 'TorusKnotBufferGeometry';
30102
30103		this.parameters = {
30104			radius: radius,
30105			tube: tube,
30106			tubularSegments: tubularSegments,
30107			radialSegments: radialSegments,
30108			p: p,
30109			q: q
30110		};
30111
30112		radius = radius || 1;
30113		tube = tube || 0.4;
30114		tubularSegments = Math.floor( tubularSegments ) || 64;
30115		radialSegments = Math.floor( radialSegments ) || 8;
30116		p = p || 2;
30117		q = q || 3;
30118
30119		// buffers
30120
30121		var indices = [];
30122		var vertices = [];
30123		var normals = [];
30124		var uvs = [];
30125
30126		// helper variables
30127
30128		var vertex = new Vector3();
30129		var normal = new Vector3();
30130
30131		var P1 = new Vector3();
30132		var P2 = new Vector3();
30133
30134		var B = new Vector3();
30135		var T = new Vector3();
30136		var N = new Vector3();
30137
30138		// generate vertices, normals and uvs
30139
30140		for ( var i = 0; i <= tubularSegments; ++ i ) {
30141
30142			// the radian "u" is used to calculate the position on the torus curve of the current tubular segement
30143
30144			var u = i / tubularSegments * p * Math.PI * 2;
30145
30146			// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.
30147			// these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions
30148
30149			calculatePositionOnCurve( u, p, q, radius, P1 );
30150			calculatePositionOnCurve( u + 0.01, p, q, radius, P2 );
30151
30152			// calculate orthonormal basis
30153
30154			T.subVectors( P2, P1 );
30155			N.addVectors( P2, P1 );
30156			B.crossVectors( T, N );
30157			N.crossVectors( B, T );
30158
30159			// normalize B, N. T can be ignored, we don't use it
30160
30161			B.normalize();
30162			N.normalize();
30163
30164			for ( var j = 0; j <= radialSegments; ++ j ) {
30165
30166				// now calculate the vertices. they are nothing more than an extrusion of the torus curve.
30167				// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.
30168
30169				var v = j / radialSegments * Math.PI * 2;
30170				var cx = - tube * Math.cos( v );
30171				var cy = tube * Math.sin( v );
30172
30173				// now calculate the final vertex position.
30174				// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve
30175
30176				vertex.x = P1.x + ( cx * N.x + cy * B.x );
30177				vertex.y = P1.y + ( cx * N.y + cy * B.y );
30178				vertex.z = P1.z + ( cx * N.z + cy * B.z );
30179
30180				vertices.push( vertex.x, vertex.y, vertex.z );
30181
30182				// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)
30183
30184				normal.subVectors( vertex, P1 ).normalize();
30185
30186				normals.push( normal.x, normal.y, normal.z );
30187
30188				// uv
30189
30190				uvs.push( i / tubularSegments );
30191				uvs.push( j / radialSegments );
30192
30193			}
30194
30195		}
30196
30197		// generate indices
30198
30199		for ( var j$1 = 1; j$1 <= tubularSegments; j$1 ++ ) {
30200
30201			for ( var i$1 = 1; i$1 <= radialSegments; i$1 ++ ) {
30202
30203				// indices
30204
30205				var a = ( radialSegments + 1 ) * ( j$1 - 1 ) + ( i$1 - 1 );
30206				var b = ( radialSegments + 1 ) * j$1 + ( i$1 - 1 );
30207				var c = ( radialSegments + 1 ) * j$1 + i$1;
30208				var d = ( radialSegments + 1 ) * ( j$1 - 1 ) + i$1;
30209
30210				// faces
30211
30212				indices.push( a, b, d );
30213				indices.push( b, c, d );
30214
30215			}
30216
30217		}
30218
30219		// build geometry
30220
30221		this.setIndex( indices );
30222		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
30223		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
30224		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
30225
30226		// this function calculates the current position on the torus curve
30227
30228		function calculatePositionOnCurve( u, p, q, radius, position ) {
30229
30230			var cu = Math.cos( u );
30231			var su = Math.sin( u );
30232			var quOverP = q / p * u;
30233			var cs = Math.cos( quOverP );
30234
30235			position.x = radius * ( 2 + cs ) * 0.5 * cu;
30236			position.y = radius * ( 2 + cs ) * su * 0.5;
30237			position.z = radius * Math.sin( quOverP ) * 0.5;
30238
30239		}
30240
30241	}
30242
30243	TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
30244	TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;
30245
30246	/**
30247	 * @author oosmoxiecode
30248	 * @author mrdoob / http://mrdoob.com/
30249	 * @author Mugen87 / https://github.com/Mugen87
30250	 */
30251
30252	// TorusGeometry
30253
30254	function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
30255
30256		Geometry.call( this );
30257
30258		this.type = 'TorusGeometry';
30259
30260		this.parameters = {
30261			radius: radius,
30262			tube: tube,
30263			radialSegments: radialSegments,
30264			tubularSegments: tubularSegments,
30265			arc: arc
30266		};
30267
30268		this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
30269		this.mergeVertices();
30270
30271	}
30272
30273	TorusGeometry.prototype = Object.create( Geometry.prototype );
30274	TorusGeometry.prototype.constructor = TorusGeometry;
30275
30276	// TorusBufferGeometry
30277
30278	function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
30279
30280		BufferGeometry.call( this );
30281
30282		this.type = 'TorusBufferGeometry';
30283
30284		this.parameters = {
30285			radius: radius,
30286			tube: tube,
30287			radialSegments: radialSegments,
30288			tubularSegments: tubularSegments,
30289			arc: arc
30290		};
30291
30292		radius = radius || 1;
30293		tube = tube || 0.4;
30294		radialSegments = Math.floor( radialSegments ) || 8;
30295		tubularSegments = Math.floor( tubularSegments ) || 6;
30296		arc = arc || Math.PI * 2;
30297
30298		// buffers
30299
30300		var indices = [];
30301		var vertices = [];
30302		var normals = [];
30303		var uvs = [];
30304
30305		// helper variables
30306
30307		var center = new Vector3();
30308		var vertex = new Vector3();
30309		var normal = new Vector3();
30310
30311		// generate vertices, normals and uvs
30312
30313		for ( var j = 0; j <= radialSegments; j ++ ) {
30314
30315			for ( var i = 0; i <= tubularSegments; i ++ ) {
30316
30317				var u = i / tubularSegments * arc;
30318				var v = j / radialSegments * Math.PI * 2;
30319
30320				// vertex
30321
30322				vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
30323				vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
30324				vertex.z = tube * Math.sin( v );
30325
30326				vertices.push( vertex.x, vertex.y, vertex.z );
30327
30328				// normal
30329
30330				center.x = radius * Math.cos( u );
30331				center.y = radius * Math.sin( u );
30332				normal.subVectors( vertex, center ).normalize();
30333
30334				normals.push( normal.x, normal.y, normal.z );
30335
30336				// uv
30337
30338				uvs.push( i / tubularSegments );
30339				uvs.push( j / radialSegments );
30340
30341			}
30342
30343		}
30344
30345		// generate indices
30346
30347		for ( var j$1 = 1; j$1 <= radialSegments; j$1 ++ ) {
30348
30349			for ( var i$1 = 1; i$1 <= tubularSegments; i$1 ++ ) {
30350
30351				// indices
30352
30353				var a = ( tubularSegments + 1 ) * j$1 + i$1 - 1;
30354				var b = ( tubularSegments + 1 ) * ( j$1 - 1 ) + i$1 - 1;
30355				var c = ( tubularSegments + 1 ) * ( j$1 - 1 ) + i$1;
30356				var d = ( tubularSegments + 1 ) * j$1 + i$1;
30357
30358				// faces
30359
30360				indices.push( a, b, d );
30361				indices.push( b, c, d );
30362
30363			}
30364
30365		}
30366
30367		// build geometry
30368
30369		this.setIndex( indices );
30370		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
30371		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
30372		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
30373
30374	}
30375
30376	TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
30377	TorusBufferGeometry.prototype.constructor = TorusBufferGeometry;
30378
30379	/**
30380	 * @author Mugen87 / https://github.com/Mugen87
30381	 * Port from https://github.com/mapbox/earcut (v2.2.2)
30382	 */
30383
30384	var Earcut = {
30385
30386		triangulate: function ( data, holeIndices, dim ) {
30387
30388			dim = dim || 2;
30389
30390			var hasHoles = holeIndices && holeIndices.length,
30391				outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length,
30392				outerNode = linkedList( data, 0, outerLen, dim, true ),
30393				triangles = [];
30394
30395			if ( ! outerNode || outerNode.next === outerNode.prev ) { return triangles; }
30396
30397			var minX, minY, maxX, maxY, x, y, invSize;
30398
30399			if ( hasHoles ) { outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); }
30400
30401			// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
30402			if ( data.length > 80 * dim ) {
30403
30404				minX = maxX = data[ 0 ];
30405				minY = maxY = data[ 1 ];
30406
30407				for ( var i = dim; i < outerLen; i += dim ) {
30408
30409					x = data[ i ];
30410					y = data[ i + 1 ];
30411					if ( x < minX ) { minX = x; }
30412					if ( y < minY ) { minY = y; }
30413					if ( x > maxX ) { maxX = x; }
30414					if ( y > maxY ) { maxY = y; }
30415
30416				}
30417
30418				// minX, minY and invSize are later used to transform coords into integers for z-order calculation
30419				invSize = Math.max( maxX - minX, maxY - minY );
30420				invSize = invSize !== 0 ? 1 / invSize : 0;
30421
30422			}
30423
30424			earcutLinked( outerNode, triangles, dim, minX, minY, invSize );
30425
30426			return triangles;
30427
30428		}
30429
30430	};
30431
30432	// create a circular doubly linked list from polygon points in the specified winding order
30433	function linkedList( data, start, end, dim, clockwise ) {
30434
30435		var i, last;
30436
30437		if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) {
30438
30439			for ( i = start; i < end;
vendor: 16,196 bytes, lines 30439-31171
30439 i += dim ) { last = insertNode( i, data[ i ], data[ i + 1 ], last ); }
30440
30441		} else {
30442
30443			for ( i = end - dim; i >= start; i -= dim ) { last = insertNode( i, data[ i ], data[ i + 1 ], last ); }
30444
30445		}
30446
30447		if ( last && equals( last, last.next ) ) {
30448
30449			removeNode( last );
30450			last = last.next;
30451
30452		}
30453
30454		return last;
30455
30456	}
30457
30458	// eliminate colinear or duplicate points
30459	function filterPoints( start, end ) {
30460
30461		if ( ! start ) { return start; }
30462		if ( ! end ) { end = start; }
30463
30464		var p = start,
30465			again;
30466		do {
30467
30468			again = false;
30469
30470			if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) {
30471
30472				removeNode( p );
30473				p = end = p.prev;
30474				if ( p === p.next ) { break; }
30475				again = true;
30476
30477			} else {
30478
30479				p = p.next;
30480
30481			}
30482
30483		} while ( again || p !== end );
30484
30485		return end;
30486
30487	}
30488
30489	// main ear slicing loop which triangulates a polygon (given as a linked list)
30490	function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) {
30491
30492		if ( ! ear ) { return; }
30493
30494		// interlink polygon nodes in z-order
30495		if ( ! pass && invSize ) { indexCurve( ear, minX, minY, invSize ); }
30496
30497		var stop = ear,
30498			prev, next;
30499
30500		// iterate through ears, slicing them one by one
30501		while ( ear.prev !== ear.next ) {
30502
30503			prev = ear.prev;
30504			next = ear.next;
30505
30506			if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) {
30507
30508				// cut off the triangle
30509				triangles.push( prev.i / dim );
30510				triangles.push( ear.i / dim );
30511				triangles.push( next.i / dim );
30512
30513				removeNode( ear );
30514
30515				// skipping the next vertex leads to less sliver triangles
30516				ear = next.next;
30517				stop = next.next;
30518
30519				continue;
30520
30521			}
30522
30523			ear = next;
30524
30525			// if we looped through the whole remaining polygon and can't find any more ears
30526			if ( ear === stop ) {
30527
30528				// try filtering points and slicing again
30529				if ( ! pass ) {
30530
30531					earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 );
30532
30533					// if this didn't work, try curing all small self-intersections locally
30534
30535				} else if ( pass === 1 ) {
30536
30537					ear = cureLocalIntersections( filterPoints( ear ), triangles, dim );
30538					earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 );
30539
30540					// as a last resort, try splitting the remaining polygon into two
30541
30542				} else if ( pass === 2 ) {
30543
30544					splitEarcut( ear, triangles, dim, minX, minY, invSize );
30545
30546				}
30547
30548				break;
30549
30550			}
30551
30552		}
30553
30554	}
30555
30556	// check whether a polygon node forms a valid ear with adjacent nodes
30557	function isEar( ear ) {
30558
30559		var a = ear.prev,
30560			b = ear,
30561			c = ear.next;
30562
30563		if ( area( a, b, c ) >= 0 ) { return false; } // reflex, can't be an ear
30564
30565		// now make sure we don't have other points inside the potential ear
30566		var p = ear.next.next;
30567
30568		while ( p !== ear.prev ) {
30569
30570			if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
30571				area( p.prev, p, p.next ) >= 0 ) { return false; }
30572			p = p.next;
30573
30574		}
30575
30576		return true;
30577
30578	}
30579
30580	function isEarHashed( ear, minX, minY, invSize ) {
30581
30582		var a = ear.prev,
30583			b = ear,
30584			c = ear.next;
30585
30586		if ( area( a, b, c ) >= 0 ) { return false; } // reflex, can't be an ear
30587
30588		// triangle bbox; min & max are calculated like this for speed
30589		var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ),
30590			minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ),
30591			maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ),
30592			maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y );
30593
30594		// z-order range for the current triangle bbox;
30595		var minZ = zOrder( minTX, minTY, minX, minY, invSize ),
30596			maxZ = zOrder( maxTX, maxTY, minX, minY, invSize );
30597
30598		var p = ear.prevZ,
30599			n = ear.nextZ;
30600
30601		// look for points inside the triangle in both directions
30602		while ( p && p.z >= minZ && n && n.z <= maxZ ) {
30603
30604			if ( p !== ear.prev && p !== ear.next &&
30605				pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
30606				area( p.prev, p, p.next ) >= 0 ) { return false; }
30607			p = p.prevZ;
30608
30609			if ( n !== ear.prev && n !== ear.next &&
30610				pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&
30611				area( n.prev, n, n.next ) >= 0 ) { return false; }
30612			n = n.nextZ;
30613
30614		}
30615
30616		// look for remaining points in decreasing z-order
30617		while ( p && p.z >= minZ ) {
30618
30619			if ( p !== ear.prev && p !== ear.next &&
30620				pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
30621				area( p.prev, p, p.next ) >= 0 ) { return false; }
30622			p = p.prevZ;
30623
30624		}
30625
30626		// look for remaining points in increasing z-order
30627		while ( n && n.z <= maxZ ) {
30628
30629			if ( n !== ear.prev && n !== ear.next &&
30630				pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&
30631				area( n.prev, n, n.next ) >= 0 ) { return false; }
30632			n = n.nextZ;
30633
30634		}
30635
30636		return true;
30637
30638	}
30639
30640	// go through all polygon nodes and cure small local self-intersections
30641	function cureLocalIntersections( start, triangles, dim ) {
30642
30643		var p = start;
30644		do {
30645
30646			var a = p.prev,
30647				b = p.next.next;
30648
30649			if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) {
30650
30651				triangles.push( a.i / dim );
30652				triangles.push( p.i / dim );
30653				triangles.push( b.i / dim );
30654
30655				// remove two nodes involved
30656				removeNode( p );
30657				removeNode( p.next );
30658
30659				p = start = b;
30660
30661			}
30662
30663			p = p.next;
30664
30665		} while ( p !== start );
30666
30667		return filterPoints( p );
30668
30669	}
30670
30671	// try splitting polygon into two and triangulate them independently
30672	function splitEarcut( start, triangles, dim, minX, minY, invSize ) {
30673
30674		// look for a valid diagonal that divides the polygon into two
30675		var a = start;
30676		do {
30677
30678			var b = a.next.next;
30679			while ( b !== a.prev ) {
30680
30681				if ( a.i !== b.i && isValidDiagonal( a, b ) ) {
30682
30683					// split the polygon in two by the diagonal
30684					var c = splitPolygon( a, b );
30685
30686					// filter colinear points around the cuts
30687					a = filterPoints( a, a.next );
30688					c = filterPoints( c, c.next );
30689
30690					// run earcut on each half
30691					earcutLinked( a, triangles, dim, minX, minY, invSize );
30692					earcutLinked( c, triangles, dim, minX, minY, invSize );
30693					return;
30694
30695				}
30696
30697				b = b.next;
30698
30699			}
30700
30701			a = a.next;
30702
30703		} while ( a !== start );
30704
30705	}
30706
30707	// link every hole into the outer loop, producing a single-ring polygon without holes
30708	function eliminateHoles( data, holeIndices, outerNode, dim ) {
30709
30710		var queue = [],
30711			i, len, start, end, list;
30712
30713		for ( i = 0, len = holeIndices.length; i < len; i ++ ) {
30714
30715			start = holeIndices[ i ] * dim;
30716			end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length;
30717			list = linkedList( data, start, end, dim, false );
30718			if ( list === list.next ) { list.steiner = true; }
30719			queue.push( getLeftmost( list ) );
30720
30721		}
30722
30723		queue.sort( compareX );
30724
30725		// process holes from left to right
30726		for ( i = 0; i < queue.length; i ++ ) {
30727
30728			eliminateHole( queue[ i ], outerNode );
30729			outerNode = filterPoints( outerNode, outerNode.next );
30730
30731		}
30732
30733		return outerNode;
30734
30735	}
30736
30737	function compareX( a, b ) {
30738
30739		return a.x - b.x;
30740
30741	}
30742
30743	// find a bridge between vertices that connects hole with an outer ring and and link it
30744	function eliminateHole( hole, outerNode ) {
30745
30746		outerNode = findHoleBridge( hole, outerNode );
30747		if ( outerNode ) {
30748
30749			var b = splitPolygon( outerNode, hole );
30750
30751			// filter collinear points around the cuts
30752			filterPoints( outerNode, outerNode.next );
30753			filterPoints( b, b.next );
30754
30755		}
30756
30757	}
30758
30759	// David Eberly's algorithm for finding a bridge between hole and outer polygon
30760	function findHoleBridge( hole, outerNode ) {
30761
30762		var p = outerNode,
30763			hx = hole.x,
30764			hy = hole.y,
30765			qx = - Infinity,
30766			m;
30767
30768		// find a segment intersected by a ray from the hole's leftmost point to the left;
30769		// segment's endpoint with lesser x will be potential connection point
30770		do {
30771
30772			if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) {
30773
30774				var x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y );
30775				if ( x <= hx && x > qx ) {
30776
30777					qx = x;
30778					if ( x === hx ) {
30779
30780						if ( hy === p.y ) { return p; }
30781						if ( hy === p.next.y ) { return p.next; }
30782
30783					}
30784
30785					m = p.x < p.next.x ? p : p.next;
30786
30787				}
30788
30789			}
30790
30791			p = p.next;
30792
30793		} while ( p !== outerNode );
30794
30795		if ( ! m ) { return null; }
30796
30797		if ( hx === qx ) { return m; } // hole touches outer segment; pick leftmost endpoint
30798
30799		// look for points inside the triangle of hole point, segment intersection and endpoint;
30800		// if there are no points found, we have a valid connection;
30801		// otherwise choose the point of the minimum angle with the ray as connection point
30802
30803		var stop = m,
30804			mx = m.x,
30805			my = m.y,
30806			tanMin = Infinity,
30807			tan;
30808
30809		p = m;
30810
30811		do {
30812
30813			if ( hx >= p.x && p.x >= mx && hx !== p.x &&
30814					pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) {
30815
30816				tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential
30817
30818				if ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) {
30819
30820					m = p;
30821					tanMin = tan;
30822
30823				}
30824
30825			}
30826
30827			p = p.next;
30828
30829		} while ( p !== stop );
30830
30831		return m;
30832
30833	}
30834
30835	// whether sector in vertex m contains sector in vertex p in the same coordinates
30836	function sectorContainsSector( m, p ) {
30837
30838		return area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0;
30839
30840	}
30841
30842	// interlink polygon nodes in z-order
30843	function indexCurve( start, minX, minY, invSize ) {
30844
30845		var p = start;
30846		do {
30847
30848			if ( p.z === null ) { p.z = zOrder( p.x, p.y, minX, minY, invSize ); }
30849			p.prevZ = p.prev;
30850			p.nextZ = p.next;
30851			p = p.next;
30852
30853		} while ( p !== start );
30854
30855		p.prevZ.nextZ = null;
30856		p.prevZ = null;
30857
30858		sortLinked( p );
30859
30860	}
30861
30862	// Simon Tatham's linked list merge sort algorithm
30863	// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
30864	function sortLinked( list ) {
30865
30866		var i, p, q, e, tail, numMerges, pSize, qSize,
30867			inSize = 1;
30868
30869		do {
30870
30871			p = list;
30872			list = null;
30873			tail = null;
30874			numMerges = 0;
30875
30876			while ( p ) {
30877
30878				numMerges ++;
30879				q = p;
30880				pSize = 0;
30881				for ( i = 0; i < inSize; i ++ ) {
30882
30883					pSize ++;
30884					q = q.nextZ;
30885					if ( ! q ) { break; }
30886
30887				}
30888
30889				qSize = inSize;
30890
30891				while ( pSize > 0 || ( qSize > 0 && q ) ) {
30892
30893					if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) {
30894
30895						e = p;
30896						p = p.nextZ;
30897						pSize --;
30898
30899					} else {
30900
30901						e = q;
30902						q = q.nextZ;
30903						qSize --;
30904
30905					}
30906
30907					if ( tail ) { tail.nextZ = e; }
30908					else { list = e; }
30909
30910					e.prevZ = tail;
30911					tail = e;
30912
30913				}
30914
30915				p = q;
30916
30917			}
30918
30919			tail.nextZ = null;
30920			inSize *= 2;
30921
30922		} while ( numMerges > 1 );
30923
30924		return list;
30925
30926	}
30927
30928	// z-order of a point given coords and inverse of the longer side of data bbox
30929	function zOrder( x, y, minX, minY, invSize ) {
30930
30931		// coords are transformed into non-negative 15-bit integer range
30932		x = 32767 * ( x - minX ) * invSize;
30933		y = 32767 * ( y - minY ) * invSize;
30934
30935		x = ( x | ( x << 8 ) ) & 0x00FF00FF;
30936		x = ( x | ( x << 4 ) ) & 0x0F0F0F0F;
30937		x = ( x | ( x << 2 ) ) & 0x33333333;
30938		x = ( x | ( x << 1 ) ) & 0x55555555;
30939
30940		y = ( y | ( y << 8 ) ) & 0x00FF00FF;
30941		y = ( y | ( y << 4 ) ) & 0x0F0F0F0F;
30942		y = ( y | ( y << 2 ) ) & 0x33333333;
30943		y = ( y | ( y << 1 ) ) & 0x55555555;
30944
30945		return x | ( y << 1 );
30946
30947	}
30948
30949	// find the leftmost node of a polygon ring
30950	function getLeftmost( start ) {
30951
30952		var p = start,
30953			leftmost = start;
30954		do {
30955
30956			if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) { leftmost = p; }
30957			p = p.next;
30958
30959		} while ( p !== start );
30960
30961		return leftmost;
30962
30963	}
30964
30965	// check if a point lies within a convex triangle
30966	function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) {
30967
30968		return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 &&
30969				( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 &&
30970				( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0;
30971
30972	}
30973
30974	// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
30975	function isValidDiagonal( a, b ) {
30976
30977		return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // dones't intersect other edges
30978			( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) && // locally visible
30979			( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) || // does not create opposite-facing sectors
30980			equals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 ); // special zero-length case
30981
30982	}
30983
30984	// signed area of a triangle
30985	function area( p, q, r ) {
30986
30987		return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y );
30988
30989	}
30990
30991	// check if two points are equal
30992	function equals( p1, p2 ) {
30993
30994		return p1.x === p2.x && p1.y === p2.y;
30995
30996	}
30997
30998	// check if two segments intersect
30999	function intersects( p1, q1, p2, q2 ) {
31000
31001		var o1 = sign( area( p1, q1, p2 ) );
31002		var o2 = sign( area( p1, q1, q2 ) );
31003		var o3 = sign( area( p2, q2, p1 ) );
31004		var o4 = sign( area( p2, q2, q1 ) );
31005
31006		if ( o1 !== o2 && o3 !== o4 ) { return true; } // general case
31007
31008		if ( o1 === 0 && onSegment( p1, p2, q1 ) ) { return true; } // p1, q1 and p2 are collinear and p2 lies on p1q1
31009		if ( o2 === 0 && onSegment( p1, q2, q1 ) ) { return true; } // p1, q1 and q2 are collinear and q2 lies on p1q1
31010		if ( o3 === 0 && onSegment( p2, p1, q2 ) ) { return true; } // p2, q2 and p1 are collinear and p1 lies on p2q2
31011		if ( o4 === 0 && onSegment( p2, q1, q2 ) ) { return true; } // p2, q2 and q1 are collinear and q1 lies on p2q2
31012
31013		return false;
31014
31015	}
31016
31017	// for collinear points p, q, r, check if point q lies on segment pr
31018	function onSegment( p, q, r ) {
31019
31020		return q.x <= Math.max( p.x, r.x ) && q.x >= Math.min( p.x, r.x ) && q.y <= Math.max( p.y, r.y ) && q.y >= Math.min( p.y, r.y );
31021
31022	}
31023
31024	function sign( num ) {
31025
31026		return num > 0 ? 1 : num < 0 ? - 1 : 0;
31027
31028	}
31029
31030	// check if a polygon diagonal intersects any polygon segments
31031	function intersectsPolygon( a, b ) {
31032
31033		var p = a;
31034		do {
31035
31036			if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
31037					intersects( p, p.next, a, b ) ) { return true; }
31038			p = p.next;
31039
31040		} while ( p !== a );
31041
31042		return false;
31043
31044	}
31045
31046	// check if a polygon diagonal is locally inside the polygon
31047	function locallyInside( a, b ) {
31048
31049		return area( a.prev, a, a.next ) < 0 ?
31050			area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 :
31051			area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0;
31052
31053	}
31054
31055	// check if the middle point of a polygon diagonal is inside the polygon
31056	function middleInside( a, b ) {
31057
31058		var p = a,
31059			inside = false,
31060			px = ( a.x + b.x ) / 2,
31061			py = ( a.y + b.y ) / 2;
31062		do {
31063
31064			if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y &&
31065					( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) )
31066				{ inside = ! inside; }
31067			p = p.next;
31068
31069		} while ( p !== a );
31070
31071		return inside;
31072
31073	}
31074
31075	// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
31076	// if one belongs to the outer ring and another to a hole, it merges it into a single ring
31077	function splitPolygon( a, b ) {
31078
31079		var a2 = new Node( a.i, a.x, a.y ),
31080			b2 = new Node( b.i, b.x, b.y ),
31081			an = a.next,
31082			bp = b.prev;
31083
31084		a.next = b;
31085		b.prev = a;
31086
31087		a2.next = an;
31088		an.prev = a2;
31089
31090		b2.next = a2;
31091		a2.prev = b2;
31092
31093		bp.next = b2;
31094		b2.prev = bp;
31095
31096		return b2;
31097
31098	}
31099
31100	// create a node and optionally link it with previous one (in a circular doubly linked list)
31101	function insertNode( i, x, y, last ) {
31102
31103		var p = new Node( i, x, y );
31104
31105		if ( ! last ) {
31106
31107			p.prev = p;
31108			p.next = p;
31109
31110		} else {
31111
31112			p.next = last.next;
31113			p.prev = last;
31114			last.next.prev = p;
31115			last.next = p;
31116
31117		}
31118
31119		return p;
31120
31121	}
31122
31123	function removeNode( p ) {
31124
31125		p.next.prev = p.prev;
31126		p.prev.next = p.next;
31127
31128		if ( p.prevZ ) { p.prevZ.nextZ = p.nextZ; }
31129		if ( p.nextZ ) { p.nextZ.prevZ = p.prevZ; }
31130
31131	}
31132
31133	function Node( i, x, y ) {
31134
31135		// vertex index in coordinates array
31136		this.i = i;
31137
31138		// vertex coordinates
31139		this.x = x;
31140		this.y = y;
31141
31142		// previous and next vertex nodes in a polygon ring
31143		this.prev = null;
31144		this.next = null;
31145
31146		// z-order curve value
31147		this.z = null;
31148
31149		// previous and next nodes in z-order
31150		this.prevZ = null;
31151		this.nextZ = null;
31152
31153		// indicates whether this is a steiner point
31154		this.steiner = false;
31155
31156	}
31157
31158	function signedArea( data, start, end, dim ) {
31159
31160		var sum = 0;
31161		for ( var i = start, j = end - dim; i < end; i += dim ) {
31162
31163			sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] );
31164			j = i;
31165
31166		}
31167
31168		return sum;
31169
31170	}
31171
31172	/**
31173	 * @author zz85 / http://www.lab4games.net/zz85/blog
31174	 */
31175
31176	var ShapeUtils = {
31177
31178		// calculate area of the contour polygon
31179
31180		area: function ( contour ) {
31181
31182			var n = contour.length;
31183			var a = 0.0;
31184
31185			for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
31186
31187				a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
31188
31189			}
31190
31191			return a * 0.5;
31192
31193		},
31194
31195		isClockWise: function ( pts ) {
31196
31197			return ShapeUtils.area( pts ) < 0;
31198
31199		},
31200
31201		triangulateShape: function ( contour, holes ) {
31202
31203			var vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ]
31204			var holeIndices = []; // array of hole indices
31205			var faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ]
31206
31207			removeDupEndPts( contour );
31208			addContour( vertices, contour );
31209
31210			//
31211
31212			var holeIndex = contour.length;
31213
31214			holes.forEach( removeDupEndPts );
31215
31216			for ( var i = 0; i < holes.length; i ++ ) {
31217
31218				holeIndices.push( holeIndex );
31219				holeIndex += holes[ i ].length;
31220				addContour( vertices, holes[ i ] );
31221
31222			}
31223
31224			//
31225
31226			var triangles = Earcut.triangulate( vertices, holeIndices );
31227
31228			//
31229
31230			for ( var i$1 = 0; i$1 < triangles.length; i$1 += 3 ) {
31231
31232				faces.push( triangles.slice( i$1, i$1 + 3 ) );
31233
31234			}
31235
31236			return faces;
31237
31238		}
31239
31240	};
31241
31242	function removeDupEndPts( points ) {
31243
31244		var l = points.length;
31245
31246		if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
31247
31248			points.pop();
31249
31250		}
31251
31252	}
31253
31254	function addContour( vertices, contour ) {
31255
31256		for ( var i = 0; i < contour.length; i ++ ) {
31257
31258			vertices.push( contour[ i ].x );
31259			vertices.push( contour[ i ].y );
31260
31261		}
31262
31263	}
31264
31265	/**
31266	 * @author zz85 / http://www.lab4games.net/zz85/blog
31267	 *
31268	 * Creates extruded geometry from a path shape.
31269	 *
31270	 * parameters = {
31271	 *
31272	 *  curveSegments: <int>, // number of points on the curves
31273	 *  steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
31274	 *  depth: <float>, // Depth to extrude the shape
31275	 *
31276	 *  bevelEnabled: <bool>, // turn on bevel
31277	 *  bevelThickness: <float>, // how deep into the original shape bevel goes
31278	 *  bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel
31279	 *  bevelOffset: <float>, // how far from shape outline does bevel start
31280	 *  bevelSegments: <int>, // number of bevel layers
31281	 *
31282	 *  extrudePath: <THREE.Curve> // curve to extrude shape along
31283	 *
31284	 *  UVGenerator: <Object> // object that provides UV generator functions
31285	 *
31286	 * }
31287	 */
31288
31289	// ExtrudeGeometry
31290
31291	function ExtrudeGeometry( shapes, options ) {
31292
31293		Geometry.call( this );
31294
31295		this.type = 'ExtrudeGeometry';
31296
31297		this.parameters = {
31298			shapes: shapes,
31299			options: options
31300		};
31301
31302		this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) );
31303		this.mergeVertices();
31304
31305	}
31306
31307	ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
31308	ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
31309
31310	ExtrudeGeometry.prototype.toJSON = function () {
31311
31312		var data = Geometry.prototype.toJSON.call( this );
31313
31314		var shapes = this.parameters.shapes;
31315		var options = this.parameters.options;
31316
31317		return toJSON( shapes, options, data );
31318
31319	};
31320
31321	// ExtrudeBufferGeometry
31322
31323	function ExtrudeBufferGeometry( shapes, options ) {
31324
31325		BufferGeometry.call( this );
31326
31327		this.type = 'ExtrudeBufferGeometry';
31328
31329		this.parameters = {
31330			shapes: shapes,
31331			options: options
31332		};
31333
31334		shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
31335
31336		var scope = this;
31337
31338		var verticesArray = [];
31339		var uvArray = [];
31340
31341		for ( var i = 0, l = shapes.length; i < l; i ++ ) {
31342
31343			var shape = shapes[ i ];
31344			addShape( shape );
31345
31346		}
31347
31348		// build geometry
31349
31350		this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
31351		this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );
31352
31353		this.computeVertexNormals();
31354
31355		// functions
31356
31357		function addShape( shape ) {
31358
31359			var placeholder = [];
31360
31361			// options
31362
31363			var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
31364			var steps = options.steps !== undefined ? options.steps : 1;
31365			var depth = options.depth !== undefined ? options.depth : 100;
31366
31367			var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
31368			var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6;
31369			var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2;
31370			var bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;
31371			var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
31372
31373			var extrudePath = options.extrudePath;
31374
31375			var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator;
31376
31377			// deprecated options
31378
31379			if ( options.amount !== undefined ) {
31380
31381				console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' );
31382				depth = options.amount;
31383
31384			}
31385
31386			//
31387
31388			var extrudePts, extrudeByPath = false;
31389			var splineTube, binormal, normal, position2;
31390
31391			if ( extrudePath ) {
31392
31393				extrudePts = extrudePath.getSpacedPoints( steps );
31394
31395				extrudeByPath = true;
31396				bevelEnabled = false; // bevels not supported for path extrusion
31397
31398				// SETUP TNB variables
31399
31400				// TODO1 - have a .isClosed in spline?
31401
31402				splineTube = extrudePath.computeFrenetFrames( steps, false );
31403
31404				// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
31405
31406				binormal = new Vector3();
31407				normal = new Vector3();
31408				position2 = new Vector3();
31409
31410			}
31411
31412			// Safeguards if bevels are not enabled
31413
31414			if ( ! bevelEnabled ) {
31415
31416				bevelSegments = 0;
31417				bevelThickness = 0;
31418				bevelSize = 0;
31419				bevelOffset = 0;
31420
31421			}
31422
31423			// Variables initialization
31424
31425			var shapePoints = shape.extractPoints( curveSegments );
31426
31427			var vertices = shapePoints.shape;
31428			var holes = shapePoints.holes;
31429
31430			var reverse = ! ShapeUtils.isClockWise( vertices );
31431
31432			if ( reverse ) {
31433
31434				vertices = vertices.reverse();
31435
31436				// Maybe we should also check if holes are in the opposite direction, just to be safe ...
31437
31438				for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
31439
31440					var ahole = holes[ h ];
31441
31442					if ( ShapeUtils.isClockWise( ahole ) ) {
31443
31444						holes[ h ] = ahole.reverse();
31445
31446					}
31447
31448				}
31449
31450			}
31451
31452
31453			var faces = ShapeUtils.triangulateShape( vertices, holes );
31454
31455			/* Vertices */
31456
31457			var contour = vertices; // vertices has all points but contour has only points of circumference
31458
31459			for ( var h$1 = 0, hl$1 = holes.length; h$1 < hl$1; h$1 ++ ) {
31460
31461				var ahole$1 = holes[ h$1 ];
31462
31463				vertices = vertices.concat( ahole$1 );
31464
31465			}
31466
31467
31468			function scalePt2( pt, vec, size ) {
31469
31470				if ( ! vec ) { console.error( "THREE.ExtrudeGeometry: vec does not exist" ); }
31471
31472				return vec.clone().multiplyScalar( size ).add( pt );
31473
31474			}
31475
31476			var vlen = vertices.length, flen = faces.length;
31477
31478
31479			// Find directions for point movement
31480
31481
31482			function getBevelVec( inPt, inPrev, inNext ) {
31483
31484				// computes for inPt the corresponding point inPt' on a new contour
31485				//   shifted by 1 unit (length of normalized vector) to the left
31486				// if we walk along contour clockwise, this new contour is outside the old one
31487				//
31488				// inPt' is the intersection of the two lines parallel to the two
31489				//  adjacent edges of inPt at a distance of 1 unit on the left side.
31490
31491				var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
31492
31493				// good reading for geometry algorithms (here: line-line intersection)
31494				// http://geomalgorithms.com/a05-_intersect-1.html
31495
31496				var v_prev_x = inPt.x - inPrev.x,
31497					v_prev_y = inPt.y - inPrev.y;
31498				var v_next_x = inNext.x - inPt.x,
31499					v_next_y = inNext.y - inPt.y;
31500
31501				var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
31502
31503				// check for collinear edges
31504				var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
31505
31506				if ( Math.abs( collinear0 ) > Number.EPSILON ) {
31507
31508					// not collinear
31509
31510					// length of vectors for normalizing
31511
31512					var v_prev_len = Math.sqrt( v_prev_lensq );
31513					var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
31514
31515					// shift adjacent points by unit vectors to the left
31516
31517					var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
31518					var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
31519
31520					var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
31521					var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
31522
31523					// scaling factor for v_prev to intersection point
31524
31525					var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
31526							( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
31527						( v_prev_x * v_next_y - v_prev_y * v_next_x );
31528
31529					// vector from inPt to intersection point
31530
31531					v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
31532					v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
31533
31534					// Don't normalize!, otherwise sharp corners become ugly
31535					//  but prevent crazy spikes
31536					var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
31537					if ( v_trans_lensq <= 2 ) {
31538
31539						return new Vector2( v_trans_x, v_trans_y );
31540
31541					} else {
31542
31543						shrink_by = Math.sqrt( v_trans_lensq / 2 );
31544
31545					}
31546
31547				} else {
31548
31549					// handle special case of collinear edges
31550
31551					var direction_eq = false; // assumes: opposite
31552
31553					if ( v_prev_x > Number.EPSILON ) {
31554
31555						if ( v_next_x > Number.EPSILON ) {
31556
31557							direction_eq = true;
31558
31559						}
31560
31561					} else {
31562
31563						if ( v_prev_x < - Number.EPSILON ) {
31564
31565							if ( v_next_x < - Number.EPSILON ) {
31566
31567								direction_eq = true;
31568
31569							}
31570
31571						} else {
31572
31573							if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
31574
31575								direction_eq = true;
31576
31577							}
31578
31579						}
31580
31581					}
31582
31583					if ( direction_eq ) {
31584
31585						// console.log("Warning: lines are a straight sequence");
31586						v_trans_x = - v_prev_y;
31587						v_trans_y = v_prev_x;
31588						shrink_by = Math.sqrt( v_prev_lensq );
31589
31590					} else {
31591
31592						// console.log("Warning: lines are a straight spike");
31593						v_trans_x = v_prev_x;
31594						v_trans_y = v_prev_y;
31595						shrink_by = Math.sqrt( v_prev_lensq / 2 );
31596
31597					}
31598
31599				}
31600
31601				return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
31602
31603			}
31604
31605
31606			var contourMovements = [];
31607
31608			for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
31609
31610				if ( j === il ) { j = 0; }
31611				if ( k === il ) { k = 0; }
31612
31613				//  (j)---(i)---(k)
31614				// console.log('i,j,k', i, j , k)
31615
31616				contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
31617
31618			}
31619
31620			var holesMovements = [];
31621			var oneHoleMovements, verticesMovements = contourMovements.concat();
31622
31623			for ( var h$2 = 0, hl$2 = holes.length; h$2 < hl$2; h$2 ++ ) {
31624
31625				var ahole$2 = holes[ h$2 ];
31626
31627				oneHoleMovements = [];
31628
31629				for ( var i$1 = 0, il$1 = ahole$2.length, j$1 = il$1 - 1, k$1 = i$1 + 1; i$1 < il$1; i$1 ++, j$1 ++, k$1 ++ ) {
31630
31631					if ( j$1 === il$1 ) { j$1 = 0; }
31632					if ( k$1 === il$1 ) { k$1 = 0; }
31633
31634					//  (j)---(i)---(k)
31635					oneHoleMovements[ i$1 ] = getBevelVec( ahole$2[ i$1 ], ahole$2[ j$1 ], ahole$2[ k$1 ] );
31636
31637				}
31638
31639				holesMovements.push( oneHoleMovements );
31640				verticesMovements = verticesMovements.concat( oneHoleMovements );
31641
31642			}
31643
31644
31645			// Loop bevelSegments, 1 for the front, 1 for the back
31646
31647			for ( var b = 0; b < bevelSegments; b ++ ) {
31648
31649				//for ( b = bevelSegments; b > 0; b -- ) {
31650
31651				var t = b / bevelSegments;
31652				var z = bevelThickness * Math.cos( t * Math.PI / 2 );
31653				var bs$1 = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;
31654
31655				// contract shape
31656
31657				for ( var i$2 = 0, il$2 = contour.length; i$2 < il$2; i$2 ++ ) {
31658
31659					var vert = scalePt2( contour[ i$2 ], contourMovements[ i$2 ], bs$1 );
31660
31661					v( vert.x, vert.y, - z );
31662
31663				}
31664
31665				// expand holes
31666
31667				for ( var h$3 = 0, hl$3 = holes.length; h$3 < hl$3; h$3 ++ ) {
31668
31669					var ahole$3 = holes[ h$3 ];
31670					oneHoleMovements = holesMovements[ h$3 ];
31671
31672					for ( var i$3 = 0, il$3 = ahole$3.length; i$3 < il$3; i$3 ++ ) {
31673
31674						var vert$1 = scalePt2( ahole$3[ i$3 ], oneHoleMovements[ i$3 ], bs$1 );
31675
31676						v( vert$1.x, vert$1.y, - z );
31677
31678					}
31679
31680				}
31681
31682			}
31683
31684			var bs = bevelSize + bevelOffset;
31685
31686			// Back facing vertices
31687
31688			for ( var i$4 = 0; i$4 < vlen; i$4 ++ ) {
31689
31690				var vert$2 = bevelEnabled ? scalePt2( vertices[ i$4 ], verticesMovements[ i$4 ], bs ) : vertices[ i$4 ];
31691
31692				if ( ! extrudeByPath ) {
31693
31694					v( vert$2.x, vert$2.y, 0 );
31695
31696				} else {
31697
31698					// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
31699
31700					normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert$2.x );
31701					binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert$2.y );
31702
31703					position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
31704
31705					v( position2.x, position2.y, position2.z );
31706
31707				}
31708
31709			}
31710
31711			// Add stepped vertices...
31712			// Including front facing vertices
31713
31714			for ( var s = 1; s <= steps; s ++ ) {
31715
31716				for ( var i$5 = 0; i$5 < vlen; i$5 ++ ) {
31717
31718					var vert$3 = bevelEnabled ? scalePt2( vertices[ i$5 ], verticesMovements[ i$5 ], bs ) : vertices[ i$5 ];
31719
31720					if ( ! extrudeByPath ) {
31721
31722						v( vert$3.x, vert$3.y, depth / steps * s );
31723
31724					} else {
31725
31726						// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
31727
31728						normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert$3.x );
31729						binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert$3.y );
31730
31731						position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
31732
31733						v( position2.x, position2.y, position2.z );
31734
31735					}
31736
31737				}
31738
31739			}
31740
31741
31742			// Add bevel segments planes
31743
31744			//for ( b = 1; b <= bevelSegments; b ++ ) {
31745			for ( var b$1 = bevelSegments - 1; b$1 >= 0; b$1 -- ) {
31746
31747				var t$1 = b$1 / bevelSegments;
31748				var z$1 = bevelThickness * Math.cos( t$1 * Math.PI / 2 );
31749				var bs$2 = bevelSize * Math.sin( t$1 * Math.PI / 2 ) + bevelOffset;
31750
31751				// contract shape
31752
31753				for ( var i$6 = 0, il$4 = contour.length; i$6 < il$4; i$6 ++ ) {
31754
31755					var vert$4 = scalePt2( contour[ i$6 ], contourMovements[ i$6 ], bs$2 );
31756					v( vert$4.x, vert$4.y, depth + z$1 );
31757
31758				}
31759
31760				// expand holes
31761
31762				for ( var h$4 = 0, hl$4 = holes.length; h$4 < hl$4; h$4 ++ ) {
31763
31764					var ahole$4 = holes[ h$4 ];
31765					oneHoleMovements = holesMovements[ h$4 ];
31766
31767					for ( var i$7 = 0, il$5 = ahole$4.length; i$7 < il$5; i$7 ++ ) {
31768
31769						var vert$5 = scalePt2( ahole$4[ i$7 ], oneHoleMovements[ i$7 ], bs$2 );
31770
31771						if ( ! extrudeByPath ) {
31772
31773							v( vert$5.x, vert$5.y, depth + z$1 );
31774
31775						} else {
31776
31777							v( vert$5.x, vert$5.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z$1 );
31778
31779						}
31780
31781					}
31782
31783				}
31784
31785			}
31786
31787			/* Faces */
31788
31789			// Top and bottom faces
31790
31791			buildLidFaces();
31792
31793			// Sides faces
31794
31795			buildSideFaces();
31796
31797
31798			/////  Internal functions
31799
31800			function buildLidFaces() {
31801
31802				var start = verticesArray.length / 3;
31803
31804				if ( bevelEnabled ) {
31805
31806					var layer = 0; // steps + 1
31807					var offset = vlen * layer;
31808
31809					// Bottom faces
31810
31811					for ( var i = 0; i < flen; i ++ ) {
31812
31813						var face = faces[ i ];
31814						f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
31815
31816					}
31817
31818					layer = steps + bevelSegments * 2;
31819					offset = vlen * layer;
31820
31821					// Top faces
31822
31823					for ( var i$1 = 0; i$1 < flen; i$1 ++ ) {
31824
31825						var face$1 = faces[ i$1 ];
31826						f3( face$1[ 0 ] + offset, face$1[ 1 ] + offset, face$1[ 2 ] + offset );
31827
31828					}
31829
31830				} else {
31831
31832					// Bottom faces
31833
31834					for ( var i$2 = 0; i$2 < flen; i$2 ++ ) {
31835
31836						var face$2 = faces[ i$2 ];
31837						f3( face$2[ 2 ], face$2[ 1 ], face$2[ 0 ] );
31838
31839					}
31840
31841					// Top faces
31842
31843					for ( var i$3 = 0; i$3 < flen; i$3 ++ ) {
31844
31845						var face$3 = faces[ i$3 ];
31846						f3( face$3[ 0 ] + vlen * steps, face$3[ 1 ] + vlen * steps, face$3[ 2 ] + vlen * steps );
31847
31848					}
31849
31850				}
31851
31852				scope.addGroup( start, verticesArray.length / 3 - start, 0 );
31853
31854			}
31855
31856			// Create faces for the z-sides of the shape
31857
31858			function buildSideFaces() {
31859
31860				var start = verticesArray.length / 3;
31861				var layeroffset = 0;
31862				sidewalls( contour, layeroffset );
31863				layeroffset += contour.length;
31864
31865				for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
31866
31867					var ahole = holes[ h ];
31868					sidewalls( ahole, layeroffset );
31869
31870					//, true
31871					layeroffset += ahole.length;
31872
31873				}
31874
31875
31876				scope.addGroup( start, verticesArray.length / 3 - start, 1 );
31877
31878
31879			}
31880
31881			function sidewalls( contour, layeroffset ) {
31882
31883				var i = contour.length;
31884
31885				while ( -- i >= 0 ) {
31886
31887					var j = i;
31888					var k = i - 1;
31889					if ( k < 0 ) { k = contour.length - 1; }
31890
31891					//console.log('b', i,j, i-1, k,vertices.length);
31892
31893					for ( var s = 0, sl = ( steps + bevelSegments * 2 ); s < sl; s ++ ) {
31894
31895						var slen1 = vlen * s;
31896						var slen2 = vlen * ( s + 1 );
31897
31898						var a = layeroffset + j + slen1,
31899							b = layeroffset + k + slen1,
31900							c = layeroffset + k + slen2,
31901							d = layeroffset + j + slen2;
31902
31903						f4( a, b, c, d );
31904
31905					}
31906
31907				}
31908
31909			}
31910
31911			function v( x, y, z ) {
31912
31913				placeholder.push( x );
31914				placeholder.push( y );
31915				placeholder.push( z );
31916
31917			}
31918
31919
31920			function f3( a, b, c ) {
31921
31922				addVertex( a );
31923				addVertex( b );
31924				addVertex( c );
31925
31926				var nextIndex = verticesArray.length / 3;
31927				var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
31928
31929				addUV( uvs[ 0 ] );
31930				addUV( uvs[ 1 ] );
31931				addUV( uvs[ 2 ] );
31932
31933			}
31934
31935			function f4( a, b, c, d ) {
31936
31937				addVertex( a );
31938				addVertex( b );
31939				addVertex( d );
31940
31941				addVertex( b );
31942				addVertex( c );
31943				addVertex( d );
31944
31945
31946				var nextIndex = verticesArray.length / 3;
31947				var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
31948
31949				addUV( uvs[ 0 ] );
31950				addUV( uvs[ 1 ] );
31951				addUV( uvs[ 3 ] );
31952
31953				addUV( uvs[ 1 ] );
31954				addUV( uvs[ 2 ] );
31955				addUV( uvs[ 3 ] );
31956
31957			}
31958
31959			function addVertex( index ) {
31960
31961				verticesArray.push( placeholder[ index * 3 + 0 ] );
31962				verticesArray.push( placeholder[ index * 3 + 1 ] );
31963				verticesArray.push( placeholder[ index * 3 + 2 ] );
31964
31965			}
31966
31967
31968			function addUV( vector2 ) {
31969
31970				uvArray.push( vector2.x );
31971				uvArray.push( vector2.y );
31972
31973			}
31974
31975		}
31976
31977	}
31978
31979	ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
31980	ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
31981
31982	ExtrudeBufferGeometry.prototype.toJSON = function () {
31983
31984		var data = BufferGeometry.prototype.toJSON.call( this );
31985
31986		var shapes = this.parameters.shapes;
31987		var options = this.parameters.options;
31988
31989		return toJSON( shapes, options, data );
31990
31991	};
31992
31993	//
31994
31995	var WorldUVGenerator = {
31996
31997		generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
31998
31999			var a_x = vertices[ indexA * 3 ];
32000			var a_y = vertices[ indexA * 3 + 1 ];
32001			var b_x = vertices[ indexB * 3 ];
32002			var b_y = vertices[ indexB * 3 + 1 ];
32003			var c_x = vertices[ indexC * 3 ];
32004			var c_y = vertices[ indexC * 3 + 1 ];
32005
32006			return [
32007				new Vector2( a_x, a_y ),
32008				new Vector2( b_x, b_y ),
32009				new Vector2( c_x, c_y )
32010			];
32011
32012		},
32013
32014		generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {
32015
32016			var a_x = vertices[ indexA * 3 ];
32017			var a_y = vertices[ indexA * 3 + 1 ];
32018			var a_z = vertices[ indexA * 3 + 2 ];
32019			var b_x = vertices[ indexB * 3 ];
32020			var b_y = vertices[ indexB * 3 + 1 ];
32021			var b_z = vertices[ indexB * 3 + 2 ];
32022			var c_x = vertices[ indexC * 3 ];
32023			var c_y = vertices[ indexC * 3 + 1 ];
32024			var c_z = vertices[ indexC * 3 + 2 ];
32025			var d_x = vertices[ indexD * 3 ];
32026			var d_y = vertices[ indexD * 3 + 1 ];
32027			var d_z = vertices[ indexD * 3 + 2 ];
32028
32029			if ( Math.abs( a_y - b_y ) < 0.01 ) {
32030
32031				return [
32032					new Vector2( a_x, 1 - a_z ),
32033					new Vector2( b_x, 1 - b_z ),
32034					new Vector2( c_x, 1 - c_z ),
32035					new Vector2( d_x, 1 - d_z )
32036				];
32037
32038			} else {
32039
32040				return [
32041					new Vector2( a_y, 1 - a_z ),
32042					new Vector2( b_y, 1 - b_z ),
32043					new Vector2( c_y, 1 - c_z ),
32044					new Vector2( d_y, 1 - d_z )
32045				];
32046
32047			}
32048
32049		}
32050	};
32051
32052	function toJSON( shapes, options, data ) {
32053
32054		//
32055
32056		data.shapes = [];
32057
32058		if ( Array.isArray( shapes ) ) {
32059
32060			for ( var i = 0, l = shapes.length; i < l; i ++ ) {
32061
32062				var shape = shapes[ i ];
32063
32064				data.shapes.push( shape.uuid );
32065
32066			}
32067
32068		} else {
32069
32070			data.shapes.push( shapes.uuid );
32071
32072		}
32073
32074		//
32075
32076		if ( options.extrudePath !== undefined ) { data.options.extrudePath = options.extrudePath.toJSON(); }
32077
32078		return data;
32079
32080	}
32081
32082	/**
32083	 * @author zz85 / http://www.lab4games.net/zz85/blog
32084	 * @author alteredq / http://alteredqualia.com/
32085	 *
32086	 * Text = 3D Text
32087	 *
32088	 * parameters = {
32089	 *  font: <THREE.Font>, // font
32090	 *
32091	 *  size: <float>, // size of the text
32092	 *  height: <float>, // thickness to extrude text
32093	 *  curveSegments: <int>, // number of points on the curves
32094	 *
32095	 *  bevelEnabled: <bool>, // turn on bevel
32096	 *  bevelThickness: <float>, // how deep into text bevel goes
32097	 *  bevelSize: <float>, // how far from text outline (including bevelOffset) is bevel
32098	 *  bevelOffset: <float> // how far from text outline does bevel start
32099	 * }
32100	 */
32101
32102	// TextGeometry
32103
32104	function TextGeometry( text, parameters ) {
32105
32106		Geometry.call( this );
32107
32108		this.type = 'TextGeometry';
32109
32110		this.parameters = {
32111			text: text,
32112			parameters: parameters
32113		};
32114
32115		this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) );
32116		this.mergeVertices();
32117
32118	}
32119
32120	TextGeometry.prototype = Object.create( Geometry.prototype );
32121	TextGeometry.prototype.constructor = TextGeometry;
32122
32123	// TextBufferGeometry
32124
32125	function TextBufferGeometry( text, parameters ) {
32126
32127		parameters = parameters || {};
32128
32129		var font = parameters.font;
32130
32131		if ( ! ( font && font.isFont ) ) {
32132
32133			console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );
32134			return new Geometry();
32135
32136		}
32137
32138		var shapes = font.generateShapes( text, parameters.size );
32139
32140		// translate parameters to ExtrudeGeometry API
32141
32142		parameters.depth = parameters.height !== undefined ? parameters.height : 50;
32143
32144		// defaults
32145
32146		if ( parameters.bevelThickness === undefined ) { parameters.bevelThickness = 10; }
32147		if ( parameters.bevelSize === undefined ) { parameters.bevelSize = 8; }
32148		if ( parameters.bevelEnabled === undefined ) { parameters.bevelEnabled = false; }
32149
32150		ExtrudeBufferGeometry.call( this, shapes, parameters );
32151
32152		this.type = 'TextBufferGeometry';
32153
32154	}
32155
32156	TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype );
32157	TextBufferGeometry.prototype.constructor = TextBufferGeometry;
32158
32159	/**
32160	 * @author mrdoob / http://mrdoob.com/
32161	 * @author benaadams / https://twitter.com/ben_a_adams
32162	 * @author Mugen87 / https://github.com/Mugen87
32163	 */
32164
32165	// SphereGeometry
32166
32167	function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
32168
32169		Geometry.call( this );
32170
32171		this.type = 'SphereGeometry';
32172
32173		this.parameters = {
32174			radius: radius,
32175			widthSegments: widthSegments,
32176			heightSegments: heightSegments,
32177			phiStart: phiStart,
32178			phiLength: phiLength,
32179			thetaStart: thetaStart,
32180			thetaLength: thetaLength
32181		};
32182
32183		this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
32184		this.mergeVertices();
32185
32186	}
32187
32188	SphereGeometry.prototype = Object.create( Geometry.prototype );
32189	SphereGeometry.prototype.constructor = SphereGeometry;
32190
32191	// SphereBufferGeometry
32192
32193	function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
32194
32195		BufferGeometry.call( this );
32196
32197		this.type = 'SphereBufferGeometry';
32198
32199		this.parameters = {
32200			radius: radius,
32201			widthSegments: widthSegments,
32202			heightSegments: heightSegments,
32203			phiStart: phiStart,
32204			phiLength: phiLength,
32205			thetaStart: thetaStart,
32206			thetaLength: thetaLength
32207		};
32208
32209		radius = radius || 1;
32210
32211		widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
32212		heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
32213
32214		phiStart = phiStart !== undefined ? phiStart : 0;
32215		phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
32216
32217		thetaStart = thetaStart !== undefined ? thetaStart : 0;
32218		thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
32219
32220		var thetaEnd = Math.min( thetaStart + thetaLength, Math.PI );
32221
32222		var index = 0;
32223		var grid = [];
32224
32225		var vertex = new Vector3();
32226		var normal = new Vector3();
32227
32228		// buffers
32229
32230		var indices = [];
32231		var vertices = [];
32232		var normals = [];
32233		var uvs = [];
32234
32235		// generate vertices, normals and uvs
32236
32237		for ( var iy = 0; iy <= heightSegments; iy ++ ) {
32238
32239			var verticesRow = [];
32240
32241			var v = iy / heightSegments;
32242
32243			// special case for the poles
32244
32245			var uOffset = 0;
32246
32247			if ( iy == 0 && thetaStart == 0 ) {
32248
32249				uOffset = 0.5 / widthSegments;
32250
32251			} else if ( iy == heightSegments && thetaEnd == Math.PI ) {
32252
32253				uOffset = - 0.5 / widthSegments;
32254
32255			}
32256
32257			for ( var ix = 0; ix <= widthSegments; ix ++ ) {
32258
32259				var u = ix / widthSegments;
32260
32261				// vertex
32262
32263				vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
32264				vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
32265				vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
32266
32267				vertices.push( vertex.x, vertex.y, vertex.z );
32268
32269				// normal
32270
32271				normal.copy( vertex ).normalize();
32272				normals.push( normal.x, normal.y, normal.z );
32273
32274				// uv
32275
32276				uvs.push( u + uOffset, 1 - v );
32277
32278				verticesRow.push( index ++ );
32279
32280			}
32281
32282			grid.push( verticesRow );
32283
32284		}
32285
32286		// indices
32287
32288		for ( var iy$1 = 0; iy$1 < heightSegments; iy$1 ++ ) {
32289
32290			for ( var ix$1 = 0; ix$1 < widthSegments; ix$1 ++ ) {
32291
32292				var a = grid[ iy$1 ][ ix$1 + 1 ];
32293				var b = grid[ iy$1 ][ ix$1 ];
32294				var c = grid[ iy$1 + 1 ][ ix$1 ];
32295				var d = grid[ iy$1 + 1 ][ ix$1 + 1 ];
32296
32297				if ( iy$1 !== 0 || thetaStart > 0 ) { indices.push( a, b, d ); }
32298				if ( iy$1 !== heightSegments - 1 || thetaEnd < Math.PI ) { indices.push( b, c, d ); }
32299
32300			}
32301
32302		}
32303
32304		// build geometry
32305
32306		this.setIndex( indices );
32307		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32308		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
32309		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32310
32311	}
32312
32313	SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32314	SphereBufferGeometry.prototype.constructor = SphereBufferGeometry;
32315
32316	/**
32317	 * @author Kaleb Murphy
32318	 * @author Mugen87 / https://github.com/Mugen87
32319	 */
32320
32321	// RingGeometry
32322
32323	function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
32324
32325		Geometry.call( this );
32326
32327		this.type = 'RingGeometry';
32328
32329		this.parameters = {
32330			innerRadius: innerRadius,
32331			outerRadius: outerRadius,
32332			thetaSegments: thetaSegments,
32333			phiSegments: phiSegments,
32334			thetaStart: thetaStart,
32335			thetaLength: thetaLength
32336		};
32337
32338		this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
32339		this.mergeVertices();
32340
32341	}
32342
32343	RingGeometry.prototype = Object.create( Geometry.prototype );
32344	RingGeometry.prototype.constructor = RingGeometry;
32345
32346	// RingBufferGeometry
32347
32348	function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
32349
32350		BufferGeometry.call( this );
32351
32352		this.type = 'RingBufferGeometry';
32353
32354		this.parameters = {
32355			innerRadius: innerRadius,
32356			outerRadius: outerRadius,
32357			thetaSegments: thetaSegments,
32358			phiSegments: phiSegments,
32359			thetaStart: thetaStart,
32360			thetaLength: thetaLength
32361		};
32362
32363		innerRadius = innerRadius || 0.5;
32364		outerRadius = outerRadius || 1;
32365
32366		thetaStart = thetaStart !== undefined ? thetaStart : 0;
32367		thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
32368
32369		thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
32370		phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;
32371
32372		// buffers
32373
32374		var indices = [];
32375		var vertices = [];
32376		var normals = [];
32377		var uvs = [];
32378
32379		// some helper variables
32380
32381		var radius = innerRadius;
32382		var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
32383		var vertex = new Vector3();
32384		var uv = new Vector2();
32385
32386		// generate vertices, normals and uvs
32387
32388		for ( var j = 0; j <= phiSegments; j ++ ) {
32389
32390			for ( var i = 0; i <= thetaSegments; i ++ ) {
32391
32392				// values are generate from the inside of the ring to the outside
32393
32394				var segment = thetaStart + i / thetaSegments * thetaLength;
32395
32396				// vertex
32397
32398				vertex.x = radius * Math.cos( segment );
32399				vertex.y = radius * Math.sin( segment );
32400
32401				vertices.push( vertex.x, vertex.y, vertex.z );
32402
32403				// normal
32404
32405				normals.push( 0, 0, 1 );
32406
32407				// uv
32408
32409				uv.x = ( vertex.x / outerRadius + 1 ) / 2;
32410				uv.y = ( vertex.y / outerRadius + 1 ) / 2;
32411
32412				uvs.push( uv.x, uv.y );
32413
32414			}
32415
32416			// increase the radius for next row of vertices
32417
32418			radius += radiusStep;
32419
32420		}
32421
32422		// indices
32423
32424		for ( var j$1 = 0; j$1 < phiSegments; j$1 ++ ) {
32425
32426			var thetaSegmentLevel = j$1 * ( thetaSegments + 1 );
32427
32428			for ( var i$1 = 0; i$1 < thetaSegments; i$1 ++ ) {
32429
32430				var segment$1 = i$1 + thetaSegmentLevel;
32431
32432				var a = segment$1;
32433				var b = segment$1 + thetaSegments + 1;
32434				var c = segment$1 + thetaSegments + 2;
32435				var d = segment$1 + 1;
32436
32437				// faces
32438
32439				indices.push( a, b, d );
32440				indices.push( b, c, d );
32441
32442			}
32443
32444		}
32445
32446		// build geometry
32447
32448		this.setIndex( indices );
32449		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32450		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
32451		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32452
32453	}
32454
32455	RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32456	RingBufferGeometry.prototype.constructor = RingBufferGeometry;
32457
32458	/**
32459	 * @author zz85 / https://github.com/zz85
32460	 * @author bhouston / http://clara.io
32461	 * @author Mugen87 / https://github.com/Mugen87
32462	 */
32463
32464	// LatheGeometry
32465
32466	function LatheGeometry( points, segments, phiStart, phiLength ) {
32467
32468		Geometry.call( this );
32469
32470		this.type = 'LatheGeometry';
32471
32472		this.parameters = {
32473			points: points,
32474			segments: segments,
32475			phiStart: phiStart,
32476			phiLength: phiLength
32477		};
32478
32479		this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );
32480		this.mergeVertices();
32481
32482	}
32483
32484	LatheGeometry.prototype = Object.create( Geometry.prototype );
32485	LatheGeometry.prototype.constructor = LatheGeometry;
32486
32487	// LatheBufferGeometry
32488
32489	function LatheBufferGeometry( points, segments, phiStart, phiLength ) {
32490
32491		BufferGeometry.call( this );
32492
32493		this.type = 'LatheBufferGeometry';
32494
32495		this.parameters = {
32496			points: points,
32497			segments: segments,
32498			phiStart: phiStart,
32499			phiLength: phiLength
32500		};
32501
32502		segments = Math.floor( segments ) || 12;
32503		phiStart = phiStart || 0;
32504		phiLength = phiLength || Math.PI * 2;
32505
32506		// clamp phiLength so it's in range of [ 0, 2PI ]
32507
32508		phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 );
32509
32510
32511		// buffers
32512
32513		var indices = [];
32514		var vertices = [];
32515		var uvs = [];
32516
32517		// helper variables
32518
32519		var inverseSegments = 1.0 / segments;
32520		var vertex = new Vector3();
32521		var uv = new Vector2();
32522
32523		// generate vertices and uvs
32524
32525		for ( var i = 0; i <= segments; i ++ ) {
32526
32527			var phi = phiStart + i * inverseSegments * phiLength;
32528
32529			var sin = Math.sin( phi );
32530			var cos = Math.cos( phi );
32531
32532			for ( var j = 0; j <= ( points.length - 1 ); j ++ ) {
32533
32534				// vertex
32535
32536				vertex.x = points[ j ].x * sin;
32537				vertex.y = points[ j ].y;
32538				vertex.z = points[ j ].x * cos;
32539
32540				vertices.push( vertex.x, vertex.y, vertex.z );
32541
32542				// uv
32543
32544				uv.x = i / segments;
32545				uv.y = j / ( points.length - 1 );
32546
32547				uvs.push( uv.x, uv.y );
32548
32549
32550			}
32551
32552		}
32553
32554		// indices
32555
32556		for ( var i$1 = 0; i$1 < segments; i$1 ++ ) {
32557
32558			for ( var j$1 = 0; j$1 < ( points.length - 1 ); j$1 ++ ) {
32559
32560				var base = j$1 + i$1 * points.length;
32561
32562				var a = base;
32563				var b = base + points.length;
32564				var c = base + points.length + 1;
32565				var d = base + 1;
32566
32567				// faces
32568
32569				indices.push( a, b, d );
32570				indices.push( b, c, d );
32571
32572			}
32573
32574		}
32575
32576		// build geometry
32577
32578		this.setIndex( indices );
32579		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32580		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32581
32582		// generate normals
32583
32584		this.computeVertexNormals();
32585
32586		// if the geometry is closed, we need to average the normals along the seam.
32587		// because the corresponding vertices are identical (but still have different UVs).
32588
32589		if ( phiLength === Math.PI * 2 ) {
32590
32591			var normals = this.attributes.normal.array;
32592			var n1 = new Vector3();
32593			var n2 = new Vector3();
32594			var n = new Vector3();
32595
32596			// this is the buffer offset for the last line of vertices
32597
32598			var base$1 = segments * points.length * 3;
32599
32600			for ( var i$2 = 0, j$2 = 0; i$2 < points.length; i$2 ++, j$2 += 3 ) {
32601
32602				// select the normal of the vertex in the first line
32603
32604				n1.x = normals[ j$2 + 0 ];
32605				n1.y = normals[ j$2 + 1 ];
32606				n1.z = normals[ j$2 + 2 ];
32607
32608				// select the normal of the vertex in the last line
32609
32610				n2.x = normals[ base$1 + j$2 + 0 ];
32611				n2.y = normals[ base$1 + j$2 + 1 ];
32612				n2.z = normals[ base$1 + j$2 + 2 ];
32613
32614				// average normals
32615
32616				n.addVectors( n1, n2 ).normalize();
32617
32618				// assign the new values to both normals
32619
32620				normals[ j$2 + 0 ] = normals[ base$1 + j$2 + 0 ] = n.x;
32621				normals[ j$2 + 1 ] = normals[ base$1 + j$2 + 1 ] = n.y;
32622				normals[ j$2 + 2 ] = normals[ base$1 + j$2 + 2 ] = n.z;
32623
32624			}
32625
32626		}
32627
32628	}
32629
32630	LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32631	LatheBufferGeometry.prototype.constructor = LatheBufferGeometry;
32632
32633	/**
32634	 * @author jonobr1 / http://jonobr1.com
32635	 * @author Mugen87 / https://github.com/Mugen87
32636	 */
32637
32638	// ShapeGeometry
32639
32640	function ShapeGeometry( shapes, curveSegments ) {
32641
32642		Geometry.call( this );
32643
32644		this.type = 'ShapeGeometry';
32645
32646		if ( typeof curveSegments === 'object' ) {
32647
32648			console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
32649
32650			curveSegments = curveSegments.curveSegments;
32651
32652		}
32653
32654		this.parameters = {
32655			shapes: shapes,
32656			curveSegments: curveSegments
32657		};
32658
32659		this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
32660		this.mergeVertices();
32661
32662	}
32663
32664	ShapeGeometry.prototype = Object.create( Geometry.prototype );
32665	ShapeGeometry.prototype.constructor = ShapeGeometry;
32666
32667	ShapeGeometry.prototype.toJSON = function () {
32668
32669		var data = Geometry.prototype.toJSON.call( this );
32670
32671		var shapes = this.parameters.shapes;
32672
32673		return toJSON$1( shapes, data );
32674
32675	};
32676
32677	// ShapeBufferGeometry
32678
32679	function ShapeBufferGeometry( shapes, curveSegments ) {
32680
32681		BufferGeometry.call( this );
32682
32683		this.type = 'ShapeBufferGeometry';
32684
32685		this.parameters = {
32686			shapes: shapes,
32687			curveSegments: curveSegments
32688		};
32689
32690		curveSegments = curveSegments || 12;
32691
32692		// buffers
32693
32694		var indices = [];
32695		var vertices = [];
32696		var normals = [];
32697		var uvs = [];
32698
32699		// helper variables
32700
32701		var groupStart = 0;
32702		var groupCount = 0;
32703
32704		// allow single and array values for "shapes" parameter
32705
32706		if ( Array.isArray( shapes ) === false ) {
32707
32708			addShape( shapes );
32709
32710		} else {
32711
32712			for ( var i = 0; i < shapes.length; i ++ ) {
32713
32714				addShape( shapes[ i ] );
32715
32716				this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support
32717
32718				groupStart += groupCount;
32719				groupCount = 0;
32720
32721			}
32722
32723		}
32724
32725		// build geometry
32726
32727		this.setIndex( indices );
32728		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32729		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
32730		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32731
32732
32733		// helper functions
32734
32735		function addShape( shape ) {
32736
32737			var indexOffset = vertices.length / 3;
32738			var points = shape.extractPoints( curveSegments );
32739
32740			var shapeVertices = points.shape;
32741			var shapeHoles = points.holes;
32742
32743			// check direction of vertices
32744
32745			if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
32746
32747				shapeVertices = shapeVertices.reverse();
32748
32749			}
32750
32751			for ( var i = 0, l = shapeHoles.length; i < l; i ++ ) {
32752
32753				var shapeHole = shapeHoles[ i ];
32754
32755				if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
32756
32757					shapeHoles[ i ] = shapeHole.reverse();
32758
32759				}
32760
32761			}
32762
32763			var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
32764
32765			// join vertices of inner and outer paths to a single array
32766
32767			for ( var i$1 = 0, l$1 = shapeHoles.length; i$1 < l$1; i$1 ++ ) {
32768
32769				var shapeHole$1 = shapeHoles[ i$1 ];
32770				shapeVertices = shapeVertices.concat( shapeHole$1 );
32771
32772			}
32773
32774			// vertices, normals, uvs
32775
32776			for ( var i$2 = 0, l$2 = shapeVertices.length; i$2 < l$2; i$2 ++ ) {
32777
32778				var vertex = shapeVertices[ i$2 ];
32779
32780				vertices.push( vertex.x, vertex.y, 0 );
32781				normals.push( 0, 0, 1 );
32782				uvs.push( vertex.x, vertex.y ); // world uvs
32783
32784			}
32785
32786			// incides
32787
32788			for ( var i$3 = 0, l$3 = faces.length; i$3 < l$3; i$3 ++ ) {
32789
32790				var face = faces[ i$3 ];
32791
32792				var a = face[ 0 ] + indexOffset;
32793				var b = face[ 1 ] + indexOffset;
32794				var c = face[ 2 ] + indexOffset;
32795
32796				indices.push( a, b, c );
32797				groupCount += 3;
32798
32799			}
32800
32801		}
32802
32803	}
32804
32805	ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32806	ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;
32807
32808	ShapeBufferGeometry.prototype.toJSON = function () {
32809
32810		var data = BufferGeometry.prototype.toJSON.call( this );
32811
32812		var shapes = this.parameters.shapes;
32813
32814		return toJSON$1( shapes, data );
32815
32816	};
32817
32818	//
32819
32820	function toJSON$1( shapes, data ) {
32821
32822		data.shapes = [];
32823
32824		if ( Array.isArray( shapes ) ) {
32825
32826			for ( var i = 0, l = shapes.length; i < l; i ++ ) {
32827
32828				var shape = shapes[ i ];
32829
32830				data.shapes.push( shape.uuid );
32831
32832			}
32833
32834		} else {
32835
32836			data.shapes.push( shapes.uuid );
32837
32838		}
32839
32840		return data;
32841
32842	}
32843
32844	/**
32845	 * @author WestLangley / http://github.com/WestLangley
32846	 * @author Mugen87 / https://github.com/Mugen87
32847	 */
32848
32849	function EdgesGeometry( geometry, thresholdAngle ) {
32850
32851		BufferGeometry.call( this );
32852
32853		this.type = 'EdgesGeometry';
32854
32855		this.parameters = {
32856			thresholdAngle: thresholdAngle
32857		};
32858
32859		thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;
32860
32861		// buffer
32862
32863		var vertices = [];
32864
32865		// helper variables
32866
32867		var thresholdDot = Math.cos( MathUtils.DEG2RAD * thresholdAngle );
32868		var edge = [ 0, 0 ], edges = {};
32869		var edge1, edge2, key;
32870		var keys = [ 'a', 'b', 'c' ];
32871
32872		// prepare source geometry
32873
32874		var geometry2;
32875
32876		if ( geometry.isBufferGeometry ) {
32877
32878			geometry2 = new Geometry();
32879			geometry2.fromBufferGeometry( geometry );
32880
32881		} else {
32882
32883			geometry2 = geometry.clone();
32884
32885		}
32886
32887		geometry2.mergeVertices();
32888		geometry2.computeFaceNormals();
32889
32890		var sourceVertices = geometry2.vertices;
32891		var faces = geometry2.faces;
32892
32893		// now create a data structure where each entry represents an edge with its adjoining faces
32894
32895		for ( var i = 0, l = faces.length; i < l; i ++ ) {
32896
32897			var face = faces[ i ];
32898
32899			for ( var j = 0; j < 3; j ++ ) {
32900
32901				edge1 = face[ keys[ j ] ];
32902				edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
32903				edge[ 0 ] = Math.min( edge1, edge2 );
32904				edge[ 1 ] = Math.max( edge1, edge2 );
32905
32906				key = edge[ 0 ] + ',' + edge[ 1 ];
32907
32908				if ( edges[ key ] === undefined ) {
32909
32910					edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };
32911
32912				} else {
32913
32914					edges[ key ].face2 = i;
32915
32916				}
32917
32918			}
32919
32920		}
32921
32922		// generate vertices
32923
32924		for ( key in edges ) {
32925
32926			var e = edges[ key ];
32927
32928			// an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.
32929
32930			if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {
32931
32932				var vertex = sourceVertices[ e.index1 ];
32933				vertices.push( vertex.x, vertex.y, vertex.z );
32934
32935				vertex = sourceVertices[ e.index2 ];
32936				vertices.push( vertex.x, vertex.y, vertex.z );
32937
32938			}
32939
32940		}
32941
32942		// build geometry
32943
32944		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32945
32946	}
32947
32948	EdgesGeometry.prototype = Object.create( BufferGeometry.prototype );
32949	EdgesGeometry.prototype.constructor = EdgesGeometry;
32950
32951	/**
32952	 * @author mrdoob / http://mrdoob.com/
32953	 * @author Mugen87 / https://github.com/Mugen87
32954	 */
32955
32956	// CylinderGeometry
32957
32958	function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
32959
32960		Geometry.call( this );
32961
32962		this.type = 'CylinderGeometry';
32963
32964		this.parameters = {
32965			radiusTop: radiusTop,
32966			radiusBottom: radiusBottom,
32967			height: height,
32968			radialSegments: radialSegments,
32969			heightSegments: heightSegments,
32970			openEnded: openEnded,
32971			thetaStart: thetaStart,
32972			thetaLength: thetaLength
32973		};
32974
32975		this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );
32976		this.mergeVertices();
32977
32978	}
32979
32980	CylinderGeometry.prototype = Object.create( Geometry.prototype );
32981	CylinderGeometry.prototype.constructor = CylinderGeometry;
32982
32983	// CylinderBufferGeometry
32984
32985	function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
32986
32987		BufferGeometry.call( this );
32988
32989		this.type = 'CylinderBufferGeometry';
32990
32991		this.parameters = {
32992			radiusTop: radiusTop,
32993			radiusBottom: radiusBottom,
32994			height: height,
32995			radialSegments: radialSegments,
32996			heightSegments: heightSegments,
32997			openEnded: openEnded,
32998			thetaStart: thetaStart,
32999			thetaLength: thetaLength
33000		};
33001
33002		var scope = this;
33003
33004		radiusTop = radiusTop !== undefined ? radiusTop : 1;
33005		radiusBottom = radiusBottom !== undefined ? radiusBottom : 1;
33006		height = height || 1;
33007
33008		radialSegments = Math.floor( radialSegments ) || 8;
33009		heightSegments = Math.floor( heightSegments ) || 1;
33010
33011		openEnded = openEnded !== undefined ? openEnded : false;
33012		thetaStart = thetaStart !== undefined ? thetaStart : 0.0;
33013		thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
33014
33015		// buffers
33016
33017		var indices = [];
33018		var vertices = [];
33019		var normals = [];
33020		var uvs = [];
33021
33022		// helper variables
33023
33024		var index = 0;
33025		var indexArray = [];
33026		var halfHeight = height / 2;
33027		var groupStart = 0;
33028
33029		// generate geometry
33030
33031		generateTorso();
33032
33033		if ( openEnded === false ) {
33034
33035			if ( radiusTop > 0 ) { generateCap( true ); }
33036			if ( radiusBottom > 0 ) { generateCap( false ); }
33037
33038		}
33039
33040		// build geometry
33041
33042		this.setIndex( indices );
33043		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
33044		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
33045		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
33046
33047		function generateTorso() {
33048
33049			var normal = new Vector3();
33050			var vertex = new Vector3();
33051
33052			var groupCount = 0;
33053
33054			// this will be used to calculate the normal
33055			var slope = ( radiusBottom - radiusTop ) / height;
33056
33057			// generate vertices, normals and uvs
33058
33059			for ( var y = 0; y <= heightSegments; y ++ ) {
33060
33061				var indexRow = [];
33062
33063				var v = y / heightSegments;
33064
33065				// calculate the radius of the current row
33066
33067				var radius = v * ( radiusBottom - radiusTop ) + radiusTop;
33068
33069				for ( var x = 0; x <= radialSegments; x ++ ) {
33070
33071					var u = x / radialSegments;
33072
33073					var theta = u * thetaLength + thetaStart;
33074
33075					var sinTheta = Math.sin( theta );
33076					var cosTheta = Math.cos( theta );
33077
33078					// vertex
33079
33080					vertex.x = radius * sinTheta;
33081					vertex.y = - v * height + halfHeight;
33082					vertex.z = radius * cosTheta;
33083					vertices.push( vertex.x, vertex.y, vertex.z );
33084
33085					// normal
33086
33087					normal.set( sinTheta, slope, cosTheta ).normalize();
33088					normals.push( normal.x, normal.y, normal.z );
33089
33090					// uv
33091
33092					uvs.push( u, 1 - v );
33093
33094					// save index of vertex in respective row
33095
33096					indexRow.push( index ++ );
33097
33098				}
33099
33100				// now save vertices of the row in our index array
33101
33102				indexArray.push( indexRow );
33103
33104			}
33105
33106			// generate indices
33107
33108			for ( var x$1 = 0; x$1 < radialSegments; x$1 ++ ) {
33109
33110				for ( var y$1 = 0; y$1 < heightSegments; y$1 ++ ) {
33111
33112					// we use the index array to access the correct indices
33113
33114					var a = indexArray[ y$1 ][ x$1 ];
33115					var b = indexArray[ y$1 + 1 ][ x$1 ];
33116					var c = indexArray[ y$1 + 1 ][ x$1 + 1 ];
33117					var d = indexArray[ y$1 ][ x$1 + 1 ];
33118
33119					// faces
33120
33121					indices.push( a, b, d );
33122					indices.push( b, c, d );
33123
33124					// update group counter
33125
33126					groupCount += 6;
33127
33128				}
33129
33130			}
33131
33132			// add a group to the geometry. this will ensure multi material support
33133
33134			scope.addGroup( groupStart, groupCount, 0 );
33135
33136			// calculate new start value for groups
33137
33138			groupStart += groupCount;
33139
33140		}
33141
33142		function generateCap( top ) {
33143
33144			var centerIndexStart, centerIndexEnd;
33145
33146			var uv = new Vector2();
33147			var vertex = new Vector3();
33148
33149			var groupCount = 0;
33150
33151			var radius = ( top === true ) ? radiusTop : radiusBottom;
33152			var sign = ( top === true ) ? 1 : - 1;
33153
33154			// save the index of the first center vertex
33155			centerIndexStart = index;
33156
33157			// first we generate the center vertex data of the cap.
33158			// because the geometry needs one set of uvs per face,
33159			// we must generate a center vertex per face/segment
33160
33161			for ( var x = 1; x <= radialSegments; x ++ ) {
33162
33163				// vertex
33164
33165				vertices.push( 0, halfHeight * sign, 0 );
33166
33167				// normal
33168
33169				normals.push( 0, sign, 0 );
33170
33171				// uv
33172
33173				uvs.push( 0.5, 0.5 );
33174
33175				// increase index
33176
33177				index ++;
33178
33179			}
33180
33181			// save the index of the last center vertex
33182
33183			centerIndexEnd = index;
33184
33185			// now we generate the surrounding vertices, normals and uvs
33186
33187			for ( var x$1 = 0; x$1 <= radialSegments; x$1 ++ ) {
33188
33189				var u = x$1 / radialSegments;
33190				var theta = u * thetaLength + thetaStart;
33191
33192				var cosTheta = Math.cos( theta );
33193				var sinTheta = Math.sin( theta );
33194
33195				// vertex
33196
33197				vertex.x = radius * sinTheta;
33198				vertex.y = halfHeight * sign;
33199				vertex.z = radius * cosTheta;
33200				vertices.push( vertex.x, vertex.y, vertex.z );
33201
33202				// normal
33203
33204				normals.push( 0, sign, 0 );
33205
33206				// uv
33207
33208				uv.x = ( cosTheta * 0.5 ) + 0.5;
33209				uv.y = ( sinTheta * 0.5 * sign ) + 0.5;
33210				uvs.push( uv.x, uv.y );
33211
33212				// increase index
33213
33214				index ++;
33215
33216			}
33217
33218			// generate indices
33219
33220			for ( var x$2 = 0; x$2 < radialSegments; x$2 ++ ) {
33221
33222				var c = centerIndexStart + x$2;
33223				var i = centerIndexEnd + x$2;
33224
33225				if ( top === true ) {
33226
33227					// face top
33228
33229					indices.push( i, i + 1, c );
33230
33231				} else {
33232
33233					// face bottom
33234
33235					indices.push( i + 1, i, c );
33236
33237				}
33238
33239				groupCount += 3;
33240
33241			}
33242
33243			// add a group to the geometry. this will ensure multi material support
33244
33245			scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );
33246
33247			// calculate new start value for groups
33248
33249			groupStart += groupCount;
33250
33251		}
33252
33253	}
33254
33255	CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
33256	CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;
33257
33258	/**
33259	 * @author abelnation / http://github.com/abelnation
33260	 */
33261
33262	// ConeGeometry
33263
33264	function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
33265
33266		CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
33267
33268		this.type = 'ConeGeometry';
33269
33270		this.parameters = {
33271			radius: radius,
33272			height: height,
33273			radialSegments: radialSegments,
33274			heightSegments: heightSegments,
33275			openEnded: openEnded,
33276			thetaStart: thetaStart,
33277			thetaLength: thetaLength
33278		};
33279
33280	}
33281
33282	ConeGeometry.prototype = Object.create( CylinderGeometry.prototype );
33283	ConeGeometry.prototype.constructor = ConeGeometry;
33284
33285	// ConeBufferGeometry
33286
33287	function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
33288
33289		CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
33290
33291		this.type = 'ConeBufferGeometry';
33292
33293		this.parameters = {
33294			radius: radius,
33295			height: height,
33296			radialSegments: radialSegments,
33297			heightSegments: heightSegments,
33298			openEnded: openEnded,
33299			thetaStart: thetaStart,
33300			thetaLength: thetaLength
33301		};
33302
33303	}
33304
33305	ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );
33306	ConeBufferGeometry.prototype.constructor = ConeBufferGeometry;
33307
33308	/**
33309	 * @author benaadams / https://twitter.com/ben_a_adams
33310	 * @author Mugen87 / https://github.com/Mugen87
33311	 * @author hughes
33312	 */
33313
33314	// CircleGeometry
33315
33316	function CircleGeometry( radius, segments, thetaStart, thetaLength ) {
33317
33318		Geometry.call( this );
33319
33320		this.type = 'CircleGeometry';
33321
33322		this.parameters = {
33323			radius: radius,
33324			segments: segments,
33325			thetaStart: thetaStart,
33326			thetaLength: thetaLength
33327		};
33328
33329		this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
33330		this.mergeVertices();
33331
33332	}
33333
33334	CircleGeometry.prototype = Object.create( Geometry.prototype );
33335	CircleGeometry.prototype.constructor = CircleGeometry;
33336
33337	// CircleBufferGeometry
33338
33339	function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {
33340
33341		BufferGeometry.call( this );
33342
33343		this.type = 'CircleBufferGeometry';
33344
33345		this.parameters = {
33346			radius: radius,
33347			segments: segments,
33348			thetaStart: thetaStart,
33349			thetaLength: thetaLength
33350		};
33351
33352		radius = radius || 1;
33353		segments = segments !== undefined ? Math.max( 3, segments ) : 8;
33354
33355		thetaStart = thetaStart !== undefined ? thetaStart : 0;
33356		thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
33357
33358		// buffers
33359
33360		var indices = [];
33361		var vertices = [];
33362		var normals = [];
33363		var uvs = [];
33364
33365		// helper variables
33366
33367		var vertex = new Vector3();
33368		var uv = new Vector2();
33369
33370		// center point
33371
33372		vertices.push( 0, 0, 0 );
33373		normals.push( 0, 0, 1 );
33374		uvs.push( 0.5, 0.5 );
33375
33376		for ( var s = 0, i = 3; s <= segments; s ++, i += 3 ) {
33377
33378			var segment = thetaStart + s / segments * thetaLength;
33379
33380			// vertex
33381
33382			vertex.x = radius * Math.cos( segment );
33383			vertex.y = radius * Math.sin( segment );
33384
33385			vertices.push( vertex.x, vertex.y, vertex.z );
33386
33387			// normal
33388
33389			normals.push( 0, 0, 1 );
33390
33391			// uvs
33392
33393			uv.x = ( vertices[ i ] / radius + 1 ) / 2;
33394			uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;
33395
33396			uvs.push( uv.x, uv.y );
33397
33398		}
33399
33400		// indices
33401
33402		for ( var i$1 = 1; i$1 <= segments; i$1 ++ ) {
33403
33404			indices.push( i$1, i$1 + 1, 0 );
33405
33406		}
33407
33408		// build geometry
33409
33410		this.setIndex( indices );
33411		this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
33412		this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
33413		this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
33414
33415	}
33416
33417	CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
33418	CircleBufferGeometry.prototype.constructor = CircleBufferGeometry;
33419
33420	var Geometries = /*#__PURE__*/Object.freeze({
33421		__proto__: null,
33422		WireframeGeometry: WireframeGeometry,
33423		ParametricGeometry: ParametricGeometry,
33424		ParametricBufferGeometry: ParametricBufferGeometry,
33425		TetrahedronGeometry: TetrahedronGeometry,
33426		TetrahedronBufferGeometry: TetrahedronBufferGeometry,
33427		OctahedronGeometry: OctahedronGeometry,
33428		OctahedronBufferGeometry: OctahedronBufferGeometry,
33429		IcosahedronGeometry: IcosahedronGeometry,
33430		IcosahedronBufferGeometry: IcosahedronBufferGeometry,
33431		DodecahedronGeometry: DodecahedronGeometry,
33432		DodecahedronBufferGeometry: DodecahedronBufferGeometry,
33433		PolyhedronGeometry: PolyhedronGeometry,
33434		PolyhedronBufferGeometry: PolyhedronBufferGeometry,
33435		TubeGeometry: TubeGeometry,
33436		TubeBufferGeometry: TubeBufferGeometry,
33437		TorusKnotGeometry: TorusKnotGeometry,
33438		TorusKnotBufferGeometry: TorusKnotBufferGeometry,
33439		TorusGeometry: TorusGeometry,
33440		TorusBufferGeometry: TorusBufferGeometry,
33441		TextGeometry: TextGeometry,
33442		TextBufferGeometry: TextBufferGeometry,
33443		SphereGeometry: SphereGeometry,
33444		SphereBufferGeometry: SphereBufferGeometry,
33445		RingGeometry: RingGeometry,
33446		RingBufferGeometry: RingBufferGeometry,
33447		PlaneGeometry: PlaneGeometry,
33448		PlaneBufferGeometry: PlaneBufferGeometry,
33449		LatheGeometry: LatheGeometry,
33450		LatheBufferGeometry: LatheBufferGeometry,
33451		ShapeGeometry: ShapeGeometry,
33452		ShapeBufferGeometry: ShapeBufferGeometry,
33453		ExtrudeGeometry: ExtrudeGeometry,
33454		ExtrudeBufferGeometry: ExtrudeBufferGeometry,
33455		EdgesGeometry: EdgesGeometry,
33456		ConeGeometry: ConeGeometry,
33457		ConeBufferGeometry: ConeBufferGeometry,
33458		CylinderGeometry: CylinderGeometry,
33459		CylinderBufferGeometry: CylinderBufferGeometry,
33460		CircleGeometry: CircleGeometry,
33461		CircleBufferGeometry: CircleBufferGeometry,
33462		BoxGeometry: BoxGeometry,
33463		BoxBufferGeometry: BoxBufferGeometry
33464	});
33465
33466	/**
33467	 * @author mrdoob / http://mrdoob.com/
33468	 *
33469	 * parameters = {
33470	 *  color: <THREE.Color>
33471	 * }
33472	 */
33473
33474	function ShadowMaterial( parameters ) {
33475
33476		Material.call( this );
33477
33478		this.type = 'ShadowMaterial';
33479
33480		this.color = new Color( 0x000000 );
33481		this.transparent = true;
33482
33483		this.setValues( parameters );
33484
33485	}
33486
33487	ShadowMaterial.prototype = Object.create( Material.prototype );
33488	ShadowMaterial.prototype.constructor = ShadowMaterial;
33489
33490	ShadowMaterial.prototype.isShadowMaterial = true;
33491
33492	ShadowMaterial.prototype.copy = function ( source ) {
33493
33494		Material.prototype.copy.call( this, source );
33495
33496		this.color.copy( source.color );
33497
33498		return this;
33499
33500	};
33501
33502	/**
33503	 * @author mrdoob / http://mrdoob.com/
33504	 */
33505
33506	function RawShaderMaterial( parameters ) {
33507
33508		ShaderMaterial.call( this, parameters );
33509
33510		this.type = 'RawShaderMaterial';
33511
33512	}
33513
33514	RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );
33515	RawShaderMaterial.prototype.constructor = RawShaderMaterial;
33516
33517	RawShaderMaterial.prototype.isRawShaderMaterial = true;
33518
33519	/**
33520	 * @author WestLangley / http://github.com/WestLangley
33521	 *
33522	 * parameters = {
33523	 *  color: <hex>,
33524	 *  roughness: <float>,
33525	 *  metalness: <float>,
33526	 *  opacity: <float>,
33527	 *
33528	 *  map: new THREE.Texture( <Image> ),
33529	 *
33530	 *  lightMap: new THREE.Texture( <Image> ),
33531	 *  lightMapIntensity: <float>
33532	 *
33533	 *  aoMap: new THREE.Texture( <Image> ),
33534	 *  aoMapIntensity: <float>
33535	 *
33536	 *  emissive: <hex>,
33537	 *  emissiveIntensity: <float>
33538	 *  emissiveMap: new THREE.Texture( <Image> ),
33539	 *
33540	 *  bumpMap: new THREE.Texture( <Image> ),
33541	 *  bumpScale: <float>,
33542	 *
33543	 *  normalMap: new THREE.Texture( <Image> ),
33544	 *  normalMapType: THREE.TangentSpaceNormalMap,
33545	 *  normalScale: <Vector2>,
33546	 *
33547	 *  displacementMap: new THREE.Texture( <Image> ),
33548	 *  displacementScale: <float>,
33549	 *  displacementBias: <float>,
33550	 *
33551	 *  roughnessMap: new THREE.Texture( <Image> ),
33552	 *
33553	 *  metalnessMap: new THREE.Texture( <Image> ),
33554	 *
33555	 *  alphaMap: new THREE.Texture( <Image> ),
33556	 *
33557	 *  envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
33558	 *  envMapIntensity: <float>
33559	 *
33560	 *  refractionRatio: <float>,
33561	 *
33562	 *  wireframe: <boolean>,
33563	 *  wireframeLinewidth: <float>,
33564	 *
33565	 *  skinning: <bool>,
33566	 *  morphTargets: <bool>,
33567	 *  morphNormals: <bool>
33568	 * }
33569	 */
33570
33571	function MeshStandardMaterial( parameters ) {
33572
33573		Material.call( this );
33574
33575		this.defines = { 'STANDARD': '' };
33576
33577		this.type = 'MeshStandardMaterial';
33578
33579		this.color = new Color( 0xffffff ); // diffuse
33580		this.roughness = 1.0;
33581		this.metalness = 0.0;
33582
33583		this.map = null;
33584
33585		this.lightMap = null;
33586		this.lightMapIntensity = 1.0;
33587
33588		this.aoMap = null;
33589		this.aoMapIntensity = 1.0;
33590
33591		this.emissive = new Color( 0x000000 );
33592		this.emissiveIntensity = 1.0;
33593		this.emissiveMap = null;
33594
33595		this.bumpMap = null;
33596		this.bumpScale = 1;
33597
33598		this.normalMap = null;
33599		this.normalMapType = TangentSpaceNormalMap;
33600		this.normalScale = new Vector2( 1, 1 );
33601
33602		this.displacementMap = null;
33603		this.displacementScale = 1;
33604		this.displacementBias = 0;
33605
33606		this.roughnessMap = null;
33607
33608		this.metalnessMap = null;
33609
33610		this.alphaMap = null;
33611
33612		this.envMap = null;
33613		this.envMapIntensity = 1.0;
33614
33615		this.refractionRatio = 0.98;
33616
33617		this.wireframe = false;
33618		this.wireframeLinewidth = 1;
33619		this.wireframeLinecap = 'round';
33620		this.wireframeLinejoin = 'round';
33621
33622		this.skinning = false;
33623		this.morphTargets = false;
33624		this.morphNormals = false;
33625
33626		this.vertexTangents = false;
33627
33628		this.setValues( parameters );
33629
33630	}
33631
33632	MeshStandardMaterial.prototype = Object.create( Material.prototype );
33633	MeshStandardMaterial.prototype.constructor = MeshStandardMaterial;
33634
33635	MeshStandardMaterial.prototype.isMeshStandardMaterial = true;
33636
33637	MeshStandardMaterial.prototype.copy = function ( source ) {
33638
33639		Material.prototype.copy.call( this, source );
33640
33641		this.defines = { 'STANDARD': '' };
33642
33643		this.color.copy( source.color );
33644		this.roughness = source.roughness;
33645		this.metalness = source.metalness;
33646
33647		this.map = source.map;
33648
33649		this.lightMap = source.lightMap;
33650		this.lightMapIntensity = source.lightMapIntensity;
33651
33652		this.aoMap = source.aoMap;
33653		this.aoMapIntensity = source.aoMapIntensity;
33654
33655		this.emissive.copy( source.emissive );
33656		this.emissiveMap = source.emissiveMap;
33657		this.emissiveIntensity = source.emissiveIntensity;
33658
33659		this.bumpMap = source.bumpMap;
33660		this.bumpScale = source.bumpScale;
33661
33662		this.normalMap = source.normalMap;
33663		this.normalMapType = source.normalMapType;
33664		this.normalScale.copy( source.normalScale );
33665
33666		this.displacementMap = source.displacementMap;
33667		this.displacementScale = source.displacementScale;
33668		this.displacementBias = source.displacementBias;
33669
33670		this.roughnessMap = source.roughnessMap;
33671
33672		this.metalnessMap = source.metalnessMap;
33673
33674		this.alphaMap = source.alphaMap;
33675
33676		this.envMap = source.envMap;
33677		this.envMapIntensity = source.envMapIntensity;
33678
33679		this.refractionRatio = source.refractionRatio;
33680
33681		this.wireframe = source.wireframe;
33682		this.wireframeLinewidth = source.wireframeLinewidth;
33683		this.wireframeLinecap = source.wireframeLinecap;
33684		this.wireframeLinejoin = source.wireframeLinejoin;
33685
33686		this.skinning = source.skinning;
33687		this.morphTargets = source.morphTargets;
33688		this.morphNormals = source.morphNormals;
33689
33690		this.vertexTangents = source.vertexTangents;
33691
33692		return this;
33693
33694	};
33695
33696	/**
33697	 * @author WestLangley / http://github.com/WestLangley
33698	 *
33699	 * parameters = {
33700	 *  clearcoat: <float>,
33701	 *  clearcoatMap: new THREE.Texture( <Image> ),
33702	 *  clearcoatRoughness: <float>,
33703	 *  clearcoatRoughnessMap: new THREE.Texture( <Image> ),
33704	 *  clearcoatNormalScale: <Vector2>,
33705	 *  clearcoatNormalMap: new THREE.Texture( <Image> ),
33706	 *
33707	 *  reflectivity: <float>,
33708	 *
33709	 *  sheen: <Color>,
33710	 *
33711	 *  transparency: <float>
33712	 * }
33713	 */
33714
33715	function MeshPhysicalMaterial( parameters ) {
33716
33717		MeshStandardMaterial.call( this );
33718
33719		this.defines = {
33720
33721			'STANDARD': '',
33722			'PHYSICAL': ''
33723
33724		};
33725
33726		this.type = 'MeshPhysicalMaterial';
33727
33728		this.clearcoat = 0.0;
33729		this.clearcoatMap = null;
33730		this.clearcoatRoughness = 0.0;
33731		this.clearcoatRoughnessMap = null;
33732		this.clearcoatNormalScale = new Vector2( 1, 1 );
33733		this.clearcoatNormalMap = null;
33734
33735		this.reflectivity = 0.5; // maps to F0 = 0.04
33736
33737		this.sheen = null; // null will disable sheen bsdf
33738
33739		this.transparency = 0.0;
33740
33741		this.setValues( parameters );
33742
33743	}
33744
33745	MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );
33746	MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;
33747
33748	MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;
33749
33750	MeshPhysicalMaterial.prototype.copy = function ( source ) {
33751
33752		MeshStandardMaterial.prototype.copy.call( this, source );
33753
33754		this.defines = {
33755
33756			'STANDARD': '',
33757			'PHYSICAL': ''
33758
33759		};
33760
33761		this.clearcoat = source.clearcoat;
33762		this.clearcoatMap = source.clearcoatMap;
33763		this.clearcoatRoughness = source.clearcoatRoughness;
33764		this.clearcoatRoughnessMap = source.clearcoatRoughnessMap;
33765		this.clearcoatNormalMap = source.clearcoatNormalMap;
33766		this.clearcoatNormalScale.copy( source.clearcoatNormalScale );
33767
33768		this.reflectivity = source.reflectivity;
33769
33770		if ( source.sheen ) {
33771
33772			this.sheen = ( this.sheen || new Color() ).copy( source.sheen );
33773
33774		} else {
33775
33776			this.sheen = null;
33777
33778		}
33779
33780		this.transparency = source.transparency;
33781
33782		return this;
33783
33784	};
33785
33786	/**
33787	 * @author mrdoob / http://mrdoob.com/
33788	 * @author alteredq / http://alteredqualia.com/
33789	 *
33790	 * parameters = {
33791	 *  color: <hex>,
33792	 *  specular: <hex>,
33793	 *  shininess: <float>,
33794	 *  opacity: <float>,
33795	 *
33796	 *  map: new THREE.Texture( <Image> ),
33797	 *
33798	 *  lightMap: new THREE.Texture( <Image> ),
33799	 *  lightMapIntensity: <float>
33800	 *
33801	 *  aoMap: new THREE.Texture( <Image> ),
33802	 *  aoMapIntensity: <float>
33803	 *
33804	 *  emissive: <hex>,
33805	 *  emissiveIntensity: <float>
33806	 *  emissiveMap: new THREE.Texture( <Image> ),
33807	 *
33808	 *  bumpMap: new THREE.Texture( <Image> ),
33809	 *  bumpScale: <float>,
33810	 *
33811	 *  normalMap: new THREE.Texture( <Image> ),
33812	 *  normalMapType: THREE.TangentSpaceNormalMap,
33813	 *  normalScale: <Vector2>,
33814	 *
33815	 *  displacementMap: new THREE.Texture( <Image> ),
33816	 *  displacementScale: <float>,
33817	 *  displacementBias: <float>,
33818	 *
33819	 *  specularMap: new THREE.Texture( <Image> ),
33820	 *
33821	 *  alphaMap: new THREE.Texture( <Image> ),
33822	 *
33823	 *  envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
33824	 *  combine: THREE.MultiplyOperation,
33825	 *  reflectivity: <float>,
33826	 *  refractionRatio: <float>,
33827	 *
33828	 *  wireframe: <boolean>,
33829	 *  wireframeLinewidth: <float>,
33830	 *
33831	 *  skinning: <bool>,
33832	 *  morphTargets: <bool>,
33833	 *  morphNormals: <bool>
33834	 * }
33835	 */
33836
33837	function MeshPhongMaterial( parameters ) {
33838
33839		Material.call( this );
33840
33841		this.type = 'MeshPhongMaterial';
33842
33843		this.color = new Color( 0xffffff ); // diffuse
33844		this.specular = new Color( 0x111111 );
33845		this.shininess = 30;
33846
33847		this.map = null;
33848
33849		this.lightMap = null;
33850		this.lightMapIntensity = 1.0;
33851
33852		this.aoMap = null;
33853		this.aoMapIntensity = 1.0;
33854
33855		this.emissive = new Color( 0x000000 );
33856		this.emissiveIntensity = 1.0;
33857		this.emissiveMap = null;
33858
33859		this.bumpMap = null;
33860		this.bumpScale = 1;
33861
33862		this.normalMap = null;
33863		this.normalMapType = TangentSpaceNormalMap;
33864		this.normalScale = new Vector2( 1, 1 );
33865
33866		this.displacementMap = null;
33867		this.displacementScale = 1;
33868		this.displacementBias = 0;
33869
33870		this.specularMap = null;
33871
33872		this.alphaMap = null;
33873
33874		this.envMap = null;
33875		this.combine = MultiplyOperation;
33876		this.reflectivity = 1;
33877		this.refractionRatio = 0.98;
33878
33879		this.wireframe = false;
33880		this.wireframeLinewidth = 1;
33881		this.wireframeLinecap = 'round';
33882		this.wireframeLinejoin = 'round';
33883
33884		this.skinning = false;
33885		this.morphTargets = false;
33886		this.morphNormals = false;
33887
33888		this.setValues( parameters );
33889
33890	}
33891
33892	MeshPhongMaterial.prototype = Object.create( Material.prototype );
33893	MeshPhongMaterial.prototype.constructor = MeshPhongMaterial;
33894
33895	MeshPhongMaterial.prototype.isMeshPhongMaterial = true;
33896
33897	MeshPhongMaterial.prototype.copy = function ( source ) {
33898
33899		Material.prototype.copy.call( this, source );
33900
33901		this.color.copy( source.color );
33902		this.specular.copy( source.specular );
33903		this.shininess = source.shininess;
33904
33905		this.map = source.map;
33906
33907		this.lightMap = source.lightMap;
33908		this.lightMapIntensity = source.lightMapIntensity;
33909
33910		this.aoMap = source.aoMap;
33911		this.aoMapIntensity = source.aoMapIntensity;
33912
33913		this.emissive.copy( source.emissive );
33914		this.emissiveMap = source.emissiveMap;
33915		this.emissiveIntensity = source.emissiveIntensity;
33916
33917		this.bumpMap = source.bumpMap;
33918		this.bumpScale = source.bumpScale;
33919
33920		this.normalMap = source.normalMap;
33921		this.normalMapType = source.normalMapType;
33922		this.normalScale.copy( source.normalScale );
33923
33924		this.displacementMap = source.displacementMap;
33925		this.displacementScale = source.displacementScale;
33926		this.displacementBias = source.displacementBias;
33927
33928		this.specularMap = source.specularMap;
33929
33930		this.alphaMap = source.alphaMap;
33931
33932		this.envMap = source.envMap;
33933		this.combine = source.combine;
33934		this.reflectivity = source.reflectivity;
33935		this.refractionRatio = source.refractionRatio;
33936
33937		this.wireframe = source.wireframe;
33938		this.wireframeLinewidth = source.wireframeLinewidth;
33939		this.wireframeLinecap = source.wireframeLinecap;
33940		this.wireframeLinejoin = source.wireframeLinejoin;
33941
33942		this.skinning = source.skinning;
33943		this.morphTargets = source.morphTargets;
33944		this.morphNormals = source.morphNormals;
33945
33946		return this;
33947
33948	};
33949
33950	/**
33951	 * @author takahirox / http://github.com/takahirox
33952	 *
33953	 * parameters = {
33954	 *  color: <hex>,
33955	 *
33956	 *  map: new THREE.Texture( <Image> ),
33957	 *  gradientMap: new THREE.Texture( <Image> ),
33958	 *
33959	 *  lightMap: new THREE.Texture( <Image> ),
33960	 *  lightMapIntensity: <float>
33961	 *
33962	 *  aoMap: new THREE.Texture( <Image> ),
33963	 *  aoMapIntensity: <float>
33964	 *
33965	 *  emissive: <hex>,
33966	 *  emissiveIntensity: <float>
33967	 *  emissiveMap: new THREE.Texture( <Image> ),
33968	 *
33969	 *  bumpMap: new THREE.Texture( <Image> ),
33970	 *  bumpScale: <float>,
33971	 *
33972	 *  normalMap: new THREE.Texture( <Image> ),
33973	 *  normalMapType: THREE.TangentSpaceNormalMap,
33974	 *  normalScale: <Vector2>,
33975	 *
33976	 *  displacementMap: new THREE.Texture( <Image> ),
33977	 *  displacementScale: <float>,
33978	 *  displacementBias: <float>,
33979	 *
33980	 *  alphaMap: new THREE.Texture( <Image> ),
33981	 *
33982	 *  wireframe: <boolean>,
33983	 *  wireframeLinewidth: <float>,
33984	 *
33985	 *  skinning: <bool>,
33986	 *  morphTargets: <bool>,
33987	 *  morphNormals: <bool>
33988	 * }
33989	 */
33990
33991	function MeshToonMaterial( parameters ) {
33992
33993		Material.call( this );
33994
33995		this.defines = { 'TOON': '' };
33996
33997		this.type = 'MeshToonMaterial';
33998
33999		this.color = new Color( 0xffffff );
34000
34001		this.map = null;
34002		this.gradientMap = null;
34003
34004		this.lightMap = null;
34005		this.lightMapIntensity = 1.0;
34006
34007		this.aoMap = null;
34008		this.aoMapIntensity = 1.0;
34009
34010		this.emissive = new Color( 0x000000 );
34011		this.emissiveIntensity = 1.0;
34012		this.emissiveMap = null;
34013
34014		this.bumpMap = null;
34015		this.bumpScale = 1;
34016
34017		this.normalMap = null;
34018		this.normalMapType = TangentSpaceNormalMap;
34019		this.normalScale = new Vector2( 1, 1 );
34020
34021		this.displacementMap = null;
34022		this.displacementScale = 1;
34023		this.displacementBias = 0;
34024
34025		this.alphaMap = null;
34026
34027		this.wireframe = false;
34028		this.wireframeLinewidth = 1;
34029		this.wireframeLinecap = 'round';
34030		this.wireframeLinejoin = 'round';
34031
34032		this.skinning = false;
34033		this.morphTargets = false;
34034		this.morphNormals = false;
34035
34036		this.setValues( parameters );
34037
34038	}
34039
34040	MeshToonMaterial.prototype = Object.create( Material.prototype );
34041	MeshToonMaterial.prototype.constructor = MeshToonMaterial;
34042
34043	MeshToonMaterial.prototype.isMeshToonMaterial = true;
34044
34045	MeshToonMaterial.prototype.copy = function ( source ) {
34046
34047		Material.prototype.copy.call( this, source );
34048
34049		this.color.copy( source.color );
34050
34051		this.map = source.map;
34052		this.gradientMap = source.gradientMap;
34053
34054		this.lightMap = source.lightMap;
34055		this.lightMapIntensity = source.lightMapIntensity;
34056
34057		this.aoMap = source.aoMap;
34058		this.aoMapIntensity = source.aoMapIntensity;
34059
34060		this.emissive.copy( source.emissive );
34061		this.emissiveMap = source.emissiveMap;
34062		this.emissiveIntensity = source.emissiveIntensity;
34063
34064		this.bumpMap = source.bumpMap;
34065		this.bumpScale = source.bumpScale;
34066
34067		this.normalMap = source.normalMap;
34068		this.normalMapType = source.normalMapType;
34069		this.normalScale.copy( source.normalScale );
34070
34071		this.displacementMap = source.displacementMap;
34072		this.displacementScale = source.displacementScale;
34073		this.displacementBias = source.displacementBias;
34074
34075		this.alphaMap = source.alphaMap;
34076
34077		this.wireframe = source.wireframe;
34078		this.wireframeLinewidth = source.wireframeLinewidth;
34079		this.wireframeLinecap = source.wireframeLinecap;
34080		this.wireframeLinejoin = source.wireframeLinejoin;
34081
34082		this.skinning = source.skinning;
34083		this.morphTargets = source.morphTargets;
34084		this.morphNormals = source.morphNormals;
34085
34086		return this;
34087
34088	};
34089
34090	/**
34091	 * @author mrdoob / http://mrdoob.com/
34092	 * @author WestLangley / http://github.com/WestLangley
34093	 *
34094	 * parameters = {
34095	 *  opacity: <float>,
34096	 *
34097	 *  bumpMap: new THREE.Texture( <Image> ),
34098	 *  bumpScale: <float>,
34099	 *
34100	 *  normalMap: new THREE.Texture( <Image> ),
34101	 *  normalMapType: THREE.TangentSpaceNormalMap,
34102	 *  normalScale: <Vector2>,
34103	 *
34104	 *  displacementMap: new THREE.Texture( <Image> ),
34105	 *  displacementScale: <float>,
34106	 *  displacementBias: <float>,
34107	 *
34108	 *  wireframe: <boolean>,
34109	 *  wireframeLinewidth: <float>
34110	 *
34111	 *  skinning: <bool>,
34112	 *  morphTargets: <bool>,
34113	 *  morphNormals: <bool>
34114	 * }
34115	 */
34116
34117	function MeshNormalMaterial( parameters ) {
34118
34119		Material.call( this );
34120
34121		this.type = 'MeshNormalMaterial';
34122
34123		this.bumpMap = null;
34124		this.bumpScale = 1;
34125
34126		this.normalMap = null;
34127		this.normalMapType = TangentSpaceNormalMap;
34128		this.normalScale = new Vector2( 1, 1 );
34129
34130		this.displacementMap = null;
34131		this.displacementScale = 1;
34132		this.displacementBias = 0;
34133
34134		this.wireframe = false;
34135		this.wireframeLinewidth = 1;
34136
34137		this.fog = false;
34138
34139		this.skinning = false;
34140		this.morphTargets = false;
34141		this.morphNormals = false;
34142
34143		this.setValues( parameters );
34144
34145	}
34146
34147	MeshNormalMaterial.prototype = Object.create( Material.prototype );
34148	MeshNormalMaterial.prototype.constructor = MeshNormalMaterial;
34149
34150	MeshNormalMaterial.prototype.isMeshNormalMaterial = true;
34151
34152	MeshNormalMaterial.prototype.copy = function ( source ) {
34153
34154		Material.prototype.copy.call( this, source );
34155
34156		this.bumpMap = source.bumpMap;
34157		this.bumpScale = source.bumpScale;
34158
34159		this.normalMap = source.normalMap;
34160		this.normalMapType = source.normalMapType;
34161		this.normalScale.copy( source.normalScale );
34162
34163		this.displacementMap = source.displacementMap;
34164		this.displacementScale = source.displacementScale;
34165		this.displacementBias = source.displacementBias;
34166
34167		this.wireframe = source.wireframe;
34168		this.wireframeLinewidth = source.wireframeLinewidth;
34169
34170		this.skinning = source.skinning;
34171		this.morphTargets = source.morphTargets;
34172		this.morphNormals = source.morphNormals;
34173
34174		return this;
34175
34176	};
34177
34178	/**
34179	 * @author mrdoob / http://mrdoob.com/
34180	 * @author alteredq / http://alteredqualia.com/
34181	 *
34182	 * parameters = {
34183	 *  color: <hex>,
34184	 *  opacity: <float>,
34185	 *
34186	 *  map: new THREE.Texture( <Image> ),
34187	 *
34188	 *  lightMap: new THREE.Texture( <Image> ),
34189	 *  lightMapIntensity: <float>
34190	 *
34191	 *  aoMap: new THREE.Texture( <Image> ),
34192	 *  aoMapIntensity: <float>
34193	 *
34194	 *  emissive: <hex>,
34195	 *  emissiveIntensity: <float>
34196	 *  emissiveMap: new THREE.Texture( <Image> ),
34197	 *
34198	 *  specularMap: new THREE.Texture( <Image> ),
34199	 *
34200	 *  alphaMap: new THREE.Texture( <Image> ),
34201	 *
34202	 *  envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
34203	 *  combine: THREE.Multiply,
34204	 *  reflectivity: <float>,
34205	 *  refractionRatio: <float>,
34206	 *
34207	 *  wireframe: <boolean>,
34208	 *  wireframeLinewidth: <float>,
34209	 *
34210	 *  skinning: <bool>,
34211	 *  morphTargets: <bool>,
34212	 *  morphNormals: <bool>
34213	 * }
34214	 */
34215
34216	function MeshLambertMaterial( parameters ) {
34217
34218		Material.call( this );
34219
34220		this.type = 'MeshLambertMaterial';
34221
34222		this.color = new Color( 0xffffff ); // diffuse
34223
34224		this.map = null;
34225
34226		this.lightMap = null;
34227		this.lightMapIntensity = 1.0;
34228
34229		this.aoMap = null;
34230		this.aoMapIntensity = 1.0;
34231
34232		this.emissive = new Color( 0x000000 );
34233		this.emissiveIntensity = 1.0;
34234		this.emissiveMap = null;
34235
34236		this.specularMap = null;
34237
34238		this.alphaMap = null;
34239
34240		this.envMap = null;
34241		this.combine = MultiplyOperation;
34242		this.reflectivity = 1;
34243		this.refractionRatio = 0.98;
34244
34245		this.wireframe = false;
34246		this.wireframeLinewidth = 1;
34247		this.wireframeLinecap = 'round';
34248		this.wireframeLinejoin = 'round';
34249
34250		this.skinning = false;
34251		this.morphTargets = false;
34252		this.morphNormals = false;
34253
34254		this.setValues( parameters );
34255
34256	}
34257
34258	MeshLambertMaterial.prototype = Object.create( Material.prototype );
34259	MeshLambertMaterial.prototype.constructor = MeshLambertMaterial;
34260
34261	MeshLambertMaterial.prototype.isMeshLambertMaterial = true;
34262
34263	MeshLambertMaterial.prototype.copy = function ( source ) {
34264
34265		Material.prototype.copy.call( this, source );
34266
34267		this.color.copy( source.color );
34268
34269		this.map = source.map;
34270
34271		this.lightMap = source.lightMap;
34272		this.lightMapIntensity = source.lightMapIntensity;
34273
34274		this.aoMap = source.aoMap;
34275		this.aoMapIntensity = source.aoMapIntensity;
34276
34277		this.emissive.copy( source.emissive );
34278		this.emissiveMap = source.emissiveMap;
34279		this.emissiveIntensity = source.emissiveIntensity;
34280
34281		this.specularMap = source.specularMap;
34282
34283		this.alphaMap = source.alphaMap;
34284
34285		this.envMap = source.envMap;
34286		this.combine = source.combine;
34287		this.reflectivity = source.reflectivity;
34288		this.refractionRatio = source.refractionRatio;
34289
34290		this.wireframe = source.wireframe;
34291		this.wireframeLinewidth = source.wireframeLinewidth;
34292		this.wireframeLinecap = source.wireframeLinecap;
34293		this.wireframeLinejoin = source.wireframeLinejoin;
34294
34295		this.skinning = source.skinning;
34296		this.morphTargets = source.morphTargets;
34297		this.morphNormals = source.morphNormals;
34298
34299		return this;
34300
34301	};
34302
34303	/**
34304	 * @author WestLangley / http://github.com/WestLangley
34305	 *
34306	 * parameters = {
34307	 *  color: <hex>,
34308	 *  opacity: <float>,
34309	 *
34310	 *  matcap: new THREE.Texture( <Image> ),
34311	 *
34312	 *  map: new THREE.Texture( <Image> ),
34313	 *
34314	 *  bumpMap: new THREE.Texture( <Image> ),
34315	 *  bumpScale: <float>,
34316	 *
34317	 *  normalMap: new THREE.Texture( <Image> ),
34318	 *  normalMapType: THREE.TangentSpaceNormalMap,
34319	 *  normalScale: <Vector2>,
34320	 *
34321	 *  displacementMap: new THREE.Texture( <Image> ),
34322	 *  displacementScale: <float>,
34323	 *  displacementBias: <float>,
34324	 *
34325	 *  alphaMap: new THREE.Texture( <Image> ),
34326	 *
34327	 *  skinning: <bool>,
34328	 *  morphTargets: <bool>,
34329	 *  morphNormals: <bool>
34330	 * }
34331	 */
34332
34333	function MeshMatcapMaterial( parameters ) {
34334
34335		Material.call( this );
34336
34337		this.defines = { 'MATCAP': '' };
34338
34339		this.type = 'MeshMatcapMaterial';
34340
34341		this.color = new Color( 0xffffff ); // diffuse
34342
34343		this.matcap = null;
34344
34345		this.map = null;
34346
34347		this.bumpMap = null;
34348		this.bumpScale = 1;
34349
34350		this.normalMap = null;
34351		this.normalMapType = TangentSpaceNormalMap;
34352		this.normalScale = new Vector2( 1, 1 );
34353
34354		this.displacementMap = null;
34355		this.displacementScale = 1;
34356		this.displacementBias = 0;
34357
34358		this.alphaMap = null;
34359
34360		this.skinning = false;
34361		this.morphTargets = false;
34362		this.morphNormals = false;
34363
34364		this.setValues( parameters );
34365
34366	}
34367
34368	MeshMatcapMaterial.prototype = Object.create( Material.prototype );
34369	MeshMatcapMaterial.prototype.constructor = MeshMatcapMaterial;
34370
34371	MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true;
34372
34373	MeshMatcapMaterial.prototype.copy = function ( source ) {
34374
34375		Material.prototype.copy.call( this, source );
34376
34377		this.defines = { 'MATCAP': '' };
34378
34379		this.color.copy( source.color );
34380
34381		this.matcap = source.matcap;
34382
34383		this.map = source.map;
34384
34385		this.bumpMap = source.bumpMap;
34386		this.bumpScale = source.bumpScale;
34387
34388		this.normalMap = source.normalMap;
34389		this.normalMapType = source.normalMapType;
34390		this.normalScale.copy( source.normalScale );
34391
34392		this.displacementMap = source.displacementMap;
34393		this.displacementScale = source.displacementScale;
34394		this.displacementBias = source.displacementBias;
34395
34396		this.alphaMap = source.alphaMap;
34397
34398		this.skinning = source.skinning;
34399		this.morphTargets = source.morphTargets;
34400		this.morphNormals = source.morphNormals;
34401
34402		return this;
34403
34404	};
34405
34406	/**
34407	 * @author alteredq / http://alteredqualia.com/
34408	 *
34409	 * parameters = {
34410	 *  color: <hex>,
34411	 *  opacity: <float>,
34412	 *
34413	 *  linewidth: <float>,
34414	 *
34415	 *  scale: <float>,
34416	 *  dashSize: <float>,
34417	 *  gapSize: <float>
34418	 * }
34419	 */
34420
34421	function LineDashedMaterial( parameters ) {
34422
34423		LineBasicMaterial.call( this );
34424
34425		this.type = 'LineDashedMaterial';
34426
34427		this.scale = 1;
34428		this.dashSize = 3;
34429		this.gapSize = 1;
34430
34431		this.setValues( parameters );
34432
34433	}
34434
34435	LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype );
34436	LineDashedMaterial.prototype.constructor = LineDashedMaterial;
34437
34438	LineDashedMaterial.prototype.isLineDashedMaterial = true;
34439
34440	LineDashedMaterial.prototype.copy = function ( source ) {
34441
34442		LineBasicMaterial.prototype.copy.call( this, source );
34443
34444		this.scale = source.scale;
34445		this.dashSize = source.dashSize;
34446		this.gapSize = source.gapSize;
34447
34448		return this;
34449
34450	};
34451
34452	var Materials = /*#__PURE__*/Object.freeze({
34453		__proto__: null,
34454		ShadowMaterial: ShadowMaterial,
34455		SpriteMaterial: SpriteMaterial,
34456		RawShaderMaterial: RawShaderMaterial,
34457		ShaderMaterial: ShaderMaterial,
34458		PointsMaterial: PointsMaterial,
34459		MeshPhysicalMaterial: MeshPhysicalMaterial,
34460		MeshStandardMaterial: MeshStandardMaterial,
34461		MeshPhongMaterial: MeshPhongMaterial,
34462		MeshToonMaterial: MeshToonMaterial,
34463		MeshNormalMaterial: MeshNormalMaterial,
34464		MeshLambertMaterial: MeshLambertMaterial,
34465		MeshDepthMaterial: MeshDepthMaterial,
34466		MeshDistanceMaterial: MeshDistanceMaterial,
34467		MeshBasicMaterial: MeshBasicMaterial,
34468		MeshMatcapMaterial: MeshMatcapMaterial,
34469		LineDashedMaterial: LineDashedMaterial,
34470		LineBasicMaterial: LineBasicMaterial,
34471		Material: Material
34472	});
34473
34474	/**
34475	 * @author tschw
34476	 * @author Ben Houston / http://clara.io/
34477	 * @author David Sarno / http://lighthaus.us/
34478	 */
34479
34480	var AnimationUtils = {
34481
34482		// same as Array.prototype.slice, but also works on typed arrays
34483		arraySlice: function ( array, from, to ) {
34484
34485			if ( AnimationUtils.isTypedArray( array ) ) {
34486
34487				// in ios9 array.subarray(from, undefined) will return empty array
34488				// but array.subarray(from) or array.subarray(from, len) is correct
34489				return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
34490
34491			}
34492
34493			return array.slice( from, to );
34494
34495		},
34496
34497		// converts an array to a specific type
34498		convertArray: function ( array, type, forceClone ) {
34499
34500			if ( ! array || // let 'undefined' and 'null' pass
34501				! forceClone && array.constructor === type ) { return array; }
34502
34503			if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
34504
34505				return new type( array ); // create typed array
34506
34507			}
34508
34509			return Array.prototype.slice.call( array ); // create Array
34510
34511		},
34512
34513		isTypedArray: function ( object ) {
34514
34515			return ArrayBuffer.isView( object ) &&
34516				! ( object instanceof DataView );
34517
34518		},
34519
34520		// returns an array by which times and values can be sorted
34521		getKeyframeOrder: function ( times ) {
34522
34523			function compareTime( i, j ) {
34524
34525				return times[ i ] - times[ j ];
34526
34527			}
34528
34529			var n = times.length;
34530			var result = new Array( n );
34531			for ( var i = 0; i !== n; ++ i ) { result[ i ] = i; }
34532
34533			result.sort( compareTime );
34534
34535			return result;
34536
34537		},
34538
34539		// uses the array previously returned by 'getKeyframeOrder' to sort data
34540		sortedArray: function ( values, stride, order ) {
34541
34542			var nValues = values.length;
34543			var result = new values.constructor( nValues );
34544
34545			for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
34546
34547				var srcOffset = order[ i ] * stride;
34548
34549				for ( var j = 0; j !== stride; ++ j ) {
34550
34551					result[ dstOffset ++ ] = values[ srcOffset + j ];
34552
34553				}
34554
34555			}
34556
34557			return result;
34558
34559		},
34560
34561		// function for parsing AOS keyframe formats
34562		flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) {
34563
34564			var i = 1, key = jsonKeys[ 0 ];
34565
34566			while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
34567
34568				key = jsonKeys[ i ++ ];
34569
34570			}
34571
34572			if ( key === undefined ) { return; } // no data
34573
34574			var value = key[ valuePropertyName ];
34575			if ( value === undefined ) { return; } // no data
34576
34577			if ( Array.isArray( value ) ) {
34578
34579				do {
34580
34581					value = key[ valuePropertyName ];
34582
34583					if ( value !== undefined ) {
34584
34585						times.push( key.time );
34586						values.push.apply( values, value ); // push all elements
34587
34588					}
34589
34590					key = jsonKeys[ i ++ ];
34591
34592				} while ( key !== undefined );
34593
34594			} else if ( value.toArray !== undefined ) {
34595
34596				// ...assume THREE.Math-ish
34597
34598				do {
34599
34600					value = key[ valuePropertyName ];
34601
34602					if ( value !== undefined ) {
34603
34604						times.push( key.time );
34605						value.toArray( values, values.length );
34606
34607					}
34608
34609					key = jsonKeys[ i ++ ];
34610
34611				} while ( key !== undefined );
34612
34613			} else {
34614
34615				// otherwise push as-is
34616
34617				do {
34618
34619					value = key[ valuePropertyName ];
34620
34621					if ( value !== undefined ) {
34622
34623						times.push( key.time );
34624						values.push( value );
34625
34626					}
34627
34628					key = jsonKeys[ i ++ ];
34629
34630				} while ( key !== undefined );
34631
34632			}
34633
34634		},
34635
34636		subclip: function ( sourceClip, name, startFrame, endFrame, fps ) {
34637
34638			fps = fps || 30;
34639
34640			var clip = sourceClip.clone();
34641
34642			clip.name = name;
34643
34644			var tracks = [];
34645
34646			for ( var i = 0; i < clip.tracks.length; ++ i ) {
34647
34648				var track = clip.tracks[ i ];
34649				var valueSize = track.getValueSize();
34650
34651				var times = [];
34652				var values = [];
34653
34654				for ( var j = 0; j < track.times.length; ++ j ) {
34655
34656					var frame = track.times[ j ] * fps;
34657
34658					if ( frame < startFrame || frame >= endFrame ) { continue; }
34659
34660					times.push( track.times[ j ] );
34661
34662					for ( var k = 0; k < valueSize; ++ k ) {
34663
34664						values.push( track.values[ j * valueSize + k ] );
34665
34666					}
34667
34668				}
34669
34670				if ( times.length === 0 ) { continue; }
34671
34672				track.times = AnimationUtils.convertArray( times, track.times.constructor );
34673				track.values = AnimationUtils.convertArray( values, track.values.constructor );
34674
34675				tracks.push( track );
34676
34677			}
34678
34679			clip.tracks = tracks;
34680
34681			// find minimum .times value across all tracks in the trimmed clip
34682
34683			var minStartTime = Infinity;
34684
34685			for ( var i$1 = 0; i$1 < clip.tracks.length; ++ i$1 ) {
34686
34687				if ( minStartTime > clip.tracks[ i$1 ].times[ 0 ] ) {
34688
34689					minStartTime = clip.tracks[ i$1 ].times[ 0 ];
34690
34691				}
34692
34693			}
34694
34695			// shift all tracks such that clip begins at t=0
34696
34697			for ( var i$2 = 0; i$2 < clip.tracks.length; ++ i$2 ) {
34698
34699				clip.tracks[ i$2 ].shift( - 1 * minStartTime );
34700
34701			}
34702
34703			clip.resetDuration();
34704
34705			return clip;
34706
34707		},
34708
34709		makeClipAdditive: function ( targetClip, referenceFrame, referenceClip, fps ) {
34710
34711			if ( referenceFrame === undefined ) { referenceFrame = 0; }
34712			if ( referenceClip === undefined ) { referenceClip = targetClip; }
34713			if ( fps === undefined || fps <= 0 ) { fps = 30; }
34714
34715			var numTracks = targetClip.tracks.length;
34716			var referenceTime = referenceFrame / fps;
34717
34718			// Make each track's values relative to the values at the reference frame
34719			var loop = function ( i ) {
34720
34721				var referenceTrack = referenceClip.tracks[ i ];
34722				var referenceTrackType = referenceTrack.ValueTypeName;
34723
34724				// Skip this track if it's non-numeric
34725				if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) { return; }
34726
34727				// Find the track in the target clip whose name and type matches the reference track
34728				var targetTrack = targetClip.tracks.find( function ( track ) {
34729
34730					return track.name === referenceTrack.name
34731					&& track.ValueTypeName === referenceTrackType;
34732
34733				} );
34734
34735				if ( targetTrack === undefined ) { return; }
34736
34737				var valueSize = referenceTrack.getValueSize();
34738				var lastIndex = referenceTrack.times.length - 1;
34739				var referenceValue = (void 0);
34740
34741				// Find the value to subtract out of the track
34742				if ( referenceTime <= referenceTrack.times[ 0 ] ) {
34743
34744					// Reference frame is earlier than the first keyframe, so just use the first keyframe
34745					referenceValue = AnimationUtils.arraySlice( referenceTrack.values, 0, referenceTrack.valueSize );
34746
34747				} else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {
34748
34749					// Reference frame is after the last keyframe, so just use the last keyframe
34750					var startIndex = lastIndex * valueSize;
34751					referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex );
34752
34753				} else {
34754
34755					// Interpolate to the reference value
34756					var interpolant = referenceTrack.createInterpolant();
34757					interpolant.evaluate( referenceTime );
34758					referenceValue = interpolant.resultBuffer;
34759
34760				}
34761
34762				// Conjugate the quaternion
34763				if ( referenceTrackType === 'quaternion' ) {
34764
34765					var referenceQuat = new Quaternion(
34766						referenceValue[ 0 ],
34767						referenceValue[ 1 ],
34768						referenceValue[ 2 ],
34769						referenceValue[ 3 ]
34770					).normalize().conjugate();
34771					referenceQuat.toArray( referenceValue );
34772
34773				}
34774
34775				// Subtract the reference value from all of the track values
34776
34777				var numTimes = targetTrack.times.length;
34778				for ( var j = 0; j < numTimes; ++ j ) {
34779
34780					var valueStart = j * valueSize;
34781
34782					if ( referenceTrackType === 'quaternion' ) {
34783
34784						// Multiply the conjugate for quaternion track types
34785						Quaternion.multiplyQuaternionsFlat(
34786							targetTrack.values,
34787							valueStart,
34788							referenceValue,
34789							0,
34790							targetTrack.values,
34791							valueStart
34792						);
34793
34794					} else {
34795
34796						// Subtract each value for all other numeric track types
34797						for ( var k = 0; k < valueSize; ++ k ) {
34798
34799							targetTrack.values[ valueStart + k ] -= referenceValue[ k ];
34800
34801						}
34802
34803					}
34804
34805				}
34806
34807			};
34808
34809			for ( var i = 0; i < numTracks; ++ i ) loop( i );
34810
34811			targetClip.blendMode = AdditiveAnimationBlendMode;
34812
34813			return targetClip;
34814
34815		}
34816
34817	};
34818
34819	/**
34820	 * Abstract base class of interpolants over parametric samples.
34821	 *
34822	 * The parameter domain is one dimensional, typically the time or a path
34823	 * along a curve defined by the data.
34824	 *
34825	 * The sample values can have any dimensionality and derived classes may
34826	 * apply special interpretations to the data.
34827	 *
34828	 * This class provides the interval seek in a Template Method, deferring
34829	 * the actual interpolation to derived classes.
34830	 *
34831	 * Time complexity is O(1) for linear access crossing at most two points
34832	 * and O(log N) for random access, where N is the number of positions.
34833	 *
34834	 * References:
34835	 *
34836	 * 		http://www.oodesign.com/template-method-pattern.html
34837	 *
34838	 * @author tschw
34839	 */
34840
34841	function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
34842
34843		this.parameterPositions = parameterPositions;
34844		this._cachedIndex = 0;
34845
34846		this.resultBuffer = resultBuffer !== undefined ?
34847			resultBuffer : new sampleValues.constructor( sampleSize );
34848		this.sampleValues = sampleValues;
34849		this.valueSize = sampleSize;
34850
34851	}
34852
34853	Object.assign( Interpolant.prototype, {
34854
34855		evaluate: function ( t ) {
34856
34857			var pp = this.parameterPositions,
34858				i1 = this._cachedIndex,
34859
34860				t1 = pp[ i1 ],
34861				t0 = pp[ i1 - 1 ];
34862
34863			validate_interval: {
34864
34865				seek: {
34866
34867					var right;
34868
34869					linear_scan: {
34870
34871						//- See http://jsperf.com/comparison-to-undefined/3
34872						//- slower code:
34873						//-
34874						//- 				if ( t >= t1 || t1 === undefined ) {
34875						forward_scan: if ( ! ( t < t1 ) ) {
34876
34877							for ( var giveUpAt = i1 + 2; ; ) {
34878
34879								if ( t1 === undefined ) {
34880
34881									if ( t < t0 ) { break forward_scan; }
34882
34883									// after end
34884
34885									i1 = pp.length;
34886									this._cachedIndex = i1;
34887									return this.afterEnd_( i1 - 1, t, t0 );
34888
34889								}
34890
34891								if ( i1 === giveUpAt ) { break; } // this loop
34892
34893								t0 = t1;
34894								t1 = pp[ ++ i1 ];
34895
34896								if ( t < t1 ) {
34897
34898									// we have arrived at the sought interval
34899									break seek;
34900
34901								}
34902
34903							}
34904
34905							// prepare binary search on the right side of the index
34906							right = pp.length;
34907							break linear_scan;
34908
34909						}
34910
34911						//- slower code:
34912						//-					if ( t < t0 || t0 === undefined ) {
34913						if ( ! ( t >= t0 ) ) {
34914
34915							// looping?
34916
34917							var t1global = pp[ 1 ];
34918
34919							if ( t < t1global ) {
34920
34921								i1 = 2; // + 1, using the scan for the details
34922								t0 = t1global;
34923
34924							}
34925
34926							// linear reverse scan
34927
34928							for ( var giveUpAt$1 = i1 - 2; ; ) {
34929
34930								if ( t0 === undefined ) {
34931
34932									// before start
34933
34934									this._cachedIndex = 0;
34935									return this.beforeStart_( 0, t, t1 );
34936
34937								}
34938
34939								if ( i1 === giveUpAt$1 ) { break; } // this loop
34940
34941								t1 = t0;
34942								t0 = pp[ -- i1 - 1 ];
34943
34944								if ( t >= t0 ) {
34945
34946									// we have arrived at the sought interval
34947									break seek;
34948
34949								}
34950
34951							}
34952
34953							// prepare binary search on the left side of the index
34954							right = i1;
34955							i1 = 0;
34956							break linear_scan;
34957
34958						}
34959
34960						// the interval is valid
34961
34962						break validate_interval;
34963
34964					} // linear scan
34965
34966					// binary search
34967
34968					while ( i1 < right ) {
34969
34970						var mid = ( i1 + right ) >>> 1;
34971
34972						if ( t < pp[ mid ] ) {
34973
34974							right = mid;
34975
34976						} else {
34977
34978							i1 = mid + 1;
34979
34980						}
34981
34982					}
34983
34984					t1 = pp[ i1 ];
34985					t0 = pp[ i1 - 1 ];
34986
34987					// check boundary cases, again
34988
34989					if ( t0 === undefined ) {
34990
34991						this._cachedIndex = 0;
34992						return this.beforeStart_( 0, t, t1 );
34993
34994					}
34995
34996					if ( t1 === undefined ) {
34997
34998						i1 = pp.length;
34999						this._cachedIndex = i1;
35000						return this.afterEnd_( i1 - 1, t0, t );
35001
35002					}
35003
35004				} // seek
35005
35006				this._cachedIndex = i1;
35007
35008				this.intervalChanged_( i1, t0, t1 );
35009
35010			} // validate_interval
35011
35012			return this.interpolate_( i1, t0, t, t1 );
35013
35014		},
35015
35016		settings: null, // optional, subclass-specific settings structure
35017		// Note: The indirection allows central control of many interpolants.
35018
35019		// --- Protected interface
35020
35021		DefaultSettings_: {},
35022
35023		getSettings_: function () {
35024
35025			return this.settings || this.DefaultSettings_;
35026
35027		},
35028
35029		copySampleValue_: function ( index ) {
35030
35031			// copies a sample value to the result buffer
35032
35033			var result = this.resultBuffer,
35034				values = this.sampleValues,
35035				stride = this.valueSize,
35036				offset = index * stride;
35037
35038			for ( var i = 0; i !== stride; ++ i ) {
35039
35040				result[ i ] = values[ offset + i ];
35041
35042			}
35043
35044			return result;
35045
35046		},
35047
35048		// Template methods for derived classes:
35049
35050		interpolate_: function ( /* i1, t0, t, t1 */ ) {
35051
35052			throw new Error( 'call to abstract method' );
35053			// implementations shall return this.resultBuffer
35054
35055		},
35056
35057		intervalChanged_: function ( /* i1, t0, t1 */ ) {
35058
35059			// empty
35060
35061		}
35062
35063	} );
35064
35065	// DECLARE ALIAS AFTER assign prototype
35066	Object.assign( Interpolant.prototype, {
35067
35068		//( 0, t, t0 ), returns this.resultBuffer
35069		beforeStart_: Interpolant.prototype.copySampleValue_,
35070
35071		//( N-1, tN-1, t ), returns this.resultBuffer
35072		afterEnd_: Interpolant.prototype.copySampleValue_,
35073
35074	} );
35075
35076	/**
35077	 * Fast and simple cubic spline interpolant.
35078	 *
35079	 * It was derived from a Hermitian construction setting the first derivative
35080	 * at each sample position to the linear slope between neighboring positions
35081	 * over their parameter interval.
35082	 *
35083	 * @author tschw
35084	 */
35085
35086	function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
35087
35088		Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
35089
35090		this._weightPrev = - 0;
35091		this._offsetPrev = - 0;
35092		this._weightNext = - 0;
35093		this._offsetNext = - 0;
35094
35095	}
35096
35097	CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
35098
35099		constructor: CubicInterpolant,
35100
35101		DefaultSettings_: {
35102
35103			endingStart: ZeroCurvatureEnding,
35104			endingEnd: ZeroCurvatureEnding
35105
35106		},
35107
35108		intervalChanged_: function ( i1, t0, t1 ) {
35109
35110			var pp = this.parameterPositions,
35111				iPrev = i1 - 2,
35112				iNext = i1 + 1,
35113
35114				tPrev = pp[ iPrev ],
35115				tNext = pp[ iNext ];
35116
35117			if ( tPrev === undefined ) {
35118
35119				switch ( this.getSettings_().endingStart ) {
35120
35121					case ZeroSlopeEnding:
35122
35123						// f'(t0) = 0
35124						iPrev = i1;
35125						tPrev = 2 * t0 - t1;
35126
35127						break;
35128
35129					case WrapAroundEnding:
35130
35131						// use the other end of the curve
35132						iPrev = pp.length - 2;
35133						tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];
35134
35135						break;
35136
35137					default: // ZeroCurvatureEnding
35138
35139						// f''(t0) = 0 a.k.a. Natural Spline
35140						iPrev = i1;
35141						tPrev = t1;
35142
35143				}
35144
35145			}
35146
35147			if ( tNext === undefined ) {
35148
35149				switch ( this.getSettings_().endingEnd ) {
35150
35151					case ZeroSlopeEnding:
35152
35153						// f'(tN) = 0
35154						iNext = i1;
35155						tNext = 2 * t1 - t0;
35156
35157						break;
35158
35159					case WrapAroundEnding:
35160
35161						// use the other end of the curve
35162						iNext = 1;
35163						tNext = t1 + pp[ 1 ] - pp[ 0 ];
35164
35165						break;
35166
35167					default: // ZeroCurvatureEnding
35168
35169						// f''(tN) = 0, a.k.a. Natural Spline
35170						iNext = i1 - 1;
35171						tNext = t0;
35172
35173				}
35174
35175			}
35176
35177			var halfDt = ( t1 - t0 ) * 0.5,
35178				stride = this.valueSize;
35179
35180			this._weightPrev = halfDt / ( t0 - tPrev );
35181			this._weightNext = halfDt / ( tNext - t1 );
35182			this._offsetPrev = iPrev * stride;
35183			this._offsetNext = iNext * stride;
35184
35185		},
35186
35187		interpolate_: function ( i1, t0, t, t1 ) {
35188
35189			var result = this.resultBuffer,
35190				values = this.sampleValues,
35191				stride = this.valueSize,
35192
35193				o1 = i1 * stride,		o0 = o1 - stride,
35194				oP = this._offsetPrev, 	oN = this._offsetNext,
35195				wP = this._weightPrev,	wN = this._weightNext,
35196
35197				p = ( t - t0 ) / ( t1 - t0 ),
35198				pp = p * p,
35199				ppp = pp * p;
35200
35201			// evaluate polynomials
35202
35203			var sP = - wP * ppp + 2 * wP * pp - wP * p;
35204			var s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1;
35205			var s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;
35206			var sN = wN * ppp - wN * pp;
35207
35208			// combine data linearly
35209
35210			for ( var i = 0; i !== stride; ++ i ) {
35211
35212				result[ i ] =
35213						sP * values[ oP + i ] +
35214						s0 * values[ o0 + i ] +
35215						s1 * values[ o1 + i ] +
35216						sN * values[ oN + i ];
35217
35218			}
35219
35220			return result;
35221
35222		}
35223
35224	} );
35225
35226	/**
35227	 * @author tschw
35228	 */
35229
35230	function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
35231
35232		Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
35233
35234	}
35235
35236	LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
35237
35238		constructor: LinearInterpolant,
35239
35240		interpolate_: function ( i1, t0, t, t1 ) {
35241
35242			var result = this.resultBuffer,
35243				values = this.sampleValues,
35244				stride = this.valueSize,
35245
35246				offset1 = i1 * stride,
35247				offset0 = offset1 - stride,
35248
35249				weight1 = ( t - t0 ) / ( t1 - t0 ),
35250				weight0 = 1 - weight1;
35251
35252			for ( var i = 0; i !== stride; ++ i ) {
35253
35254				result[ i ] =
35255						values[ offset0 + i ] * weight0 +
35256						values[ offset1 + i ] * weight1;
35257
35258			}
35259
35260			return result;
35261
35262		}
35263
35264	} );
35265
35266	/**
35267	 *
35268	 * Interpolant that evaluates to the sample value at the position preceeding
35269	 * the parameter.
35270	 *
35271	 * @author tschw
35272	 */
35273
35274	function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
35275
35276		Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
35277
35278	}
35279
35280	DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
35281
35282		constructor: DiscreteInterpolant,
35283
35284		interpolate_: function ( i1 /*, t0, t, t1 */ ) {
35285
35286			return this.copySampleValue_( i1 - 1 );
35287
35288		}
35289
35290	} );
35291
35292	/**
35293	 *
35294	 * A timed sequence of keyframes for a specific property.
35295	 *
35296	 *
35297	 * @author Ben Houston / http://clara.io/
35298	 * @author David Sarno / http://lighthaus.us/
35299	 * @author tschw
35300	 */
35301
35302	function KeyframeTrack( name, times, values, interpolation ) {
35303
35304		if ( name === undefined ) { throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); }
35305		if ( times === undefined || times.length === 0 ) { throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + n
35305ame ); }
35306
35307		this.name = name;
35308
35309		this.times = AnimationUtils.convertArray( times, this.TimeBufferType );
35310		this.values = AnimationUtils.convertArray( values, this.ValueBufferType );
35311
35312		this.setInterpolation( interpolation || this.DefaultInterpolation );
35313
35314	}
35315
35316	// Static methods
35317
35318	Object.assign( KeyframeTrack, {
35319
35320		// Serialization (in static context, because of constructor invocation
35321		// and automatic invocation of .toJSON):
35322
35323		toJSON: function ( track ) {
35324
35325			var trackType = track.constructor;
35326
35327			var json;
35328
35329			// derived classes can define a static toJSON method
35330			if ( trackType.toJSON !== undefined ) {
35331
35332				json = trackType.toJSON( track );
35333
35334			} else {
35335
35336				// by default, we assume the data can be serialized as-is
35337				json = {
35338
35339					'name': track.name,
35340					'times': AnimationUtils.convertArray( track.times, Array ),
35341					'values': AnimationUtils.convertArray( track.values, Array )
35342
35343				};
35344
35345				var interpolation = track.getInterpolation();
35346
35347				if ( interpolation !== track.DefaultInterpolation ) {
35348
35349					json.interpolation = interpolation;
35350
35351				}
35352
35353			}
35354
35355			json.type = track.ValueTypeName; // mandatory
35356
35357			return json;
35358
35359		}
35360
35361	} );
35362
35363	Object.assign( KeyframeTrack.prototype, {
35364
35365		constructor: KeyframeTrack,
35366
35367		TimeBufferType: Float32Array,
35368
35369		ValueBufferType: Float32Array,
35370
35371		DefaultInterpolation: InterpolateLinear,
35372
35373		InterpolantFactoryMethodDiscrete: function ( result ) {
35374
35375			return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result );
35376
35377		},
35378
35379		InterpolantFactoryMethodLinear: function ( result ) {
35380
35381			return new LinearInterpolant( this.times, this.values, this.getValueSize(), result );
35382
35383		},
35384
35385		InterpolantFactoryMethodSmooth: function ( result ) {
35386
35387			return new CubicInterpolant( this.times, this.values, this.getValueSize(), result );
35388
35389		},
35390
35391		setInterpolation: function ( interpolation ) {
35392
35393			var factoryMethod;
35394
35395			switch ( interpolation ) {
35396
35397				case InterpolateDiscrete:
35398
35399					factoryMethod = this.InterpolantFactoryMethodDiscrete;
35400
35401					break;
35402
35403				case InterpolateLinear:
35404
35405					factoryMethod = this.InterpolantFactoryMethodLinear;
35406
35407					break;
35408
35409				case InterpolateSmooth:
35410
35411					factoryMethod = this.InterpolantFactoryMethodSmooth;
35412
35413					break;
35414
35415			}
35416
35417			if ( factoryMethod === undefined ) {
35418
35419				var message = "unsupported interpolation for " +
35420					this.ValueTypeName + " keyframe track named " + this.name;
35421
35422				if ( this.createInterpolant === undefined ) {
35423
35424					// fall back to default, unless the default itself is messed up
35425					if ( interpolation !== this.DefaultInterpolation ) {
35426
35427						this.setInterpolation( this.DefaultInterpolation );
35428
35429					} else {
35430
35431						throw new Error( message ); // fatal, in this case
35432
35433					}
35434
35435				}
35436
35437				console.warn( 'THREE.KeyframeTrack:', message );
35438				return this;
35439
35440			}
35441
35442			this.createInterpolant = factoryMethod;
35443
35444			return this;
35445
35446		},
35447
35448		getInterpolation: function () {
35449
35450			switch ( this.createInterpolant ) {
35451
35452				case this.InterpolantFactoryMethodDiscrete:
35453
35454					return InterpolateDiscrete;
35455
35456				case this.InterpolantFactoryMethodLinear:
35457
35458					return InterpolateLinear;
35459
35460				case this.InterpolantFactoryMethodSmooth:
35461
35462					return InterpolateSmooth;
35463
35464			}
35465
35466		},
35467
35468		getValueSize: function () {
35469
35470			return this.values.length / this.times.length;
35471
35472		},
35473
35474		// move all keyframes either forwards or backwards in time
35475		shift: function ( timeOffset ) {
35476
35477			if ( timeOffset !== 0.0 ) {
35478
35479				var times = this.times;
35480
35481				for ( var i = 0, n = times.length; i !== n; ++ i ) {
35482
35483					times[ i ] += timeOffset;
35484
35485				}
35486
35487			}
35488
35489			return this;
35490
35491		},
35492
35493		// scale all keyframe times by a factor (useful for frame <-> seconds conversions)
35494		scale: function ( timeScale ) {
35495
35496			if ( timeScale !== 1.0 ) {
35497
35498				var times = this.times;
35499
35500				for ( var i = 0, n = times.length; i !== n; ++ i ) {
35501
35502					times[ i ] *= timeScale;
35503
35504				}
35505
35506			}
35507
35508			return this;
35509
35510		},
35511
35512		// removes keyframes before and after animation without changing any values within the range [startTime, endTime].
35513		// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
35514		trim: function ( startTime, endTime ) {
35515
35516			var times = this.times,
35517				nKeys = times.length;
35518
35519			var from = 0,
35520				to = nKeys - 1;
35521
35522			while ( from !== nKeys && times[ from ] < startTime ) {
35523
35524				++ from;
35525
35526			}
35527
35528			while ( to !== - 1 && times[ to ] > endTime ) {
35529
35530				-- to;
35531
35532			}
35533
35534			++ to; // inclusive -> exclusive bound
35535
35536			if ( from !== 0 || to !== nKeys ) {
35537
35538				// empty tracks are forbidden, so keep at least one keyframe
35539				if ( from >= to ) {
35540
35541					to = Math.max( to, 1 );
35542					from = to - 1;
35543
35544				}
35545
35546				var stride = this.getValueSize();
35547				this.times = AnimationUtils.arraySlice( times, from, to );
35548				this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride );
35549
35550			}
35551
35552			return this;
35553
35554		},
35555
35556		// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
35557		validate: function () {
35558
35559			var valid = true;
35560
35561			var valueSize = this.getValueSize();
35562			if ( valueSize - Math.floor( valueSize ) !== 0 ) {
35563
35564				console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this );
35565				valid = false;
35566
35567			}
35568
35569			var times = this.times,
35570				values = this.values,
35571
35572				nKeys = times.length;
35573
35574			if ( nKeys === 0 ) {
35575
35576				console.error( 'THREE.KeyframeTrack: Track is empty.', this );
35577				valid = false;
35578
35579			}
35580
35581			var prevTime = null;
35582
35583			for ( var i = 0; i !== nKeys; i ++ ) {
35584
35585				var currTime = times[ i ];
35586
35587				if ( typeof currTime === 'number' && isNaN( currTime ) ) {
35588
35589					console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime );
35590					valid = false;
35591					break;
35592
35593				}
35594
35595				if ( prevTime !== null && prevTime > currTime ) {
35596
35597					console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime );
35598					valid = false;
35599					break;
35600
35601				}
35602
35603				prevTime = currTime;
35604
35605			}
35606
35607			if ( values !== undefined ) {
35608
35609				if ( AnimationUtils.isTypedArray( values ) ) {
35610
35611					for ( var i$1 = 0, n = values.length; i$1 !== n; ++ i$1 ) {
35612
35613						var value = values[ i$1 ];
35614
35615						if ( isNaN( value ) ) {
35616
35617							console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i$1, value );
35618							valid = false;
35619							break;
35620
35621						}
35622
35623					}
35624
35625				}
35626
35627			}
35628
35629			return valid;
35630
35631		},
35632
35633		// removes equivalent sequential keys as common in morph target sequences
35634		// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
35635		optimize: function () {
35636
35637			// times or values may be shared with other tracks, so overwriting is unsafe
35638			var times = AnimationUtils.arraySlice( this.times ),
35639				values = AnimationUtils.arraySlice( this.values ),
35640				stride = this.getValueSize(),
35641
35642				smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
35643
35644				lastIndex = times.length - 1;
35645
35646			var writeIndex = 1;
35647
35648			for ( var i = 1; i < lastIndex; ++ i ) {
35649
35650				var keep = false;
35651
35652				var time = times[ i ];
35653				var timeNext = times[ i + 1 ];
35654
35655				// remove adjacent keyframes scheduled at the same time
35656
35657				if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {
35658
35659					if ( ! smoothInterpolation ) {
35660
35661						// remove unnecessary keyframes same as their neighbors
35662
35663						var offset = i * stride,
35664							offsetP = offset - stride,
35665							offsetN = offset + stride;
35666
35667						for ( var j = 0; j !== stride; ++ j ) {
35668
35669							var value = values[ offset + j ];
35670
35671							if ( value !== values[ offsetP + j ] ||
35672								value !== values[ offsetN + j ] ) {
35673
35674								keep = true;
35675								break;
35676
35677							}
35678
35679						}
35680
35681					} else {
35682
35683						keep = true;
35684
35685					}
35686
35687				}
35688
35689				// in-place compaction
35690
35691				if ( keep ) {
35692
35693					if ( i !== writeIndex ) {
35694
35695						times[ writeIndex ] = times[ i ];
35696
35697						var readOffset = i * stride,
35698							writeOffset = writeIndex * stride;
35699
35700						for ( var j$1 = 0; j$1 !== stride; ++ j$1 ) {
35701
35702							values[ writeOffset + j$1 ] = values[ readOffset + j$1 ];
35703
35704						}
35705
35706					}
35707
35708					++ writeIndex;
35709
35710				}
35711
35712			}
35713
35714			// flush last keyframe (compaction looks ahead)
35715
35716			if ( lastIndex > 0 ) {
35717
35718				times[ writeIndex ] = times[ lastIndex ];
35719
35720				for ( var readOffset$1 = lastIndex * stride, writeOffset$1 = writeIndex * stride, j$2 = 0; j$2 !== stride; ++ j$2 ) {
35721
35722					values[ writeOffset$1 + j$2 ] = values[ readOffset$1 + j$2 ];
35723
35724				}
35725
35726				++ writeIndex;
35727
35728			}
35729
35730			if ( writeIndex !== times.length ) {
35731
35732				this.times = AnimationUtils.arraySlice( times, 0, writeIndex );
35733				this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );
35734
35735			} else {
35736
35737				this.times = times;
35738				this.values = values;
35739
35740			}
35741
35742			return this;
35743
35744		},
35745
35746		clone: function () {
35747
35748			var times = AnimationUtils.arraySlice( this.times, 0 );
35749			var values = AnimationUtils.arraySlice( this.values, 0 );
35750
35751			var TypedKeyframeTrack = this.constructor;
35752			var track = new TypedKeyframeTrack( this.name, times, values );
35753
35754			// Interpolant argument to constructor is not saved, so copy the factory method directly.
35755			track.createInterpolant = this.createInterpolant;
35756
35757			return track;
35758
35759		}
35760
35761	} );
35762
35763	/**
35764	 *
35765	 * A Track of Boolean keyframe values.
35766	 *
35767	 *
35768	 * @author Ben Houston / http://clara.io/
35769	 * @author David Sarno / http://lighthaus.us/
35770	 * @author tschw
35771	 */
35772
35773	function BooleanKeyframeTrack( name, times, values ) {
35774
35775		KeyframeTrack.call( this, name, times, values );
35776
35777	}
35778
35779	BooleanKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35780
35781		constructor: BooleanKeyframeTrack,
35782
35783		ValueTypeName: 'bool',
35784		ValueBufferType: Array,
35785
35786		DefaultInterpolation: InterpolateDiscrete,
35787
35788		InterpolantFactoryMethodLinear: undefined,
35789		InterpolantFactoryMethodSmooth: undefined
35790
35791		// Note: Actually this track could have a optimized / compressed
35792		// representation of a single value and a custom interpolant that
35793		// computes "firstValue ^ isOdd( index )".
35794
35795	} );
35796
35797	/**
35798	 *
35799	 * A Track of keyframe values that represent color.
35800	 *
35801	 *
35802	 * @author Ben Houston / http://clara.io/
35803	 * @author David Sarno / http://lighthaus.us/
35804	 * @author tschw
35805	 */
35806
35807	function ColorKeyframeTrack( name, times, values, interpolation ) {
35808
35809		KeyframeTrack.call( this, name, times, values, interpolation );
35810
35811	}
35812
35813	ColorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35814
35815		constructor: ColorKeyframeTrack,
35816
35817		ValueTypeName: 'color'
35818
35819		// ValueBufferType is inherited
35820
35821		// DefaultInterpolation is inherited
35822
35823		// Note: Very basic implementation and nothing special yet.
35824		// However, this is the place for color space parameterization.
35825
35826	} );
35827
35828	/**
35829	 *
35830	 * A Track of numeric keyframe values.
35831	 *
35832	 * @author Ben Houston / http://clara.io/
35833	 * @author David Sarno / http://lighthaus.us/
35834	 * @author tschw
35835	 */
35836
35837	function NumberKeyframeTrack( name, times, values, interpolation ) {
35838
35839		KeyframeTrack.call( this, name, times, values, interpolation );
35840
35841	}
35842
35843	NumberKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35844
35845		constructor: NumberKeyframeTrack,
35846
35847		ValueTypeName: 'number'
35848
35849		// ValueBufferType is inherited
35850
35851		// DefaultInterpolation is inherited
35852
35853	} );
35854
35855	/**
35856	 * Spherical linear unit quaternion interpolant.
35857	 *
35858	 * @author tschw
35859	 */
35860
35861	function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
35862
35863		Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
35864
35865	}
35866
35867	QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
35868
35869		constructor: QuaternionLinearInterpolant,
35870
35871		interpolate_: function ( i1, t0, t, t1 ) {
35872
35873			var result = this.resultBuffer,
35874				values = this.sampleValues,
35875				stride = this.valueSize,
35876
35877				alpha = ( t - t0 ) / ( t1 - t0 );
35878
35879			var offset = i1 * stride;
35880
35881			for ( var end = offset + stride; offset !== end; offset += 4 ) {
35882
35883				Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha );
35884
35885			}
35886
35887			return result;
35888
35889		}
35890
35891	} );
35892
35893	/**
35894	 *
35895	 * A Track of quaternion keyframe values.
35896	 *
35897	 * @author Ben Houston / http://clara.io/
35898	 * @author David Sarno / http://lighthaus.us/
35899	 * @author tschw
35900	 */
35901
35902	function QuaternionKeyframeTrack( name, times, values, interpolation ) {
35903
35904		KeyframeTrack.call( this, name, times, values, interpolation );
35905
35906	}
35907
35908	QuaternionKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35909
35910		constructor: QuaternionKeyframeTrack,
35911
35912		ValueTypeName: 'quaternion',
35913
35914		// ValueBufferType is inherited
35915
35916		DefaultInterpolation: InterpolateLinear,
35917
35918		InterpolantFactoryMethodLinear: function ( result ) {
35919
35920			return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result );
35921
35922		},
35923
35924		InterpolantFactoryMethodSmooth: undefined // not yet implemented
35925
35926	} );
35927
35928	/**
35929	 *
35930	 * A Track that interpolates Strings
35931	 *
35932	 *
35933	 * @author Ben Houston / http://clara.io/
35934	 * @author David Sarno / http://lighthaus.us/
35935	 * @author tschw
35936	 */
35937
35938	function StringKeyframeTrack( name, times, values, interpolation ) {
35939
35940		KeyframeTrack.call( this, name, times, values, interpolation );
35941
35942	}
35943
35944	StringKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35945
35946		constructor: StringKeyframeTrack,
35947
35948		ValueTypeName: 'string',
35949		ValueBufferType: Array,
35950
35951		DefaultInterpolation: InterpolateDiscrete,
35952
35953		InterpolantFactoryMethodLinear: undefined,
35954
35955		InterpolantFactoryMethodSmooth: undefined
35956
35957	} );
35958
35959	/**
35960	 *
35961	 * A Track of vectored keyframe values.
35962	 *
35963	 *
35964	 * @author Ben Houston / http://clara.io/
35965	 * @author David Sarno / http://lighthaus.us/
35966	 * @author tschw
35967	 */
35968
35969	function VectorKeyframeTrack( name, times, values, interpolation ) {
35970
35971		KeyframeTrack.call( this, name, times, values, interpolation );
35972
35973	}
35974
35975	VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35976
35977		constructor: VectorKeyframeTrack,
35978
35979		ValueTypeName: 'vector'
35980
35981		// ValueBufferType is inherited
35982
35983		// DefaultInterpolation is inherited
35984
35985	} );
35986
35987	/**
35988	 *
35989	 * Reusable set of Tracks that represent an animation.
35990	 *
35991	 * @author Ben Houston / http://clara.io/
35992	 * @author David Sarno / http://lighthaus.us/
35993	 */
35994
35995	function AnimationClip( name, duration, tracks, blendMode ) {
35996
35997		this.name = name;
35998		this.tracks = tracks;
35999		this.duration = ( duration !== undefined ) ? duration : - 1;
36000		this.blendMode = ( blendMode !== undefined ) ? blendMode : NormalAnimationBlendMode;
36001
36002		this.uuid = MathUtils.generateUUID();
36003
36004		// this means it should figure out its duration by scanning the tracks
36005		if ( this.duration < 0 ) {
36006
36007			this.resetDuration();
36008
36009		}
36010
36011	}
36012
36013	function getTrackTypeForValueTypeName( typeName ) {
36014
36015		switch ( typeName.toLowerCase() ) {
36016
36017			case 'scalar':
36018			case 'double':
36019			case 'float':
36020			case 'number':
36021			case 'integer':
36022
36023				return NumberKeyframeTrack;
36024
36025			case 'vector':
36026			case 'vector2':
36027			case 'vector3':
36028			case 'vector4':
36029
36030				return VectorKeyframeTrack;
36031
36032			case 'color':
36033
36034				return ColorKeyframeTrack;
36035
36036			case 'quaternion':
36037
36038				return QuaternionKeyframeTrack;
36039
36040			case 'bool':
36041			case 'boolean':
36042
36043				return BooleanKeyframeTrack;
36044
36045			case 'string':
36046
36047				return StringKeyframeTrack;
36048
36049		}
36050
36051		throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );
36052
36053	}
36054
36055	function parseKeyframeTrack( json ) {
36056
36057		if ( json.type === undefined ) {
36058
36059			throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );
36060
36061		}
36062
36063		var trackType = getTrackTypeForValueTypeName( json.type );
36064
36065		if ( json.times === undefined ) {
36066
36067			var times = [], values = [];
36068
36069			AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
36070
36071			json.times = times;
36072			json.values = values;
36073
36074		}
36075
36076		// derived classes can define a static parse method
36077		if ( trackType.parse !== undefined ) {
36078
36079			return trackType.parse( json );
36080
36081		} else {
36082
36083			// by default, we assume a constructor compatible with the base
36084			return new trackType( json.name, json.times, json.values, json.interpolation );
36085
36086		}
36087
36088	}
36089
36090	Object.assign( AnimationClip, {
36091
36092		parse: function ( json ) {
36093
36094			var tracks = [],
36095				jsonTracks = json.tracks,
36096				frameTime = 1.0 / ( json.fps || 1.0 );
36097
36098			for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {
36099
36100				tracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) );
36101
36102			}
36103
36104			return new AnimationClip( json.name, json.duration, tracks, json.blendMode );
36105
36106		},
36107
36108		toJSON: function ( clip ) {
36109
36110			var tracks = [],
36111				clipTracks = clip.tracks;
36112
36113			var json = {
36114
36115				'name': clip.name,
36116				'duration': clip.duration,
36117				'tracks': tracks,
36118				'uuid': clip.uuid,
36119				'blendMode': clip.blendMode
36120
36121			};
36122
36123			for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {
36124
36125				tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );
36126
36127			}
36128
36129			return json;
36130
36131		},
36132
36133		CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) {
36134
36135			var numMorphTargets = morphTargetSequence.length;
36136			var tracks = [];
36137
36138			for ( var i = 0; i < numMorphTargets; i ++ ) {
36139
36140				var times = [];
36141				var values = [];
36142
36143				times.push(
36144					( i + numMorphTargets - 1 ) % numMorphTargets,
36145					i,
36146					( i + 1 ) % numMorphTargets );
36147
36148				values.push( 0, 1, 0 );
36149
36150				var order = AnimationUtils.getKeyframeOrder( times );
36151				times = AnimationUtils.sortedArray( times, 1, order );
36152				values = AnimationUtils.sortedArray( values, 1, order );
36153
36154				// if there is a key at the first frame, duplicate it as the
36155				// last frame as well for perfect loop.
36156				if ( ! noLoop && times[ 0 ] === 0 ) {
36157
36158					times.push( numMorphTargets );
36159					values.push( values[ 0 ] );
36160
36161				}
36162
36163				tracks.push(
36164					new NumberKeyframeTrack(
36165						'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
36166						times, values
36167					).scale( 1.0 / fps ) );
36168
36169			}
36170
36171			return new AnimationClip( name, - 1, tracks );
36172
36173		},
36174
36175		findByName: function ( objectOrClipArray, name ) {
36176
36177			var clipArray = objectOrClipArray;
36178
36179			if ( ! Array.isArray( objectOrClipArray ) ) {
36180
36181				var o = objectOrClipArray;
36182				clipArray = o.geometry && o.geometry.animations || o.animations;
36183
36184			}
36185
36186			for ( var i = 0; i < clipArray.length; i ++ ) {
36187
36188				if ( clipArray[ i ].name === name ) {
36189
36190					return clipArray[ i ];
36191
36192				}
36193
36194			}
36195
36196			return null;
36197
36198		},
36199
36200		CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) {
36201
36202			var animationToMorphTargets = {};
36203
36204			// tested with https://regex101.com/ on trick sequences
36205			// such flamingo_flyA_003, flamingo_run1_003, crdeath0059
36206			var pattern = /^([\w-]*?)([\d]+)$/;
36207
36208			// sort morph target names into animation groups based
36209			// patterns like Walk_001, Walk_002, Run_001, Run_002
36210			for ( var i = 0, il = morphTargets.length; i < il; i ++ ) {
36211
36212				var morphTarget = morphTargets[ i ];
36213				var parts = morphTarget.name.match( pattern );
36214
36215				if ( parts && parts.length > 1 ) {
36216
36217					var name = parts[ 1 ];
36218
36219					var animationMorphTargets = animationToMorphTargets[ name ];
36220
36221					if ( ! animationMorphTargets ) {
36222
36223						animationToMorphTargets[ name ] = animationMorphTargets = [];
36224
36225					}
36226
36227					animationMorphTargets.push( morphTarget );
36228
36229				}
36230
36231			}
36232
36233			var clips = [];
36234
36235			for ( var name$1 in animationToMorphTargets ) {
36236
36237				clips.push( AnimationClip.CreateFromMorphTargetSequence( name$1, animationToMorphTargets[ name$1 ], fps, noLoop ) );
36238
36239			}
36240
36241			return clips;
36242
36243		},
36244
36245		// parse the animation.hierarchy format
36246		parseAnimation: function ( animation, bones ) {
36247
36248			if ( ! animation ) {
36249
36250				console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' );
36251				return null;
36252
36253			}
36254
36255			var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {
36256
36257				// only return track if there are actually keys.
36258				if ( animationKeys.length !== 0 ) {
36259
36260					var times = [];
36261					var values = [];
36262
36263					AnimationUtils.flattenJSON( animationKeys, times, values, propertyName );
36264
36265					// empty keys are filtered out, so check again
36266					if ( times.length !== 0 ) {
36267
36268						destTracks.push( new trackType( trackName, times, values ) );
36269
36270					}
36271
36272				}
36273
36274			};
36275
36276			var tracks = [];
36277
36278			var clipName = animation.name || 'default';
36279			var fps = animation.fps || 30;
36280			var blendMode = animation.blendMode;
36281
36282			// automatic length determination in AnimationClip.
36283			var duration = animation.length || - 1;
36284
36285			var hierarchyTracks = animation.hierarchy || [];
36286
36287			for ( var h = 0; h < hierarchyTracks.length; h ++ ) {
36288
36289				var animationKeys = hierarchyTracks[ h ].keys;
36290
36291				// skip empty tracks
36292				if ( ! animationKeys || animationKeys.length === 0 ) { continue; }
36293
36294				// process morph targets
36295				if ( animationKeys[ 0 ].morphTargets ) {
36296
36297					// figure out all morph targets used in this track
36298					var morphTargetNames = {};
36299
36300					var k = (void 0);
36301
36302					for ( k = 0; k < animationKeys.length; k ++ ) {
36303
36304						if ( animationKeys[ k ].morphTargets ) {
36305
36306							for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {
36307
36308								morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1;
36309
36310							}
36311
36312						}
36313
36314					}
36315
36316					// create a track for each morph target with all zero
36317					// morphTargetInfluences except for the keys in which
36318					// the morphTarget is named.
36319					for ( var morphTargetName in morphTargetNames ) {
36320
36321						var times = [];
36322						var values = [];
36323
36324						for ( var m$1 = 0; m$1 !== animationKeys[ k ].morphTargets.length; ++ m$1 ) {
36325
36326							var animationKey = animationKeys[ k ];
36327
36328							times.push( animationKey.time );
36329							values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );
36330
36331						}
36332
36333						tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );
36334
36335					}
36336
36337					duration = morphTargetNames.length * ( fps || 1.0 );
36338
36339				} else {
36340
36341					// ...assume skeletal animation
36342
36343					var boneName = '.bones[' + bones[ h ].name + ']';
36344
36345					addNonemptyTrack(
36346						VectorKeyframeTrack, boneName + '.position',
36347						animationKeys, 'pos', tracks );
36348
36349					addNonemptyTrack(
36350						QuaternionKeyframeTrack, boneName + '.quaternion',
36351						animationKeys, 'rot', tracks );
36352
36353					addNonemptyTrack(
36354						VectorKeyframeTrack, boneName + '.scale',
36355						animationKeys, 'scl', tracks );
36356
36357				}
36358
36359			}
36360
36361			if ( tracks.length === 0 ) {
36362
36363				return null;
36364
36365			}
36366
36367			var clip = new AnimationClip( clipName, duration, tracks, blendMode );
36368
36369			return clip;
36370
36371		}
36372
36373	} );
36374
36375	Object.assign( AnimationClip.prototype, {
36376
36377		resetDuration: function () {
36378
36379			var tracks = this.tracks;
36380			var duration = 0;
36381
36382			for ( var i = 0, n = tracks.length; i !== n; ++ i ) {
36383
36384				var track = this.tracks[ i ];
36385
36386				duration = Math.max( duration, track.times[ track.times.length - 1 ] );
36387
36388			}
36389
36390			this.duration = duration;
36391
36392			return this;
36393
36394		},
36395
36396		trim: function () {
36397
36398			for ( var i = 0; i < this.tracks.length; i ++ ) {
36399
36400				this.tracks[ i ].trim( 0, this.duration );
36401
36402			}
36403
36404			return this;
36405
36406		},
36407
36408		validate: function () {
36409
36410			var valid = true;
36411
36412			for ( var i = 0; i < this.tracks.length; i ++ ) {
36413
36414				valid = valid && this.tracks[ i ].validate();
36415
36416			}
36417
36418			return valid;
36419
36420		},
36421
36422		optimize: function () {
36423
36424			for ( var i = 0; i < this.tracks.length; i ++ ) {
36425
36426				this.tracks[ i ].optimize();
36427
36428			}
36429
36430			return this;
36431
36432		},
36433
36434		clone: function () {
36435
36436			var tracks = [];
36437
36438			for ( var i = 0; i < this.tracks.length; i ++ ) {
36439
36440				tracks.push( this.tracks[ i ].clone() );
36441
36442			}
36443
36444			return new AnimationClip( this.name, this.duration, tracks, this.blendMode );
36445
36446		}
36447
36448	} );
36449
36450	/**
36451	 * @author mrdoob / http://mrdoob.com/
36452	 */
36453
36454	var Cache = {
36455
36456		enabled: false,
36457
36458		files: {},
36459
36460		add: function ( key, file ) {
36461
36462			if ( this.enabled === false ) { return; }
36463
36464			// console.log( 'THREE.Cache', 'Adding key:', key );
36465
36466			this.files[ key ] = file;
36467
36468		},
36469
36470		get: function ( key ) {
36471
36472			if ( this.enabled === false ) { return; }
36473
36474			// console.log( 'THREE.Cache', 'Checking key:', key );
36475
36476			return this.files[ key ];
36477
36478		},
36479
36480		remove: function ( key ) {
36481
36482			delete this.files[ key ];
36483
36484		},
36485
36486		clear: function () {
36487
36488			this.files = {};
36489
36490		}
36491
36492	};
36493
36494	/**
36495	 * @author mrdoob / http://mrdoob.com/
36496	 */
36497
36498	function LoadingManager( onLoad, onProgress, onError ) {
36499
36500		var scope = this;
36501
36502		var isLoading = false;
36503		var itemsLoaded = 0;
36504		var itemsTotal = 0;
36505		var urlModifier = undefined;
36506		var handlers = [];
36507
36508		// Refer to #5689 for the reason why we don't set .onStart
36509		// in the constructor
36510
36511		this.onStart = undefined;
36512		this.onLoad = onLoad;
36513		this.onProgress = onProgress;
36514		this.onError = onError;
36515
36516		this.itemStart = function ( url ) {
36517
36518			itemsTotal ++;
36519
36520			if ( isLoading === false ) {
36521
36522				if ( scope.onStart !== undefined ) {
36523
36524					scope.onStart( url, itemsLoaded, itemsTotal );
36525
36526				}
36527
36528			}
36529
36530			isLoading = true;
36531
36532		};
36533
36534		this.itemEnd = function ( url ) {
36535
36536			itemsLoaded ++;
36537
36538			if ( scope.onProgress !== undefined ) {
36539
36540				scope.onProgress( url, itemsLoaded, itemsTotal );
36541
36542			}
36543
36544			if ( itemsLoaded === itemsTotal ) {
36545
36546				isLoading = false;
36547
36548				if ( scope.onLoad !== undefined ) {
36549
36550					scope.onLoad();
36551
36552				}
36553
36554			}
36555
36556		};
36557
36558		this.itemError = function ( url ) {
36559
36560			if ( scope.onError !== undefined ) {
36561
36562				scope.onError( url );
36563
36564			}
36565
36566		};
36567
36568		this.resolveURL = function ( url ) {
36569
36570			if ( urlModifier ) {
36571
36572				return urlModifier( url );
36573
36574			}
36575
36576			return url;
36577
36578		};
36579
36580		this.setURLModifier = function ( transform ) {
36581
36582			urlModifier = transform;
36583
36584			return this;
36585
36586		};
36587
36588		this.addHandler = function ( regex, loader ) {
36589
36590			handlers.push( regex, loader );
36591
36592			return this;
36593
36594		};
36595
36596		this.removeHandler = function ( regex ) {
36597
36598			var index = handlers.indexOf( regex );
36599
36600			if ( index !== - 1 ) {
36601
36602				handlers.splice( index, 2 );
36603
36604			}
36605
36606			return this;
36607
36608		};
36609
36610		this.getHandler = function ( file ) {
36611
36612			for ( var i = 0, l = handlers.length; i < l; i += 2 ) {
36613
36614				var regex = handlers[ i ];
36615				var loader = handlers[ i + 1 ];
36616
36617				if ( regex.global ) { regex.lastIndex = 0; } // see #17920
36618
36619				if ( regex.test( file ) ) {
36620
36621					return loader;
36622
36623				}
36624
36625			}
36626
36627			return null;
36628
36629		};
36630
36631	}
36632
36633	var DefaultLoadingManager = new LoadingManager();
36634
36635	/**
36636	 * @author alteredq / http://alteredqualia.com/
36637	 */
36638
36639	function Loader( manager ) {
36640
36641		this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
36642
36643		this.crossOrigin = 'anonymous';
36644		this.path = '';
36645		this.resourcePath = '';
36646		this.requestHeader = {};
36647
36648	}
36649
36650	Object.assign( Loader.prototype, {
36651
36652		load: function ( /* url, onLoad, onProgress, onError */ ) {},
36653
36654		loadAsync: function ( url, onProgress ) {
36655
36656			var scope = this;
36657
36658			return new Promise( function ( resolve, reject ) {
36659
36660				scope.load( url, resolve, onProgress, reject );
36661
36662			} );
36663
36664		},
36665
36666		parse: function ( /* data */ ) {},
36667
36668		setCrossOrigin: function ( crossOrigin ) {
36669
36670			this.crossOrigin = crossOrigin;
36671			return this;
36672
36673		},
36674
36675		setPath: function ( path ) {
36676
36677			this.path = path;
36678			return this;
36679
36680		},
36681
36682		setResourcePath: function ( resourcePath ) {
36683
36684			this.resourcePath = resourcePath;
36685			return this;
36686
36687		},
36688
36689		setRequestHeader: function ( requestHeader ) {
36690
36691			this.requestHeader = requestHeader;
36692			return this;
36693
36694		}
36695
36696	} );
36697
36698	/**
36699	 * @author mrdoob / http://mrdoob.com/
36700	 */
36701
36702	var loading = {};
36703
36704	function FileLoader( manager ) {
36705
36706		Loader.call( this, manager );
36707
36708	}
36709
36710	FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36711
36712		constructor: FileLoader,
36713
36714		load: function ( url, onLoad, onProgress, onError ) {
36715
36716			if ( url === undefined ) { url = ''; }
36717
36718			if ( this.path !== undefined ) { url = this.path + url; }
36719
36720			url = this.manager.resolveURL( url );
36721
36722			var scope = this;
36723
36724			var cached = Cache.get( url );
36725
36726			if ( cached !== undefined ) {
36727
36728				scope.manager.itemStart( url );
36729
36730				setTimeout( function () {
36731
36732					if ( onLoad ) { onLoad( cached ); }
36733
36734					scope.manager.itemEnd( url );
36735
36736				}, 0 );
36737
36738				return cached;
36739
36740			}
36741
36742			// Check if request is duplicate
36743
36744			if ( loading[ url ] !== undefined ) {
36745
36746				loading[ url ].push( {
36747
36748					onLoad: onLoad,
36749					onProgress: onProgress,
36750					onError: onError
36751
36752				} );
36753
36754				return;
36755
36756			}
36757
36758			// Check for data: URI
36759			var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
36760			var dataUriRegexResult = url.match( dataUriRegex );
36761			var request;
36762
36763			// Safari can not handle Data URIs through XMLHttpRequest so process manually
36764			if ( dataUriRegexResult ) {
36765
36766				var mimeType = dataUriRegexResult[ 1 ];
36767				var isBase64 = !! dataUriRegexResult[ 2 ];
36768
36769				var data = dataUriRegexResult[ 3 ];
36770				data = decodeURIComponent( data );
36771
36772				if ( isBase64 ) { data = atob( data ); }
36773
36774				try {
36775
36776					var response;
36777					var responseType = ( this.responseType || '' ).toLowerCase();
36778
36779					switch ( responseType ) {
36780
36781						case 'arraybuffer':
36782						case 'blob':
36783
36784							var view = new Uint8Array( data.length );
36785
36786							for ( var i = 0; i < data.length; i ++ ) {
36787
36788								view[ i ] = data.charCodeAt( i );
36789
36790							}
36791
36792							if ( responseType === 'blob' ) {
36793
36794								response = new Blob( [ view.buffer ], { type: mimeType } );
36795
36796							} else {
36797
36798								response = view.buffer;
36799
36800							}
36801
36802							break;
36803
36804						case 'document':
36805
36806							var parser = new DOMParser();
36807							response = parser.parseFromString( data, mimeType );
36808
36809							break;
36810
36811						case 'json':
36812
36813							response = JSON.parse( data );
36814
36815							break;
36816
36817						default: // 'text' or other
36818
36819							response = data;
36820
36821							break;
36822
36823					}
36824
36825					// Wait for next browser tick like standard XMLHttpRequest event dispatching does
36826					setTimeout( function () {
36827
36828						if ( onLoad ) { onLoad( response ); }
36829
36830						scope.manager.itemEnd( url );
36831
36832					}, 0 );
36833
36834				} catch ( error ) {
36835
36836					// Wait for next browser tick like standard XMLHttpRequest event dispatching does
36837					setTimeout( function () {
36838
36839						if ( onError ) { onError( error ); }
36840
36841						scope.manager.itemError( url );
36842						scope.manager.itemEnd( url );
36843
36844					}, 0 );
36845
36846				}
36847
36848			} else {
36849
36850				// Initialise array for duplicate requests
36851
36852				loading[ url ] = [];
36853
36854				loading[ url ].push( {
36855
36856					onLoad: onLoad,
36857					onProgress: onProgress,
36858					onError: onError
36859
36860				} );
36861
36862				request = new XMLHttpRequest();
36863
36864				request.open( 'GET', url, true );
36865
36866				request.addEventListener( 'load', function ( event ) {
36867
36868					var response = this.response;
36869
36870					var callbacks = loading[ url ];
36871
36872					delete loading[ url ];
36873
36874					if ( this.status === 200 || this.status === 0 ) {
36875
36876						// Some browsers return HTTP Status 0 when using non-http protocol
36877						// e.g. 'file://' or 'data://'. Handle as success.
36878
36879						if ( this.status === 0 ) { console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); }
36880
36881						// Add to cache only on HTTP success, so that we do not cache
36882						// error response bodies as proper responses to requests.
36883						Cache.add( url, response );
36884
36885						for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36886
36887							var callback = callbacks[ i ];
36888							if ( callback.onLoad ) { callback.onLoad( response ); }
36889
36890						}
36891
36892						scope.manager.itemEnd( url );
36893
36894					} else {
36895
36896						for ( var i$1 = 0, il$1 = callbacks.length; i$1 < il$1; i$1 ++ ) {
36897
36898							var callback$1 = callbacks[ i$1 ];
36899							if ( callback$1.onError ) { callback$1.onError( event ); }
36900
36901						}
36902
36903						scope.manager.itemError( url );
36904						scope.manager.itemEnd( url );
36905
36906					}
36907
36908				}, false );
36909
36910				request.addEventListener( 'progress', function ( event ) {
36911
36912					var callbacks = loading[ url ];
36913
36914					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36915
36916						var callback = callbacks[ i ];
36917						if ( callback.onProgress ) { callback.onProgress( event ); }
36918
36919					}
36920
36921				}, false );
36922
36923				request.addEventListener( 'error', function ( event ) {
36924
36925					var callbacks = loading[ url ];
36926
36927					delete loading[ url ];
36928
36929					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36930
36931						var callback = callbacks[ i ];
36932						if ( callback.onError ) { callback.onError( event ); }
36933
36934					}
36935
36936					scope.manager.itemError( url );
36937					scope.manager.itemEnd( url );
36938
36939				}, false );
36940
36941				request.addEventListener( 'abort', function ( event ) {
36942
36943					var callbacks = loading[ url ];
36944
36945					delete loading[ url ];
36946
36947					for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36948
36949						var callback = callbacks[ i ];
36950						if ( callback.onError ) { callback.onError( event ); }
36951
36952					}
36953
36954					scope.manager.itemError( url );
36955					scope.manager.itemEnd( url );
36956
36957				}, false );
36958
36959				if ( this.responseType !== undefined ) { request.responseType = this.responseType; }
36960				if ( this.withCredentials !== undefined ) { request.withCredentials = this.withCredentials; }
36961
36962				if ( request.overrideMimeType ) { request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); }
36963
36964				for ( var header in this.requestHeader ) {
36965
36966					request.setRequestHeader( header, this.requestHeader[ header ] );
36967
36968				}
36969
36970				request.send( null );
36971
36972			}
36973
36974			scope.manager.itemStart( url );
36975
36976			return request;
36977
36978		},
36979
36980		setResponseType: function ( value ) {
36981
36982			this.responseType = value;
36983			return this;
36984
36985		},
36986
36987		setWithCredentials: function ( value ) {
36988
36989			this.withCredentials = value;
36990			return this;
36991
36992		},
36993
36994		setMimeType: function ( value ) {
36995
36996			this.mimeType = value;
36997			return this;
36998
36999		}
37000
37001	} );
37002
37003	/**
37004	 * @author bhouston / http://clara.io/
37005	 */
37006
37007	function AnimationLoader( manager ) {
37008
37009		Loader.call( this, manager );
37010
37011	}
37012
37013	AnimationLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
37014
37015		constructor: AnimationLoader,
37016
37017		load: function ( url, onLoad, onProgress, onError ) {
37018
37019			var scope = this;
37020
37021			var loader = new FileLoader( scope.manager );
37022			loader.setPath( scope.path );
37023			loader.load( url, function ( text ) {
37024
37025				try {
37026
37027					onLoad( scope.parse( JSON.parse( text ) ) );
37028
37029				} catch ( e ) {
37030
37031					if ( onError ) {
37032
37033						onError( e );
37034
37035					} else {
37036
37037						console.error( e );
37038
37039					}
37040
37041					scope.manager.itemError( url );
37042
37043				}
37044
37045			}, onProgress, onError );
37046
37047		},
37048
37049		parse: function ( json ) {
37050
37051			var animations = [];
37052
37053			for ( var i = 0; i < json.length; i ++ ) {
37054
37055				var clip = AnimationClip.parse( json[ i ] );
37056
37057				animations.push( clip );
37058
37059			}
37060
37061			return animations;
37062
37063		}
37064
37065	} );
37066
37067	/**
37068	 * @author mrdoob / http://mrdoob.com/
37069	 *
37070	 * Abstract Base class to block based textures loader (dds, pvr, ...)
37071	 *
37072	 * Sub classes have to implement the parse() method which will be used in load().
37073	 */
37074
37075	function CompressedTextureLoader( manager ) {
37076
37077		Loader.call( this, manager );
37078
37079	}
37080
37081	CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
37082
37083		constructor: CompressedTextureLoader,
37084
37085		load: function ( url, onLoad, onProgress, onError ) {
37086
37087			var scope = this;
37088
37089			var images = [];
37090
37091			var texture = new CompressedTexture();
37092			texture.image = images;
37093
37094			var loader = new FileLoader( this.manager );
37095			loader.setPath( this.path );
37096			loader.setResponseType( 'arraybuffer' );
37097
37098			var loaded = 0;
37099
37100			function loadTexture( i ) {
37101
37102				loader.load( url[ i ], function ( buffer ) {
37103
37104					var texDatas = scope.parse( buffer, true );
37105
37106					images[ i ] = {
37107						width: texDatas.width,
37108						height: texDatas.height,
37109						format: texDatas.format,
37110						mipmaps: texDatas.mipmaps
37111					};
37112
37113					loaded += 1;
37114
37115					if ( loaded === 6 ) {
37116
37117						if ( texDatas.mipmapCount === 1 )
37118							{ texture.minFilter = LinearFilter; }
37119
37120						texture.format = texDatas.format;
37121						texture.needsUpdate = true;
37122
37123						if ( onLoad ) { onLoad( texture ); }
37124
37125					}
37126
37127				}, onProgress, onError );
37128
37129			}
37130
37131			if ( Array.isArray( url ) ) {
37132
37133				for ( var i = 0, il = url.length; i < il; ++ i ) {
37134
37135					loadTexture( i );
37136
37137				}
37138
37139			} else {
37140
37141				// compressed cubemap texture stored in a single DDS file
37142
37143				loader.load( url, function ( buffer ) {
37144
37145					var texDatas = scope.parse( buffer, true );
37146
37147					if ( texDatas.isCubemap ) {
37148
37149						var faces = texDatas.mipmaps.length / texDatas.mipmapCount;
37150
37151						for ( var f = 0; f < faces; f ++ ) {
37152
37153							images[ f ] = { mipmaps: [] };
37154
37155							for ( var i = 0; i < texDatas.mipmapCount; i ++ ) {
37156
37157								images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );
37158								images[ f ].format = texDatas.format;
37159								images[ f ].width = texDatas.width;
37160								images[ f ].height = texDatas.height;
37161
37162							}
37163
37164						}
37165
37166					} else {
37167
37168						texture.image.width = texDatas.width;
37169						texture.image.height = texDatas.height;
37170						texture.mipmaps = texDatas.mipmaps;
37171
37172					}
37173
37174					if ( texDatas.mipmapCount === 1 ) {
37175
37176						texture.minFilter = LinearFilter;
37177
37178					}
37179
37180					texture.format = texDatas.format;
37181					texture.needsUpdate = true;
37182
37183					if ( onLoad ) { onLoad( texture ); }
37184
37185				}, onProgress, onError );
37186
37187			}
37188
37189			return texture;
37190
37191		}
37192
37193	} );
37194
37195	/**
37196	 * @author Nikos M. / https://github.com/foo123/
37197	 *
37198	 * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
37199	 *
37200	 * Sub classes have to implement the parse() method which will be used in load().
37201	 */
37202
37203	function DataTextureLoader( manager ) {
37204
37205		Loader.call( this, manager );
37206
37207	}
37208
37209	DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
37210
37211		constructor: DataTextureLoader,
37212
37213		load: function ( url, onLoad, onProgress, onError ) {
37214
37215			var scope = this;
37216
37217			var texture = new DataTexture();
37218
37219			var loader = new FileLoader( this.manager );
37220			loader.setResponseType( 'arraybuffer' );
37221			loader.setPath( this.path );
37222			loader.load( url, function ( buffer ) {
37223
37224				var texData = scope.parse( buffer );
37225
37226				if ( ! texData ) { return; }
37227
37228				if ( texData.image !== undefined ) {
37229
37230					texture.image = texData.image;
37231
37232				} else if ( texData.data !== undefined ) {
37233
37234					texture.image.width = texData.width;
37235					texture.image.height = texData.height;
37236					texture.image.data = texData.data;
37237
37238				}
37239
37240				texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
37241				texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
37242
37243				texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
37244				texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
37245
37246				texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
37247
37248				if ( texData.format !== undefined ) {
37249
37250					texture.format = texData.format;
37251
37252				}
37253
37254				if ( texData.type !== undefined ) {
37255
37256					texture.type = texData.type;
37257
37258				}
37259
37260				if ( texData.mipmaps !== undefined ) {
37261
37262					texture.mipmaps = texData.mipmaps;
37263					texture.minFilter = LinearMipmapLinearFilter; // presumably...
37264
37265				}
37266
37267				if ( texData.mipmapCount === 1 ) {
37268
37269					texture.minFilter = LinearFilter;
37270
37271				}
37272
37273				texture.needsUpdate = true;
37274
37275				if ( onLoad ) { onLoad( texture, texData ); }
37276
37277			}, onProgress, onError );
37278
37279
37280			return texture;
37281
37282		}
37283
37284	} );
37285
37286	/**
37287	 * @author mrdoob / http://mrdoob.com/
37288	 */
37289
37290	function ImageLoader( manager ) {
37291
37292		Loader.call( this, manager );
37293
37294	}
37295
37296	ImageLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
37297
37298		constructor: ImageLoader,
37299
37300		load: function ( url, onLoad, onProgress, onError ) {
37301
37302			if ( this.path !== undefined ) { url = this.path + url; }
37303
37304			url = this.manager.resolveURL( url );
37305
37306			var scope = this;
37307
37308			var cached = Cache.get( url );
37309
37310			if ( cached !== undefined ) {
37311
37312				scope.manager.itemStart( url );
37313
37314				setTimeout( function () {
37315
37316					if ( onLoad ) { onLoad( cached ); }
37317
37318					scope.manager.itemEnd( url );
37319
37320				}, 0 );
37321
37322				return cached;
37323
37324			}
37325
37326			var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
37327
37328			function onImageLoad() {
37329
37330				image.removeEventListener( 'load', onImageLoad, false );
37331				image.removeEventListener( 'error', onImageError, false );
37332
37333				Cache.add( url, this );
37334
37335				if ( onLoad ) { onLoad( this ); }
37336
37337				scope.manager.itemEnd( url );
37338
37339			}
37340
37341			function onImageError( event ) {
37342
37343				image.removeEventListener( 'load', onImageLoad, false );
37344				image.removeEventListener( 'error', onImageError, false );
37345
37346				if ( onError ) { onError( event ); }
37347
37348				scope.manager.itemError( url );
37349				scope.manager.itemEnd( url );
37350
37351			}
37352
37353			image.addEventListener( 'load', onImageLoad, false );
37354			image.addEventListener( 'error', onImageError, false );
37355
37356			if ( url.substr( 0, 5 ) !== 'data:' ) {
37357
37358				if ( this.crossOrigin !== undefined ) { image.crossOrigin = this.crossOrigin; }
37359
37360			}
37361
37362			scope.manager.itemStart( url );
37363
37364			image.src = url;
37365
37366			return image;
37367
37368		}
37369
37370	} );
37371
37372	/**
37373	 * @author mrdoob / http://mrdoob.com/
37374	 */
37375
37376
37377	function CubeTextureLoader( manager ) {
37378
37379		Loader.call( this, manager );
37380
37381	}
37382
37383	CubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
37384
37385		constructor: CubeTextureLoader,
37386
37387		load: function ( urls, onLoad, onProgress, onError ) {
37388
37389			var texture = new CubeTexture();
37390
37391			var loader = new ImageLoader( this.manager );
37392			loader.setCrossOrigin( this.crossOrigin );
37393			loader.setPath( this.path );
37394
37395			var loaded = 0;
37396
37397			function loadTexture( i ) {
37398
37399				loader.load( urls[ i ], function ( image ) {
37400
37401					texture.images[ i ] = image;
37402
37403					loaded ++;
37404
37405					if ( loaded === 6 ) {
37406
37407						texture.needsUpdate = true;
37408
37409						if ( onLoad ) { onLoad( texture ); }
37410
37411					}
37412
37413				}, undefined, onError );
37414
37415			}
37416
37417			for ( var i = 0; i < urls.length; ++ i ) {
37418
37419				loadTexture( i );
37420
37421			}
37422
37423			return texture;
37424
37425		}
37426
37427	} );
37428
37429	/**
37430	 * @author mrdoob / http://mrdoob.com/
37431	 */
37432
37433	function TextureLoader( manager ) {
37434
37435		Loader.call( this, manager );
37436
37437	}
37438
37439	TextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
37440
37441		constructor: TextureLoader,
37442
37443		load: function ( url, onLoad, onProgress, onError ) {
37444
37445			var texture = new Texture();
37446
37447			var loader = new ImageLoader( this.manager );
37448			loader.setCrossOrigin( this.crossOrigin );
37449			loader.setPath( this.path );
37450
37451			loader.load( url, function ( image ) {
37452
37453				texture.image = image;
37454
37455				// JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.
37456				var isJPEG = url.search( /\.jpe?g($|\?)/i ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
37457
37458				texture.format = isJPEG ? RGBFormat : RGBAFormat;
37459				texture.needsUpdate = true;
37460
37461				if ( onLoad !== undefined ) {
37462
37463					onLoad( texture );
37464
37465				}
37466
37467			}, onProgress, onError );
37468
37469			return texture;
37470
37471		}
37472
37473	} );
37474
37475	/**
37476	 * @author zz85 / http://www.lab4games.net/zz85/blog
37477	 * Extensible curve object
37478	 *
37479	 * Some common of curve methods:
37480	 * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )
37481	 * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )
37482	 * .getPoints(), .getSpacedPoints()
37483	 * .getLength()
37484	 * .updateArcLengths()
37485	 *
37486	 * This following curves inherit from THREE.Curve:
37487	 *
37488	 * -- 2D curves --
37489	 * THREE.ArcCurve
37490	 * THREE.CubicBezierCurve
37491	 * THREE.EllipseCurve
37492	 * THREE.LineCurve
37493	 * THREE.QuadraticBezierCurve
37494	 * THREE.SplineCurve
37495	 *
37496	 * -- 3D curves --
37497	 * THREE.CatmullRomCurve3
37498	 * THREE.CubicBezierCurve3
37499	 * THREE.LineCurve3
37500	 * THREE.QuadraticBezierCurve3
37501	 *
37502	 * A series of curves can be represented as a THREE.CurvePath.
37503	 *
37504	 **/
37505
37506	/**************************************************************
37507	 *	Abstract Curve base class
37508	 **************************************************************/
37509
37510	function Curve() {
37511
37512		this.type = 'Curve';
37513
37514		this.arcLengthDivisions = 200;
37515
37516	}
37517
37518	Object.assign( Curve.prototype, {
37519
37520		// Virtual base class method to overwrite and implement in subclasses
37521		//	- t [0 .. 1]
37522
37523		getPoint: function ( /* t, optionalTarget */ ) {
37524
37525			console.warn( 'THREE.Curve: .getPoint() not implemented.' );
37526			return null;
37527
37528		},
37529
37530		// Get point at relative position in curve according to arc length
37531		// - u [0 .. 1]
37532
37533		getPointAt: function ( u, optionalTarget ) {
37534
37535			var t = this.getUtoTmapping( u );
37536			return this.getPoint( t, optionalTarget );
37537
37538		},
37539
37540		// Get sequence of points using getPoint( t )
37541
37542		getPoints: function ( divisions ) {
37543
37544			if ( divisions === undefined ) { divisions = 5; }
37545
37546			var points = [];
37547
37548			for ( var d = 0; d <= divisions; d ++ ) {
37549
37550				points.push( this.getPoint( d / divisions ) );
37551
37552			}
37553
37554			return points;
37555
37556		},
37557
37558		// Get sequence of points using getPointAt( u )
37559
37560		getSpacedPoints: function ( divisions ) {
37561
37562			if ( divisions === undefined ) { divisions = 5; }
37563
37564			var points = [];
37565
37566			for ( var d = 0; d <= divisions; d ++ ) {
37567
37568				points.push( this.getPointAt( d / divisions ) );
37569
37570			}
37571
37572			return points;
37573
37574		},
37575
37576		// Get total curve arc length
37577
37578		getLength: function () {
37579
37580			var lengths = this.getLengths();
37581			return lengths[ lengths.length - 1 ];
37582
37583		},
37584
37585		// Get list of cumulative segment lengths
37586
37587		getLengths: function ( divisions ) {
37588
37589			if ( divisions === undefined ) { divisions = this.arcLengthDivisions; }
37590
37591			if ( this.cacheArcLengths &&
37592				( this.cacheArcLengths.length === divisions + 1 ) &&
37593				! this.needsUpdate ) {
37594
37595				return this.cacheArcLengths;
37596
37597			}
37598
37599			this.needsUpdate = false;
37600
37601			var cache = [];
37602			var current, last = this.getPoint( 0 );
37603			var sum = 0;
37604
37605			cache.push( 0 );
37606
37607			for ( var p = 1; p <= divisions; p ++ ) {
37608
37609				current = this.getPoint( p / divisions );
37610				sum += current.distanceTo( last );
37611				cache.push( sum );
37612				last = current;
37613
37614			}
37615
37616			this.cacheArcLengths = cache;
37617
37618			return cache; // { sums: cache, sum: sum }; Sum is in the last element.
37619
37620		},
37621
37622		updateArcLengths: function () {
37623
37624			this.needsUpdate = true;
37625			this.getLengths();
37626
37627		},
37628
37629		// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
37630
37631		getUtoTmapping: function ( u, distance ) {
37632
37633			var arcLengths = this.getLengths();
37634
37635			var i = 0, il = arcLengths.length;
37636
37637			var targetArcLength; // The targeted u distance value to get
37638
37639			if ( distance ) {
37640
37641				targetArcLength = distance;
37642
37643			} else {
37644
37645				targetArcLength = u * arcLengths[ il - 1 ];
37646
37647			}
37648
37649			// binary search for the index with largest value smaller than target u distance
37650
37651			var low = 0, high = il - 1, comparison;
37652
37653			while ( low <= high ) {
37654
37655				i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
37656
37657				comparison = arcLengths[ i ] - targetArcLength;
37658
37659				if ( comparison < 0 ) {
37660
37661					low = i + 1;
37662
37663				} else if ( comparison > 0 ) {
37664
37665					high = i - 1;
37666
37667				} else {
37668
37669					high = i;
37670					break;
37671
37672					// DONE
37673
37674				}
37675
37676			}
37677
37678			i = high;
37679
37680			if ( arcLengths[ i ] === targetArcLength ) {
37681
37682				return i / ( il - 1 );
37683
37684			}
37685
37686			// we could get finer grain at lengths, or use simple interpolation between two points
37687
37688			var lengthBefore = arcLengths[ i ];
37689			var lengthAfter = arcLengths[ i + 1 ];
37690
37691			var segmentLength = lengthAfter - lengthBefore;
37692
37693			// determine where we are between the 'before' and 'after' points
37694
37695			var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
37696
37697			// add that fractional amount to t
37698
37699			var t = ( i + segmentFraction ) / ( il - 1 );
37700
37701			return t;
37702
37703		},
37704
37705		// Returns a unit vector tangent at t
37706		// In case any sub curve does not implement its tangent derivation,
37707		// 2 points a small delta apart will be used to find its gradient
37708		// which seems to give a reasonable approximation
37709
37710		getTangent: function ( t, optionalTarget ) {
37711
37712			var delta = 0.0001;
37713			var t1 = t - delta;
37714			var t2 = t + delta;
37715
37716			// Capping in case of danger
37717
37718			if ( t1 < 0 ) { t1 = 0; }
37719			if ( t2 > 1 ) { t2 = 1; }
37720
37721			var pt1 = this.getPoint( t1 );
37722			var pt2 = this.getPoint( t2 );
37723
37724			var tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() );
37725
37726			tangent.copy( pt2 ).sub( pt1 ).normalize();
37727
37728			return tangent;
37729
37730		},
37731
37732		getTangentAt: function ( u, optionalTarget ) {
37733
37734			var t = this.getUtoTmapping( u );
37735			return this.getTangent( t, optionalTarget );
37736
37737		},
37738
37739		computeFrenetFrames: function ( segments, closed ) {
37740
37741			// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
37742
37743			var normal = new Vector3();
37744
37745			var tangents = [];
37746			var normals = [];
37747			var binormals = [];
37748
37749			var vec = new Vector3();
37750			var mat = new Matrix4();
37751
37752			// compute the tangent vectors for each segment on the curve
37753
37754			for ( var i = 0; i <= segments; i ++ ) {
37755
37756				var u = i / segments;
37757
37758				tangents[ i ] = this.getTangentAt( u, new Vector3() );
37759				tangents[ i ].normalize();
37760
37761			}
37762
37763			// select an initial normal vector perpendicular to the first tangent vector,
37764			// and in the direction of the minimum tangent xyz component
37765
37766			normals[ 0 ] = new Vector3();
37767			binormals[ 0 ] = new Vector3();
37768			var min = Number.MAX_VALUE;
37769			var tx = Math.abs( tangents[ 0 ].x );
37770			var ty = Math.abs( tangents[ 0 ].y );
37771			var tz = Math.abs( tangents[ 0 ].z );
37772
37773			if ( tx <= min ) {
37774
37775				min = tx;
37776				normal.set( 1, 0, 0 );
37777
37778			}
37779
37780			if ( ty <= min ) {
37781
37782				min = ty;
37783				normal.set( 0, 1, 0 );
37784
37785			}
37786
37787			if ( tz <= min ) {
37788
37789				normal.set( 0, 0, 1 );
37790
37791			}
37792
37793			vec.crossVectors( tangents[ 0 ], normal ).normalize();
37794
37795			normals[ 0 ].crossVectors( tangents[ 0 ], vec );
37796			binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );
37797
37798
37799			// compute the slowly-varying normal and binormal vectors for each segment on the curve
37800
37801			for ( var i$1 = 1; i$1 <= segments; i$1 ++ ) {
37802
37803				normals[ i$1 ] = normals[ i$1 - 1 ].clone();
37804
37805				binormals[ i$1 ] = binormals[ i$1 - 1 ].clone();
37806
37807				vec.crossVectors( tangents[ i$1 - 1 ], tangents[ i$1 ] );
37808
37809				if ( vec.length() > Number.EPSILON ) {
37810
37811					vec.normalize();
37812
37813					var theta = Math.acos( MathUtils.clamp( tangents[ i$1 - 1 ].dot( tangents[ i$1 ] ), - 1, 1 ) ); // clamp for floating pt errors
37814
37815					normals[ i$1 ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
37816
37817				}
37818
37819				binormals[ i$1 ].crossVectors( tangents[ i$1 ], normals[ i$1 ] );
37820
37821			}
37822
37823			// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
37824
37825			if ( closed === true ) {
37826
37827				var theta$1 = Math.acos( MathUtils.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );
37828				theta$1 /= segments;
37829
37830				if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {
37831
37832					theta$1 = - theta$1;
37833
37834				}
37835
37836				for ( var i$2 = 1; i$2 <= segments; i$2 ++ ) {
37837
37838					// twist a little...
37839					normals[ i$2 ].applyMatrix4( mat.makeRotationAxis( tangents[ i$2 ], theta$1 * i$2 ) );
37840					binormals[ i$2 ].crossVectors( tangents[ i$2 ], normals[ i$2 ] );
37841
37842				}
37843
37844			}
37845
37846			return {
37847				tangents: tangents,
37848				normals: normals,
37849				binormals: binormals
37850			};
37851
37852		},
37853
37854		clone: function () {
37855
37856			return new this.constructor().copy( this );
37857
37858		},
37859
37860		copy: function ( source ) {
37861
37862			this.arcLengthDivisions = source.arcLengthDivisions;
37863
37864			return this;
37865
37866		},
37867
37868		toJSON: function () {
37869
37870			var data = {
37871				metadata: {
37872					version: 4.5,
37873					type: 'Curve',
37874					generator: 'Curve.toJSON'
37875				}
37876			};
37877
37878			data.arcLengthDivisions = this.arcLengthDivisions;
37879			data.type = this.type;
37880
37881			return data;
37882
37883		},
37884
37885		fromJSON: function ( json ) {
37886
37887			this.arcLengthDivisions = json.arcLengthDivisions;
37888
37889			return this;
37890
37891		}
37892
37893	} );
37894
37895	function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
37896
37897		Curve.call( this );
37898
37899		this.type = 'EllipseCurve';
37900
37901		this.aX = aX || 0;
37902		this.aY = aY || 0;
37903
37904		this.xRadius = xRadius || 1;
37905		this.yRadius = yRadius || 1;
37906
37907		this.aStartAngle = aStartAngle || 0;
37908		this.aEndAngle = aEndAngle || 2 * Math.PI;
37909
37910		this.aClockwise = aClockwise || false;
37911
37912		this.aRotation = aRotation || 0;
37913
37914	}
37915
37916	EllipseCurve.prototype = Object.create( Curve.prototype );
37917	EllipseCurve.prototype.constructor = EllipseCurve;
37918
37919	EllipseCurve.prototype.isEllipseCurve = true;
37920
37921	EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) {
37922
37923		var point = optionalTarget || new Vector2();
37924
37925		var twoPi = Math.PI * 2;
37926		var deltaAngle = this.aEndAngle - this.aStartAngle;
37927		var samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
37928
37929		// ensures that deltaAngle is 0 .. 2 PI
37930		while ( deltaAngle < 0 ) { deltaAngle += twoPi; }
37931		while ( deltaAngle > twoPi ) { deltaAngle -= twoPi; }
37932
37933		if ( deltaAngle < Number.EPSILON ) {
37934
37935			if ( samePoints ) {
37936
37937				deltaAngle = 0;
37938
37939			} else {
37940
37941				deltaAngle = twoPi;
37942
37943			}
37944
37945		}
37946
37947		if ( this.aClockwise === true && ! samePoints ) {
37948
37949			if ( deltaAngle === twoPi ) {
37950
37951				deltaAngle = - twoPi;
37952
37953			} else {
37954
37955				deltaAngle = deltaAngle - twoPi;
37956
37957			}
37958
37959		}
37960
37961		var angle = this.aStartAngle + t * deltaAngle;
37962		var x = this.aX + this.xRadius * Math.cos( angle );
37963		var y = this.aY + this.yRadius * Math.sin( angle );
37964
37965		if ( this.aRotation !== 0 ) {
37966
37967			var cos = Math.cos( this.aRotation );
37968			var sin = Math.sin( this.aRotation );
37969
37970			var tx = x - this.aX;
37971			var ty = y - this.aY;
37972
37973			// Rotate the point about the center of the ellipse.
37974			x = tx * cos - ty * sin + this.aX;
37975			y = tx * sin + ty * cos + this.aY;
37976
37977		}
37978
37979		return point.set( x, y );
37980
37981	};
37982
37983	EllipseCurve.prototype.copy = function ( source ) {
37984
37985		Curve.prototype.copy.call( this, source );
37986
37987		this.aX = source.aX;
37988		this.aY = source.aY;
37989
37990		this.xRadius = source.xRadius;
37991		this.yRadius = source.yRadius;
37992
37993		this.aStartAngle = source.aStartAngle;
37994		this.aEndAngle = source.aEndAngle;
37995
37996		this.aClockwise = source.aClockwise;
37997
37998		this.aRotation = source.aRotation;
37999
38000		return this;
38001
38002	};
38003
38004
38005	EllipseCurve.prototype.toJSON = function () {
38006
38007		var data = Curve.prototype.toJSON.call( this );
38008
38009		data.aX = this.aX;
38010		data.aY = this.aY;
38011
38012		data.xRadius = this.xRadius;
38013		data.yRadius = this.yRadius;
38014
38015		data.aStartAngle = this.aStartAngle;
38016		data.aEndAngle = this.aEndAngle;
38017
38018		data.aClockwise = this.aClockwise;
38019
38020		data.aRotation = this.aRotation;
38021
38022		return data;
38023
38024	};
38025
38026	EllipseCurve.prototype.fromJSON = function ( json ) {
38027
38028		Curve.prototype.fromJSON.call( this, json );
38029
38030		this.aX = json.aX;
38031		this.aY = json.aY;
38032
38033		this.xRadius = json.xRadius;
38034		this.yRadius = json.yRadius;
38035
38036		this.aStartAngle = json.aStartAngle;
38037		this.aEndAngle = json.aEndAngle;
38038
38039		this.aClockwise = json.aClockwise;
38040
38041		this.aRotation = json.aRotation;
38042
38043		return this;
38044
38045	};
38046
38047	function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
38048
38049		EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
38050
38051		this.type = 'ArcCurve';
38052
38053	}
38054
38055	ArcCurve.prototype = Object.create( EllipseCurve.prototype );
38056	ArcCurve.prototype.constructor = ArcCurve;
38057
38058	ArcCurve.prototype.isArcCurve = true;
38059
38060	/**
38061	 * @author zz85 https://github.com/zz85
38062	 *
38063	 * Centripetal CatmullRom Curve - which is useful for avoiding
38064	 * cusps and self-intersections in non-uniform catmull rom curves.
38065	 * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
38066	 *
38067	 * curve.type accepts centripetal(default), chordal and catmullrom
38068	 * curve.tension is used for catmullrom which defaults to 0.5
38069	 */
38070
38071
38072	/*
38073	Based on an optimized c++ solution in
38074	 - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
38075	 - http://ideone.com/NoEbVM
38076
38077	This CubicPoly class could be used for reusing some variables and calculations,
38078	but for three.js curve use, it could be possible inlined and flatten into a single function call
38079	which can be placed in CurveUtils.
38080	*/
38081
38082	function CubicPoly() {
38083
38084		var c0 = 0, c1 = 0, c2 = 0, c3 = 0;
38085
38086		/*
38087		 * Compute coefficients for a cubic polynomial
38088		 *   p(s) = c0 + c1*s + c2*s^2 + c3*s^3
38089		 * such that
38090		 *   p(0) = x0, p(1) = x1
38091		 *  and
38092		 *   p'(0) = t0, p'(1) = t1.
38093		 */
38094		function init( x0, x1, t0, t1 ) {
38095
38096			c0 = x0;
38097			c1 = t0;
38098			c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
38099			c3 = 2 * x0 - 2 * x1 + t0 + t1;
38100
38101		}
38102
38103		return {
38104
38105			initCatmullRom: function ( x0, x1, x2, x3, tension ) {
38106
38107				init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
38108
38109			},
38110
38111			initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {
38112
38113				// compute tangents when parameterized in [t1,t2]
38114				var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
38115				var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
38116
38117				// rescale tangents for parametrization in [0,1]
38118				t1 *= dt1;
38119				t2 *= dt1;
38120
38121				init( x1, x2, t1, t2 );
38122
38123			},
38124
38125			calc: function ( t ) {
38126
38127				var t2 = t * t;
38128				var t3 = t2 * t;
38129				return c0 + c1 * t + c2 * t2 + c3 * t3;
38130
38131			}
38132
38133		};
38134
38135	}
38136
38137	//
38138
38139	var tmp = new Vector3();
38140	var px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly();
38141
38142	function CatmullRomCurve3( points, closed, curveType, tension ) {
38143
38144		Curve.call( this );
38145
38146		this.type = 'CatmullRomCurve3';
38147
38148		this.points = points || [];
38149		this.closed = closed || false;
38150		this.curveType = curveType || 'centripetal';
38151		this.tension = tension || 0.5;
38152
38153	}
38154
38155	CatmullRomCurve3.prototype = Object.create( Curve.prototype );
38156	CatmullRomCurve3.prototype.constructor = CatmullRomCurve3;
38157
38158	CatmullRomCurve3.prototype.isCatmullRomCurve3 = true;
38159
38160	CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) {
38161
38162		var point = optionalTarget || new Vector3();
38163
38164		var points = this.points;
38165		var l = points.length;
38166
38167		var p = ( l - ( this.closed ? 0 : 1 ) ) * t;
38168		var intPoint = Math.floor( p );
38169		var weight = p - intPoint;
38170
38171		if ( this.closed ) {
38172
38173			intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;
38174
38175		} else if ( weight === 0 && intPoint === l - 1 ) {
38176
38177			intPoint = l - 2;
38178			weight = 1;
38179
38180		}
38181
38182		var p0, p1, p2, p3; // 4 points
38183
38184		if ( this.closed || intPoint > 0 ) {
38185
38186			p0 = points[ ( intPoint - 1 ) % l ];
38187
38188		} else {
38189
38190			// extrapolate first point
38191			tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
38192			p0 = tmp;
38193
38194		}
38195
38196		p1 = points[ intPoint % l ];
38197		p2 = points[ ( intPoint + 1 ) % l ];
38198
38199		if ( this.closed || intPoint + 2 < l ) {
38200
38201			p3 = points[ ( intPoint + 2 ) % l ];
38202
38203		} else {
38204
38205			// extrapolate last point
38206			tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
38207			p3 = tmp;
38208
38209		}
38210
38211		if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {
38212
38213			// init Centripetal / Chordal Catmull-Rom
38214			var pow = this.curveType === 'chordal' ? 0.5 : 0.25;
38215			var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
38216			var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
38217			var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
38218
38219			// safety check for repeated points
38220			if ( dt1 < 1e-4 ) { dt1 = 1.0; }
38221			if ( dt0 < 1e-4 ) { dt0 = dt1; }
38222			if ( dt2 < 1e-4 ) { dt2 = dt1; }
38223
38224			px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
38225			py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
38226			pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
38227
38228		} else if ( this.curveType === 'catmullrom' ) {
38229
38230			px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );
38231			py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );
38232			pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );
38233
38234		}
38235
38236		point.set(
38237			px.calc( weight ),
38238			py.calc( weight ),
38239			pz.calc( weight )
38240		);
38241
38242		return point;
38243
38244	};
38245
38246	CatmullRomCurve3.prototype.copy = function ( source ) {
38247
38248		Curve.prototype.copy.call( this, source );
38249
38250		this.points = [];
38251
38252		for ( var i = 0, l = source.points.length; i < l; i ++ ) {
38253
38254			var point = source.points[ i ];
38255
38256			this.points.push( point.clone() );
38257
38258		}
38259
38260		this.closed = source.closed;
38261		this.curveType = source.curveType;
38262		this.tension = source.tension;
38263
38264		return this;
38265
38266	};
38267
38268	CatmullRomCurve3.prototype.toJSON = function () {
38269
38270		var data = Curve.prototype.toJSON.call( this );
38271
38272		data.points = [];
38273
38274		for ( var i = 0, l = this.points.length; i < l; i ++ ) {
38275
38276			var point = this.points[ i ];
38277			data.points.push( point.toArray() );
38278
38279		}
38280
38281		data.closed = this.closed;
38282		data.curveType = this.curveType;
38283		data.tension = this.tension;
38284
38285		return data;
38286
38287	};
38288
38289	CatmullRomCurve3.prototype.fromJSON = function ( json ) {
38290
38291		Curve.prototype.fromJSON.call( this, json );
38292
38293		this.points = [];
38294
38295		for ( var i = 0, l = json.points.length; i < l; i ++ ) {
38296
38297			var point = json.points[ i ];
38298			this.points.push( new Vector3().fromArray( point ) );
38299
38300		}
38301
38302		this.closed = json.closed;
38303		this.curveType = json.curveType;
38304		this.tension = json.tension;
38305
38306		return this;
38307
38308	};
38309
38310	/**
38311	 * @author zz85 / http://www.lab4games.net/zz85/blog
38312	 *
38313	 * Bezier Curves formulas obtained from
38314	 * http://en.wikipedia.org/wiki/Bézier_curve
38315	 */
38316
38317	function CatmullRom( t, p0, p1, p2, p3 ) {
38318
38319		var v0 = ( p2 - p0 ) * 0.5;
38320		var v1 = ( p3 - p1 ) * 0.5;
38321		var t2 = t * t;
38322		var t3 = t * t2;
38323		return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
38324
38325	}
38326
38327	//
38328
38329	function QuadraticBezierP0( t, p ) {
38330
38331		var k = 1 - t;
38332		return k * k * p;
38333
38334	}
38335
38336	function QuadraticBezierP1( t, p ) {
38337
38338		return 2 * ( 1 - t ) * t * p;
38339
38340	}
38341
38342	function QuadraticBezierP2( t, p ) {
38343
38344		return t * t * p;
38345
38346	}
38347
38348	function QuadraticBezier( t, p0, p1, p2 ) {
38349
38350		return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +
38351			QuadraticBezierP2( t, p2 );
38352
38353	}
38354
38355	//
38356
38357	function CubicBezierP0( t, p ) {
38358
38359		var k = 1 - t;
38360		return k * k * k * p;
38361
38362	}
38363
38364	function CubicBezierP1( t, p ) {
38365
38366		var k = 1 - t;
38367		return 3 * k * k * t * p;
38368
38369	}
38370
38371	function CubicBezierP2( t, p ) {
38372
38373		return 3 * ( 1 - t ) * t * t * p;
38374
38375	}
38376
38377	function CubicBezierP3( t, p ) {
38378
38379		return t * t * t * p;
38380
38381	}
38382
38383	function CubicBezier( t, p0, p1, p2, p3 ) {
38384
38385		return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +
38386			CubicBezierP3( t, p3 );
38387
38388	}
38389
38390	function CubicBezierCurve( v0, v1, v2, v3 ) {
38391
38392		Curve.call( this );
38393
38394		this.type = 'CubicBezierCurve';
38395
38396		this.v0 = v0 || new Vector2();
38397		this.v1 = v1 || new Vector2();
38398		this.v2 = v2 || new Vector2();
38399		this.v3 = v3 || new Vector2();
38400
38401	}
38402
38403	CubicBezierCurve.prototype = Object.create( Curve.prototype );
38404	CubicBezierCurve.prototype.constructor = CubicBezierCurve;
38405
38406	CubicBezierCurve.prototype.isCubicBezierCurve = true;
38407
38408	CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
38409
38410		var point = optionalTarget || new Vector2();
38411
38412		var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
38413
38414		point.set(
38415			CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
38416			CubicBezier( t, v0.y, v1.y, v2.y, v3.y )
38417		);
38418
38419		return point;
38420
38421	};
38422
38423	CubicBezierCurve.prototype.copy = function ( source ) {
38424
38425		Curve.prototype.copy.call( this, source );
38426
38427		this.v0.copy( source.v0 );
38428		this.v1.copy( source.v1 );
38429		this.v2.copy( source.v2 );
38430		this.v3.copy( source.v3 );
38431
38432		return this;
38433
38434	};
38435
38436	CubicBezierCurve.prototype.toJSON = function () {
38437
38438		var data = Curve.prototype.toJSON.call( this );
38439
38440		data.v0 = this.v0.toArray();
38441		data.v1 = this.v1.toArray();
38442		data.v2 = this.v2.toArray();
38443		data.v3 = this.v3.toArray();
38444
38445		return data;
38446
38447	};
38448
38449	CubicBezierCurve.prototype.fromJSON = function ( json ) {
38450
38451		Curve.prototype.fromJSON.call( this, json );
38452
38453		this.v0.fromArray( json.v0 );
38454		this.v1.fromArray( json.v1 );
38455		this.v2.fromArray( json.v2 );
38456		this.v3.fromArray( json.v3 );
38457
38458		return this;
38459
38460	};
38461
38462	function CubicBezierCurve3( v0, v1, v2, v3 ) {
38463
38464		Curve.call( this );
38465
38466		this.type = 'CubicBezierCurve3';
38467
38468		this.v0 = v0 || new Vector3();
38469		this.v1 = v1 || new Vector3();
38470		this.v2 = v2 || new Vector3();
38471		this.v3 = v3 || new Vector3();
38472
38473	}
38474
38475	CubicBezierCurve3.prototype = Object.create( Curve.prototype );
38476	CubicBezierCurve3.prototype.constructor = CubicBezierCurve3;
38477
38478	CubicBezierCurve3.prototype.isCubicBezierCurve3 = true;
38479
38480	CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
38481
38482		var point = optionalTarget || new Vector3();
38483
38484		var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
38485
38486		point.set(
38487			CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
38488			CubicBezier( t, v0.y, v1.y, v2.y, v3.y ),
38489			CubicBezier( t, v0.z, v1.z, v2.z, v3.z )
38490		);
38491
38492		return point;
38493
38494	};
38495
38496	CubicBezierCurve3.prototype.copy = function ( source ) {
38497
38498		Curve.prototype.copy.call( this, source );
38499
38500		this.v0.copy( source.v0 );
38501		this.v1.copy( source.v1 );
38502		this.v2.copy( source.v2 );
38503		this.v3.copy( source.v3 );
38504
38505		return this;
38506
38507	};
38508
38509	CubicBezierCurve3.prototype.toJSON = function () {
38510
38511		var data = Curve.prototype.toJSON.call( this );
38512
38513		data.v0 = this.v0.toArray();
38514		data.v1 = this.v1.toArray();
38515		data.v2 = this.v2.toArray();
38516		data.v3 = this.v3.toArray();
38517
38518		return data;
38519
38520	};
38521
38522	CubicBezierCurve3.prototype.fromJSON = function ( json ) {
38523
38524		Curve.prototype.fromJSON.call( this, json );
38525
38526		this.v0.fromArray( json.v0 );
38527		this.v1.fromArray( json.v1 );
38528		this.v2.fromArray( json.v2 );
38529		this.v3.fromArray( json.v3 );
38530
38531		return this;
38532
38533	};
38534
38535	function LineCurve( v1, v2 ) {
38536
38537		Curve.call( this );
38538
38539		this.type = 'LineCurve';
38540
38541		this.v1 = v1 || new Vector2();
38542		this.v2 = v2 || new Vector2();
38543
38544	}
38545
38546	LineCurve.prototype = Object.create( Curve.prototype );
38547	LineCurve.prototype.constructor = LineCurve;
38548
38549	LineCurve.prototype.isLineCurve = true;
38550
38551	LineCurve.prototype.getPoint = function ( t, optionalTarget ) {
38552
38553		var point = optionalTarget || new Vector2();
38554
38555		if ( t === 1 ) {
38556
38557			point.copy( this.v2 );
38558
38559		} else {
38560
38561			point.copy( this.v2 ).sub( this.v1 );
38562			point.multiplyScalar( t ).add( this.v1 );
38563
38564		}
38565
38566		return point;
38567
38568	};
38569
38570	// Line curve is linear, so we can overwrite default getPointAt
38571
38572	LineCurve.prototype.getPointAt = function ( u, optionalTarget ) {
38573
38574		return this.getPoint( u, optionalTarget );
38575
38576	};
38577
38578	LineCurve.prototype.getTangent = function ( t, optionalTarget ) {
38579
38580		var tangent = optionalTarget || new Vector2();
38581
38582		tangent.copy( this.v2 ).sub( this.v1 ).normalize();
38583
38584		return tangent;
38585
38586	};
38587
38588	LineCurve.prototype.copy = function ( source ) {
38589
38590		Curve.prototype.copy.call( this, source );
38591
38592		this.v1.copy( source.v1 );
38593		this.v2.copy( source.v2 );
38594
38595		return this;
38596
38597	};
38598
38599	LineCurve.prototype.toJSON = function () {
38600
38601		var data = Curve.prototype.toJSON.call( this );
38602
38603		data.v1 = this.v1.toArray();
38604		data.v2 = this.v2.toArray();
38605
38606		return data;
38607
38608	};
38609
38610	LineCurve.prototype.fromJSON = function ( json ) {
38611
38612		Curve.prototype.fromJSON.call( this, json );
38613
38614		this.v1.fromArray( json.v1 );
38615		this.v2.fromArray( json.v2 );
38616
38617		return this;
38618
38619	};
38620
38621	function LineCurve3( v1, v2 ) {
38622
38623		Curve.call( this );
38624
38625		this.type = 'LineCurve3';
38626
38627		this.v1 = v1 || new Vector3();
38628		this.v2 = v2 || new Vector3();
38629
38630	}
38631
38632	LineCurve3.prototype = Object.create( Curve.prototype );
38633	LineCurve3.prototype.constructor = LineCurve3;
38634
38635	LineCurve3.prototype.isLineCurve3 = true;
38636
38637	LineCurve3.prototype.getPoint = function ( t, optionalTarget ) {
38638
38639		var point = optionalTarget || new Vector3();
38640
38641		if ( t === 1 ) {
38642
38643			point.copy( this.v2 );
38644
38645		} else {
38646
38647			point.copy( this.v2 ).sub( this.v1 );
38648			point.multiplyScalar( t ).add( this.v1 );
38649
38650		}
38651
38652		return point;
38653
38654	};
38655
38656	// Line curve is linear, so we can overwrite default getPointAt
38657
38658	LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) {
38659
38660		return this.getPoint( u, optionalTarget );
38661
38662	};
38663
38664	LineCurve3.prototype.copy = function ( source ) {
38665
38666		Curve.prototype.copy.call( this, source );
38667
38668		this.v1.copy( source.v1 );
38669		this.v2.copy( source.v2 );
38670
38671		return this;
38672
38673	};
38674
38675	LineCurve3.prototype.toJSON = function () {
38676
38677		var data = Curve.prototype.toJSON.call( this );
38678
38679		data.v1 = this.v1.toArray();
38680		data.v2 = this.v2.toArray();
38681
38682		return data;
38683
38684	};
38685
38686	LineCurve3.prototype.fromJSON = function ( json ) {
38687
38688		Curve.prototype.fromJSON.call( this, json );
38689
38690		this.v1.fromArray( json.v1 );
38691		this.v2.fromArray( json.v2 );
38692
38693		return this;
38694
38695	};
38696
38697	function QuadraticBezierCurve( v0, v1, v2 ) {
38698
38699		Curve.call( this );
38700
38701		this.type = 'QuadraticBezierCurve';
38702
38703		this.v0 = v0 || new Vector2();
38704		this.v1 = v1 || new Vector2();
38705		this.v2 = v2 || new Vector2();
38706
38707	}
38708
38709	QuadraticBezierCurve.prototype = Object.create( Curve.prototype );
38710	QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;
38711
38712	QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true;
38713
38714	QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
38715
38716		var point = optionalTarget || new Vector2();
38717
38718		var v0 = this.v0, v1 = this.v1, v2 = this.v2;
38719
38720		point.set(
38721			QuadraticBezier( t, v0.x, v1.x, v2.x ),
38722			QuadraticBezier( t, v0.y, v1.y, v2.y )
38723		);
38724
38725		return point;
38726
38727	};
38728
38729	QuadraticBezierCurve.prototype.copy = function ( source ) {
38730
38731		Curve.prototype.copy.call( this, source );
38732
38733		this.v0.copy( source.v0 );
38734		this.v1.copy( source.v1 );
38735		this.v2.copy( source.v2 );
38736
38737		return this;
38738
38739	};
38740
38741	QuadraticBezierCurve.prototype.toJSON = function () {
38742
38743		var data = Curve.prototype.toJSON.call( this );
38744
38745		data.v0 = this.v0.toArray();
38746		data.v1 = this.v1.toArray();
38747		data.v2 = this.v2.toArray();
38748
38749		return data;
38750
38751	};
38752
38753	QuadraticBezierCurve.prototype.fromJSON = function ( json ) {
38754
38755		Curve.prototype.fromJSON.call( this, json );
38756
38757		this.v0.fromArray( json.v0 );
38758		this.v1.fromArray( json.v1 );
38759		this.v2.fromArray( json.v2 );
38760
38761		return this;
38762
38763	};
38764
38765	function QuadraticBezierCurve3( v0, v1, v2 ) {
38766
38767		Curve.call( this );
38768
38769		this.type = 'QuadraticBezierCurve3';
38770
38771		this.v0 = v0 || new Vector3();
38772		this.v1 = v1 || new Vector3();
38773		this.v2 = v2 || new Vector3();
38774
38775	}
38776
38777	QuadraticBezierCurve3.prototype = Object.create( Curve.prototype );
38778	QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;
38779
38780	QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true;
38781
38782	QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
38783
38784		var point = optionalTarget || new Vector3();
38785
38786		var v0 = this.v0, v1 = this.v1, v2 = this.v2;
38787
38788		point.set(
38789			QuadraticBezier( t, v0.x, v1.x, v2.x ),
38790			QuadraticBezier( t, v0.y, v1.y, v2.y ),
38791			QuadraticBezier( t, v0.z, v1.z, v2.z )
38792		);
38793
38794		return point;
38795
38796	};
38797
38798	QuadraticBezierCurve3.prototype.copy = function ( source ) {
38799
38800		Curve.prototype.copy.call( this, source );
38801
38802		this.v0.copy( source.v0 );
38803		this.v1.copy( source.v1 );
38804		this.v2.copy( source.v2 );
38805
38806		return this;
38807
38808	};
38809
38810	QuadraticBezierCurve3.prototype.toJSON = function () {
38811
38812		var data = Curve.prototype.toJSON.call( this );
38813
38814		data.v0 = this.v0.toArray();
38815		data.v1 = this.v1.toArray();
38816		data.v2 = this.v2.toArray();
38817
38818		return data;
38819
38820	};
38821
38822	QuadraticBezierCurve3.prototype.fromJSON = function ( json ) {
38823
38824		Curve.prototype.fromJSON.call( this, json );
38825
38826		this.v0.fromArray( json.v0 );
38827		this.v1.fromArray( json.v1 );
38828		this.v2.fromArray( json.v2 );
38829
38830		return this;
38831
38832	};
38833
38834	function SplineCurve( points /* array of Vector2 */ ) {
38835
38836		Curve.call( this );
38837
38838		this.type = 'SplineCurve';
38839
38840		this.points = points || [];
38841
38842	}
38843
38844	SplineCurve.prototype = Object.create( Curve.prototype );
38845	SplineCurve.prototype.constructor = SplineCurve;
38846
38847	SplineCurve.prototype.isSplineCurve = true;
38848
38849	SplineCurve.prototype.getPoint = function ( t, optionalTarget ) {
38850
38851		var point = optionalTarget || new Vector2();
38852
38853		var points = this.points;
38854		var p = ( points.length - 1 ) * t;
38855
38856		var intPoint = Math.floor( p );
38857		var weight = p - intPoint;
38858
38859		var p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
38860		var p1 = points[ intPoint ];
38861		var p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
38862		var p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
38863
38864		point.set(
38865			CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ),
38866			CatmullRom( weight, p0.y, p1.y, p2.y, p3.y )
38867		);
38868
38869		return point;
38870
38871	};
38872
38873	SplineCurve.prototype.copy = function ( source ) {
38874
38875		Curve.prototype.copy.call( this, source );
38876
38877		this.points = [];
38878
38879		for ( var i = 0, l = source.points.length; i < l; i ++ ) {
38880
38881			var point = source.points[ i ];
38882
38883			this.points.push( point.clone() );
38884
38885		}
38886
38887		return this;
38888
38889	};
38890
38891	SplineCurve.prototype.toJSON = function () {
38892
38893		var data = Curve.prototype.toJSON.call( this );
38894
38895		data.points = [];
38896
38897		for ( var i = 0, l = this.points.length; i < l; i ++ ) {
38898
38899			var point = this.points[ i ];
38900			data.points.push( point.toArray() );
38901
38902		}
38903
38904		return data;
38905
38906	};
38907
38908	SplineCurve.prototype.fromJSON = function ( json ) {
38909
38910		Curve.prototype.fromJSON.call( this, json );
38911
38912		this.points = [];
38913
38914		for ( var i = 0, l = json.points.length; i < l; i ++ ) {
38915
38916			var point = json.points[ i ];
38917			this.points.push( new Vector2().fromArray( point ) );
38918
38919		}
38920
38921		return this;
38922
38923	};
38924
38925	var Curves = /*#__PURE__*/Object.freeze({
38926		__proto__: null,
38927		ArcCurve: ArcCurve,
38928		CatmullRomCurve3: CatmullRomCurve3,
38929		CubicBezierCurve: CubicBezierCurve,
38930		CubicBezierCurve3: CubicBezierCurve3,
38931		EllipseCurve: EllipseCurve,
38932		LineCurve: LineCurve,
38933		LineCurve3: LineCurve3,
38934		QuadraticBezierCurve: QuadraticBezierCurve,
38935		QuadraticBezierCurve3: QuadraticBezierCurve3,
38936		SplineCurve: SplineCurve
38937	});
38938
38939	/**
38940	 * @author zz85 / http://www.lab4games.net/zz85/blog
38941	 *
38942	 **/
38943
38944	/**************************************************************
38945	 *	Curved Path - a curve path is simply a array of connected
38946	 *  curves, but retains the api of a curve
38947	 **************************************************************/
38948
38949	function CurvePath() {
38950
38951		Curve.call( this );
38952
38953		this.type = 'CurvePath';
38954
38955		this.curves = [];
38956		this.autoClose = false; // Automatically closes the path
38957
38958	}
38959
38960	CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {
38961
38962		constructor: CurvePath,
38963
38964		add: function ( curve ) {
38965
38966			this.curves.push( curve );
38967
38968		},
38969
38970		closePath: function () {
38971
38972			// Add a line curve if start and end of lines are not connected
38973			var startPoint = this.curves[ 0 ].getPoint( 0 );
38974			var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );
38975
38976			if ( ! startPoint.equals( endPoint ) ) {
38977
38978				this.curves.push( new LineCurve( endPoint, startPoint ) );
38979
38980			}
38981
38982		},
38983
38984		// To get accurate point with reference to
38985		// entire path distance at time t,
38986		// following has to be done:
38987
38988		// 1. Length of each sub path have to be known
38989		// 2. Locate and identify type of curve
38990		// 3. Get t for the curve
38991		// 4. Return curve.getPointAt(t')
38992
38993		getPoint: function ( t ) {
38994
38995			var d = t * this.getLength();
38996			var curveLengths = this.getCurveLengths();
38997			var i = 0;
38998
38999			// To think about boundaries points.
39000
39001			while ( i < curveLengths.length ) {
39002
39003				if ( curveLengths[ i ] >= d ) {
39004
39005					var diff = curveLengths[ i ] - d;
39006					var curve = this.curves[ i ];
39007
39008					var segmentLength = curve.getLength();
39009					var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
39010
39011					return curve.getPointAt( u );
39012
39013				}
39014
39015				i ++;
39016
39017			}
39018
39019			return null;
39020
39021			// loop where sum != 0, sum > d , sum+1 <d
39022
39023		},
39024
39025		// We cannot use the default THREE.Curve getPoint() with getLength() because in
39026		// THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
39027		// getPoint() depends on getLength
39028
39029		getLength: function () {
39030
39031			var lens = this.getCurveLengths();
39032			return lens[ lens.length - 1 ];
39033
39034		},
39035
39036		// cacheLengths must be recalculated.
39037		updateArcLengths: function () {
39038
39039			this.needsUpdate = true;
39040			this.cacheLengths = null;
39041			this.getCurveLengths();
39042
39043		},
39044
39045		// Compute lengths and cache them
39046		// We cannot overwrite getLengths() because UtoT mapping uses it.
39047
39048		getCurveLengths: function () {
39049
39050			// We use cache values if curves and cache array are same length
39051
39052			if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) {
39053
39054				return this.cacheLengths;
39055
39056			}
39057
39058			// Get length of sub-curve
39059			// Push sums into cached array
39060
39061			var lengths = [];
39062			var sums = 0;
39063
39064			for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
39065
39066				sums += this.curves[ i ].getLength();
39067				lengths.push( sums );
39068
39069			}
39070
39071			this.cacheLengths = lengths;
39072
39073			return lengths;
39074
39075		},
39076
39077		getSpacedPoints: function ( divisions ) {
39078
39079			if ( divisions === undefined ) { divisions = 40; }
39080
39081			var points = [];
39082
39083			for ( var i = 0; i <= divisions; i ++ ) {
39084
39085				points.push( this.getPoint( i / divisions ) );
39086
39087			}
39088
39089			if ( this.autoClose ) {
39090
39091				points.push( points[ 0 ] );
39092
39093			}
39094
39095			return points;
39096
39097		},
39098
39099		getPoints: function ( divisions ) {
39100
39101			divisions = divisions || 12;
39102
39103			var points = [];
39104			var last;
39105
39106			for ( var i = 0, curves = this.curves; i < curves.length; i ++ ) {
39107
39108				var curve = curves[ i ];
39109				var resolution = ( curve && curve.isEllipseCurve ) ? divisions * 2
39110					: ( curve && ( curve.isLineCurve || curve.isLineCurve3 ) ) ? 1
39111						: ( curve && curve.isSplineCurve ) ? divisions * curve.points.length
39112							: divisions;
39113
39114				var pts = curve.getPoints( resolution );
39115
39116				for ( var j = 0; j < pts.length; j ++ ) {
39117
39118					var point = pts[ j ];
39119
39120					if ( last && last.equals( point ) ) { continue; } // ensures no consecutive points are duplicates
39121
39122					points.push( point );
39123					last = point;
39124
39125				}
39126
39127			}
39128
39129			if ( this.autoClose && points.length > 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) {
39130
39131				points.push( points[ 0 ] );
39132
39133			}
39134
39135			return points;
39136
39137		},
39138
39139		copy: function ( source ) {
39140
39141			Curve.prototype.copy.call( this, source );
39142
39143			this.curves = [];
39144
39145			for ( var i = 0, l = source.curves.length; i < l; i ++ ) {
39146
39147				var curve = source.curves[ i ];
39148
39149				this.curves.push( curve.clone() );
39150
39151			}
39152
39153			this.autoClose = source.autoClose;
39154
39155			return this;
39156
39157		},
39158
39159		toJSON: function () {
39160
39161			var data = Curve.prototype.toJSON.call( this );
39162
39163			data.autoClose = this.autoClose;
39164			data.curves = [];
39165
39166			for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
39167
39168				var curve = this.curves[ i ];
39169				data.curves.push( curve.toJSON() );
39170
39171			}
39172
39173			return data;
39174
39175		},
39176
39177		fromJSON: function ( json ) {
39178
39179			Curve.prototype.fromJSON.call( this, json );
39180
39181			this.autoClose = json.autoClose;
39182			this.curves = [];
39183
39184			for ( var i = 0, l = json.curves.length; i < l; i ++ ) {
39185
39186				var curve = json.curves[ i ];
39187				this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) );
39188
39189			}
39190
39191			return this;
39192
39193		}
39194
39195	} );
39196
39197	/**
39198	 * @author zz85 / http://www.lab4games.net/zz85/blog
39199	 * Creates free form 2d path using series of points, lines or curves.
39200	 **/
39201
39202	function Path( points ) {
39203
39204		CurvePath.call( this );
39205
39206		this.type = 'Path';
39207
39208		this.currentPoint = new Vector2();
39209
39210		if ( points ) {
39211
39212			this.setFromPoints( points );
39213
39214		}
39215
39216	}
39217
39218	Path.prototype = Object.assign( Object.create( CurvePath.prototype ), {
39219
39220		constructor: Path,
39221
39222		setFromPoints: function ( points ) {
39223
39224			this.moveTo( points[ 0 ].x, points[ 0 ].y );
39225
39226			for ( var i = 1, l = points.length; i < l; i ++ ) {
39227
39228				this.lineTo( points[ i ].x, points[ i ].y );
39229
39230			}
39231
39232			return this;
39233
39234		},
39235
39236		moveTo: function ( x, y ) {
39237
39238			this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?
39239
39240			return this;
39241
39242		},
39243
39244		lineTo: function ( x, y ) {
39245
39246			var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );
39247			this.curves.push( curve );
39248
39249			this.currentPoint.set( x, y );
39250
39251			return this;
39252
39253		},
39254
39255		quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
39256
39257			var curve = new QuadraticBezierCurve(
39258				this.currentPoint.clone(),
39259				new Vector2( aCPx, aCPy ),
39260				new Vector2( aX, aY )
39261			);
39262
39263			this.curves.push( curve );
39264
39265			this.currentPoint.set( aX, aY );
39266
39267			return this;
39268
39269		},
39270
39271		bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
39272
39273			var curve = new CubicBezierCurve(
39274				this.currentPoint.clone(),
39275				new Vector2( aCP1x, aCP1y ),
39276				new Vector2( aCP2x, aCP2y ),
39277				new Vector2( aX, aY )
39278			);
39279
39280			this.curves.push( curve );
39281
39282			this.currentPoint.set( aX, aY );
39283
39284			return this;
39285
39286		},
39287
39288		splineThru: function ( pts /*Array of Vector*/ ) {
39289
39290			var npts = [ this.currentPoint.clone() ].concat( pts );
39291
39292			var curve = new SplineCurve( npts );
39293			this.curves.push( curve );
39294
39295			this.currentPoint.copy( pts[ pts.length - 1 ] );
39296
39297			return this;
39298
39299		},
39300
39301		arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
39302
39303			var x0 = this.currentPoint.x;
39304			var y0 = this.currentPoint.y;
39305
39306			this.absarc( aX + x0, aY + y0, aRadius,
39307				aStartAngle, aEndAngle, aClockwise );
39308
39309			return this;
39310
39311		},
39312
39313		absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
39314
39315			this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
39316
39317			return this;
39318
39319		},
39320
39321		ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
39322
39323			var x0 = this.currentPoint.x;
39324			var y0 = this.currentPoint.y;
39325
39326			this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
39327
39328			return this;
39329
39330		},
39331
39332		absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
39333
39334			var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
39335
39336			if ( this.curves.length > 0 ) {
39337
39338				// if a previous curve is present, attempt to join
39339				var firstPoint = curve.getPoint( 0 );
39340
39341				if ( ! firstPoint.equals( this.currentPoint ) ) {
39342
39343					this.lineTo( firstPoint.x, firstPoint.y );
39344
39345				}
39346
39347			}
39348
39349			this.curves.push( curve );
39350
39351			var lastPoint = curve.getPoint( 1 );
39352			this.currentPoint.copy( lastPoint );
39353
39354			return this;
39355
39356		},
39357
39358		copy: function ( source ) {
39359
39360			CurvePath.prototype.copy.call( this, source );
39361
39362			this.currentPoint.copy( source.currentPoint );
39363
39364			return this;
39365
39366		},
39367
39368		toJSON: function () {
39369
39370			var data = CurvePath.prototype.toJSON.call( this );
39371
39372			data.currentPoint = this.currentPoint.toArray();
39373
39374			return data;
39375
39376		},
39377
39378		fromJSON: function ( json ) {
39379
39380			CurvePath.prototype.fromJSON.call( this, json );
39381
39382			this.currentPoint.fromArray( json.currentPoint );
39383
39384			return this;
39385
39386		}
39387
39388	} );
39389
39390	/**
39391	 * @author zz85 / http://www.lab4games.net/zz85/blog
39392	 * Defines a 2d shape plane using paths.
39393	 **/
39394
39395	// STEP 1 Create a path.
39396	// STEP 2 Turn path into shape.
39397	// STEP 3 ExtrudeGeometry takes in Shape/Shapes
39398	// STEP 3a - Extract points from each shape, turn to vertices
39399	// STEP 3b - Triangulate each shape, add faces.
39400
39401	function Shape( points ) {
39402
39403		Path.call( this, points );
39404
39405		this.uuid = MathUtils.generateUUID();
39406
39407		this.type = 'Shape';
39408
39409		this.holes = [];
39410
39411	}
39412
39413	Shape.prototype = Object.assign( Object.create( Path.prototype ), {
39414
39415		constructor: Shape,
39416
39417		getPointsHoles: function ( divisions ) {
39418
39419			var holesPts = [];
39420
39421			for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
39422
39423				holesPts[ i ] = this.holes[ i ].getPoints( divisions );
39424
39425			}
39426
39427			return holesPts;
39428
39429		},
39430
39431		// get points of shape and holes (keypoints based on segments parameter)
39432
39433		extractPoints: function ( divisions ) {
39434
39435			return {
39436
39437				shape: this.getPoints( divisions ),
39438				holes: this.getPointsHoles( divisions )
39439
39440			};
39441
39442		},
39443
39444		copy: function ( source ) {
39445
39446			Path.prototype.copy.call( this, source );
39447
39448			this.holes = [];
39449
39450			for ( var i = 0, l = source.holes.length; i < l; i ++ ) {
39451
39452				var hole = source.holes[ i ];
39453
39454				this.holes.push( hole.clone() );
39455
39456			}
39457
39458			return this;
39459
39460		},
39461
39462		toJSON: function () {
39463
39464			var data = Path.prototype.toJSON.call( this );
39465
39466			data.uuid = this.uuid;
39467			data.holes = [];
39468
39469			for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
39470
39471				var hole = this.holes[ i ];
39472				data.holes.push( hole.toJSON() );
39473
39474			}
39475
39476			return data;
39477
39478		},
39479
39480		fromJSON: function ( json ) {
39481
39482			Path.prototype.fromJSON.call( this, json );
39483
39484			this.uuid = json.uuid;
39485			this.holes = [];
39486
39487			for ( var i = 0, l = json.holes.length; i < l; i ++ ) {
39488
39489				var hole = json.holes[ i ];
39490				this.holes.push( new Path().fromJSON( hole ) );
39491
39492			}
39493
39494			return this;
39495
39496		}
39497
39498	} );
39499
39500	/**
39501	 * @author mrdoob / http://mrdoob.com/
39502	 * @author alteredq / http://alteredqualia.com/
39503	 */
39504
39505	function Light( color, intensity ) {
39506
39507		Object3D.call( this );
39508
39509		this.type = 'Light';
39510
39511		this.color = new Color( color );
39512		this.intensity = intensity !== undefined ? intensity : 1;
39513
39514		this.receiveShadow = undefined;
39515
39516	}
39517
39518	Light.prototype = Object.assign( Object.create( Object3D.prototype ), {
39519
39520		constructor: Light,
39521
39522		isLight: true,
39523
39524		copy: function ( source ) {
39525
39526			Object3D.prototype.copy.call( this, source );
39527
39528			this.color.copy( source.color );
39529			this.intensity = source.intensity;
39530
39531			return this;
39532
39533		},
39534
39535		toJSON: function ( meta ) {
39536
39537			var data = Object3D.prototype.toJSON.call( this, meta );
39538
39539			data.object.color = this.color.getHex();
39540			data.object.intensity = this.intensity;
39541
39542			if ( this.groundColor !== undefined ) { data.object.groundColor = this.groundColor.getHex(); }
39543
39544			if ( this.distance !== undefined ) { data.object.distance = this.distance; }
39545			if ( this.angle !== undefined ) { data.object.angle = this.angle; }
39546			if ( this.decay !== undefined ) { data.object.decay = this.decay; }
39547			if ( this.penumbra !== undefined ) { data.object.penumbra = this.penumbra; }
39548
39549			if ( this.shadow !== undefined ) { data.object.shadow = this.shadow.toJSON(); }
39550
39551			return data;
39552
39553		}
39554
39555	} );
39556
39557	/**
39558	 * @author alteredq / http://alteredqualia.com/
39559	 */
39560
39561	function HemisphereLight( skyColor, groundColor, intensity ) {
39562
39563		Light.call( this, skyColor, intensity );
39564
39565		this.type = 'HemisphereLight';
39566
39567		this.castShadow = undefined;
39568
39569		this.position.copy( Object3D.DefaultUp );
39570		this.updateMatrix();
39571
39572		this.groundColor = new Color( groundColor );
39573
39574	}
39575
39576	HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {
39577
39578		constructor: HemisphereLight,
39579
39580		isHemisphereLight: true,
39581
39582		copy: function ( source ) {
39583
39584			Light.prototype.copy.call( this, source );
39585
39586			this.groundColor.copy( source.groundColor );
39587
39588			return this;
39589
39590		}
39591
39592	} );
39593
39594	/**
39595	 * @author mrdoob / http://mrdoob.com/
39596	 */
39597
39598	function LightShadow( camera ) {
39599
39600		this.camera = camera;
39601
39602		this.bias = 0;
39603		this.normalBias = 0;
39604		this.radius = 1;
39605
39606		this.mapSize = new Vector2( 512, 512 );
39607
39608		this.map = null;
39609		this.mapPass = null;
39610		this.matrix = new Matrix4();
39611
39612		this.autoUpdate = true;
39613		this.needsUpdate = false;
39614
39615		this._frustum = new Frustum();
39616		this._frameExtents = new Vector2( 1, 1 );
39617
39618		this._viewportCount = 1;
39619
39620		this._viewports = [
39621
39622			new Vector4( 0, 0, 1, 1 )
39623
39624		];
39625
39626	}
39627
39628	Object.assign( LightShadow.prototype, {
39629
39630		_projScreenMatrix: new Matrix4(),
39631
39632		_lightPositionWorld: new Vector3(),
39633
39634		_lookTarget: new Vector3(),
39635
39636		getViewportCount: function () {
39637
39638			return this._viewportCount;
39639
39640		},
39641
39642		getFrustum: function () {
39643
39644			return this._frustum;
39645
39646		},
39647
39648		updateMatrices: function ( light ) {
39649
39650			var shadowCamera = this.camera,
39651				shadowMatrix = this.matrix,
39652				projScreenMatrix = this._projScreenMatrix,
39653				lookTarget = this._lookTarget,
39654				lightPositionWorld = this._lightPositionWorld;
39655
39656			lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
39657			shadowCamera.position.copy( lightPositionWorld );
39658
39659			lookTarget.setFromMatrixPosition( light.target.matrixWorld );
39660			shadowCamera.lookAt( lookTarget );
39661			shadowCamera.updateMatrixWorld();
39662
39663			projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
39664			this._frustum.setFromProjectionMatrix( projScreenMatrix );
39665
39666			shadowMatrix.set(
39667				0.5, 0.0, 0.0, 0.5,
39668				0.0, 0.5, 0.0, 0.5,
39669				0.0, 0.0, 0.5, 0.5,
39670				0.0, 0.0, 0.0, 1.0
39671			);
39672
39673			shadowMatrix.multiply( shadowCamera.projectionMatrix );
39674			shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
39675
39676		},
39677
39678		getViewport: function ( viewportIndex ) {
39679
39680			return this._viewports[ viewportIndex ];
39681
39682		},
39683
39684		getFrameExtents: function () {
39685
39686			return this._frameExtents;
39687
39688		},
39689
39690		copy: function ( source ) {
39691
39692			this.camera = source.camera.clone();
39693
39694			this.bias = source.bias;
39695			this.radius = source.radius;
39696
39697			this.mapSize.copy( source.mapSize );
39698
39699			return this;
39700
39701		},
39702
39703		clone: function () {
39704
39705			return new this.constructor().copy( this );
39706
39707		},
39708
39709		toJSON: function () {
39710
39711			var object = {};
39712
39713			if ( this.bias !== 0 ) { object.bias = this.bias; }
39714			if ( this.normalBias !== 0 ) { object.normalBias = this.normalBias; }
39715			if ( this.radius !== 1 ) { object.radius = this.radius; }
39716			if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) { object.mapSize = this.mapSize.toArray(); }
39717
39718			object.camera = this.camera.toJSON( false ).object;
39719			delete object.camera.matrix;
39720
39721			return object;
39722
39723		}
39724
39725	} );
39726
39727	/**
39728	 * @author mrdoob / http://mrdoob.com/
39729	 */
39730
39731	function SpotLightShadow() {
39732
39733		LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );
39734
39735	}
39736
39737	SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
39738
39739		constructor: SpotLightShadow,
39740
39741		isSpotLightShadow: true,
39742
39743		updateMatrices: function ( light ) {
39744
39745			var camera = this.camera;
39746
39747			var fov = MathUtils.RAD2DEG * 2 * light.angle;
39748			var aspect = this.mapSize.width / this.mapSize.height;
39749			var far = light.distance || camera.far;
39750
39751			if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {
39752
39753				camera.fov = fov;
39754				camera.aspect = aspect;
39755				camera.far = far;
39756				camera.updateProjectionMatrix();
39757
39758			}
39759
39760			LightShadow.prototype.updateMatrices.call( this, light );
39761
39762		}
39763
39764	} );
39765
39766	/**
39767	 * @author alteredq / http://alteredqualia.com/
39768	 */
39769
39770	function SpotLight( color, intensity, distance, angle, penumbra, decay ) {
39771
39772		Light.call( this, color, intensity );
39773
39774		this.type = 'SpotLight';
39775
39776		this.position.copy( Object3D.DefaultUp );
39777		this.updateMatrix();
39778
39779		this.target = new Object3D();
39780
39781		Object.defineProperty( this, 'power', {
39782			get: function () {
39783
39784				// intensity = power per solid angle.
39785				// ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39786				return this.intensity * Math.PI;
39787
39788			},
39789			set: function ( power ) {
39790
39791				// intensity = power per solid angle.
39792				// ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39793				this.intensity = power / Math.PI;
39794
39795			}
39796		} );
39797
39798		this.distance = ( distance !== undefined ) ? distance : 0;
39799		this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
39800		this.penumbra = ( penumbra !== undefined ) ? penumbra : 0;
39801		this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.
39802
39803		this.shadow = new SpotLightShadow();
39804
39805	}
39806
39807	SpotLight.prototype = Object.assign( Object.create( Light.prototype ), {
39808
39809		constructor: SpotLight,
39810
39811		isSpotLight: true,
39812
39813		copy: function ( source ) {
39814
39815			Light.prototype.copy.call( this, source );
39816
39817			this.distance = source.distance;
39818			this.angle = source.angle;
39819			this.penumbra = source.penumbra;
39820			this.decay = source.decay;
39821
39822			this.target = source.target.clone();
39823
39824			this.shadow = source.shadow.clone();
39825
39826			return this;
39827
39828		}
39829
39830	} );
39831
39832	function PointLightShadow() {
39833
39834		LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) );
39835
39836		this._frameExtents = new Vector2( 4, 2 );
39837
39838		this._viewportCount = 6;
39839
39840		this._viewports = [
39841			// These viewports map a cube-map onto a 2D texture with the
39842			// following orientation:
39843			//
39844			//  xzXZ
39845			//   y Y
39846			//
39847			// X - Positive x direction
39848			// x - Negative x direction
39849			// Y - Positive y direction
39850			// y - Negative y direction
39851			// Z - Positive z direction
39852			// z - Negative z direction
39853
39854			// positive X
39855			new Vector4( 2, 1, 1, 1 ),
39856			// negative X
39857			new Vector4( 0, 1, 1, 1 ),
39858			// positive Z
39859			new Vector4( 3, 1, 1, 1 ),
39860			// negative Z
39861			new Vector4( 1, 1, 1, 1 ),
39862			// positive Y
39863			new Vector4( 3, 0, 1, 1 ),
39864			// negative Y
39865			new Vector4( 1, 0, 1, 1 )
39866		];
39867
39868		this._cubeDirections = [
39869			new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
39870			new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
39871		];
39872
39873		this._cubeUps = [
39874			new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
39875			new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ),	new Vector3( 0, 0, - 1 )
39876		];
39877
39878	}
39879
39880	PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
39881
39882		constructor: PointLightShadow,
39883
39884		isPointLightShadow: true,
39885
39886		updateMatrices: function ( light, viewportIndex ) {
39887
39888			if ( viewportIndex === undefined ) { viewportIndex = 0; }
39889
39890			var camera = this.camera,
39891				shadowMatrix = this.matrix,
39892				lightPositionWorld = this._lightPositionWorld,
39893				lookTarget = this._lookTarget,
39894				projScreenMatrix = this._projScreenMatrix;
39895
39896			lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
39897			camera.position.copy( lightPositionWorld );
39898
39899			lookTarget.copy( camera.position );
39900			lookTarget.add( this._cubeDirections[ viewportIndex ] );
39901			camera.up.copy( this._cubeUps[ viewportIndex ] );
39902			camera.lookAt( lookTarget );
39903			camera.updateMatrixWorld();
39904
39905			shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z );
39906
39907			projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
39908			this._frustum.setFromProjectionMatrix( projScreenMatrix );
39909
39910		}
39911
39912	} );
39913
39914	/**
39915	 * @author mrdoob / http://mrdoob.com/
39916	 */
39917
39918
39919	function PointLight( color, intensity, distance, decay ) {
39920
39921		Light.call( this, color, intensity );
39922
39923		this.type = 'PointLight';
39924
39925		Object.defineProperty( this, 'power', {
39926			get: function () {
39927
39928				// intensity = power per solid angle.
39929				// ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39930				return this.intensity * 4 * Math.PI;
39931
39932			},
39933			set: function ( power ) {
39934
39935				// intensity = power per solid angle.
39936				// ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39937				this.intensity = power / ( 4 * Math.PI );
39938
39939			}
39940		} );
39941
39942		this.distance = ( distance !== undefined ) ? distance : 0;
39943		this.decay = ( decay !== undefined ) ? decay : 1;	// for physically correct lights, should be 2.
39944
39945		this.shadow = new PointLightShadow();
39946
39947	}
39948
39949	PointLight.prototype = Object.assign( Object.create( Light.prototype ), {
39950
39951		constructor: PointLight,
39952
39953		isPointLight: true,
39954
39955		copy: function ( source ) {
39956
39957			Light.prototype.copy.call( this, source );
39958
39959			this.distance = source.distance;
39960			this.decay = source.decay;
39961
39962			this.shadow = source.shadow.clone();
39963
39964			return this;
39965
39966		}
39967
39968	} );
39969
39970	/**
39971	 * @author alteredq / http://alteredqualia.com/
39972	 * @author arose / http://github.com/arose
39973	 */
39974
39975	function OrthographicCamera( left, right, top, bottom, near, far ) {
39976
39977		Camera.call( this );
39978
39979		this.type = 'OrthographicCamera';
39980
39981		this.zoom = 1;
39982		this.view = null;
39983
39984		this.left = ( left !== undefined ) ? left : - 1;
39985		this.right = ( right !== undefined ) ? right : 1;
39986		this.top = ( top !== undefined ) ? top : 1;
39987		this.bottom = ( bottom !== undefined ) ? bottom : - 1;
39988
39989		this.near = ( near !== undefined ) ? near : 0.1;
39990		this.far = ( far !== undefined ) ? far : 2000;
39991
39992		this.updateProjectionMatrix();
39993
39994	}
39995
39996	OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
39997
39998		constructor: OrthographicCamera,
39999
40000		isOrthographicCamera: true,
40001
40002		copy: function ( source, recursive ) {
40003
40004			Camera.prototype.copy.call( this, source, recursive );
40005
40006			this.left = source.left;
40007			this.right = source.right;
40008			this.top = source.top;
40009			this.bottom = source.bottom;
40010			this.near = source.near;
40011			this.far = source.far;
40012
40013			this.zoom = source.zoom;
40014			this.view = source.view === null ? null : Object.assign( {}, source.view );
40015
40016			return this;
40017
40018		},
40019
40020		setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
40021
40022			if ( this.view === null ) {
40023
40024				this.view = {
40025					enabled: true,
40026					fullWidth: 1,
40027					fullHeight: 1,
40028					offsetX: 0,
40029					offsetY: 0,
40030					width: 1,
40031					height: 1
40032				};
40033
40034			}
40035
40036			this.view.enabled = true;
40037			this.view.fullWidth = fullWidth;
40038			this.view.fullHeight = fullHeight;
40039			this.view.offsetX = x;
40040			this.view.offsetY = y;
40041			this.view.width = width;
40042			this.view.height = height;
40043
40044			this.updateProjectionMatrix();
40045
40046		},
40047
40048		clearViewOffset: function () {
40049
40050			if ( this.view !== null ) {
40051
40052				this.view.enabled = false;
40053
40054			}
40055
40056			this.updateProjectionMatrix();
40057
40058		},
40059
40060		updateProjectionMatrix: function () {
40061
40062			var dx = ( this.right - this.left ) / ( 2 * this.zoom );
40063			var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
40064			var cx = ( this.right + this.left ) / 2;
40065			var cy = ( this.top + this.bottom ) / 2;
40066
40067			var left = cx - dx;
40068			var right = cx + dx;
40069			var top = cy + dy;
40070			var bottom = cy - dy;
40071
40072			if ( this.view !== null && this.view.enabled ) {
40073
40074				var scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom;
40075				var scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom;
40076
40077				left += scaleW * this.view.offsetX;
40078				right = left + scaleW * this.view.width;
40079				top -= scaleH * this.view.offsetY;
40080				bottom = top - scaleH * this.view.height;
40081
40082			}
40083
40084			this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );
40085
40086			this.projectionMatrixInverse.getInverse( this.projectionMatrix );
40087
40088		},
40089
40090		toJSON: function ( meta ) {
40091
40092			var data = Object3D.prototype.toJSON.call( this, meta );
40093
40094			data.object.zoom = this.zoom;
40095			data.object.left = this.left;
40096			data.object.right = this.right;
40097			data.object.top = this.top;
40098			data.object.bottom = this.bottom;
40099			data.object.near = this.near;
40100			data.object.far = this.far;
40101
40102			if ( this.view !== null ) { data.object.view = Object.assign( {}, this.view ); }
40103
40104			return data;
40105
40106		}
40107
40108	} );
40109
40110	/**
40111	 * @author mrdoob / http://mrdoob.com/
40112	 */
40113
40114	function DirectionalLightShadow() {
40115
40116		LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );
40117
40118	}
40119
40120	DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
40121
40122		constructor: DirectionalLightShadow,
40123
40124		isDirectionalLightShadow: true,
40125
40126		updateMatrices: function ( light ) {
40127
40128			LightShadow.prototype.updateMatrices.call( this, light );
40129
40130		}
40131
40132	} );
40133
40134	/**
40135	 * @author mrdoob / http://mrdoob.com/
40136	 * @author alteredq / http://alteredqualia.com/
40137	 */
40138
40139	function DirectionalLight( color, intensity ) {
40140
40141		Light.call( this, color, intensity );
40142
40143		this.type = 'DirectionalLight';
40144
40145		this.position.copy( Object3D.DefaultUp );
40146		this.updateMatrix();
40147
40148		this.target = new Object3D();
40149
40150		this.shadow = new DirectionalLightShadow();
40151
40152	}
40153
40154	DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {
40155
40156		constructor: DirectionalLight,
40157
40158		isDirectionalLight: true,
40159
40160		copy: function ( source ) {
40161
40162			Light.prototype.copy.call( this, source );
40163
40164			this.target = source.target.clone();
40165
40166			this.shadow = source.shadow.clone();
40167
40168			return this;
40169
40170		}
40171
40172	} );
40173
40174	/**
40175	 * @author mrdoob / http://mrdoob.com/
40176	 */
40177
40178	function AmbientLight( color, intensity ) {
40179
40180		Light.call( this, color, intensity );
40181
40182		this.type = 'AmbientLight';
40183
40184		this.castShadow = undefined;
40185
40186	}
40187
40188	AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {
40189
40190		constructor: AmbientLight,
40191
40192		isAmbientLight: true
40193
40194	} );
40195
40196	/**
40197	 * @author abelnation / http://github.com/abelnation
40198	 */
40199
40200	function RectAreaLight( color, intensity, width, height ) {
40201
40202		Light.call( this, color, intensity );
40203
40204		this.type = 'RectAreaLight';
40205
40206		this.width = ( width !== undefined ) ? width : 10;
40207		this.height = ( height !== undefined ) ? height : 10;
40208
40209	}
40210
40211	RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {
40212
40213		constructor: RectAreaLight,
40214
40215		isRectAreaLight: true,
40216
40217		copy: function ( source ) {
40218
40219			Light.prototype.copy.call( this, source );
40220
40221			this.width = source.width;
40222			this.height = source.height;
40223
40224			return this;
40225
40226		},
40227
40228		toJSON: function ( meta ) {
40229
40230			var data = Light.prototype.toJSON.call( this, meta );
40231
40232			data.object.width = this.width;
40233			data.object.height = this.height;
40234
40235			return data;
40236
40237		}
40238
40239	} );
40240
40241	/**
40242	 * @author bhouston / http://clara.io
40243	 * @author WestLangley / http://github.com/WestLangley
40244	 *
40245	 * Primary reference:
40246	 *   https://graphics.stanford.edu/papers/envmap/envmap.pdf
40247	 *
40248	 * Secondary reference:
40249	 *   https://www.ppsloan.org/publications/StupidSH36.pdf
40250	 */
40251
40252	// 3-band SH defined by 9 coefficients
40253
40254	function SphericalHarmonics3() {
40255
40256		this.coefficients = [];
40257
40258		for ( var i = 0; i < 9; i ++ ) {
40259
40260			this.coefficients.push( new Vector3() );
40261
40262		}
40263
40264	}
40265
40266	Object.assign( SphericalHarmonics3.prototype, {
40267
40268		isSphericalHarmonics3: true,
40269
40270		set: function ( coefficients ) {
40271
40272			for ( var i = 0; i < 9; i ++ ) {
40273
40274				this.coefficients[ i ].copy( coefficients[ i ] );
40275
40276			}
40277
40278			return this;
40279
40280		},
40281
40282		zero: function () {
40283
40284			for ( var i = 0; i < 9; i ++ ) {
40285
40286				this.coefficients[ i ].set( 0, 0, 0 );
40287
40288			}
40289
40290			return this;
40291
40292		},
40293
40294		// get the radiance in the direction of the normal
40295		// target is a Vector3
40296		getAt: function ( normal, target ) {
40297
40298			// normal is assumed to be unit length
40299
40300			var x = normal.x, y = normal.y, z = normal.z;
40301
40302			var coeff = this.coefficients;
40303
40304			// band 0
40305			target.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 );
40306
40307			// band 1
40308			target.addScaledVector( coeff[ 1 ], 0.488603 * y );
40309			target.addScaledVector( coeff[ 2 ], 0.488603 * z );
40310			target.addScaledVector( coeff[ 3 ], 0.488603 * x );
40311
40312			// band 2
40313			target.addScaledVector( coeff[ 4 ], 1.092548 * ( x * y ) );
40314			target.addScaledVector( coeff[ 5 ], 1.092548 * ( y * z ) );
40315			target.addScaledVector( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) );
40316			target.addScaledVector( coeff[ 7 ], 1.092548 * ( x * z ) );
40317			target.addScaledVector( coeff[ 8 ], 0.546274 * ( x * x - y * y ) );
40318
40319			return target;
40320
40321		},
40322
40323		// get the irradiance (radiance convolved with cosine lobe) in the direction of the normal
40324		// target is a Vector3
40325		// https://graphics.stanford.edu/papers/envmap/envmap.pdf
40326		getIrradianceAt: function ( normal, target ) {
40327
40328			// normal is assumed to be unit length
40329
40330			var x = normal.x, y = normal.y, z = normal.z;
40331
40332			var coeff = this.coefficients;
40333
40334			// band 0
40335			target.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 ); // π * 0.282095
40336
40337			// band 1
40338			target.addScaledVector( coeff[ 1 ], 2.0 * 0.511664 * y ); // ( 2 * π / 3 ) * 0.488603
40339			target.addScaledVector( coeff[ 2 ], 2.0 * 0.511664 * z );
40340			target.addScaledVector( coeff[ 3 ], 2.0 * 0.511664 * x );
40341
40342			// band 2
40343			target.addScaledVector( coeff[ 4 ], 2.0 * 0.429043 * x * y ); // ( π / 4 ) * 1.092548
40344			target.addScaledVector( coeff[ 5 ], 2.0 * 0.429043 * y * z );
40345			target.addScaledVector( coeff[ 6 ], 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3
40346			target.addScaledVector( coeff[ 7 ], 2.0 * 0.429043 * x * z );
40347			target.addScaledVector( coeff[ 8 ], 0.429043 * ( x * x - y * y ) ); // ( π / 4 ) * 0.546274
40348
40349			return target;
40350
40351		},
40352
40353		add: function ( sh ) {
40354
40355			for ( var i = 0; i < 9; i ++ ) {
40356
40357				this.coefficients[ i ].add( sh.coefficients[ i ] );
40358
40359			}
40360
40361			return this;
40362
40363		},
40364
40365		addScaledSH: function ( sh, s ) {
40366
40367			for ( var i = 0; i < 9; i ++ ) {
40368
40369				this.coefficients[ i ].addScaledVector( sh.coefficients[ i ], s );
40370
40371			}
40372
40373			return this;
40374
40375		},
40376
40377		scale: function ( s ) {
40378
40379			for ( var i = 0; i < 9; i ++ ) {
40380
40381				this.coefficients[ i ].multiplyScalar( s );
40382
40383			}
40384
40385			return this;
40386
40387		},
40388
40389		lerp: function ( sh, alpha ) {
40390
40391			for ( var i = 0; i < 9; i ++ ) {
40392
40393				this.coefficients[ i ].lerp( sh.coefficients[ i ], alpha );
40394
40395			}
40396
40397			return this;
40398
40399		},
40400
40401		equals: function ( sh ) {
40402
40403			for ( var i = 0; i < 9; i ++ ) {
40404
40405				if ( ! this.coefficients[ i ].equals( sh.coefficients[ i ] ) ) {
40406
40407					return false;
40408
40409				}
40410
40411			}
40412
40413			return true;
40414
40415		},
40416
40417		copy: function ( sh ) {
40418
40419			return this.set( sh.coefficients );
40420
40421		},
40422
40423		clone: function () {
40424
40425			return new this.constructor().copy( this );
40426
40427		},
40428
40429		fromArray: function ( array, offset ) {
40430
40431			if ( offset === undefined ) { offset = 0; }
40432
40433			var coefficients = this.coefficients;
40434
40435			for ( var i = 0; i < 9; i ++ ) {
40436
40437				coefficients[ i ].fromArray( array, offset + ( i * 3 ) );
40438
40439			}
40440
40441			return this;
40442
40443		},
40444
40445		toArray: function ( array, offset ) {
40446
40447			if ( array === undefined ) { array = []; }
40448			if ( offset === undefined ) { offset = 0; }
40449
40450			var coefficients = this.coefficients;
40451
40452			for ( var i = 0; i < 9; i ++ ) {
40453
40454				coefficients[ i ].toArray( array, offset + ( i * 3 ) );
40455
40456			}
40457
40458			return array;
40459
40460		}
40461
40462	} );
40463
40464	Object.assign( SphericalHarmonics3, {
40465
40466		// evaluate the basis functions
40467		// shBasis is an Array[ 9 ]
40468		getBasisAt: function ( normal, shBasis ) {
40469
40470			// normal is assumed to be unit length
40471
40472			var x = normal.x, y = normal.y, z = normal.z;
40473
40474			// band 0
40475			shBasis[ 0 ] = 0.282095;
40476
40477			// band 1
40478			shBasis[ 1 ] = 0.488603 * y;
40479			shBasis[ 2 ] = 0.488603 * z;
40480			shBasis[ 3 ] = 0.488603 * x;
40481
40482			// band 2
40483			shBasis[ 4 ] = 1.092548 * x * y;
40484			shBasis[ 5 ] = 1.092548 * y * z;
40485			shBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 );
40486			shBasis[ 7 ] = 1.092548 * x * z;
40487			shBasis[ 8 ] = 0.546274 * ( x * x - y * y );
40488
40489		}
40490
40491	} );
40492
40493	/**
40494	 * @author WestLangley / http://github.com/WestLangley
40495	 *
40496	 * A LightProbe is a source of indirect-diffuse light
40497	 */
40498
40499	function LightProbe( sh, intensity ) {
40500
40501		Light.call( this, undefined, intensity );
40502
40503		this.type = 'LightProbe';
40504
40505		this.sh = ( sh !== undefined ) ? sh : new SphericalHarmonics3();
40506
40507	}
40508
40509	LightProbe.prototype = Object.assign( Object.create( Light.prototype ), {
40510
40511		constructor: LightProbe,
40512
40513		isLightProbe: true,
40514
40515		copy: function ( source ) {
40516
40517			Light.prototype.copy.call( this, source );
40518
40519			this.sh.copy( source.sh );
40520
40521			return this;
40522
40523		},
40524
40525		fromJSON: function ( json ) {
40526
40527			this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON();
40528			this.sh.fromArray( json.sh );
40529
40530			return this;
40531
40532		},
40533
40534		toJSON: function ( meta ) {
40535
40536			var data = Light.prototype.toJSON.call( this, meta );
40537
40538			data.object.sh = this.sh.toArray();
40539
40540			return data;
40541
40542		}
40543
40544	} );
40545
40546	/**
40547	 * @author mrdoob / http://mrdoob.com/
40548	 */
40549
40550	function MaterialLoader( manager ) {
40551
40552		Loader.call( this, manager );
40553
40554		this.textures = {};
40555
40556	}
40557
40558	MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
40559
40560		constructor: MaterialLoader,
40561
40562		load: function ( url, onLoad, onProgress, onError ) {
40563
40564			var scope = this;
40565
40566			var loader = new FileLoader( scope.manager );
40567			loader.setPath( scope.path );
40568			loader.load( url, function ( text ) {
40569
40570				try {
40571
40572					onLoad( scope.parse( JSON.parse( text ) ) );
40573
40574				} catch ( e ) {
40575
40576					if ( onError ) {
40577
40578						onError( e );
40579
40580					} else {
40581
40582						console.error( e );
40583
40584					}
40585
40586					scope.manager.itemError( url );
40587
40588				}
40589
40590			}, onProgress, onError );
40591
40592		},
40593
40594		parse: function ( json ) {
40595
40596			var textures = this.textures;
40597
40598			function getTexture( name ) {
40599
40600				if ( textures[ name ] === undefined ) {
40601
40602					console.warn( 'THREE.MaterialLoader: Undefined texture', name );
40603
40604				}
40605
40606				return textures[ name ];
40607
40608			}
40609
40610			var material = new Materials[ json.type ]();
40611
40612			if ( json.uuid !== undefined ) { material.uuid = json.uuid; }
40613			if ( json.name !== undefined ) { material.name = json.name; }
40614			if ( json.color !== undefined ) { material.color.setHex( json.color ); }
40615			if ( json.roughness !== undefined ) { material.roughness = json.roughness; }
40616			if ( json.metalness !== undefined ) { material.metalness = json.metalness; }
40617			if ( json.sheen !== undefined ) { material.sheen = new Color().setHex( json.sheen ); }
40618			if ( json.emissive !== undefined ) { material.emissive.setHex( json.emissive ); }
40619			if ( json.specular !== undefined ) { material.specular.setHex( json.specular ); }
40620			if ( json.shininess !== undefined ) { material.shininess = json.shininess; }
40621			if ( json.clearcoat !== undefined ) { material.clearcoat = json.clearcoat; }
40622			if ( json.clearcoatRoughness !== undefined ) { material.clearcoatRoughness = json.clearcoatRoughness; }
40623			if ( json.fog !== undefined ) { material.fog = json.fog; }
40624			if ( json.flatShading !== undefined ) { material.flatShading = json.flatShading; }
40625			if ( json.blending !== undefined ) { material.blending = json.blending; }
40626			if ( json.combine !== undefined ) { material.combine = json.combine; }
40627			if ( json.side !== undefined ) { material.side = json.side; }
40628			if ( json.opacity !== undefined ) { material.opacity = json.opacity; }
40629			if ( json.transparent !== undefined ) { material.transparent = json.transparent; }
40630			if ( json.alphaTest !== undefined ) { material.alphaTest = json.alphaTest; }
40631			if ( json.depthTest !== undefined ) { material.depthTest = json.depthTest; }
40632			if ( json.depthWrite !== undefined ) { material.depthWrite = json.depthWrite; }
40633			if ( json.colorWrite !== undefined ) { material.colorWrite = json.colorWrite; }
40634
40635			if ( json.stencilWrite !== undefined ) { material.stencilWrite = json.stencilWrite; }
40636			if ( json.stencilWriteMask !== undefined ) { material.stencilWriteMask = json.stencilWriteMask; }
40637			if ( json.stencilFunc !== undefined ) { material.stencilFunc = json.stencilFunc; }
40638			if ( json.stencilRef !== undefined ) { material.stencilRef = json.stencilRef; }
40639			if ( json.stencilFuncMask !== undefined ) { material.stencilFuncMask = json.stencilFuncMask; }
40640			if ( json.stencilFail !== undefined ) { material.stencilFail = json.stencilFail; }
40641			if ( json.stencilZFail !== undefined ) { material.stencilZFail = json.stencilZFail; }
40642			if ( json.stencilZPass !== undefined ) { material.stencilZPass = json.stencilZPass; }
40643
40644			if ( json.wireframe !== undefined ) { material.wireframe = json.wireframe; }
40645			if ( json.wireframeLinewidth !== undefined ) { material.wireframeLinewidth = json.wireframeLinewidth; }
40646			if ( json.wireframeLinecap !== undefined ) { material.wireframeLinecap = json.wireframeLinecap; }
40647			if ( json.wireframeLinejoin !== undefined ) { material.wireframeLinejoin = json.wireframeLinejoin; }
40648
40649			if ( json.rotation !== undefined ) { material.rotation = json.rotation; }
40650
40651			if ( json.linewidth !== 1 ) { material.linewidth = json.linewidth; }
40652			if ( json.dashSize !== undefined ) { material.dashSize = json.dashSize; }
40653			if ( json.gapSize !== undefined ) { material.gapSize = json.gapSize; }
40654			if ( json.scale !== undefined ) { material.scale = json.scale; }
40655
40656			if ( json.polygonOffset !== undefined ) { material.polygonOffset = json.polygonOffset; }
40657			if ( json.polygonOffsetFactor !== undefined ) { material.polygonOffsetFactor = json.polygonOffsetFactor; }
40658			if ( json.polygonOffsetUnits !== undefined ) { material.polygonOffsetUnits = json.polygonOffsetUnits; }
40659
40660			if ( json.skinning !== undefined ) { material.skinning = json.skinning; }
40661			if ( json.morphTargets !== undefined ) { material.morphTargets = json.morphTargets; }
40662			if ( json.morphNormals !== undefined ) { material.morphNormals = json.morphNormals; }
40663			if ( json.dithering !== undefined ) { material.dithering = json.dithering; }
40664
40665			if ( json.vertexTangents !== undefined ) { material.vertexTangents = json.vertexTangents; }
40666
40667			if ( json.visible !== undefined ) { material.visible = json.visible; }
40668
40669			if ( json.toneMapped !== undefined ) { material.toneMapped = json.toneMapped; }
40670
40671			if ( json.userData !== undefined ) { material.userData = json.userData; }
40672
40673			if ( json.vertexColors !== undefined ) {
40674
40675				if ( typeof json.vertexColors === 'number' ) {
40676
40677					material.vertexColors = ( json.vertexColors > 0 ) ? true : false;
40678
40679				} else {
40680
40681					material.vertexColors = json.vertexColors;
40682
40683				}
40684
40685			}
40686
40687			// Shader Material
40688
40689			if ( json.uniforms !== undefined ) {
40690
40691				for ( var name in json.uniforms ) {
40692
40693					var uniform = json.uniforms[ name ];
40694
40695					material.uniforms[ name ] = {};
40696
40697					switch ( uniform.type ) {
40698
40699						case 't':
40700							material.uniforms[ name ].value = getTexture( uniform.value );
40701							break;
40702
40703						case 'c':
40704							material.uniforms[ name ].value = new Color().setHex( uniform.value );
40705							break;
40706
40707						case 'v2':
40708							material.uniforms[ name ].value = new Vector2().fromArray( uniform.value );
40709							break;
40710
40711						case 'v3':
40712							material.uniforms[ name ].value = new Vector3().fromArray( uniform.value );
40713							break;
40714
40715						case 'v4':
40716							material.uniforms[ name ].value = new Vector4().fromArray( uniform.value );
40717							break;
40718
40719						case 'm3':
40720							material.uniforms[ name ].value = new Matrix3().fromArray( uniform.value );
40721
40722						case 'm4':
40723							material.uniforms[ name ].value = new Matrix4().fromArray( uniform.value );
40724							break;
40725
40726						default:
40727							material.uniforms[ name ].value = uniform.value;
40728
40729					}
40730
40731				}
40732
40733			}
40734
40735			if ( json.defines !== undefined ) { material.defines = json.defines; }
40736			if ( json.vertexShader !== undefined ) { material.vertexShader = json.vertexShader; }
40737			if ( json.fragmentShader !== undefined ) { material.fragmentShader = json.fragmentShader; }
40738
40739			if ( json.extensions !== undefined ) {
40740
40741				for ( var key in json.extensions ) {
40742
40743					material.extensions[ key ] = json.extensions[ key ];
40744
40745				}
40746
40747			}
40748
40749			// Deprecated
40750
40751			if ( json.shading !== undefined ) { material.flatShading = json.shading === 1; } // THREE.FlatShading
40752
40753			// for PointsMaterial
40754
40755			if ( json.size !== undefined ) { material.size = json.size; }
40756			if ( json.sizeAttenuation !== undefined ) { material.sizeAttenuation = json.sizeAttenuation; }
40757
40758			// maps
40759
40760			if ( json.map !== undefined ) { material.map = getTexture( json.map ); }
40761			if ( json.matcap !== undefined ) { material.matcap = getTexture( json.matcap ); }
40762
40763			if ( json.alphaMap !== undefined ) { material.alphaMap = getTexture( json.alphaMap ); }
40764
40765			if ( json.bumpMap !== undefined ) { material.bumpMap = getTexture( json.bumpMap ); }
40766			if ( json.bumpScale !== undefined ) { material.bumpScale = json.bumpScale; }
40767
40768			if ( json.normalMap !== undefined ) { material.normalMap = getTexture( json.normalMap ); }
40769			if ( json.normalMapType !== undefined ) { material.normalMapType = json.normalMapType; }
40770			if ( json.normalScale !== undefined ) {
40771
40772				var normalScale = json.normalScale;
40773
40774				if ( Array.isArray( normalScale ) === false ) {
40775
40776					// Blender exporter used to export a scalar. See #7459
40777
40778					normalScale = [ normalScale, normalScale ];
40779
40780				}
40781
40782				material.normalScale = new Vector2().fromArray( normalScale );
40783
40784			}
40785
40786			if ( json.displacementMap !== undefined ) { material.displacementMap = getTexture( json.displacementMap ); }
40787			if ( json.displacementScale !== undefined ) { material.displacementScale = json.displacementScale; }
40788			if ( json.displacementBias !== undefined ) { material.displacementBias = json.displacementBias; }
40789
40790			if ( json.roughnessMap !== undefined ) { material.roughnessMap = getTexture( json.roughnessMap ); }
40791			if ( json.metalnessMap !== undefined ) { material.metalnessMap = getTexture( json.metalnessMap ); }
40792
40793			if ( json.emissiveMap !== undefined ) { material.emissiveMap = getTexture( json.emissiveMap ); }
40794			if ( json.emissiveIntensity !== undefined ) { material.emissiveIntensity = json.emissiveIntensity; }
40795
40796			if ( json.specularMap !== undefined ) { material.specularMap = getTexture( json.specularMap ); }
40797
40798			if ( json.envMap !== undefined ) { material.envMap = getTexture( json.envMap ); }
40799			if ( json.envMapIntensity !== undefined ) { material.envMapIntensity = json.envMapIntensity; }
40800
40801			if ( json.reflectivity !== undefined ) { material.reflectivity = json.reflectivity; }
40802			if ( json.refractionRatio !== undefined ) { material.refractionRatio = json.refractionRatio; }
40803
40804			if ( json.lightMap !== undefined ) { material.lightMap = getTexture( json.lightMap ); }
40805			if ( json.lightMapIntensity !== undefined ) { material.lightMapIntensity = json.lightMapIntensity; }
40806
40807			if ( json.aoMap !== undefined ) { material.aoMap = getTexture( json.aoMap ); }
40808			if ( json.aoMapIntensity !== undefined ) { material.aoMapIntensity = json.aoMapIntensity; }
40809
40810			if ( json.gradientMap !== undefined ) { material.gradientMap = getTexture( json.gradientMap ); }
40811
40812			if ( json.clearcoatMap !== undefined ) { material.clearcoatMap = getTexture( json.clearcoatMap ); }
40813			if ( json.clearcoatRoughnessMap !== undefined ) { material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap ); }
40814			if ( json.clearcoatNormalMap !== undefined ) { material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); }
40815			if ( json.clearcoatNormalScale !== undefined ) { material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); }
40816
40817			return material;
40818
40819		},
40820
40821		setTextures: function ( value ) {
40822
40823			this.textures = value;
40824			return this;
40825
40826		}
40827
40828	} );
40829
40830	/**
40831	 * @author Don McCurdy / https://www.donmccurdy.com
40832	 */
40833
40834	var LoaderUtils = {
40835
40836		decodeText: function ( array ) {
40837
40838			if ( typeof TextDecoder !== 'undefined' ) {
40839
40840				return new TextDecoder().decode( array );
40841
40842			}
40843
40844			// Avoid the String.fromCharCode.apply(null, array) shortcut, which
40845			// throws a "maximum call stack size exceeded" error for large arrays.
40846
40847			var s = '';
40848
40849			for ( var i = 0, il = array.length; i < il; i ++ ) {
40850
40851				// Implicitly assumes little-endian.
40852				s += String.fromCharCode( array[ i ] );
40853
40854			}
40855
40856			try {
40857
40858				// merges multi-byte utf-8 characters.
40859
40860				return decodeURIComponent( escape( s ) );
40861
40862			} catch ( e ) { // see #16358
40863
40864				return s;
40865
40866			}
40867
40868		},
40869
40870		extractUrlBase: function ( url ) {
40871
40872			var index = url.lastIndexOf( '/' );
40873
40874			if ( index === - 1 ) { return './'; }
40875
40876			return url.substr( 0, index + 1 );
40877
40878		}
40879
40880	};
40881
40882	/**
40883	 * @author benaadams / https://twitter.com/ben_a_adams
40884	 */
40885
40886	function InstancedBufferGeometry() {
40887
40888		BufferGeometry.call( this );
40889
40890		this.type = 'InstancedBufferGeometry';
40891		this.instanceCount = Infinity;
40892
40893	}
40894
40895	InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), {
40896
40897		constructor: InstancedBufferGeometry,
40898
40899		isInstancedBufferGeometry: true,
40900
40901		copy: function ( source ) {
40902
40903			BufferGeometry.prototype.copy.call( this, source );
40904
40905			this.instanceCount = source.instanceCount;
40906
40907			return this;
40908
40909		},
40910
40911		clone: function () {
40912
40913			return new this.constructor().copy( this );
40914
40915		},
40916
40917		toJSON: function () {
40918
40919			var data = BufferGeometry.prototype.toJSON.call( this );
40920
40921			data.instanceCount = this.instanceCount;
40922
40923			data.isInstancedBufferGeometry = true;
40924
40925			return data;
40926
40927		}
40928
40929	} );
40930
40931	/**
40932	 * @author benaadams / https://twitter.com/ben_a_adams
40933	 */
40934
40935	function InstancedBufferAttribute( array, itemSize, normalized, meshPerAttribute ) {
40936
40937		if ( typeof ( normalized ) === 'number' ) {
40938
40939			meshPerAttribute = normalized;
40940
40941			normalized = false;
40942
40943			console.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' );
40944
40945		}
40946
40947		BufferAttribute.call( this, array, itemSize, normalized );
40948
40949		this.meshPerAttribute = meshPerAttribute || 1;
40950
40951	}
40952
40953	InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), {
40954
40955		constructor: InstancedBufferAttribute,
40956
40957		isInstancedBufferAttribute: true,
40958
40959		copy: function ( source ) {
40960
40961			BufferAttribute.prototype.copy.call( this, source );
40962
40963			this.meshPerAttribute = source.meshPerAttribute;
40964
40965			return this;
40966
40967		},
40968
40969		toJSON: function ()	{
40970
40971			var data = BufferAttribute.prototype.toJSON.call( this );
40972
40973			data.meshPerAttribute = this.meshPerAttribute;
40974
40975			data.isInstancedBufferAttribute = true;
40976
40977			return data;
40978
40979		}
40980
40981	} );
40982
40983	/**
40984	 * @author mrdoob / http://mrdoob.com/
40985	 */
40986
40987	function BufferGeometryLoader( manager ) {
40988
40989		Loader.call( this, manager );
40990
40991	}
40992
40993	BufferGeometryLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
40994
40995		constructor: BufferGeometryLoader,
40996
40997		load: function ( url, onLoad, onProgress, onError ) {
40998
40999			var scope = this;
41000
41001			var loader = new FileLoader( scope.manager );
41002			loader.setPath( scope.path );
41003			loader.load( url, function ( text ) {
41004
41005				try {
41006
41007					onLoad( scope.parse( JSON.parse( text ) ) );
41008
41009				} catch ( e ) {
41010
41011					if ( onError ) {
41012
41013						onError( e );
41014
41015					} else {
41016
41017						console.error( e );
41018
41019					}
41020
41021					scope.manager.itemError( url );
41022
41023				}
41024
41025			}, onProgress, onError );
41026
41027		},
41028
41029		parse: function ( json ) {
41030
41031			var interleavedBufferMap = {};
41032			var arrayBufferMap = {};
41033
41034			function getInterleavedBuffer( json, uuid ) {
41035
41036				if ( interleavedBufferMap[ uuid ] !== undefined ) { return interleavedBufferMap[ uuid ]; }
41037
41038				var interleavedBuffers = json.interleavedBuffers;
41039				var interleavedBuffer = interleavedBuffers[ uuid ];
41040
41041				var buffer = getArrayBuffer( json, interleavedBuffer.buffer );
41042
41043				var array = new TYPED_ARRAYS[ interleavedBuffer.type ]( buffer );
41044				var ib = new InterleavedBuffer( array, interleavedBuffer.stride );
41045				ib.uuid = interleavedBuffer.uuid;
41046
41047				interleavedBufferMap[ uuid ] = ib;
41048
41049				return ib;
41050
41051			}
41052
41053			function getArrayBuffer( json, uuid ) {
41054
41055				if ( arrayBufferMap[ uuid ] !== undefined ) { return arrayBufferMap[ uuid ]; }
41056
41057				var arrayBuffers = json.arrayBuffers;
41058				var arrayBuffer = arrayBuffers[ uuid ];
41059
41060				var ab = new Uint32Array( arrayBuffer ).buffer;
41061
41062				arrayBufferMap[ uuid ] = ab;
41063
41064				return ab;
41065
41066			}
41067
41068			var geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry();
41069
41070			var index = json.data.index;
41071
41072			if ( index !== undefined ) {
41073
41074				var typedArray = new TYPED_ARRAYS[ index.type ]( index.array );
41075				geometry.setIndex( new BufferAttribute( typedArray, 1 ) );
41076
41077			}
41078
41079			var attributes = json.data.attributes;
41080
41081			for ( var key in attributes ) {
41082
41083				var attribute = attributes[ key ];
41084				var bufferAttribute = (void 0);
41085
41086				if ( attribute.isInterleavedBufferAttribute ) {
41087
41088					var interleavedBuffer = getInterleavedBuffer( json.data, attribute.data );
41089					bufferAttribute = new InterleavedBufferAttribute( interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized );
41090
41091				} else {
41092
41093					var typedArray$1 = new TYPED_ARRAYS[ attribute.type ]( attribute.array );
41094					var bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute;
41095					bufferAttribute = new bufferAttributeConstr( typedArray$1, attribute.itemSize, attribute.normalized );
41096
41097				}
41098
41099				if ( attribute.name !== undefined ) { bufferAttribute.name = attribute.name; }
41100				geometry.setAttribute( key, bufferAttribute );
41101
41102			}
41103
41104			var morphAttributes = json.data.morphAttributes;
41105
41106			if ( morphAttributes ) {
41107
41108				for ( var key$1 in morphAttributes ) {
41109
41110					var attributeArray = morphAttributes[ key$1 ];
41111
41112					var array = [];
41113
41114					for ( var i = 0, il = attributeArray.length; i < il; i ++ ) {
41115
41116						var attribute$1 = attributeArray[ i ];
41117						var bufferAttribute$1 = (void 0);
41118
41119						if ( attribute$1.isInterleavedBufferAttribute ) {
41120
41121							var interleavedBuffer$1 = getInterleavedBuffer( json.data, attribute$1.data );
41122							bufferAttribute$1 = new InterleavedBufferAttribute( interleavedBuffer$1, attribute$1.itemSize, attribute$1.offset, attribute$1.normalized );
41123
41124						} else {
41125
41126							var typedArray$2 = new TYPED_ARRAYS[ attribute$1.type ]( attribute$1.array );
41127							bufferAttribute$1 = new BufferAttribute( typedArray$2, attribute$1.itemSize, attribute$1.normalized );
41128
41129						}
41130
41131						if ( attribute$1.name !== undefined ) { bufferAttribute$1.name = attribute$1.name; }
41132						array.push( bufferAttribute$1 );
41133
41134					}
41135
41136					geometry.morphAttributes[ key$1 ] = array;
41137
41138				}
41139
41140			}
41141
41142			var morphTargetsRelative = json.data.morphTargetsRelative;
41143
41144			if ( morphTargetsRelative ) {
41145
41146				geometry.morphTargetsRelative = true;
41147
41148			}
41149
41150			var groups = json.data.groups || json.data.drawcalls || json.data.offsets;
41151
41152			if ( groups !== undefined ) {
41153
41154				for ( var i$1 = 0, n = groups.length; i$1 !== n; ++ i$1 ) {
41155
41156					var group = groups[ i$1 ];
41157
41158					geometry.addGroup( group.start, group.count, group.materialIndex );
41159
41160				}
41161
41162			}
41163
41164			var boundingSphere = json.data.boundingSphere;
41165
41166			if ( boundingSphere !== undefined ) {
41167
41168				var center = new Vector3();
41169
41170				if ( boundingSphere.center !== undefined ) {
41171
41172					center.fromArray( boundingSphere.center );
41173
41174				}
41175
41176				geometry.boundingSphere = new Sphere( center, boundingSphere.radius );
41177
41178			}
41179
41180			if ( json.name ) { geometry.name = json.name; }
41181			if ( json.userData ) { geometry.userData = json.userData; }
41182
41183			return geometry;
41184
41185		}
41186
41187	} );
41188
41189	var TYPED_ARRAYS = {
41190		Int8Array: Int8Array,
41191		Uint8Array: Uint8Array,
41192		// Workaround for IE11 pre KB2929437. See #11440
41193		Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array,
41194		Int16Array: Int16Array,
41195		Uint16Array: Uint16Array,
41196		Int32Array: Int32Array,
41197		Uint32Array: Uint32Array,
41198		Float32Array: Float32Array,
41199		Float64Array: Float64Array
41200	};
41201
41202	/**
41203	 * @author mrdoob / http://mrdoob.com/
41204	 */
41205
41206	function ObjectLoader( manager ) {
41207
41208		Loader.call( this, manager );
41209
41210	}
41211
41212	ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
41213
41214		constructor: ObjectLoader,
41215
41216		load: function ( url, onLoad, onProgress, onError ) {
41217
41218			var scope = this;
41219
41220			var path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
41221			this.resourcePath = this.resourcePath || path;
41222
41223			var loader = new FileLoader( scope.manager );
41224			loader.setPath( this.path );
41225			loader.load( url, function ( text ) {
41226
41227				var json = null;
41228
41229				try {
41230
41231					json = JSON.parse( text );
41232
41233				} catch ( error ) {
41234
41235					if ( onError !== undefined ) { onError( error ); }
41236
41237					console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );
41238
41239					return;
41240
41241				}
41242
41243				var metadata = json.metadata;
41244
41245				if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {
41246
41247					console.error( 'THREE.ObjectLoader: Can\'t load ' + url );
41248					return;
41249
41250				}
41251
41252				scope.parse( json, onLoad );
41253
41254			}, onProgress, onError );
41255
41256		},
41257
41258		parse: function ( json, onLoad ) {
41259
41260			var shapes = this.parseShape( json.shapes );
41261			var geometries = this.parseGeometries( json.geometries, shapes );
41262
41263			var images = this.parseImages( json.images, function () {
41264
41265				if ( onLoad !== undefined ) { onLoad( object ); }
41266
41267			} );
41268
41269			var textures = this.parseTextures( json.textures, images );
41270			var materials = this.parseMaterials( json.materials, textures );
41271
41272			var object = this.parseObject( json.object, geometries, materials );
41273
41274			if ( json.animations ) {
41275
41276				object.animations = this.parseAnimations( json.animations );
41277
41278			}
41279
41280			if ( json.images === undefined || json.images.length === 0 ) {
41281
41282				if ( onLoad !== undefined ) { onLoad( object ); }
41283
41284			}
41285
41286			return object;
41287
41288		},
41289
41290		parseShape: function ( json ) {
41291
41292			var shapes = {};
41293
41294			if ( json !== undefined ) {
41295
41296				for ( var i = 0, l = json.length; i < l; i ++ ) {
41297
41298					var shape = new Shape().fromJSON( json[ i ] );
41299
41300					shapes[ shape.uuid ] = shape;
41301
41302				}
41303
41304			}
41305
41306			return shapes;
41307
41308		},
41309
41310		parseGeometries: function ( json, shapes ) {
41311
41312			var geometries = {};
41313			var geometryShapes;
41314
41315			if ( json !== undefined ) {
41316
41317				var bufferGeometryLoader = new BufferGeometryLoader();
41318
41319				for ( var i = 0, l = json.length; i < l; i ++ ) {
41320
41321					var geometry = (void 0);
41322					var data = json[ i ];
41323
41324					switch ( data.type ) {
41325
41326						case 'PlaneGeometry':
41327						case 'PlaneBufferGeometry':
41328
41329							geometry = new Geometries[ data.type ](
41330								data.width,
41331								data.height,
41332								data.widthSegments,
41333								data.heightSegments
41334							);
41335
41336							break;
41337
41338						case 'BoxGeometry':
41339						case 'BoxBufferGeometry':
41340						case 'CubeGeometry': // backwards compatible
41341
41342							geometry = new Geometries[ data.type ](
41343								data.width,
41344								data.height,
41345								data.depth,
41346								data.widthSegments,
41347								data.heightSegments,
41348								data.depthSegments
41349							);
41350
41351							break;
41352
41353						case 'CircleGeometry':
41354						case 'CircleBufferGeometry':
41355
41356							geometry = new Geometries[ data.type ](
41357								data.radius,
41358								data.segments,
41359								data.thetaStart,
41360								data.thetaLength
41361							);
41362
41363							break;
41364
41365						case 'CylinderGeometry':
41366						case 'CylinderBufferGeometry':
41367
41368							geometry = new Geometries[ data.type ](
41369								data.radiusTop,
41370								data.radiusBottom,
41371								data.height,
41372								data.radialSegments,
41373								data.heightSegments,
41374								data.openEnded,
41375								data.thetaStart,
41376								data.thetaLength
41377							);
41378
41379							break;
41380
41381						case 'ConeGeometry':
41382						case 'ConeBufferGeometry':
41383
41384							geometry = new Geometries[ data.type ](
41385								data.radius,
41386								data.height,
41387								data.radialSegments,
41388								data.heightSegments,
41389								data.openEnded,
41390								data.thetaStart,
41391								data.thetaLength
41392							);
41393
41394							break;
41395
41396						case 'SphereGeometry':
41397						case 'SphereBufferGeometry':
41398
41399							geometry = new Geometries[ data.type ](
41400								data.radius,
41401								data.widthSegments,
41402								data.heightSegments,
41403								data.phiStart,
41404								data.phiLength,
41405								data.thetaStart,
41406								data.thetaLength
41407							);
41408
41409							break;
41410
41411						case 'DodecahedronGeometry':
41412						case 'DodecahedronBufferGeometry':
41413						case 'IcosahedronGeometry':
41414						case 'IcosahedronBufferGeometry':
41415						case 'OctahedronGeometry':
41416						case 'OctahedronBufferGeometry':
41417						case 'TetrahedronGeometry':
41418						case 'TetrahedronBufferGeometry':
41419
41420							geometry = new Geometries[ data.type ](
41421								data.radius,
41422								data.detail
41423							);
41424
41425							break;
41426
41427						case 'RingGeometry':
41428						case 'RingBufferGeometry':
41429
41430							geometry = new Geometries[ data.type ](
41431								data.innerRadius,
41432								data.outerRadius,
41433								data.thetaSegments,
41434								data.phiSegments,
41435								data.thetaStart,
41436								data.thetaLength
41437							);
41438
41439							break;
41440
41441						case 'TorusGeometry':
41442						case 'TorusBufferGeometry':
41443
41444							geometry = new Geometries[ data.type ](
41445								data.radius,
41446								data.tube,
41447								data.radialSegments,
41448								data.tubularSegments,
41449								data.arc
41450							);
41451
41452							break;
41453
41454						case 'TorusKnotGeometry':
41455						case 'TorusKnotBufferGeometry':
41456
41457							geometry = new Geometries[ data.type ](
41458								data.radius,
41459								data.tube,
41460								data.tubularSegments,
41461								data.radialSegments,
41462								data.p,
41463								data.q
41464							);
41465
41466							break;
41467
41468						case 'TubeGeometry':
41469						case 'TubeBufferGeometry':
41470
41471							// This only works for built-in curves (e.g. CatmullRomCurve3).
41472							// User defined curves or instances of CurvePath will not be deserialized.
41473							geometry = new Geometries[ data.type ](
41474								new Curves[ data.path.type ]().fromJSON( data.path ),
41475								data.tubularSegments,
41476								data.radius,
41477								data.radialSegments,
41478								data.closed
41479							);
41480
41481							break;
41482
41483						case 'LatheGeometry':
41484						case 'LatheBufferGeometry':
41485
41486							geometry = new Geometries[ data.type ](
41487								data.points,
41488								data.segments,
41489								data.phiStart,
41490								data.phiLength
41491							);
41492
41493							break;
41494
41495						case 'PolyhedronGeometry':
41496						case 'PolyhedronBufferGeometry':
41497
41498							geometry = new Geometries[ data.type ](
41499								data.vertices,
41500								data.indices,
41501								data.radius,
41502								data.details
41503							);
41504
41505							break;
41506
41507						case 'ShapeGeometry':
41508						case 'ShapeBufferGeometry':
41509
41510							geometryShapes = [];
41511
41512							for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) {
41513
41514								var shape = shapes[ data.shapes[ j ] ];
41515
41516								geometryShapes.push( shape );
41517
41518							}
41519
41520							geometry = new Geometries[ data.type ](
41521								geometryShapes,
41522								data.curveSegments
41523							);
41524
41525							break;
41526
41527
41528						case 'ExtrudeGeometry':
41529						case 'ExtrudeBufferGeometry':
41530
41531							geometryShapes = [];
41532
41533							for ( var j$1 = 0, jl$1 = data.shapes.length; j$1 < jl$1; j$1 ++ ) {
41534
41535								var shape$1 = shapes[ data.shapes[ j$1 ] ];
41536
41537								geometryShapes.push( shape$1 );
41538
41539							}
41540
41541							var extrudePath = data.options.extrudePath;
41542
41543							if ( extrudePath !== undefined ) {
41544
41545								data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath );
41546
41547							}
41548
41549							geometry = new Geometries[ data.type ](
41550								geometryShapes,
41551								data.options
41552							);
41553
41554							break;
41555
41556						case 'BufferGeometry':
41557						case 'InstancedBufferGeometry':
41558
41559							geometry = bufferGeometryLoader.parse( data );
41560
41561							break;
41562
41563						case 'Geometry':
41564
41565							console.error( 'THREE.ObjectLoader: Loading "Geometry" is not supported anymore.' );
41566
41567							break;
41568
41569						default:
41570
41571							console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
41572
41573							continue;
41574
41575					}
41576
41577					geometry.uuid = data.uuid;
41578
41579					if ( data.name !== undefined ) { geometry.name = data.name; }
41580					if ( geometry.isBufferGeometry === true && data.userData !== undefined ) { geometry.userData = data.userData; }
41581
41582					geometries[ data.uuid ] = geometry;
41583
41584				}
41585
41586			}
41587
41588			return geometries;
41589
41590		},
41591
41592		parseMaterials: function ( json, textures ) {
41593
41594			var cache = {}; // MultiMaterial
41595			var materials = {};
41596
41597			if ( json !== undefined ) {
41598
41599				var loader = new MaterialLoader();
41600				loader.setTextures( textures );
41601
41602				for ( var i = 0, l = json.length; i < l; i ++ ) {
41603
41604					var data = json[ i ];
41605
41606					if ( data.type === 'MultiMaterial' ) {
41607
41608						// Deprecated
41609
41610						var array = [];
41611
41612						for ( var j = 0; j < data.materials.length; j ++ ) {
41613
41614							var material = data.materials[ j ];
41615
41616							if ( cache[ material.uuid ] === undefined ) {
41617
41618								cache[ material.uuid ] = loader.parse( material );
41619
41620							}
41621
41622							array.push( cache[ material.uuid ] );
41623
41624						}
41625
41626						materials[ data.uuid ] = array;
41627
41628					} else {
41629
41630						if ( cache[ data.uuid ] === undefined ) {
41631
41632							cache[ data.uuid ] = loader.parse( data );
41633
41634						}
41635
41636						materials[ data.uuid ] = cache[ data.uuid ];
41637
41638					}
41639
41640				}
41641
41642			}
41643
41644			return materials;
41645
41646		},
41647
41648		parseAnimations: function ( json ) {
41649
41650			var animations = [];
41651
41652			for ( var i = 0; i < json.length; i ++ ) {
41653
41654				var data = json[ i ];
41655
41656				var clip = AnimationClip.parse( data );
41657
41658				if ( data.uuid !== undefined ) { clip.uuid = data.uuid; }
41659
41660				animations.push( clip );
41661
41662			}
41663
41664			return animations;
41665
41666		},
41667
41668		parseImages: function ( json, onLoad ) {
41669
41670			var scope = this;
41671			var images = {};
41672
41673			var loader;
41674
41675			function loadImage( url ) {
41676
41677				scope.manager.itemStart( url );
41678
41679				return loader.load( url, function () {
41680
41681					scope.manager.itemEnd( url );
41682
41683				}, undefined, function () {
41684
41685					scope.manager.itemError( url );
41686					scope.manager.itemEnd( url );
41687
41688				} );
41689
41690			}
41691
41692			if ( json !== undefined && json.length > 0 ) {
41693
41694				var manager = new LoadingManager( onLoad );
41695
41696				loader = new ImageLoader( manager );
41697				loader.setCrossOrigin( this.crossOrigin );
41698
41699				for ( var i = 0, il = json.length; i < il; i ++ ) {
41700
41701					var image = json[ i ];
41702					var url = image.url;
41703
41704					if ( Array.isArray( url ) ) {
41705
41706						// load array of images e.g CubeTexture
41707
41708						images[ image.uuid ] = [];
41709
41710						for ( var j = 0, jl = url.length; j < jl; j ++ ) {
41711
41712							var currentUrl = url[ j ];
41713
41714							var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : 
41714scope.resourcePath + currentUrl;
41715
41716							images[ image.uuid ].push( loadImage( path ) );
41717
41718						}
41719
41720					} else {
41721
41722						// load single image
41723
41724						var path$1 = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.resourcePath + image.url;
41725
41726						images[ image.uuid ] = loadImage( path$1 );
41727
41728					}
41729
41730				}
41731
41732			}
41733
41734			return images;
41735
41736		},
41737
41738		parseTextures: function ( json, images ) {
41739
41740			function parseConstant( value, type ) {
41741
41742				if ( typeof value === 'number' ) { return value; }
41743
41744				console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
41745
41746				return type[ value ];
41747
41748			}
41749
41750			var textures = {};
41751
41752			if ( json !== undefined ) {
41753
41754				for ( var i = 0, l = json.length; i < l; i ++ ) {
41755
41756					var data = json[ i ];
41757
41758					if ( data.image === undefined ) {
41759
41760						console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
41761
41762					}
41763
41764					if ( images[ data.image ] === undefined ) {
41765
41766						console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
41767
41768					}
41769
41770					var texture = (void 0);
41771
41772					if ( Array.isArray( images[ data.image ] ) ) {
41773
41774						texture = new CubeTexture( images[ data.image ] );
41775
41776					} else {
41777
41778						texture = new Texture( images[ data.image ] );
41779
41780					}
41781
41782					texture.needsUpdate = true;
41783
41784					texture.uuid = data.uuid;
41785
41786					if ( data.name !== undefined ) { texture.name = data.name; }
41787
41788					if ( data.mapping !== undefined ) { texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); }
41789
41790					if ( data.offset !== undefined ) { texture.offset.fromArray( data.offset ); }
41791					if ( data.repeat !== undefined ) { texture.repeat.fromArray( data.repeat ); }
41792					if ( data.center !== undefined ) { texture.center.fromArray( data.center ); }
41793					if ( data.rotation !== undefined ) { texture.rotation = data.rotation; }
41794
41795					if ( data.wrap !== undefined ) {
41796
41797						texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
41798						texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );
41799
41800					}
41801
41802					if ( data.format !== undefined ) { texture.format = data.format; }
41803					if ( data.type !== undefined ) { texture.type = data.type; }
41804					if ( data.encoding !== undefined ) { texture.encoding = data.encoding; }
41805
41806					if ( data.minFilter !== undefined ) { texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); }
41807					if ( data.magFilter !== undefined ) { texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); }
41808					if ( data.anisotropy !== undefined ) { texture.anisotropy = data.anisotropy; }
41809
41810					if ( data.flipY !== undefined ) { texture.flipY = data.flipY; }
41811
41812					if ( data.premultiplyAlpha !== undefined ) { texture.premultiplyAlpha = data.premultiplyAlpha; }
41813					if ( data.unpackAlignment !== undefined ) { texture.unpackAlignment = data.unpackAlignment; }
41814
41815					textures[ data.uuid ] = texture;
41816
41817				}
41818
41819			}
41820
41821			return textures;
41822
41823		},
41824
41825		parseObject: function ( data, geometries, materials ) {
41826
41827			var object;
41828
41829			function getGeometry( name ) {
41830
41831				if ( geometries[ name ] === undefined ) {
41832
41833					console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
41834
41835				}
41836
41837				return geometries[ name ];
41838
41839			}
41840
41841			function getMaterial( name ) {
41842
41843				if ( name === undefined ) { return undefined; }
41844
41845				if ( Array.isArray( name ) ) {
41846
41847					var array = [];
41848
41849					for ( var i = 0, l = name.length; i < l; i ++ ) {
41850
41851						var uuid = name[ i ];
41852
41853						if ( materials[ uuid ] === undefined ) {
41854
41855							console.warn( 'THREE.ObjectLoader: Undefined material', uuid );
41856
41857						}
41858
41859						array.push( materials[ uuid ] );
41860
41861					}
41862
41863					return array;
41864
41865				}
41866
41867				if ( materials[ name ] === undefined ) {
41868
41869					console.warn( 'THREE.ObjectLoader: Undefined material', name );
41870
41871				}
41872
41873				return materials[ name ];
41874
41875			}
41876
41877			var geometry, material;
41878
41879			switch ( data.type ) {
41880
41881				case 'Scene':
41882
41883					object = new Scene();
41884
41885					if ( data.background !== undefined ) {
41886
41887						if ( Number.isInteger( data.background ) ) {
41888
41889							object.background = new Color( data.background );
41890
41891						}
41892
41893					}
41894
41895					if ( data.fog !== undefined ) {
41896
41897						if ( data.fog.type === 'Fog' ) {
41898
41899							object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );
41900
41901						} else if ( data.fog.type === 'FogExp2' ) {
41902
41903							object.fog = new FogExp2( data.fog.color, data.fog.density );
41904
41905						}
41906
41907					}
41908
41909					break;
41910
41911				case 'PerspectiveCamera':
41912
41913					object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
41914
41915					if ( data.focus !== undefined ) { object.focus = data.focus; }
41916					if ( data.zoom !== undefined ) { object.zoom = data.zoom; }
41917					if ( data.filmGauge !== undefined ) { object.filmGauge = data.filmGauge; }
41918					if ( data.filmOffset !== undefined ) { object.filmOffset = data.filmOffset; }
41919					if ( data.view !== undefined ) { object.view = Object.assign( {}, data.view ); }
41920
41921					break;
41922
41923				case 'OrthographicCamera':
41924
41925					object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
41926
41927					if ( data.zoom !== undefined ) { object.zoom = data.zoom; }
41928					if ( data.view !== undefined ) { object.view = Object.assign( {}, data.view ); }
41929
41930					break;
41931
41932				case 'AmbientLight':
41933
41934					object = new AmbientLight( data.color, data.intensity );
41935
41936					break;
41937
41938				case 'DirectionalLight':
41939
41940					object = new DirectionalLight( data.color, data.intensity );
41941
41942					break;
41943
41944				case 'PointLight':
41945
41946					object = new PointLight( data.color, data.intensity, data.distance, data.decay );
41947
41948					break;
41949
41950				case 'RectAreaLight':
41951
41952					object = new RectAreaLight( data.color, data.intensity, data.width, data.height );
41953
41954					break;
41955
41956				case 'SpotLight':
41957
41958					object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
41959
41960					break;
41961
41962				case 'HemisphereLight':
41963
41964					object = new HemisphereLight( data.color, data.groundColor, data.intensity );
41965
41966					break;
41967
41968				case 'LightProbe':
41969
41970					object = new LightProbe().fromJSON( data );
41971
41972					break;
41973
41974				case 'SkinnedMesh':
41975
41976					console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
41977
41978				case 'Mesh':
41979
41980					geometry = getGeometry( data.geometry );
41981					material = getMaterial( data.material );
41982
41983					object = new Mesh( geometry, material );
41984
41985					break;
41986
41987				case 'InstancedMesh':
41988
41989					geometry = getGeometry( data.geometry );
41990					material = getMaterial( data.material );
41991					var count = data.count;
41992					var instanceMatrix = data.instanceMatrix;
41993
41994					object = new InstancedMesh( geometry, material, count );
41995					object.instanceMatrix = new BufferAttribute( new Float32Array( instanceMatrix.array ), 16 );
41996
41997					break;
41998
41999				case 'LOD':
42000
42001					object = new LOD();
42002
42003					break;
42004
42005				case 'Line':
42006
42007					object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
42008
42009					break;
42010
42011				case 'LineLoop':
42012
42013					object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );
42014
42015					break;
42016
42017				case 'LineSegments':
42018
42019					object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );
42020
42021					break;
42022
42023				case 'PointCloud':
42024				case 'Points':
42025
42026					object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );
42027
42028					break;
42029
42030				case 'Sprite':
42031
42032					object = new Sprite( getMaterial( data.material ) );
42033
42034					break;
42035
42036				case 'Group':
42037
42038					object = new Group();
42039
42040					break;
42041
42042				default:
42043
42044					object = new Object3D();
42045
42046			}
42047
42048			object.uuid = data.uuid;
42049
42050			if ( data.name !== undefined ) { object.name = data.name; }
42051
42052			if ( data.matrix !== undefined ) {
42053
42054				object.matrix.fromArray( data.matrix );
42055
42056				if ( data.matrixAutoUpdate !== undefined ) { object.matrixAutoUpdate = data.matrixAutoUpdate; }
42057				if ( object.matrixAutoUpdate ) { object.matrix.decompose( object.position, object.quaternion, object.scale ); }
42058
42059			} else {
42060
42061				if ( data.position !== undefined ) { object.position.fromArray( data.position ); }
42062				if ( data.rotation !== undefined ) { object.rotation.fromArray( data.rotation ); }
42063				if ( data.quaternion !== undefined ) { object.quaternion.fromArray( data.quaternion ); }
42064				if ( data.scale !== undefined ) { object.scale.fromArray( data.scale ); }
42065
42066			}
42067
42068			if ( data.castShadow !== undefined ) { object.castShadow = data.castShadow; }
42069			if ( data.receiveShadow !== undefined ) { object.receiveShadow = data.receiveShadow; }
42070
42071			if ( data.shadow ) {
42072
42073				if ( data.shadow.bias !== undefined ) { object.shadow.bias = data.shadow.bias; }
42074				if ( data.shadow.normalBias !== undefined ) { object.shadow.normalBias = data.shadow.normalBias; }
42075				if ( data.shadow.radius !== undefined ) { object.shadow.radius = data.shadow.radius; }
42076				if ( data.shadow.mapSize !== undefined ) { object.shadow.mapSize.fromArray( data.shadow.mapSize ); }
42077				if ( data.shadow.camera !== undefined ) { object.shadow.camera = this.parseObject( data.shadow.camera ); }
42078
42079			}
42080
42081			if ( data.visible !== undefined ) { object.visible = data.visible; }
42082			if ( data.frustumCulled !== undefined ) { object.frustumCulled = data.frustumCulled; }
42083			if ( data.renderOrder !== undefined ) { object.renderOrder = data.renderOrder; }
42084			if ( data.userData !== undefined ) { object.userData = data.userData; }
42085			if ( data.layers !== undefined ) { object.layers.mask = data.layers; }
42086
42087			if ( data.children !== undefined ) {
42088
42089				var children = data.children;
42090
42091				for ( var i = 0; i < children.length; i ++ ) {
42092
42093					object.add( this.parseObject( children[ i ], geometries, materials ) );
42094
42095				}
42096
42097			}
42098
42099			if ( data.type === 'LOD' ) {
42100
42101				if ( data.autoUpdate !== undefined ) { object.autoUpdate = data.autoUpdate; }
42102
42103				var levels = data.levels;
42104
42105				for ( var l = 0; l < levels.length; l ++ ) {
42106
42107					var level = levels[ l ];
42108					var child = object.getObjectByProperty( 'uuid', level.object );
42109
42110					if ( child !== undefined ) {
42111
42112						object.addLevel( child, level.distance );
42113
42114					}
42115
42116				}
42117
42118			}
42119
42120			return object;
42121
42122		}
42123
42124	} );
42125
42126	var TEXTURE_MAPPING = {
42127		UVMapping: UVMapping,
42128		CubeReflectionMapping: CubeReflectionMapping,
42129		CubeRefractionMapping: CubeRefractionMapping,
42130		EquirectangularReflectionMapping: EquirectangularReflectionMapping,
42131		EquirectangularRefractionMapping: EquirectangularRefractionMapping,
42132		CubeUVReflectionMapping: CubeUVReflectionMapping,
42133		CubeUVRefractionMapping: CubeUVRefractionMapping
42134	};
42135
42136	var TEXTURE_WRAPPING = {
42137		RepeatWrapping: RepeatWrapping,
42138		ClampToEdgeWrapping: ClampToEdgeWrapping,
42139		MirroredRepeatWrapping: MirroredRepeatWrapping
42140	};
42141
42142	var TEXTURE_FILTER = {
42143		NearestFilter: NearestFilter,
42144		NearestMipmapNearestFilter: NearestMipmapNearestFilter,
42145		NearestMipmapLinearFilter: NearestMipmapLinearFilter,
42146		LinearFilter: LinearFilter,
42147		LinearMipmapNearestFilter: LinearMipmapNearestFilter,
42148		LinearMipmapLinearFilter: LinearMipmapLinearFilter
42149	};
42150
42151	/**
42152	 * @author thespite / http://clicktorelease.com/
42153	 */
42154
42155
42156	function ImageBitmapLoader( manager ) {
42157
42158		if ( typeof createImageBitmap === 'undefined' ) {
42159
42160			console.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' );
42161
42162		}
42163
42164		if ( typeof fetch === 'undefined' ) {
42165
42166			console.warn( 'THREE.ImageBitmapLoader: fetch() not supported.' );
42167
42168		}
42169
42170		Loader.call( this, manager );
42171
42172		this.options = { premultiplyAlpha: 'none' };
42173
42174	}
42175
42176	ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
42177
42178		constructor: ImageBitmapLoader,
42179
42180		setOptions: function setOptions( options ) {
42181
42182			this.options = options;
42183
42184			return this;
42185
42186		},
42187
42188		load: function ( url, onLoad, onProgress, onError ) {
42189
42190			if ( url === undefined ) { url = ''; }
42191
42192			if ( this.path !== undefined ) { url = this.path + url; }
42193
42194			url = this.manager.resolveURL( url );
42195
42196			var scope = this;
42197
42198			var cached = Cache.get( url );
42199
42200			if ( cached !== undefined ) {
42201
42202				scope.manager.itemStart( url );
42203
42204				setTimeout( function () {
42205
42206					if ( onLoad ) { onLoad( cached ); }
42207
42208					scope.manager.itemEnd( url );
42209
42210				}, 0 );
42211
42212				return cached;
42213
42214			}
42215
42216			fetch( url ).then( function ( res ) {
42217
42218				return res.blob();
42219
42220			} ).then( function ( blob ) {
42221
42222				return createImageBitmap( blob, scope.options );
42223
42224			} ).then( function ( imageBitmap ) {
42225
42226				Cache.add( url, imageBitmap );
42227
42228				if ( onLoad ) { onLoad( imageBitmap ); }
42229
42230				scope.manager.itemEnd( url );
42231
42232			} ).catch( function ( e ) {
42233
42234				if ( onError ) { onError( e ); }
42235
42236				scope.manager.itemError( url );
42237				scope.manager.itemEnd( url );
42238
42239			} );
42240
42241			scope.manager.itemStart( url );
42242
42243		}
42244
42245	} );
42246
42247	/**
42248	 * @author zz85 / http://www.lab4games.net/zz85/blog
42249	 * minimal class for proxing functions to Path. Replaces old "extractSubpaths()"
42250	 **/
42251
42252	function ShapePath() {
42253
42254		this.type = 'ShapePath';
42255
42256		this.color = new Color();
42257
42258		this.subPaths = [];
42259		this.currentPath = null;
42260
42261	}
42262
42263	Object.assign( ShapePath.prototype, {
42264
42265		moveTo: function ( x, y ) {
42266
42267			this.currentPath = new Path();
42268			this.subPaths.push( this.currentPath );
42269			this.currentPath.moveTo( x, y );
42270
42271			return this;
42272
42273		},
42274
42275		lineTo: function ( x, y ) {
42276
42277			this.currentPath.lineTo( x, y );
42278
42279			return this;
42280
42281		},
42282
42283		quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
42284
42285			this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );
42286
42287			return this;
42288
42289		},
42290
42291		bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
42292
42293			this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );
42294
42295			return this;
42296
42297		},
42298
42299		splineThru: function ( pts ) {
42300
42301			this.currentPath.splineThru( pts );
42302
42303			return this;
42304
42305		},
42306
42307		toShapes: function ( isCCW, noHoles ) {
42308
42309			function toShapesNoHoles( inSubpaths ) {
42310
42311				var shapes = [];
42312
42313				for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {
42314
42315					var tmpPath = inSubpaths[ i ];
42316
42317					var tmpShape = new Shape();
42318					tmpShape.curves = tmpPath.curves;
42319
42320					shapes.push( tmpShape );
42321
42322				}
42323
42324				return shapes;
42325
42326			}
42327
42328			function isPointInsidePolygon( inPt, inPolygon ) {
42329
42330				var polyLen = inPolygon.length;
42331
42332				// inPt on polygon contour => immediate success    or
42333				// toggling of inside/outside at every single! intersection point of an edge
42334				//  with the horizontal line through inPt, left of inPt
42335				//  not counting lowerY endpoints of edges and whole edges on that line
42336				var inside = false;
42337				for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
42338
42339					var edgeLowPt = inPolygon[ p ];
42340					var edgeHighPt = inPolygon[ q ];
42341
42342					var edgeDx = edgeHighPt.x - edgeLowPt.x;
42343					var edgeDy = edgeHighPt.y - edgeLowPt.y;
42344
42345					if ( Math.abs( edgeDy ) > Number.EPSILON ) {
42346
42347						// not parallel
42348						if ( edgeDy < 0 ) {
42349
42350							edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
42351							edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
42352
42353						}
42354
42355						if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) 		{ continue; }
42356
42357						if ( inPt.y === edgeLowPt.y ) {
42358
42359							if ( inPt.x === edgeLowPt.x )		{ return	true; }		// inPt is on contour ?
42360							// continue;				// no intersection or edgeLowPt => doesn't count !!!
42361
42362						} else {
42363
42364							var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
42365							if ( perpEdge === 0 )				{ return	true; }		// inPt is on contour ?
42366							if ( perpEdge < 0 ) 				{ continue; }
42367							inside = ! inside;		// true intersection left of inPt
42368
42369						}
42370
42371					} else {
42372
42373						// parallel or collinear
42374						if ( inPt.y !== edgeLowPt.y ) 		{ continue; }			// parallel
42375						// edge lies on the same horizontal line as inPt
42376						if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
42377							 ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) )		{ return	true; }	// inPt: Point on contour !
42378						// continue;
42379
42380					}
42381
42382				}
42383
42384				return	inside;
42385
42386			}
42387
42388			var isClockWise = ShapeUtils.isClockWise;
42389
42390			var subPaths = this.subPaths;
42391			if ( subPaths.length === 0 ) { return []; }
42392
42393			if ( noHoles === true )	{ return	toShapesNoHoles( subPaths ); }
42394
42395
42396			var solid, tmpPath, tmpShape, shapes = [];
42397
42398			if ( subPaths.length === 1 ) {
42399
42400				tmpPath = subPaths[ 0 ];
42401				tmpShape = new Shape();
42402				tmpShape.curves = tmpPath.curves;
42403				shapes.push( tmpShape );
42404				return shapes;
42405
42406			}
42407
42408			var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
42409			holesFirst = isCCW ? ! holesFirst : holesFirst;
42410
42411			// console.log("Holes first", holesFirst);
42412
42413			var betterShapeHoles = [];
42414			var newShapes = [];
42415			var newShapeHoles = [];
42416			var mainIdx = 0;
42417			var tmpPoints;
42418
42419			newShapes[ mainIdx ] = undefined;
42420			newShapeHoles[ mainIdx ] = [];
42421
42422			for ( var i = 0, l = subPaths.length; i < l; i ++ ) {
42423
42424				tmpPath = subPaths[ i ];
42425				tmpPoints = tmpPath.getPoints();
42426				solid = isClockWise( tmpPoints );
42427				solid = isCCW ? ! solid : solid;
42428
42429				if ( solid ) {
42430
42431					if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) )	{ mainIdx ++; }
42432
42433					newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };
42434					newShapes[ mainIdx ].s.curves = tmpPath.curves;
42435
42436					if ( holesFirst )	{ mainIdx ++; }
42437					newShapeHoles[ mainIdx ] = [];
42438
42439					//console.log('cw', i);
42440
42441				} else {
42442
42443					newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
42444
42445					//console.log('ccw', i);
42446
42447				}
42448
42449			}
42450
42451			// only Holes? -> probably all Shapes with wrong orientation
42452			if ( ! newShapes[ 0 ] )	{ return	toShapesNoHoles( subPaths ); }
42453
42454
42455			if ( newShapes.length > 1 ) {
42456
42457				var ambiguous = false;
42458				var toChange = [];
42459
42460				for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
42461
42462					betterShapeHoles[ sIdx ] = [];
42463
42464				}
42465
42466				for ( var sIdx$1 = 0, sLen$1 = newShapes.length; sIdx$1 < sLen$1; sIdx$1 ++ ) {
42467
42468					var sho = newShapeHoles[ sIdx$1 ];
42469
42470					for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {
42471
42472						var ho = sho[ hIdx ];
42473						var hole_unassigned = true;
42474
42475						for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
42476
42477							if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
42478
42479								if ( sIdx$1 !== s2Idx )	{ toChange.push( { froms: sIdx$1, tos: s2Idx, hole: hIdx } ); }
42480								if ( hole_unassigned ) {
42481
42482									hole_unassigned = false;
42483									betterShapeHoles[ s2Idx ].push( ho );
42484
42485								} else {
42486
42487									ambiguous = true;
42488
42489								}
42490
42491							}
42492
42493						}
42494
42495						if ( hole_unassigned ) {
42496
42497							betterShapeHoles[ sIdx$1 ].push( ho );
42498
42499						}
42500
42501					}
42502
42503				}
42504				// console.log("ambiguous: ", ambiguous);
42505
42506				if ( toChange.length > 0 ) {
42507
42508					// console.log("to change: ", toChange);
42509					if ( ! ambiguous )	{ newShapeHoles = betterShapeHoles; }
42510
42511				}
42512
42513			}
42514
42515			var tmpHoles;
42516
42517			for ( var i$1 = 0, il = newShapes.length; i$1 < il; i$1 ++ ) {
42518
42519				tmpShape = newShapes[ i$1 ].s;
42520				shapes.push( tmpShape );
42521				tmpHoles = newShapeHoles[ i$1 ];
42522
42523				for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
42524
42525					tmpShape.holes.push( tmpHoles[ j ].h );
42526
42527				}
42528
42529			}
42530
42531			//console.log("shape", shapes);
42532
42533			return shapes;
42534
42535		}
42536
42537	} );
42538
42539	/**
42540	 * @author zz85 / http://www.lab4games.net/zz85/blog
42541	 * @author mrdoob / http://mrdoob.com/
42542	 */
42543
42544
42545	function Font( data ) {
42546
42547		this.type = 'Font';
42548
42549		this.data = data;
42550
42551	}
42552
42553	Object.assign( Font.prototype, {
42554
42555		isFont: true,
42556
42557		generateShapes: function ( text, size ) {
42558
42559			if ( size === undefined ) { size = 100; }
42560
42561			var shapes = [];
42562			var paths = createPaths( text, size, this.data );
42563
42564			for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
42565
42566				Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
42567
42568			}
42569
42570			return shapes;
42571
42572		}
42573
42574	} );
42575
42576	function createPaths( text, size, data ) {
42577
42578		var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // workaround for IE11, see #13988
42579		var scale = size / data.resolution;
42580		var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
42581
42582		var paths = [];
42583
42584		var offsetX = 0, offsetY = 0;
42585
42586		for ( var i = 0; i < chars.length; i ++ ) {
42587
42588			var char = chars[ i ];
42589
42590			if ( char === '\n' ) {
42591
42592				offsetX = 0;
42593				offsetY -= line_height;
42594
42595			} else {
42596
42597				var ret = createPath( char, scale, offsetX, offsetY, data );
42598				offsetX += ret.offsetX;
42599				paths.push( ret.path );
42600
42601			}
42602
42603		}
42604
42605		return paths;
42606
42607	}
42608
42609	function createPath( char, scale, offsetX, offsetY, data ) {
42610
42611		var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
42612
42613		if ( ! glyph ) {
42614
42615			console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
42616
42617			return;
42618
42619		}
42620
42621		var path = new ShapePath();
42622
42623		var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
42624
42625		if ( glyph.o ) {
42626
42627			var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
42628
42629			for ( var i = 0, l = outline.length; i < l; ) {
42630
42631				var action = outline[ i ++ ];
42632
42633				switch ( action ) {
42634
42635					case 'm': // moveTo
42636
42637						x = outline[ i ++ ] * scale + offsetX;
42638						y = outline[ i ++ ] * scale + offsetY;
42639
42640						path.moveTo( x, y );
42641
42642						break;
42643
42644					case 'l': // lineTo
42645
42646						x = outline[ i ++ ] * scale + offsetX;
42647						y = outline[ i ++ ] * scale + offsetY;
42648
42649						path.lineTo( x, y );
42650
42651						break;
42652
42653					case 'q': // quadraticCurveTo
42654
42655						cpx = outline[ i ++ ] * scale + offsetX;
42656						cpy = outline[ i ++ ] * scale + offsetY;
42657						cpx1 = outline[ i ++ ] * scale + offsetX;
42658						cpy1 = outline[ i ++ ] * scale + offsetY;
42659
42660						path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
42661
42662						break;
42663
42664					case 'b': // bezierCurveTo
42665
42666						cpx = outline[ i ++ ] * scale + offsetX;
42667						cpy = outline[ i ++ ] * scale + offsetY;
42668						cpx1 = outline[ i ++ ] * scale + offsetX;
42669						cpy1 = outline[ i ++ ] * scale + offsetY;
42670						cpx2 = outline[ i ++ ] * scale + offsetX;
42671						cpy2 = outline[ i ++ ] * scale + offsetY;
42672
42673						path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
42674
42675						break;
42676
42677				}
42678
42679			}
42680
42681		}
42682
42683		return { offsetX: glyph.ha * scale, path: path };
42684
42685	}
42686
42687	/**
42688	 * @author mrdoob / http://mrdoob.com/
42689	 */
42690
42691	function FontLoader( manager ) {
42692
42693		Loader.call( this, manager );
42694
42695	}
42696
42697	FontLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
42698
42699		constructor: FontLoader,
42700
42701		load: function ( url, onLoad, onProgress, onError ) {
42702
42703			var scope = this;
42704
42705			var loader = new FileLoader( this.manager );
42706			loader.setPath( this.path );
42707			loader.load( url, function ( text ) {
42708
42709				var json;
42710
42711				try {
42712
42713					json = JSON.parse( text );
42714
42715				} catch ( e ) {
42716
42717					console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );
42718					json = JSON.parse( text.substring( 65, text.length - 2 ) );
42719
42720				}
42721
42722				var font = scope.parse( json );
42723
42724				if ( onLoad ) { onLoad( font ); }
42725
42726			}, onProgress, onError );
42727
42728		},
42729
42730		parse: function ( json ) {
42731
42732			return new Font( json );
42733
42734		}
42735
42736	} );
42737
42738	/**
42739	 * @author mrdoob / http://mrdoob.com/
42740	 */
42741
42742	var _context;
42743
42744	var AudioContext = {
42745
42746		getContext: function () {
42747
42748			if ( _context === undefined ) {
42749
42750				_context = new ( window.AudioContext || window.webkitAudioContext )();
42751
42752			}
42753
42754			return _context;
42755
42756		},
42757
42758		setContext: function ( value ) {
42759
42760			_context = value;
42761
42762		}
42763
42764	};
42765
42766	/**
42767	 * @author Reece Aaron Lecrivain / http://reecenotes.com/
42768	 */
42769
42770	function AudioLoader( manager ) {
42771
42772		Loader.call( this, manager );
42773
42774	}
42775
42776	AudioLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
42777
42778		constructor: AudioLoader,
42779
42780		load: function ( url, onLoad, onProgress, onError ) {
42781
42782			var scope = this;
42783
42784			var loader = new FileLoader( scope.manager );
42785			loader.setResponseType( 'arraybuffer' );
42786			loader.setPath( scope.path );
42787			loader.load( url, function ( buffer ) {
42788
42789				try {
42790
42791					// Create a copy of the buffer. The `decodeAudioData` method
42792					// detaches the buffer when complete, preventing reuse.
42793					var bufferCopy = buffer.slice( 0 );
42794
42795					var context = AudioContext.getContext();
42796					context.decodeAudioData( bufferCopy, function ( audioBuffer ) {
42797
42798						onLoad( audioBuffer );
42799
42800					} );
42801
42802				} catch ( e ) {
42803
42804					if ( onError ) {
42805
42806						onError( e );
42807
42808					} else {
42809
42810						console.error( e );
42811
42812					}
42813
42814					scope.manager.itemError( url );
42815
42816				}
42817
42818			}, onProgress, onError );
42819
42820		}
42821
42822	} );
42823
42824	/**
42825	 * @author WestLangley / http://github.com/WestLangley
42826	 */
42827
42828	function HemisphereLightProbe( skyColor, groundColor, intensity ) {
42829
42830		LightProbe.call( this, undefined, intensity );
42831
42832		var color1 = new Color().set( skyColor );
42833		var color2 = new Color().set( groundColor );
42834
42835		var sky = new Vector3( color1.r, color1.g, color1.b );
42836		var ground = new Vector3( color2.r, color2.g, color2.b );
42837
42838		// without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI );
42839		var c0 = Math.sqrt( Math.PI );
42840		var c1 = c0 * Math.sqrt( 0.75 );
42841
42842		this.sh.coefficients[ 0 ].copy( sky ).add( ground ).multiplyScalar( c0 );
42843		this.sh.coefficients[ 1 ].copy( sky ).sub( ground ).multiplyScalar( c1 );
42844
42845	}
42846
42847	HemisphereLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), {
42848
42849		constructor: HemisphereLightProbe,
42850
42851		isHemisphereLightProbe: true,
42852
42853		copy: function ( source ) { // modifying colors not currently supported
42854
42855			LightProbe.prototype.copy.call( this, source );
42856
42857			return this;
42858
42859		},
42860
42861		toJSON: function ( meta ) {
42862
42863			var data = LightProbe.prototype.toJSON.call( this, meta );
42864
42865			// data.sh = this.sh.toArray(); // todo
42866
42867			return data;
42868
42869		}
42870
42871	} );
42872
42873	/**
42874	 * @author WestLangley / http://github.com/WestLangley
42875	 */
42876
42877	function AmbientLightProbe( color, intensity ) {
42878
42879		LightProbe.call( this, undefined, intensity );
42880
42881		var color1 = new Color().set( color );
42882
42883		// without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI );
42884		this.sh.coefficients[ 0 ].set( color1.r, color1.g, color1.b ).multiplyScalar( 2 * Math.sqrt( Math.PI ) );
42885
42886	}
42887
42888	AmbientLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), {
42889
42890		constructor: AmbientLightProbe,
42891
42892		isAmbientLightProbe: true,
42893
42894		copy: function ( source ) { // modifying color not currently supported
42895
42896			LightProbe.prototype.copy.call( this, source );
42897
42898			return this;
42899
42900		},
42901
42902		toJSON: function ( meta ) {
42903
42904			var data = LightProbe.prototype.toJSON.call( this, meta );
42905
42906			// data.sh = this.sh.toArray(); // todo
42907
42908			return data;
42909
42910		}
42911
42912	} );
42913
42914	var _eyeRight = new Matrix4();
42915	var _eyeLeft = new Matrix4();
42916
42917	/**
42918	 * @author mrdoob / http://mrdoob.com/
42919	 */
42920
42921	function StereoCamera() {
42922
42923		this.type = 'StereoCamera';
42924
42925		this.aspect = 1;
42926
42927		this.eyeSep = 0.064;
42928
42929		this.cameraL = new PerspectiveCamera();
42930		this.cameraL.layers.enable( 1 );
42931		this.cameraL.matrixAutoUpdate = false;
42932
42933		this.cameraR = new PerspectiveCamera();
42934		this.cameraR.layers.enable( 2 );
42935		this.cameraR.matrixAutoUpdate = false;
42936
42937		this._cache = {
42938			focus: null,
42939			fov: null,
42940			aspect: null,
42941			near: null,
42942			far: null,
42943			zoom: null,
42944			eyeSep: null
42945		};
42946
42947	}
42948
42949	Object.assign( StereoCamera.prototype, {
42950
42951		update: function ( camera ) {
42952
42953			var cache = this._cache;
42954
42955			var needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov ||
42956				cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near ||
42957				cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep;
42958
42959			if ( needsUpdate ) {
42960
42961				cache.focus = camera.focus;
42962				cache.fov = camera.fov;
42963				cache.aspect = camera.aspect * this.aspect;
42964				cache.near = camera.near;
42965				cache.far = camera.far;
42966				cache.zoom = camera.zoom;
42967				cache.eyeSep = this.eyeSep;
42968
42969				// Off-axis stereoscopic effect based on
42970				// http://paulbourke.net/stereographics/stereorender/
42971
42972				var projectionMatrix = camera.projectionMatrix.clone();
42973				var eyeSepHalf = cache.eyeSep / 2;
42974				var eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus;
42975				var ymax = ( cache.near * Math.tan( MathUtils.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom;
42976				var xmin, xmax;
42977
42978				// translate xOffset
42979
42980				_eyeLeft.elements[ 12 ] = - eyeSepHalf;
42981				_eyeRight.elements[ 12 ] = eyeSepHalf;
42982
42983				// for left eye
42984
42985				xmin = - ymax * cache.aspect + eyeSepOnProjection;
42986				xmax = ymax * cache.aspect + eyeSepOnProjection;
42987
42988				projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
42989				projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
42990
42991				this.cameraL.projectionMatrix.copy( projectionMatrix );
42992
42993				// for right eye
42994
42995				xmin = - ymax * cache.aspect - eyeSepOnProjection;
42996				xmax = ymax * cache.aspect - eyeSepOnProjection;
42997
42998				projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
42999				projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
43000
43001				this.cameraR.projectionMatrix.copy( projectionMatrix );
43002
43003			}
43004
43005			this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft );
43006			this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight );
43007
43008		}
43009
43010	} );
43011
43012	/**
43013	 * @author alteredq / http://alteredqualia.com/
43014	 */
43015
43016	function Clock( autoStart ) {
43017
43018		this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
43019
43020		this.startTime = 0;
43021		this.oldTime = 0;
43022		this.elapsedTime = 0;
43023
43024		this.running = false;
43025
43026	}
43027
43028	Object.assign( Clock.prototype, {
43029
43030		start: function () {
43031
43032			this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732
43033
43034			this.oldTime = this.startTime;
43035			this.elapsedTime = 0;
43036			this.running = true;
43037
43038		},
43039
43040		stop: function () {
43041
43042			this.getElapsedTime();
43043			this.running = false;
43044			this.autoStart = false;
43045
43046		},
43047
43048		getElapsedTime: function () {
43049
43050			this.getDelta();
43051			return this.elapsedTime;
43052
43053		},
43054
43055		getDelta: function () {
43056
43057			var diff = 0;
43058
43059			if ( this.autoStart && ! this.running ) {
43060
43061				this.start();
43062				return 0;
43063
43064			}
43065
43066			if ( this.running ) {
43067
43068				var newTime = ( typeof performance === 'undefined' ? Date : performance ).now();
43069
43070				diff = ( newTime - this.oldTime ) / 1000;
43071				this.oldTime = newTime;
43072
43073				this.elapsedTime += diff;
43074
43075			}
43076
43077			return diff;
43078
43079		}
43080
43081	} );
43082
43083	/**
43084	 * @author mrdoob / http://mrdoob.com/
43085	 */
43086
43087	var _position$2 = new Vector3();
43088	var _quaternion$3 = new Quaternion();
43089	var _scale$1 = new Vector3();
43090	var _orientation = new Vector3();
43091
43092	function AudioListener() {
43093
43094		Object3D.call( this );
43095
43096		this.type = 'AudioListener';
43097
43098		this.context = AudioContext.getContext();
43099
43100		this.gain = this.context.createGain();
43101		this.gain.connect( this.context.destination );
43102
43103		this.filter = null;
43104
43105		this.timeDelta = 0;
43106
43107		// private
43108
43109		this._clock = new Clock();
43110
43111	}
43112
43113	AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
43114
43115		constructor: AudioListener,
43116
43117		getInput: function () {
43118
43119			return this.gain;
43120
43121		},
43122
43123		removeFilter: function ( ) {
43124
43125			if ( this.filter !== null ) {
43126
43127				this.gain.disconnect( this.filter );
43128				this.filter.disconnect( this.context.destination );
43129				this.gain.connect( this.context.destination );
43130				this.filter = null;
43131
43132			}
43133
43134			return this;
43135
43136		},
43137
43138		getFilter: function () {
43139
43140			return this.filter;
43141
43142		},
43143
43144		setFilter: function ( value ) {
43145
43146			if ( this.filter !== null ) {
43147
43148				this.gain.disconnect( this.filter );
43149				this.filter.disconnect( this.context.destination );
43150
43151			} else {
43152
43153				this.gain.disconnect( this.context.destination );
43154
43155			}
43156
43157			this.filter = value;
43158			this.gain.connect( this.filter );
43159			this.filter.connect( this.context.destination );
43160
43161			return this;
43162
43163		},
43164
43165		getMasterVolume: function () {
43166
43167			return this.gain.gain.value;
43168
43169		},
43170
43171		setMasterVolume: function ( value ) {
43172
43173			this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
43174
43175			return this;
43176
43177		},
43178
43179		updateMatrixWorld: function ( force ) {
43180
43181			Object3D.prototype.updateMatrixWorld.call( this, force );
43182
43183			var listener = this.context.listener;
43184			var up = this.up;
43185
43186			this.timeDelta = this._clock.getDelta();
43187
43188			this.matrixWorld.decompose( _position$2, _quaternion$3, _scale$1 );
43189
43190			_orientation.set( 0, 0, - 1 ).applyQuaternion( _quaternion$3 );
43191
43192			if ( listener.positionX ) {
43193
43194				// code path for Chrome (see #14393)
43195
43196				var endTime = this.context.currentTime + this.timeDelta;
43197
43198				listener.positionX.linearRampToValueAtTime( _position$2.x, endTime );
43199				listener.positionY.linearRampToValueAtTime( _position$2.y, endTime );
43200				listener.positionZ.linearRampToValueAtTime( _position$2.z, endTime );
43201				listener.forwardX.linearRampToValueAtTime( _orientation.x, endTime );
43202				listener.forwardY.linearRampToValueAtTime( _orientation.y, endTime );
43203				listener.forwardZ.linearRampToValueAtTime( _orientation.z, endTime );
43204				listener.upX.linearRampToValueAtTime( up.x, endTime );
43205				listener.upY.linearRampToValueAtTime( up.y, endTime );
43206				listener.upZ.linearRampToValueAtTime( up.z, endTime );
43207
43208			} else {
43209
43210				listener.setPosition( _position$2.x, _position$2.y, _position$2.z );
43211				listener.setOrientation( _orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z );
43212
43213			}
43214
43215		}
43216
43217	} );
43218
43219	/**
43220	 * @author mrdoob / http://mrdoob.com/
43221	 * @author Reece Aaron Lecrivain / http://reecenotes.com/
43222	 */
43223
43224	function Audio( listener ) {
43225
43226		Object3D.call( this );
43227
43228		this.type = 'Audio';
43229
43230		this.listener = listener;
43231		this.context = listener.context;
43232
43233		this.gain = this.context.createGain();
43234		this.gain.connect( listener.getInput() );
43235
43236		this.autoplay = false;
43237
43238		this.buffer = null;
43239		this.detune = 0;
43240		this.loop = false;
43241		this.loopStart = 0;
43242		this.loopEnd = 0;
43243		this.offset = 0;
43244		this.duration = undefined;
43245		this.playbackRate = 1;
43246		this.isPlaying = false;
43247		this.hasPlaybackControl = true;
43248		this.sourceType = 'empty';
43249
43250		this._startedAt = 0;
43251		this._progress = 0;
43252
43253		this.filters = [];
43254
43255	}
43256
43257	Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
43258
43259		constructor: Audio,
43260
43261		getOutput: function () {
43262
43263			return this.gain;
43264
43265		},
43266
43267		setNodeSource: function ( audioNode ) {
43268
43269			this.hasPlaybackControl = false;
43270			this.sourceType = 'audioNode';
43271			this.source = audioNode;
43272			this.connect();
43273
43274			return this;
43275
43276		},
43277
43278		setMediaElementSource: function ( mediaElement ) {
43279
43280			this.hasPlaybackControl = false;
43281			this.sourceType = 'mediaNode';
43282			this.source = this.context.createMediaElementSource( mediaElement );
43283			this.connect();
43284
43285			return this;
43286
43287		},
43288
43289		setMediaStreamSource: function ( mediaStream ) {
43290
43291			this.hasPlaybackControl = false;
43292			this.sourceType = 'mediaStreamNode';
43293			this.source = this.context.createMediaStreamSource( mediaStream );
43294			this.connect();
43295
43296			return this;
43297
43298		},
43299
43300		setBuffer: function ( audioBuffer ) {
43301
43302			this.buffer = audioBuffer;
43303			this.sourceType = 'buffer';
43304
43305			if ( this.autoplay ) { this.play(); }
43306
43307			return this;
43308
43309		},
43310
43311		play: function ( delay ) {
43312
43313			if ( delay === undefined ) { delay = 0; }
43314
43315			if ( this.isPlaying === true ) {
43316
43317				console.warn( 'THREE.Audio: Audio is already playing.' );
43318				return;
43319
43320			}
43321
43322			if ( this.hasPlaybackControl === false ) {
43323
43324				console.warn( 'THREE.Audio: this Audio has no playback control.' );
43325				return;
43326
43327			}
43328
43329			this._startedAt = this.context.currentTime + delay;
43330
43331			var source = this.context.createBufferSource();
43332			source.buffer = this.buffer;
43333			source.loop = this.loop;
43334			source.loopStart = this.loopStart;
43335			source.loopEnd = this.loopEnd;
43336			source.onended = this.onEnded.bind( this );
43337			source.start( this._startedAt, this._progress + this.offset, this.duration );
43338
43339			this.isPlaying = true;
43340
43341			this.source = source;
43342
43343			this.setDetune( this.detune );
43344			this.setPlaybackRate( this.playbackRate );
43345
43346			return this.connect();
43347
43348		},
43349
43350		pause: function () {
43351
43352			if ( this.hasPlaybackControl === false ) {
43353
43354				console.warn( 'THREE.Audio: this Audio has no playback control.' );
43355				return;
43356
43357			}
43358
43359			if ( this.isPlaying === true ) {
43360
43361				// update current progress
43362
43363				this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;
43364
43365				if ( this.loop === true ) {
43366
43367					// ensure _progress does not exceed duration with looped audios
43368
43369					this._progress = this._progress % ( this.duration || this.buffer.duration );
43370
43371				}
43372
43373				this.source.stop();
43374				this.source.onended = null;
43375
43376				this.isPlaying = false;
43377
43378			}
43379
43380			return this;
43381
43382		},
43383
43384		stop: function () {
43385
43386			if ( this.hasPlaybackControl === false ) {
43387
43388				console.warn( 'THREE.Audio: this Audio has no playback control.' );
43389				return;
43390
43391			}
43392
43393			this._progress = 0;
43394
43395			this.source.stop();
43396			this.source.onended = null;
43397			this.isPlaying = false;
43398
43399			return this;
43400
43401		},
43402
43403		connect: function () {
43404
43405			if ( this.filters.length > 0 ) {
43406
43407				this.source.connect( this.filters[ 0 ] );
43408
43409				for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
43410
43411					this.filters[ i - 1 ].connect( this.filters[ i ] );
43412
43413				}
43414
43415				this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
43416
43417			} else {
43418
43419				this.source.connect( this.getOutput() );
43420
43421			}
43422
43423			return this;
43424
43425		},
43426
43427		disconnect: function () {
43428
43429			if ( this.filters.length > 0 ) {
43430
43431				this.source.disconnect( this.filters[ 0 ] );
43432
43433				for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
43434
43435					this.filters[ i - 1 ].disconnect( this.filters[ i ] );
43436
43437				}
43438
43439				this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
43440
43441			} else {
43442
43443				this.source.disconnect( this.getOutput() );
43444
43445			}
43446
43447			return this;
43448
43449		},
43450
43451		getFilters: function () {
43452
43453			return this.filters;
43454
43455		},
43456
43457		setFilters: function ( value ) {
43458
43459			if ( ! value ) { value = []; }
43460
43461			if ( this.isPlaying === true ) {
43462
43463				this.disconnect();
43464				this.filters = value;
43465				this.connect();
43466
43467			} else {
43468
43469				this.filters = value;
43470
43471			}
43472
43473			return this;
43474
43475		},
43476
43477		setDetune: function ( value ) {
43478
43479			this.detune = value;
43480
43481			if ( this.source.detune === undefined ) { return; } // only set detune when available
43482
43483			if ( this.isPlaying === true ) {
43484
43485				this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );
43486
43487			}
43488
43489			return this;
43490
43491		},
43492
43493		getDetune: function () {
43494
43495			return this.detune;
43496
43497		},
43498
43499		getFilter: function () {
43500
43501			return this.getFilters()[ 0 ];
43502
43503		},
43504
43505		setFilter: function ( filter ) {
43506
43507			return this.setFilters( filter ? [ filter ] : [] );
43508
43509		},
43510
43511		setPlaybackRate: function ( value ) {
43512
43513			if ( this.hasPlaybackControl === false ) {
43514
43515				console.warn( 'THREE.Audio: this Audio has no playback control.' );
43516				return;
43517
43518			}
43519
43520			this.playbackRate = value;
43521
43522			if ( this.isPlaying === true ) {
43523
43524				this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );
43525
43526			}
43527
43528			return this;
43529
43530		},
43531
43532		getPlaybackRate: function () {
43533
43534			return this.playbackRate;
43535
43536		},
43537
43538		onEnded: function () {
43539
43540			this.isPlaying = false;
43541
43542		},
43543
43544		getLoop: function () {
43545
43546			if ( this.hasPlaybackControl === false ) {
43547
43548				console.warn( 'THREE.Audio: this Audio has no playback control.' );
43549				return false;
43550
43551			}
43552
43553			return this.loop;
43554
43555		},
43556
43557		setLoop: function ( value ) {
43558
43559			if ( this.hasPlaybackControl === false ) {
43560
43561				console.warn( 'THREE.Audio: this Audio has no playback control.' );
43562				return;
43563
43564			}
43565
43566			this.loop = value;
43567
43568			if ( this.isPlaying === true ) {
43569
43570				this.source.loop = this.loop;
43571
43572			}
43573
43574			return this;
43575
43576		},
43577
43578		setLoopStart: function ( value ) {
43579
43580			this.loopStart = value;
43581
43582			return this;
43583
43584		},
43585
43586		setLoopEnd: function ( value ) {
43587
43588			this.loopEnd = value;
43589
43590			return this;
43591
43592		},
43593
43594		getVolume: function () {
43595
43596			return this.gain.gain.value;
43597
43598		},
43599
43600		setVolume: function ( value ) {
43601
43602			this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
43603
43604			return this;
43605
43606		}
43607
43608	} );
43609
43610	/**
43611	 * @author mrdoob / http://mrdoob.com/
43612	 */
43613
43614	var _position$3 = new Vector3();
43615	var _quaternion$4 = new Quaternion();
43616	var _scale$2 = new Vector3();
43617	var _orientation$1 = new Vector3();
43618
43619	function PositionalAudio( listener ) {
43620
43621		Audio.call( this, listener );
43622
43623		this.panner = this.context.createPanner();
43624		this.panner.panningModel = 'HRTF';
43625		this.panner.connect( this.gain );
43626
43627	}
43628
43629	PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
43630
43631		constructor: PositionalAudio,
43632
43633		getOutput: function () {
43634
43635			return this.panner;
43636
43637		},
43638
43639		getRefDistance: function () {
43640
43641			return this.panner.refDistance;
43642
43643		},
43644
43645		setRefDistance: function ( value ) {
43646
43647			this.panner.refDistance = value;
43648
43649			return this;
43650
43651		},
43652
43653		getRolloffFactor: function () {
43654
43655			return this.panner.rolloffFactor;
43656
43657		},
43658
43659		setRolloffFactor: function ( value ) {
43660
43661			this.panner.rolloffFactor = value;
43662
43663			return this;
43664
43665		},
43666
43667		getDistanceModel: function () {
43668
43669			return this.panner.distanceModel;
43670
43671		},
43672
43673		setDistanceModel: function ( value ) {
43674
43675			this.panner.distanceModel = value;
43676
43677			return this;
43678
43679		},
43680
43681		getMaxDistance: function () {
43682
43683			return this.panner.maxDistance;
43684
43685		},
43686
43687		setMaxDistance: function ( value ) {
43688
43689			this.panner.maxDistance = value;
43690
43691			return this;
43692
43693		},
43694
43695		setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
43696
43697			this.panner.coneInnerAngle = coneInnerAngle;
43698			this.panner.coneOuterAngle = coneOuterAngle;
43699			this.panner.coneOuterGain = coneOuterGain;
43700
43701			return this;
43702
43703		},
43704
43705		updateMatrixWorld: function ( force ) {
43706
43707			Object3D.prototype.updateMatrixWorld.call( this, force );
43708
43709			if ( this.hasPlaybackControl === true && this.isPlaying === false ) { return; }
43710
43711			this.matrixWorld.decompose( _position$3, _quaternion$4, _scale$2 );
43712
43713			_orientation$1.set( 0, 0, 1 ).applyQuaternion( _quaternion$4 );
43714
43715			var panner = this.panner;
43716
43717			if ( panner.positionX ) {
43718
43719				// code path for Chrome and Firefox (see #14393)
43720
43721				var endTime = this.context.currentTime + this.listener.timeDelta;
43722
43723				panner.positionX.linearRampToValueAtTime( _position$3.x, endTime );
43724				panner.positionY.linearRampToValueAtTime( _position$3.y, endTime );
43725				panner.positionZ.linearRampToValueAtTime( _position$3.z, endTime );
43726				panner.orientationX.linearRampToValueAtTime( _orientation$1.x, endTime );
43727				panner.orientationY.linearRampToValueAtTime( _orientation$1.y, endTime );
43728				panner.orientationZ.linearRampToValueAtTime( _orientation$1.z, endTime );
43729
43730			} else {
43731
43732				panner.setPosition( _position$3.x, _position$3.y, _position$3.z );
43733				panner.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z );
43734
43735			}
43736
43737		}
43738
43739	} );
43740
43741	/**
43742	 * @author mrdoob / http://mrdoob.com/
43743	 */
43744
43745	function AudioAnalyser( audio, fftSize ) {
43746
43747		this.analyser = audio.context.createAnalyser();
43748		this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;
43749
43750		this.data = new Uint8Array( this.analyser.frequencyBinCount );
43751
43752		audio.getOutput().connect( this.analyser );
43753
43754	}
43755
43756	Object.assign( AudioAnalyser.prototype, {
43757
43758		getFrequencyData: function () {
43759
43760			this.analyser.getByteFrequencyData( this.data );
43761
43762			return this.data;
43763
43764		},
43765
43766		getAverageFrequency: function () {
43767
43768			var value = 0;
43769			var data = this.getFrequencyData();
43770
43771			for ( var i = 0; i < data.length; i ++ ) {
43772
43773				value += data[ i ];
43774
43775			}
43776
43777			return value / data.length;
43778
43779		}
43780
43781	} );
43782
43783	/**
43784	 *
43785	 * Buffered scene graph property that allows weighted accumulation.
43786	 *
43787	 *
43788	 * @author Ben Houston / http://clara.io/
43789	 * @author David Sarno / http://lighthaus.us/
43790	 * @author tschw
43791	 */
43792
43793	function PropertyMixer( binding, typeName, valueSize ) {
43794
43795		this.binding = binding;
43796		this.valueSize = valueSize;
43797
43798		var mixFunction,
43799			mixFunctionAdditive,
43800			setIdentity;
43801
43802		// buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ]
43803		//
43804		// interpolators can use .buffer as their .result
43805		// the data then goes to 'incoming'
43806		//
43807		// 'accu0' and 'accu1' are used frame-interleaved for
43808		// the cumulative result and are compared to detect
43809		// changes
43810		//
43811		// 'orig' stores the original state of the property
43812		//
43813		// 'add' is used for additive cumulative results
43814		//
43815		// 'work' is optional and is only present for quaternion types. It is used
43816		// to store intermediate quaternion multiplication results
43817
43818		switch ( typeName ) {
43819
43820			case 'quaternion':
43821				mixFunction = this._slerp;
43822				mixFunctionAdditive = this._slerpAdditive;
43823				setIdentity = this._setAdditiveIdentityQuaternion;
43824
43825				this.buffer = new Float64Array( valueSize * 6 );
43826				this._workIndex = 5;
43827				break;
43828
43829			case 'string':
43830			case 'bool':
43831				mixFunction = this._select;
43832
43833				// Use the regular mix function and for additive on these types,
43834				// additive is not relevant for non-numeric types
43835				mixFunctionAdditive = this._select;
43836
43837				setIdentity = this._setAdditiveIdentityOther;
43838
43839				this.buffer = new Array( valueSize * 5 );
43840				break;
43841
43842			default:
43843				mixFunction = this._lerp;
43844				mixFunctionAdditive = this._lerpAdditive;
43845				setIdentity = this._setAdditiveIdentityNumeric;
43846
43847				this.buffer = new Float64Array( valueSize * 5 );
43848
43849		}
43850
43851		this._mixBufferRegion = mixFunction;
43852		this._mixBufferRegionAdditive = mixFunctionAdditive;
43853		this._setIdentity = setIdentity;
43854		this._origIndex = 3;
43855		this._addIndex = 4;
43856
43857		this.cumulativeWeight = 0;
43858		this.cumulativeWeightAdditive = 0;
43859
43860		this.useCount = 0;
43861		this.referenceCount = 0;
43862
43863	}
43864
43865	Object.assign( PropertyMixer.prototype, {
43866
43867		// accumulate data in the 'incoming' region into 'accu<i>'
43868		accumulate: function ( accuIndex, weight ) {
43869
43870			// note: happily accumulating nothing when weight = 0, the caller knows
43871			// the weight and shouldn't have made the call in the first place
43872
43873			var buffer = this.buffer,
43874				stride = this.valueSize,
43875				offset = accuIndex * stride + stride;
43876
43877			var currentWeight = this.cumulativeWeight;
43878
43879			if ( currentWeight === 0 ) {
43880
43881				// accuN := incoming * weight
43882
43883				for ( var i = 0; i !== stride; ++ i ) {
43884
43885					buffer[ offset + i ] = buffer[ i ];
43886
43887				}
43888
43889				currentWeight = weight;
43890
43891			} else {
43892
43893				// accuN := accuN + incoming * weight
43894
43895				currentWeight += weight;
43896				var mix = weight / currentWeight;
43897				this._mixBufferRegion( buffer, offset, 0, mix, stride );
43898
43899			}
43900
43901			this.cumulativeWeight = currentWeight;
43902
43903		},
43904
43905		// accumulate data in the 'incoming' region into 'add'
43906		accumulateAdditive: function ( weight ) {
43907
43908			var buffer = this.buffer,
43909				stride = this.valueSize,
43910				offset = stride * this._addIndex;
43911
43912			if ( this.cumulativeWeightAdditive === 0 ) {
43913
43914				// add = identity
43915
43916				this._setIdentity();
43917
43918			}
43919
43920			// add := add + incoming * weight
43921
43922			this._mixBufferRegionAdditive( buffer, offset, 0, weight, stride );
43923			this.cumulativeWeightAdditive += weight;
43924
43925		},
43926
43927		// apply the state of 'accu<i>' to the binding when accus differ
43928		apply: function ( accuIndex ) {
43929
43930			var stride = this.valueSize,
43931				buffer = this.buffer,
43932				offset = accuIndex * stride + stride,
43933
43934				weight = this.cumulativeWeight,
43935				weightAdditive = this.cumulativeWeightAdditive,
43936
43937				binding = this.binding;
43938
43939			this.cumulativeWeight = 0;
43940			this.cumulativeWeightAdditive = 0;
43941
43942			if ( weight < 1 ) {
43943
43944				// accuN := accuN + original * ( 1 - cumulativeWeight )
43945
43946				var originalValueOffset = stride * this._origIndex;
43947
43948				this._mixBufferRegion(
43949					buffer, offset, originalValueOffset, 1 - weight, stride );
43950
43951			}
43952
43953			if ( weightAdditive > 0 ) {
43954
43955				// accuN := accuN + additive accuN
43956
43957				this._mixBufferRegionAdditive( buffer, offset, this._addIndex * stride, 1, stride );
43958
43959			}
43960
43961			for ( var i = stride, e = stride + stride; i !== e; ++ i ) {
43962
43963				if ( buffer[ i ] !== buffer[ i + stride ] ) {
43964
43965					// value has changed -> update scene graph
43966
43967					binding.setValue( buffer, offset );
43968					break;
43969
43970				}
43971
43972			}
43973
43974		},
43975
43976		// remember the state of the bound property and copy it to both accus
43977		saveOriginalState: function () {
43978
43979			var binding = this.binding;
43980
43981			var buffer = this.buffer,
43982				stride = this.valueSize,
43983
43984				originalValueOffset = stride * this._origIndex;
43985
43986			binding.getValue( buffer, originalValueOffset );
43987
43988			// accu[0..1] := orig -- initially detect changes against the original
43989			for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {
43990
43991				buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];
43992
43993			}
43994
43995			// Add to identity for additive
43996			this._setIdentity();
43997
43998			this.cumulativeWeight = 0;
43999			this.cumulativeWeightAdditive = 0;
44000
44001		},
44002
44003		// apply the state previously taken via 'saveOriginalState' to the binding
44004		restoreOriginalState: function () {
44005
44006			var originalValueOffset = this.valueSize * 3;
44007			this.binding.setValue( this.buffer, originalValueOffset );
44008
44009		},
44010
44011		_setAdditiveIdentityNumeric: function () {
44012
44013			var startIndex = this._addIndex * this.valueSize;
44014			var endIndex = startIndex + this.valueSize;
44015
44016			for ( var i = startIndex; i < endIndex; i ++ ) {
44017
44018				this.buffer[ i ] = 0;
44019
44020			}
44021
44022		},
44023
44024		_setAdditiveIdentityQuaternion: function () {
44025
44026			this._setAdditiveIdentityNumeric();
44027			this.buffer[ this._addIndex * 4 + 3 ] = 1;
44028
44029		},
44030
44031		_setAdditiveIdentityOther: function () {
44032
44033			var startIndex = this._origIndex * this.valueSize;
44034			var targetIndex = this._addIndex * this.valueSize;
44035
44036			for ( var i = 0; i < this.valueSize; i ++ ) {
44037
44038				this.buffer[ targetIndex + i ] = this.buffer[ startIndex + i ];
44039
44040			}
44041
44042		},
44043
44044
44045		// mix functions
44046
44047		_select: function ( buffer, dstOffset, srcOffset, t, stride ) {
44048
44049			if ( t >= 0.5 ) {
44050
44051				for ( var i = 0; i !== stride; ++ i ) {
44052
44053					buffer[ dstOffset + i ] = buffer[ srcOffset + i ];
44054
44055				}
44056
44057			}
44058
44059		},
44060
44061		_slerp: function ( buffer, dstOffset, srcOffset, t ) {
44062
44063			Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t );
44064
44065		},
44066
44067		_slerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) {
44068
44069			var workOffset = this._workIndex * stride;
44070
44071			// Store result in intermediate buffer offset
44072			Quaternion.multiplyQuaternionsFlat( buffer, workOffset, buffer, dstOffset, buffer, srcOffset );
44073
44074			// Slerp to the intermediate result
44075			Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t );
44076
44077		},
44078
44079		_lerp: function ( buffer, dstOffset, srcOffset, t, stride ) {
44080
44081			var s = 1 - t;
44082
44083			for ( var i = 0; i !== stride; ++ i ) {
44084
44085				var j = dstOffset + i;
44086
44087				buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;
44088
44089			}
44090
44091		},
44092
44093		_lerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) {
44094
44095			for ( var i = 0; i !== stride; ++ i ) {
44096
44097				var j = dstOffset + i;
44098
44099				buffer[ j ] = buffer[ j ] + buffer[ srcOffset + i ] * t;
44100
44101			}
44102
44103		}
44104
44105	} );
44106
44107	/**
44108	 *
44109	 * A reference to a real property in the scene graph.
44110	 *
44111	 *
44112	 * @author Ben Houston / http://clara.io/
44113	 * @author David Sarno / http://lighthaus.us/
44114	 * @author tschw
44115	 */
44116
44117	// Characters [].:/ are reserved for track binding syntax.
44118	var _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
44119	var _reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' );
44120
44121	// Attempts to allow node names from any language. ES5's `\w` regexp matches
44122	// only latin characters, and the unicode \p{L} is not yet supported. So
44123	// instead, we exclude reserved characters and match everything else.
44124	var _wordChar = '[^' + _RESERVED_CHARS_RE + ']';
44125	var _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']';
44126
44127	// Parent directories, delimited by '/' or ':'. Currently unused, but must
44128	// be matched to parse the rest of the track name.
44129	var _directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar );
44130
44131	// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
44132	var _nodeRe = /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot );
44133
44134	// Object on target node, and accessor. May not contain reserved
44135	// characters. Accessor may contain any character except closing bracket.
44136	var _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar );
44137
44138	// Property and accessor. May not contain reserved characters. Accessor may
44139	// contain any non-bracket characters.
44140	var _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar );
44141
44142	var _trackRe = new RegExp( ''
44143		+ '^'
44144		+ _directoryRe
44145		+ _nodeRe
44146		+ _objectRe
44147		+ _propertyRe
44148		+ '$'
44149	);
44150
44151	var _supportedObjectNames = [ 'material', 'materials', 'bones' ];
44152
44153	function Composite( targetGroup, path, optionalParsedPath ) {
44154
44155		var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path );
44156
44157		this._targetGroup = targetGroup;
44158		this._bindings = targetGroup.subscribe_( path, parsedPath );
44159
44160	}
44161
44162	Object.assign( Composite.prototype, {
44163
44164		getValue: function ( array, offset ) {
44165
44166			this.bind(); // bind all binding
44167
44168			var firstValidIndex = this._targetGroup.nCachedObjects_,
44169				binding = this._bindings[ firstValidIndex ];
44170
44171			// and only call .getValue on the first
44172			if ( binding !== undefined ) { binding.getValue( array, offset ); }
44173
44174		},
44175
44176		setValue: function ( array, offset ) {
44177
44178			var bindings = this._bindings;
44179
44180			for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
44181
44182				bindings[ i ].setValue( array, offset );
44183
44184			}
44185
44186		},
44187
44188		bind: function () {
44189
44190			var bindings = this._bindings;
44191
44192			for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
44193
44194				bindings[ i ].bind();
44195
44196			}
44197
44198		},
44199
44200		unbind: function () {
44201
44202			var bindings = this._bindings;
44203
44204			for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
44205
44206				bindings[ i ].unbind();
44207
44208			}
44209
44210		}
44211
44212	} );
44213
44214
44215	function PropertyBinding( rootNode, path, parsedPath ) {
44216
44217		this.path = path;
44218		this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path );
44219
44220		this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode;
44221
44222		this.rootNode = rootNode;
44223
44224	}
44225
44226	Object.assign( PropertyBinding, {
44227
44228		Composite: Composite,
44229
44230		create: function ( root, path, parsedPath ) {
44231
44232			if ( ! ( root && root.isAnimationObjectGroup ) ) {
44233
44234				return new PropertyBinding( root, path, parsedPath );
44235
44236			} else {
44237
44238				return new PropertyBinding.Composite( root, path, parsedPath );
44239
44240			}
44241
44242		},
44243
44244		/**
44245		 * Replaces spaces with underscores and removes unsupported characters from
44246		 * node names, to ensure compatibility with parseTrackName().
44247		 *
44248		 * @param {string} name Node name to be sanitized.
44249		 * @return {string}
44250		 */
44251		sanitizeNodeName: function ( name ) {
44252
44253			return name.replace( /\s/g, '_' ).replace( _reservedRe, '' );
44254
44255		},
44256
44257		parseTrackName: function ( trackName ) {
44258
44259			var matches = _trackRe.exec( trackName );
44260
44261			if ( ! matches ) {
44262
44263				throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
44264
44265			}
44266
44267			var results = {
44268				// directoryName: matches[ 1 ], // (tschw) currently unused
44269				nodeName: matches[ 2 ],
44270				objectName: matches[ 3 ],
44271				objectIndex: matches[ 4 ],
44272				propertyName: matches[ 5 ], // required
44273				propertyIndex: matches[ 6 ]
44274			};
44275
44276			var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
44277
44278			if ( lastDot !== undefined && lastDot !== - 1 ) {
44279
44280				var objectName = results.nodeName.substring( lastDot + 1 );
44281
44282				// Object names must be checked against an allowlist. Otherwise, there
44283				// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
44284				// 'bar' could be the objectName, or part of a nodeName (which can
44285				// include '.' characters).
44286				if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) {
44287
44288					results.nodeName = results.nodeName.substring( 0, lastDot );
44289					results.objectName = objectName;
44290
44291				}
44292
44293			}
44294
44295			if ( results.propertyName === null || results.propertyName.length === 0 ) {
44296
44297				throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
44298
44299			}
44300
44301			return results;
44302
44303		},
44304
44305		findNode: function ( root, nodeName ) {
44306
44307			if ( ! nodeName || nodeName === "" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
44308
44309				return root;
44310
44311			}
44312
44313			// search into skeleton bones.
44314			if ( root.skeleton ) {
44315
44316				var bone = root.skeleton.getBoneByName( nodeName );
44317
44318				if ( bone !== undefined ) {
44319
44320					return bone;
44321
44322				}
44323
44324			}
44325
44326			// search into node subtree.
44327			if ( root.children ) {
44328
44329				var searchNodeSubtree = function ( children ) {
44330
44331					for ( var i = 0; i < children.length; i ++ ) {
44332
44333						var childNode = children[ i ];
44334
44335						if ( childNode.name === nodeName || childNode.uuid === nodeName ) {
44336
44337							return childNode;
44338
44339						}
44340
44341						var result = searchNodeSubtree( childNode.children );
44342
44343						if ( result ) { return result; }
44344
44345					}
44346
44347					return null;
44348
44349				};
44350
44351				var subTreeNode = searchNodeSubtree( root.children );
44352
44353				if ( subTreeNode ) {
44354
44355					return subTreeNode;
44356
44357				}
44358
44359			}
44360
44361			return null;
44362
44363		}
44364
44365	} );
44366
44367	Object.assign( PropertyBinding.prototype, { // prototype, continued
44368
44369		// these are used to "bind" a nonexistent property
44370		_getValue_unavailable: function () {},
44371		_setValue_unavailable: function () {},
44372
44373		BindingType: {
44374			Direct: 0,
44375			EntireArray: 1,
44376			ArrayElement: 2,
44377			HasFromToArray: 3
44378		},
44379
44380		Versioning: {
44381			None: 0,
44382			NeedsUpdate: 1,
44383			MatrixWorldNeedsUpdate: 2
44384		},
44385
44386		GetterByBindingType: [
44387
44388			function getValue_direct( buffer, offset ) {
44389
44390				buffer[ offset ] = this.node[ this.propertyName ];
44391
44392			},
44393
44394			function getValue_array( buffer, offset ) {
44395
44396				var source = this.resolvedProperty;
44397
44398				for ( var i = 0, n = source.length; i !== n; ++ i ) {
44399
44400					buffer[ offset ++ ] = source[ i ];
44401
44402				}
44403
44404			},
44405
44406			function getValue_arrayElement( buffer, offset ) {
44407
44408				buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];
44409
44410			},
44411
44412			function getValue_toArray( buffer, offset ) {
44413
44414				this.resolvedProperty.toArray( buffer, offset );
44415
44416			}
44417
44418		],
44419
44420		SetterByBindingTypeAndVersioning: [
44421
44422			[
44423				// Direct
44424
44425				function setValue_direct( buffer, offset ) {
44426
44427					this.targetObject[ this.propertyName ] = buffer[ offset ];
44428
44429				},
44430
44431				function setValue_direct_setNeedsUpdate( buffer, offset ) {
44432
44433					this.targetObject[ this.propertyName ] = buffer[ offset ];
44434					this.targetObject.needsUpdate = true;
44435
44436				},
44437
44438				function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {
44439
44440					this.targetObject[ this.propertyName ] = buffer[ offset ];
44441					this.targetObject.matrixWorldNeedsUpdate = true;
44442
44443				}
44444
44445			], [
44446
44447				// EntireArray
44448
44449				function setValue_array( buffer, offset ) {
44450
44451					var dest = this.resolvedProperty;
44452
44453					for ( var i = 0, n = dest.length; i !== n; ++ i ) {
44454
44455						dest[ i ] = buffer[ offset ++ ];
44456
44457					}
44458
44459				},
44460
44461				function setValue_array_setNeedsUpdate( buffer, offset ) {
44462
44463					var dest = this.resolvedProperty;
44464
44465					for ( var i = 0, n = dest.length; i !== n; ++ i ) {
44466
44467						dest[ i ] = buffer[ offset ++ ];
44468
44469					}
44470
44471					this.targetObject.needsUpdate = true;
44472
44473				},
44474
44475				function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {
44476
44477					var dest = this.resolvedProperty;
44478
44479					for ( var i = 0, n = dest.length; i !== n; ++ i ) {
44480
44481						dest[ i ] = buffer[ offset ++ ];
44482
44483					}
44484
44485					this.targetObject.matrixWorldNeedsUpdate = true;
44486
44487				}
44488
44489			], [
44490
44491				// ArrayElement
44492
44493				function setValue_arrayElement( buffer, offset ) {
44494
44495					this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
44496
44497				},
44498
44499				function setValue_arrayElement_setNeedsUpdate( buffer, offset ) {
44500
44501					this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
44502					this.targetObject.needsUpdate = true;
44503
44504				},
44505
44506				function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {
44507
44508					this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
44509					this.targetObject.matrixWorldNeedsUpdate = true;
44510
44511				}
44512
44513			], [
44514
44515				// HasToFromArray
44516
44517				function setValue_fromArray( buffer, offset ) {
44518
44519					this.resolvedProperty.fromArray( buffer, offset );
44520
44521				},
44522
44523				function setValue_fromArray_setNeedsUpdate( buffer, offset ) {
44524
44525					this.resolvedProperty.fromArray( buffer, offset );
44526					this.targetObject.needsUpdate = true;
44527
44528				},
44529
44530				function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {
44531
44532					this.resolvedProperty.fromArray( buffer, offset );
44533					this.targetObject.matrixWorldNeedsUpdate = true;
44534
44535				}
44536
44537			]
44538
44539		],
44540
44541		getValue: function getValue_unbound( targetArray, offset ) {
44542
44543			this.bind();
44544			this.getValue( targetArray, offset );
44545
44546			// Note: This class uses a State pattern on a per-method basis:
44547			// 'bind' sets 'this.getValue' / 'setValue' and shadows the
44548			// prototype version of these methods with one that represents
44549			// the bound state. When the property is not found, the methods
44550			// become no-ops.
44551
44552		},
44553
44554		setValue: function getValue_unbound( sourceArray, offset ) {
44555
44556			this.bind();
44557			this.setValue( sourceArray, offset );
44558
44559		},
44560
44561		// create getter / setter pair for a property in the scene graph
44562		bind: function () {
44563
44564			var targetObject = this.node,
44565				parsedPath = this.parsedPath,
44566
44567				objectName = parsedPath.objectName,
44568				propertyName = parsedPath.propertyName,
44569				propertyIndex = parsedPath.propertyIndex;
44570
44571			if ( ! targetObject ) {
44572
44573				targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode;
44574
44575				this.node = targetObject;
44576
44577			}
44578
44579			// set fail state so we can just 'return' on error
44580			this.getValue = this._getValue_unavailable;
44581			this.setValue = this._setValue_unavailable;
44582
44583			// ensure there is a value node
44584			if ( ! targetObject ) {
44585
44586				console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' );
44587				return;
44588
44589			}
44590
44591			if ( objectName ) {
44592
44593				var objectIndex = parsedPath.objectIndex;
44594
44595				// special cases were we need to reach deeper into the hierarchy to get the face materials....
44596				switch ( objectName ) {
44597
44598					case 'materials':
44599
44600						if ( ! targetObject.material ) {
44601
44602							console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this );
44603							return;
44604
44605						}
44606
44607						if ( ! targetObject.material.materials ) {
44608
44609							console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this );
44610							return;
44611
44612						}
44613
44614						targetObject = targetObject.material.materials;
44615
44616						break;
44617
44618					case 'bones':
44619
44620						if ( ! targetObject.skeleton ) {
44621
44622							console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this );
44623							return;
44624
44625						}
44626
44627						// potential future optimization: skip this if propertyIndex is already an integer
44628						// and convert the integer string to a true integer.
44629
44630						targetObject = targetObject.skeleton.bones;
44631
44632						// support resolving morphTarget names into indices.
44633						for ( var i = 0; i < targetObject.length; i ++ ) {
44634
44635							if ( targetObject[ i ].name === objectIndex ) {
44636
44637								objectIndex = i;
44638								break;
44639
44640							}
44641
44642						}
44643
44644						break;
44645
44646					default:
44647
44648						if ( targetObject[ objectName ] === undefined ) {
44649
44650							console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this );
44651							return;
44652
44653						}
44654
44655						targetObject = targetObject[ objectName ];
44656
44657				}
44658
44659
44660				if ( objectIndex !== undefined ) {
44661
44662					if ( targetObject[ objectIndex ] === undefined ) {
44663
44664						console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject );
44665						return;
44666
44667					}
44668
44669					targetObject = targetObject[ objectIndex ];
44670
44671				}
44672
44673			}
44674
44675			// resolve property
44676			var nodeProperty = targetObject[ propertyName ];
44677
44678			if ( nodeProperty === undefined ) {
44679
44680				var nodeName = parsedPath.nodeName;
44681
44682				console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName +
44683					'.' + propertyName + ' but it wasn\'t found.', targetObject );
44684				return;
44685
44686			}
44687
44688			// determine versioning scheme
44689			var versioning = this.Versioning.None;
44690
44691			this.targetObject = targetObject;
44692
44693			if ( targetObject.needsUpdate !== undefined ) { // material
44694
44695				versioning = this.Versioning.NeedsUpdate;
44696
44697			} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform
44698
44699				versioning = this.Versioning.MatrixWorldNeedsUpdate;
44700
44701			}
44702
44703			// determine how the property gets bound
44704			var bindingType = this.BindingType.Direct;
44705
44706			if ( propertyIndex !== undefined ) {
44707
44708				// access a sub element of the property array (only primitives are supported right now)
44709
44710				if ( propertyName === "morphTargetInfluences" ) {
44711
44712					// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
44713
44714					// support resolving morphTarget names into indices.
44715					if ( ! targetObject.geometry ) {
44716
44717						console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this );
44718						return;
44719
44720					}
44721
44722					if ( targetObject.geometry.isBufferGeometry ) {
44723
44724						if ( ! targetObject.geometry.morphAttributes ) {
44725
44726							console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this );
44727							return;
44728
44729						}
44730
44731						if ( targetObject.morphTargetDictionary[ propertyIndex ] !== undefined ) {
44732
44733							propertyIndex = targetObject.morphTargetDictionary[ propertyIndex ];
44734
44735						}
44736
44737
44738					} else {
44739
44740						console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences on THREE.Geometry. Use THREE.BufferGeometry instead.', this );
44741						return;
44742
44743					}
44744
44745				}
44746
44747				bindingType = this.BindingType.ArrayElement;
44748
44749				this.resolvedProperty = nodeProperty;
44750				this.propertyIndex = propertyIndex;
44751
44752			} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {
44753
44754				// must use copy for Object3D.Euler/Quaternion
44755
44756				bindingType = this.BindingType.HasFromToArray;
44757
44758				this.resolvedProperty = nodeProperty;
44759
44760			} else if ( Array.isArray( nodeProperty ) ) {
44761
44762				bindingType = this.BindingType.EntireArray;
44763
44764				this.resolvedProperty = nodeProperty;
44765
44766			} else {
44767
44768				this.propertyName = propertyName;
44769
44770			}
44771
44772			// select getter / setter
44773			this.getValue = this.GetterByBindingType[ bindingType ];
44774			this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];
44775
44776		},
44777
44778		unbind: function () {
44779
44780			this.node = null;
44781
44782			// back to the prototype version of getValue / setValue
44783			// note: avoiding to mutate the shape of 'this' via 'delete'
44784			this.getValue = this._getValue_unbound;
44785			this.setValue = this._setValue_unbound;
44786
44787		}
44788
44789	} );
44790
44791	// DECLARE ALIAS AFTER assign prototype
44792	Object.assign( PropertyBinding.prototype, {
44793
44794		// initial state of these methods that calls 'bind'
44795		_getValue_unbound: PropertyBinding.prototype.getValue,
44796		_setValue_unbound: PropertyBinding.prototype.setValue,
44797
44798	} );
44799
44800	/**
44801	 *
44802	 * A group of objects that receives a shared animation state.
44803	 *
44804	 * Usage:
44805	 *
44806	 *  - Add objects you would otherwise pass as 'root' to the
44807	 *    constructor or the .clipAction method of AnimationMixer.
44808	 *
44809	 *  - Instead pass this object as 'root'.
44810	 *
44811	 *  - You can also add and remove objects later when the mixer
44812	 *    is running.
44813	 *
44814	 * Note:
44815	 *
44816	 *    Objects of this class appear as one object to the mixer,
44817	 *    so cache control of the individual objects must be done
44818	 *    on the group.
44819	 *
44820	 * Limitation:
44821	 *
44822	 *  - The animated properties must be compatible among the
44823	 *    all objects in the group.
44824	 *
44825	 *  - A single property can either be controlled through a
44826	 *    target group or directly, but not both.
44827	 *
44828	 * @author tschw
44829	 */
44830
44831	function AnimationObjectGroup() {
44832
44833		this.uuid = MathUtils.generateUUID();
44834
44835		// cached objects followed by the active ones
44836		this._objects = Array.prototype.slice.call( arguments );
44837
44838		this.nCachedObjects_ = 0; // threshold
44839		// note: read by PropertyBinding.Composite
44840
44841		var indices = {};
44842		this._indicesByUUID = indices; // for bookkeeping
44843
44844		for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
44845
44846			indices[ arguments[ i ].uuid ] = i;
44847
44848		}
44849
44850		this._paths = []; // inside: string
44851		this._parsedPaths = []; // inside: { we don't care, here }
44852		this._bindings = []; // inside: Array< PropertyBinding >
44853		this._bindingsIndicesByPath = {}; // inside: indices in these arrays
44854
44855		var scope = this;
44856
44857		this.stats = {
44858
44859			objects: {
44860				get total() {
44861
44862					return scope._objects.length;
44863
44864				},
44865				get inUse() {
44866
44867					return this.total - scope.nCachedObjects_;
44868
44869				}
44870			},
44871			get bindingsPerObject() {
44872
44873				return scope._bindings.length;
44874
44875			}
44876
44877		};
44878
44879	}
44880
44881	Object.assign( AnimationObjectGroup.prototype, {
44882
44883		isAnimationObjectGroup: true,
44884
44885		add: function () {
44886
44887			var objects = this._objects,
44888				indicesByUUID = this._indicesByUUID,
44889				paths = this._paths,
44890				parsedPaths = this._parsedPaths,
44891				bindings = this._bindings,
44892				nBindings = bindings.length;
44893
44894			var knownObject = undefined,
44895				nObjects = objects.length,
44896				nCachedObjects = this.nCachedObjects_;
44897
44898			for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
44899
44900				var object = arguments[ i ],
44901					uuid = object.uuid;
44902				var index = indicesByUUID[ uuid ];
44903
44904				if ( index === undefined ) {
44905
44906					// unknown object -> add it to the ACTIVE region
44907
44908					index = nObjects ++;
44909					indicesByUUID[ uuid ] = index;
44910					objects.push( object );
44911
44912					// accounting is done, now do the same for all bindings
44913
44914					for ( var j = 0, m = nBindings; j !== m; ++ j ) {
44915
44916						bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) );
44917
44918					}
44919
44920				} else if ( index < nCachedObjects ) {
44921
44922					knownObject = objects[ index ];
44923
44924					// move existing object to the ACTIVE region
44925
44926					var firstActiveIndex = -- nCachedObjects,
44927						lastCachedObject = objects[ firstActiveIndex ];
44928
44929					indicesByUUID[ lastCachedObject.uuid ] = index;
44930					objects[ index ] = lastCachedObject;
44931
44932					indicesByUUID[ uuid ] = firstActiveIndex;
44933					objects[ firstActiveIndex ] = object;
44934
44935					// accounting is done, now do the same for all bindings
44936
44937					for ( var j$1 = 0, m$1 = nBindings; j$1 !== m$1; ++ j$1 ) {
44938
44939						var bindingsForPath = bindings[ j$1 ],
44940							lastCached = bindingsForPath[ firstActiveIndex ];
44941
44942						var binding = bindingsForPath[ index ];
44943
44944						bindingsForPath[ index ] = lastCached;
44945
44946						if ( binding === undefined ) {
44947
44948							// since we do not bother to create new bindings
44949							// for objects that are cached, the binding may
44950							// or may not exist
44951
44952							binding = new PropertyBinding( object, paths[ j$1 ], parsedPaths[ j$1 ] );
44953
44954						}
44955
44956						bindingsForPath[ firstActiveIndex ] = binding;
44957
44958					}
44959
44960				} else if ( objects[ index ] !== knownObject ) {
44961
44962					console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' +
44963						'detected. Clean the caches or recreate your infrastructure when reloading scenes.' );
44964
44965				} // else the object is already where we want it to be
44966
44967			} // for arguments
44968
44969			this.nCachedObjects_ = nCachedObjects;
44970
44971		},
44972
44973		remove: function () {
44974
44975			var objects = this._objects,
44976				indicesByUUID = this._indicesByUUID,
44977				bindings = this._bindings,
44978				nBindings = bindings.length;
44979
44980			var nCachedObjects = this.nCachedObjects_;
44981
44982			for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
44983
44984				var object = arguments[ i ],
44985					uuid = object.uuid,
44986					index = indicesByUUID[ uuid ];
44987
44988				if ( index !== undefined && index >= nCachedObjects ) {
44989
44990					// move existing object into the CACHED region
44991
44992					var lastCachedIndex = nCachedObjects ++,
44993						firstActiveObject = objects[ lastCachedIndex ];
44994
44995					indicesByUUID[ firstActiveObject.uuid ] = index;
44996					objects[ index ] = firstActiveObject;
44997
44998					indicesByUUID[ uuid ] = lastCachedIndex;
44999					objects[ lastCachedIndex ] = object;
45000
45001					// accounting is done, now do the same for all bindings
45002
45003					for ( var j = 0, m = nBindings; j !== m; ++ j ) {
45004
45005						var bindingsForPath = bindings[ j ],
45006							firstActive = bindingsForPath[ lastCachedIndex ],
45007							binding = bindingsForPath[ index ];
45008
45009						bindingsForPath[ index ] = firstActive;
45010						bindingsForPath[ lastCachedIndex ] = binding;
45011
45012					}
45013
45014				}
45015
45016			} // for arguments
45017
45018			this.nCachedObjects_ = nCachedObjects;
45019
45020		},
45021
45022		// remove & forget
45023		uncache: function () {
45024
45025			var objects = this._objects,
45026				indicesByUUID = this._indicesByUUID,
45027				bindings = this._bindings,
45028				nBindings = bindings.length;
45029
45030			var nCachedObjects = this.nCachedObjects_,
45031				nObjects = objects.length;
45032
45033			for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
45034
45035				var object = arguments[ i ],
45036					uuid = object.uuid,
45037					index = indicesByUUID[ uuid ];
45038
45039				if ( index !== undefined ) {
45040
45041					delete indicesByUUID[ uuid ];
45042
45043					if ( index < nCachedObjects ) {
45044
45045						// object is cached, shrink the CACHED region
45046
45047						var firstActiveIndex = -- nCachedObjects,
45048							lastCachedObject = objects[ firstActiveIndex ],
45049							lastIndex = -- nObjects,
45050							lastObject = objects[ lastIndex ];
45051
45052						// last cached object takes this object's place
45053						indicesByUUID[ lastCachedObject.uuid ] = index;
45054						objects[ index ] = lastCachedObject;
45055
45056						// last object goes to the activated slot and pop
45057						indicesByUUID[ lastObject.uuid ] = firstActiveIndex;
45058						objects[ firstActiveIndex ] = lastObject;
45059						objects.pop();
45060
45061						// accounting is done, now do the same for all bindings
45062
45063						for ( var j = 0, m = nBindings; j !== m; ++ j ) {
45064
45065							var bindingsForPath = bindings[ j ],
45066								lastCached = bindingsForPath[ firstActiveIndex ],
45067								last = bindingsForPath[ lastIndex ];
45068
45069							bindingsForPath[ index ] = lastCached;
45070							bindingsForPath[ firstActiveIndex ] = last;
45071							bindingsForPath.pop();
45072
45073						}
45074
45075					} else {
45076
45077						// object is active, just swap with the last and pop
45078
45079						var lastIndex$1 = -- nObjects,
45080							lastObject$1 = objects[ lastIndex$1 ];
45081
45082						indicesByUUID[ lastObject$1.uuid ] = index;
45083						objects[ index ] = lastObject$1;
45084						objects.pop();
45085
45086						// accounting is done, now do the same for all bindings
45087
45088						for ( var j$1 = 0, m$1 = nBindings; j$1 !== m$1; ++ j$1 ) {
45089
45090							var bindingsForPath$1 = bindings[ j$1 ];
45091
45092							bindingsForPath$1[ index ] = bindingsForPath$1[ lastIndex$1 ];
45093							bindingsForPath$1.pop();
45094
45095						}
45096
45097					} // cached or active
45098
45099				} // if object is known
45100
45101			} // for arguments
45102
45103			this.nCachedObjects_ = nCachedObjects;
45104
45105		},
45106
45107		// Internal interface used by befriended PropertyBinding.Composite:
45108
45109		subscribe_: function ( path, parsedPath ) {
45110
45111			// returns an array of bindings for the given path that is changed
45112			// according to the contained objects in the group
45113
45114			var indicesByPath = this._bindingsIndicesByPath,
45115				index = indicesByPath[ path ],
45116				bindings = this._bindings;
45117
45118			if ( index !== undefined ) { return bindings[ index ]; }
45119
45120			var paths = this._paths,
45121				parsedPaths = this._parsedPaths,
45122				objects = this._objects,
45123				nObjects = objects.length,
45124				nCachedObjects = this.nCachedObjects_,
45125				bindingsForPath = new Array( nObjects );
45126
45127			index = bindings.length;
45128
45129			indicesByPath[ path ] = index;
45130
45131			paths.push( path );
45132			parsedPaths.push( parsedPath );
45133			bindings.push( bindingsForPath );
45134
45135			for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) {
45136
45137				var object = objects[ i ];
45138				bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath );
45139
45140			}
45141
45142			return bindingsForPath;
45143
45144		},
45145
45146		unsubscribe_: function ( path ) {
45147
45148			// tells the group to forget about a property path and no longer
45149			// update the array previously obtained with 'subscribe_'
45150
45151			var indicesByPath = this._bindingsIndicesByPath,
45152				index = indicesByPath[ path ];
45153
45154			if ( index !== undefined ) {
45155
45156				var paths = this._paths,
45157					parsedPaths = this._parsedPaths,
45158					bindings = this._bindings,
45159					lastBindingsIndex = bindings.length - 1,
45160					lastBindings = bindings[ lastBindingsIndex ],
45161					lastBindingsPath = path[ lastBindingsIndex ];
45162
45163				indicesByPath[ lastBindingsPath ] = index;
45164
45165				bindings[ index ] = lastBindings;
45166				bindings.pop();
45167
45168				parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];
45169				parsedPaths.pop();
45170
45171				paths[ index ] = paths[ lastBindingsIndex ];
45172				paths.pop();
45173
45174			}
45175
45176		}
45177
45178	} );
45179
45180	/**
45181	 *
45182	 * Action provided by AnimationMixer for scheduling clip playback on specific
45183	 * objects.
45184	 *
45185	 * @author Ben Houston / http://clara.io/
45186	 * @author David Sarno / http://lighthaus.us/
45187	 * @author tschw
45188	 *
45189	 */
45190
45191	function AnimationAction( mixer, clip, localRoot, blendMode ) {
45192
45193		this._mixer = mixer;
45194		this._clip = clip;
45195		this._localRoot = localRoot || null;
45196		this.blendMode = blendMode || clip.blendMode;
45197
45198		var tracks = clip.tracks,
45199			nTracks = tracks.length,
45200			interpolants = new Array( nTracks );
45201
45202		var interpolantSettings = {
45203			endingStart: ZeroCurvatureEnding,
45204			endingEnd: ZeroCurvatureEnding
45205		};
45206
45207		for ( var i = 0; i !== nTracks; ++ i ) {
45208
45209			var interpolant = tracks[ i ].createInterpolant( null );
45210			interpolants[ i ] = interpolant;
45211			interpolant.settings = interpolantSettings;
45212
45213		}
45214
45215		this._interpolantSettings = interpolantSettings;
45216
45217		this._interpolants = interpolants; // bound by the mixer
45218
45219		// inside: PropertyMixer (managed by the mixer)
45220		this._propertyBindings = new Array( nTracks );
45221
45222		this._cacheIndex = null; // for the memory manager
45223		this._byClipCacheIndex = null; // for the memory manager
45224
45225		this._timeScaleInterpolant = null;
45226		this._weightInterpolant = null;
45227
45228		this.loop = LoopRepeat;
45229		this._loopCount = - 1;
45230
45231		// global mixer time when the action is to be started
45232		// it's set back to 'null' upon start of the action
45233		this._startTime = null;
45234
45235		// scaled local time of the action
45236		// gets clamped or wrapped to 0..clip.duration according to loop
45237		this.time = 0;
45238
45239		this.timeScale = 1;
45240		this._effectiveTimeScale = 1;
45241
45242		this.weight = 1;
45243		this._effectiveWeight = 1;
45244
45245		this.repetitions = Infinity; // no. of repetitions when looping
45246
45247		this.paused = false; // true -> zero effective time scale
45248		this.enabled = true; // false -> zero effective weight
45249
45250		this.clampWhenFinished = false;// keep feeding the last frame?
45251
45252		this.zeroSlopeAtStart = true;// for smooth interpolation w/o separate
45253		this.zeroSlopeAtEnd = true;// clips for start, loop and end
45254
45255	}
45256
45257	Object.assign( AnimationAction.prototype, {
45258
45259		// State & Scheduling
45260
45261		play: function () {
45262
45263			this._mixer._activateAction( this );
45264
45265			return this;
45266
45267		},
45268
45269		stop: function () {
45270
45271			this._mixer._deactivateAction( this );
45272
45273			return this.reset();
45274
45275		},
45276
45277		reset: function () {
45278
45279			this.paused = false;
45280			this.enabled = true;
45281
45282			this.time = 0; // restart clip
45283			this._loopCount = - 1;// forget previous loops
45284			this._startTime = null;// forget scheduling
45285
45286			return this.stopFading().stopWarping();
45287
45288		},
45289
45290		isRunning: function () {
45291
45292			return this.enabled && ! this.paused && this.timeScale !== 0 &&
45293				this._startTime === null && this._mixer._isActiveAction( this );
45294
45295		},
45296
45297		// return true when play has been called
45298		isScheduled: function () {
45299
45300			return this._mixer._isActiveAction( this );
45301
45302		},
45303
45304		startAt: function ( time ) {
45305
45306			this._startTime = time;
45307
45308			return this;
45309
45310		},
45311
45312		setLoop: function ( mode, repetitions ) {
45313
45314			this.loop = mode;
45315			this.repetitions = repetitions;
45316
45317			return this;
45318
45319		},
45320
45321		// Weight
45322
45323		// set the weight stopping any scheduled fading
45324		// although .enabled = false yields an effective weight of zero, this
45325		// method does *not* change .enabled, because it would be confusing
45326		setEffectiveWeight: function ( weight ) {
45327
45328			this.weight = weight;
45329
45330			// note: same logic as when updated at runtime
45331			this._effectiveWeight = this.enabled ? weight : 0;
45332
45333			return this.stopFading();
45334
45335		},
45336
45337		// return the weight considering fading and .enabled
45338		getEffectiveWeight: function () {
45339
45340			return this._effectiveWeight;
45341
45342		},
45343
45344		fadeIn: function ( duration ) {
45345
45346			return this._scheduleFading( duration, 0, 1 );
45347
45348		},
45349
45350		fadeOut: function ( duration ) {
45351
45352			return this._scheduleFading( duration, 1, 0 );
45353
45354		},
45355
45356		crossFadeFrom: function ( fadeOutAction, duration, warp ) {
45357
45358			fadeOutAction.fadeOut( duration );
45359			this.fadeIn( duration );
45360
45361			if ( warp ) {
45362
45363				var fadeInDuration = this._clip.duration,
45364					fadeOutDuration = fadeOutAction._clip.duration,
45365
45366					startEndRatio = fadeOutDuration / fadeInDuration,
45367					endStartRatio = fadeInDuration / fadeOutDuration;
45368
45369				fadeOutAction.warp( 1.0, startEndRatio, duration );
45370				this.warp( endStartRatio, 1.0, duration );
45371
45372			}
45373
45374			return this;
45375
45376		},
45377
45378		crossFadeTo: function ( fadeInAction, duration, warp ) {
45379
45380			return fadeInAction.crossFadeFrom( this, duration, warp );
45381
45382		},
45383
45384		stopFading: function () {
45385
45386			var weightInterpolant = this._weightInterpolant;
45387
45388			if ( weightInterpolant !== null ) {
45389
45390				this._weightInterpolant = null;
45391				this._mixer._takeBackControlInterpolant( weightInterpolant );
45392
45393			}
45394
45395			return this;
45396
45397		},
45398
45399		// Time Scale Control
45400
45401		// set the time scale stopping any scheduled warping
45402		// although .paused = true yields an effective time scale of zero, this
45403		// method does *not* change .paused, because it would be confusing
45404		setEffectiveTimeScale: function ( timeScale ) {
45405
45406			this.timeScale = timeScale;
45407			this._effectiveTimeScale = this.paused ? 0 : timeScale;
45408
45409			return this.stopWarping();
45410
45411		},
45412
45413		// return the time scale considering warping and .paused
45414		getEffectiveTimeScale: function () {
45415
45416			return this._effectiveTimeScale;
45417
45418		},
45419
45420		setDuration: function ( duration ) {
45421
45422			this.timeScale = this._clip.duration / duration;
45423
45424			return this.stopWarping();
45425
45426		},
45427
45428		syncWith: function ( action ) {
45429
45430			this.time = action.time;
45431			this.timeScale = action.timeScale;
45432
45433			return this.stopWarping();
45434
45435		},
45436
45437		halt: function ( duration ) {
45438
45439			return this.warp( this._effectiveTimeScale, 0, duration );
45440
45441		},
45442
45443		warp: function ( startTimeScale, endTimeScale, duration ) {
45444
45445			var mixer = this._mixer,
45446				now = mixer.time,
45447				timeScale = this.timeScale;
45448
45449			var interpolant = this._timeScaleInterpolant;
45450
45451			if ( interpolant === null ) {
45452
45453				interpolant = mixer._lendControlInterpolant();
45454				this._timeScaleInterpolant = interpolant;
45455
45456			}
45457
45458			var times = interpolant.parameterPositions,
45459				values = interpolant.sampleValues;
45460
45461			times[ 0 ] = now;
45462			times[ 1 ] = now + duration;
45463
45464			values[ 0 ] = startTimeScale / timeScale;
45465			values[ 1 ] = endTimeScale / timeScale;
45466
45467			return this;
45468
45469		},
45470
45471		stopWarping: function () {
45472
45473			var timeScaleInterpolant = this._timeScaleInterpolant;
45474
45475			if ( timeScaleInterpolant !== null ) {
45476
45477				this._timeScaleInterpolant = null;
45478				this._mixer._takeBackControlInterpolant( timeScaleInterpolant );
45479
45480			}
45481
45482			return this;
45483
45484		},
45485
45486		// Object Accessors
45487
45488		getMixer: function () {
45489
45490			return this._mixer;
45491
45492		},
45493
45494		getClip: function () {
45495
45496			return this._clip;
45497
45498		},
45499
45500		getRoot: function () {
45501
45502			return this._localRoot || this._mixer._root;
45503
45504		},
45505
45506		// Interna
45507
45508		_update: function ( time, deltaTime, timeDirection, accuIndex ) {
45509
45510			// called by the mixer
45511
45512			if ( ! this.enabled ) {
45513
45514				// call ._updateWeight() to update ._effectiveWeight
45515
45516				this._updateWeight( time );
45517				return;
45518
45519			}
45520
45521			var startTime = this._startTime;
45522
45523			if ( startTime !== null ) {
45524
45525				// check for scheduled start of action
45526
45527				var timeRunning = ( time - startTime ) * timeDirection;
45528				if ( timeRunning < 0 || timeDirection === 0 ) {
45529
45530					return; // yet to come / don't decide when delta = 0
45531
45532				}
45533
45534				// start
45535
45536				this._startTime = null; // unschedule
45537				deltaTime = timeDirection * timeRunning;
45538
45539			}
45540
45541			// apply time scale and advance time
45542
45543			deltaTime *= this._updateTimeScale( time );
45544			var clipTime = this._updateTime( deltaTime );
45545
45546			// note: _updateTime may disable the action resulting in
45547			// an effective weight of 0
45548
45549			var weight = this._updateWeight( time );
45550
45551			if ( weight > 0 ) {
45552
45553				var interpolants = this._interpolants;
45554				var propertyMixers = this._propertyBindings;
45555
45556				switch ( this.blendMode ) {
45557
45558					case AdditiveAnimationBlendMode:
45559
45560						for ( var j = 0, m = interpolants.length; j !== m; ++ j ) {
45561
45562							interpolants[ j ].evaluate( clipTime );
45563							propertyMixers[ j ].accumulateAdditive( weight );
45564
45565						}
45566
45567						break;
45568
45569					case NormalAnimationBlendMode:
45570					default:
45571
45572						for ( var j$1 = 0, m$1 = interpolants.length; j$1 !== m$1; ++ j$1 ) {
45573
45574							interpolants[ j$1 ].evaluate( clipTime );
45575							propertyMixers[ j$1 ].accumulate( accuIndex, weight );
45576
45577						}
45578
45579				}
45580
45581			}
45582
45583		},
45584
45585		_updateWeight: function ( time ) {
45586
45587			var weight = 0;
45588
45589			if ( this.enabled ) {
45590
45591				weight = this.weight;
45592				var interpolant = this._weightInterpolant;
45593
45594				if ( interpolant !== null ) {
45595
45596					var interpolantValue = interpolant.evaluate( time )[ 0 ];
45597
45598					weight *= interpolantValue;
45599
45600					if ( time > interpolant.parameterPositions[ 1 ] ) {
45601
45602						this.stopFading();
45603
45604						if ( interpolantValue === 0 ) {
45605
45606							// faded out, disable
45607							this.enabled = false;
45608
45609						}
45610
45611					}
45612
45613				}
45614
45615			}
45616
45617			this._effectiveWeight = weight;
45618			return weight;
45619
45620		},
45621
45622		_updateTimeScale: function ( time ) {
45623
45624			var timeScale = 0;
45625
45626			if ( ! this.paused ) {
45627
45628				timeScale = this.timeScale;
45629
45630				var interpolant = this._timeScaleInterpolant;
45631
45632				if ( interpolant !== null ) {
45633
45634					var interpolantValue = interpolant.evaluate( time )[ 0 ];
45635
45636					timeScale *= interpolantValue;
45637
45638					if ( time > interpolant.parameterPositions[ 1 ] ) {
45639
45640						this.stopWarping();
45641
45642						if ( timeScale === 0 ) {
45643
45644							// motion has halted, pause
45645							this.paused = true;
45646
45647						} else {
45648
45649							// warp done - apply final time scale
45650							this.timeScale = timeScale;
45651
45652						}
45653
45654					}
45655
45656				}
45657
45658			}
45659
45660			this._effectiveTimeScale = timeScale;
45661			return timeScale;
45662
45663		},
45664
45665		_updateTime: function ( deltaTime ) {
45666
45667			var duration = this._clip.duration;
45668			var loop = this.loop;
45669
45670			var time = this.time + deltaTime;
45671			var loopCount = this._loopCount;
45672
45673			var pingPong = ( loop === LoopPingPong );
45674
45675			if ( deltaTime === 0 ) {
45676
45677				if ( loopCount === - 1 ) { return time; }
45678
45679				return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time;
45680
45681			}
45682
45683			if ( loop === LoopOnce ) {
45684
45685				if ( loopCount === - 1 ) {
45686
45687					// just started
45688
45689					this._loopCount = 0;
45690					this._setEndings( true, true, false );
45691
45692				}
45693
45694				handle_stop: {
45695
45696					if ( time >= duration ) {
45697
45698						time = duration;
45699
45700					} else if ( time < 0 ) {
45701
45702						time = 0;
45703
45704					} else {
45705
45706						this.time = time;
45707
45708						break handle_stop;
45709
45710					}
45711
45712					if ( this.clampWhenFinished ) { this.paused = true; }
45713					else { this.enabled = false; }
45714
45715					this.time = time;
45716
45717					this._mixer.dispatchEvent( {
45718						type: 'finished', action: this,
45719						direction: deltaTime < 0 ? - 1 : 1
45720					} );
45721
45722				}
45723
45724			} else { // repetitive Repeat or PingPong
45725
45726				if ( loopCount === - 1 ) {
45727
45728					// just started
45729
45730					if ( deltaTime >= 0 ) {
45731
45732						loopCount = 0;
45733
45734						this._setEndings( true, this.repetitions === 0, pingPong );
45735
45736					} else {
45737
45738						// when looping in reverse direction, the initial
45739						// transition through zero counts as a repetition,
45740						// so leave loopCount at -1
45741
45742						this._setEndings( this.repetitions === 0, true, pingPong );
45743
45744					}
45745
45746				}
45747
45748				if ( time >= duration || time < 0 ) {
45749
45750					// wrap around
45751
45752					var loopDelta = Math.floor( time / duration ); // signed
45753					time -= duration * loopDelta;
45754
45755					loopCount += Math.abs( loopDelta );
45756
45757					var pending = this.repetitions - loopCount;
45758
45759					if ( pending <= 0 ) {
45760
45761						// have to stop (switch state, clamp time, fire event)
45762
45763						if ( this.clampWhenFinished ) { this.paused = true; }
45764						else { this.enabled = false; }
45765
45766						time = deltaTime > 0 ? duration : 0;
45767
45768						this.time = time;
45769
45770						this._mixer.dispatchEvent( {
45771							type: 'finished', action: this,
45772							direction: deltaTime > 0 ? 1 : - 1
45773						} );
45774
45775					} else {
45776
45777						// keep running
45778
45779						if ( pending === 1 ) {
45780
45781							// entering the last round
45782
45783							var atStart = deltaTime < 0;
45784							this._setEndings( atStart, ! atStart, pingPong );
45785
45786						} else {
45787
45788							this._setEndings( false, false, pingPong );
45789
45790						}
45791
45792						this._loopCount = loopCount;
45793
45794						this.time = time;
45795
45796						this._mixer.dispatchEvent( {
45797							type: 'loop', action: this, loopDelta: loopDelta
45798						} );
45799
45800					}
45801
45802				} else {
45803
45804					this.time = time;
45805
45806				}
45807
45808				if ( pingPong && ( loopCount & 1 ) === 1 ) {
45809
45810					// invert time for the "pong round"
45811
45812					return duration - time;
45813
45814				}
45815
45816			}
45817
45818			return time;
45819
45820		},
45821
45822		_setEndings: function ( atStart, atEnd, pingPong ) {
45823
45824			var settings = this._interpolantSettings;
45825
45826			if ( pingPong ) {
45827
45828				settings.endingStart = ZeroSlopeEnding;
45829				settings.endingEnd = ZeroSlopeEnding;
45830
45831			} else {
45832
45833				// assuming for LoopOnce atStart == atEnd == true
45834
45835				if ( atStart ) {
45836
45837					settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
45838
45839				} else {
45840
45841					settings.endingStart = WrapAroundEnding;
45842
45843				}
45844
45845				if ( atEnd ) {
45846
45847					settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
45848
45849				} else {
45850
45851					settings.endingEnd 	 = WrapAroundEnding;
45852
45853				}
45854
45855			}
45856
45857		},
45858
45859		_scheduleFading: function ( duration, weightNow, weightThen ) {
45860
45861			var mixer = this._mixer, now = mixer.time;
45862			var interpolant = this._weightInterpolant;
45863
45864			if ( interpolant === null ) {
45865
45866				interpolant = mixer._lendControlInterpolant();
45867				this._weightInterpolant = interpolant;
45868
45869			}
45870
45871			var times = interpolant.parameterPositions,
45872				values = interpolant.sampleValues;
45873
45874			times[ 0 ] = now;
45875			values[ 0 ] = weightNow;
45876			times[ 1 ] = now + duration;
45877			values[ 1 ] = weightThen;
45878
45879			return this;
45880
45881		}
45882
45883	} );
45884
45885	/**
45886	 *
45887	 * Player for AnimationClips.
45888	 *
45889	 *
45890	 * @author Ben Houston / http://clara.io/
45891	 * @author David Sarno / http://lighthaus.us/
45892	 * @author tschw
45893	 */
45894
45895	function AnimationMixer( root ) {
45896
45897		this._root = root;
45898		this._initMemoryManager();
45899		this._accuIndex = 0;
45900
45901		this.time = 0;
45902
45903		this.timeScale = 1.0;
45904
45905	}
45906
45907	AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
45908
45909		constructor: AnimationMixer,
45910
45911		_bindAction: function ( action, prototypeAction ) {
45912
45913			var root = action._localRoot || this._root,
45914				tracks = action._clip.tracks,
45915				nTracks = tracks.length,
45916				bindings = action._propertyBindings,
45917				interpolants = action._interpolants,
45918				rootUuid = root.uuid,
45919				bindingsByRoot = this._bindingsByRootAndName;
45920
45921			var bindingsByName = bindingsByRoot[ rootUuid ];
45922
45923			if ( bindingsByName === undefined ) {
45924
45925				bindingsByName = {};
45926				bindingsByRoot[ rootUuid ] = bindingsByName;
45927
45928			}
45929
45930			for ( var i = 0; i !== nTracks; ++ i ) {
45931
45932				var track = tracks[ i ],
45933					trackName = track.name;
45934
45935				var binding = bindingsByName[ trackName ];
45936
45937				if ( binding !== undefined ) {
45938
45939					bindings[ i ] = binding;
45940
45941				} else {
45942
45943					binding = bindings[ i ];
45944
45945					if ( binding !== undefined ) {
45946
45947						// existing binding, make sure the cache knows
45948
45949						if ( binding._cacheIndex === null ) {
45950
45951							++ binding.referenceCount;
45952							this._addInactiveBinding( binding, rootUuid, trackName );
45953
45954						}
45955
45956						continue;
45957
45958					}
45959
45960					var path = prototypeAction && prototypeAction.
45961						_propertyBindings[ i ].binding.parsedPath;
45962
45963					binding = new PropertyMixer(
45964						PropertyBinding.create( root, trackName, path ),
45965						track.ValueTypeName, track.getValueSize() );
45966
45967					++ binding.referenceCount;
45968					this._addInactiveBinding( binding, rootUuid, trackName );
45969
45970					bindings[ i ] = binding;
45971
45972				}
45973
45974				interpolants[ i ].resultBuffer = binding.buffer;
45975
45976			}
45977
45978		},
45979
45980		_activateAction: function ( action ) {
45981
45982			if ( ! this._isActiveAction( action ) ) {
45983
45984				if ( action._cacheIndex === null ) {
45985
45986					// this action has been forgotten by the cache, but the user
45987					// appears to be still using it -> rebind
45988
45989					var rootUuid = ( action._localRoot || this._root ).uuid,
45990						clipUuid = action._clip.uuid,
45991						actionsForClip = this._actionsByClip[ clipUuid ];
45992
45993					this._bindAction( action,
45994						actionsForClip && actionsForClip.knownActions[ 0 ] );
45995
45996					this._addInactiveAction( action, clipUuid, rootUuid );
45997
45998				}
45999
46000				var bindings = action._propertyBindings;
46001
46002				// increment reference counts / sort out state
46003				for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
46004
46005					var binding = bindings[ i ];
46006
46007					if ( binding.useCount ++ === 0 ) {
46008
46009						this._lendBinding( binding );
46010						binding.saveOriginalState();
46011
46012					}
46013
46014				}
46015
46016				this._lendAction( action );
46017
46018			}
46019
46020		},
46021
46022		_deactivateAction: function ( action ) {
46023
46024			if ( this._isActiveAction( action ) ) {
46025
46026				var bindings = action._propertyBindings;
46027
46028				// decrement reference counts / sort out state
46029				for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
46030
46031					var binding = bindings[ i ];
46032
46033					if ( -- binding.useCount === 0 ) {
46034
46035						binding.restoreOriginalState();
46036						this._takeBackBinding( binding );
46037
46038					}
46039
46040				}
46041
46042				this._takeBackAction( action );
46043
46044			}
46045
46046		},
46047
46048		// Memory manager
46049
46050		_initMemoryManager: function () {
46051
46052			this._actions = []; // 'nActiveActions' followed by inactive ones
46053			this._nActiveActions = 0;
46054
46055			this._actionsByClip = {};
46056			// inside:
46057			// {
46058			// 	knownActions: Array< AnimationAction > - used as prototypes
46059			// 	actionByRoot: AnimationAction - lookup
46060			// }
46061
46062
46063			this._bindings = []; // 'nActiveBindings' followed by inactive ones
46064			this._nActiveBindings = 0;
46065
46066			this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
46067
46068
46069			this._controlInterpolants = []; // same game as above
46070			this._nActiveControlInterpolants = 0;
46071
46072			var scope = this;
46073
46074			this.stats = {
46075
46076				actions: {
46077					get total() {
46078
46079						return scope._actions.length;
46080
46081					},
46082					get inUse() {
46083
46084						return scope._nActiveActions;
46085
46086					}
46087				},
46088				bindings: {
46089					get total() {
46090
46091						return scope._bindings.length;
46092
46093					},
46094					get inUse() {
46095
46096						return scope._nActiveBindings;
46097
46098					}
46099				},
46100				controlInterpolants: {
46101					get total() {
46102
46103						return scope._controlInterpolants.length;
46104
46105					},
46106					get inUse() {
46107
46108						return scope._nActiveControlInterpolants;
46109
46110					}
46111				}
46112
46113			};
46114
46115		},
46116
46117		// Memory management for AnimationAction objects
46118
46119		_isActiveAction: function ( action ) {
46120
46121			var index = action._cacheIndex;
46122			return index !== null && index < this._nActiveActions;
46123
46124		},
46125
46126		_addInactiveAction: function ( action, clipUuid, rootUuid ) {
46127
46128			var actions = this._actions,
46129				actionsByClip = this._actionsByClip;
46130
46131			var actionsForClip = actionsByClip[ clipUuid ];
46132
46133			if ( actionsForClip === undefined ) {
46134
46135				actionsForClip = {
46136
46137					knownActions: [ action ],
46138					actionByRoot: {}
46139
46140				};
46141
46142				action._byClipCacheIndex = 0;
46143
46144				actionsByClip[ clipUuid ] = actionsForClip;
46145
46146			} else {
46147
46148				var knownActions = actionsForClip.knownActions;
46149
46150				action._byClipCacheIndex = knownActions.length;
46151				knownActions.push( action );
46152
46153			}
46154
46155			action._cacheIndex = actions.length;
46156			actions.push( action );
46157
46158			actionsForClip.actionByRoot[ rootUuid ] = action;
46159
46160		},
46161
46162		_removeInactiveAction: function ( action ) {
46163
46164			var actions = this._actions,
46165				lastInactiveAction = actions[ actions.length - 1 ],
46166				cacheIndex = action._cacheIndex;
46167
46168			lastInactiveAction._cacheIndex = cacheIndex;
46169			actions[ cacheIndex ] = lastInactiveAction;
46170			actions.pop();
46171
46172			action._cacheIndex = null;
46173
46174
46175			var clipUuid = action._clip.uuid,
46176				actionsByClip = this._actionsByClip,
46177				actionsForClip = actionsByClip[ clipUuid ],
46178				knownActionsForClip = actionsForClip.knownActions,
46179
46180				lastKnownAction =
46181					knownActionsForClip[ knownActionsForClip.length - 1 ],
46182
46183				byClipCacheIndex = action._byClipCacheIndex;
46184
46185			lastKnownAction._byClipCacheIndex = byClipCacheIndex;
46186			knownActionsForClip[ byClipCacheIndex ] = lastKnownAction;
46187			knownActionsForClip.pop();
46188
46189			action._byClipCacheIndex = null;
46190
46191
46192			var actionByRoot = actionsForClip.actionByRoot,
46193				rootUuid = ( action._localRoot || this._root ).uuid;
46194
46195			delete actionByRoot[ rootUuid ];
46196
46197			if ( knownActionsForClip.length === 0 ) {
46198
46199				delete actionsByClip[ clipUuid ];
46200
46201			}
46202
46203			this._removeInactiveBindingsForAction( action );
46204
46205		},
46206
46207		_removeInactiveBindingsForAction: function ( action ) {
46208
46209			var bindings = action._propertyBindings;
46210
46211			for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
46212
46213				var binding = bindings[ i ];
46214
46215				if ( -- binding.referenceCount === 0 ) {
46216
46217					this._removeInactiveBinding( binding );
46218
46219				}
46220
46221			}
46222
46223		},
46224
46225		_lendAction: function ( action ) {
46226
46227			// [ active actions |  inactive actions  ]
46228			// [  active actions >| inactive actions ]
46229			//                 s        a
46230			//                  <-swap->
46231			//                 a        s
46232
46233			var actions = this._actions,
46234				prevIndex = action._cacheIndex,
46235
46236				lastActiveIndex = this._nActiveActions ++,
46237
46238				firstInactiveAction = actions[ lastActiveIndex ];
46239
46240			action._cacheIndex = lastActiveIndex;
46241			actions[ lastActiveIndex ] = action;
46242
46243			firstInactiveAction._cacheIndex = prevIndex;
46244			actions[ prevIndex ] = firstInactiveAction;
46245
46246		},
46247
46248		_takeBackAction: function ( action ) {
46249
46250			// [  active actions  | inactive actions ]
46251			// [ active actions |< inactive actions  ]
46252			//        a        s
46253			//         <-swap->
46254			//        s        a
46255
46256			var actions = this._actions,
46257				prevIndex = action._cacheIndex,
46258
46259				firstInactiveIndex = -- this._nActiveActions,
46260
46261				lastActiveAction = actions[ firstInactiveIndex ];
46262
46263			action._cacheIndex = firstInactiveIndex;
46264			actions[ firstInactiveIndex ] = action;
46265
46266			lastActiveAction._cacheIndex = prevIndex;
46267			actions[ prevIndex ] = lastActiveAction;
46268
46269		},
46270
46271		// Memory management for PropertyMixer objects
46272
46273		_addInactiveBinding: function ( binding, rootUuid, trackName ) {
46274
46275			var bindingsByRoot = this._bindingsByRootAndName,
46276				bindings = this._bindings;
46277
46278			var bindingByName = bindingsByRoot[ rootUuid ];
46279
46280			if ( bindingByName === undefined ) {
46281
46282				bindingByName = {};
46283				bindingsByRoot[ rootUuid ] = bindingByName;
46284
46285			}
46286
46287			bindingByName[ trackName ] = binding;
46288
46289			binding._cacheIndex = bindings.length;
46290			bindings.push( binding );
46291
46292		},
46293
46294		_removeInactiveBinding: function ( binding ) {
46295
46296			var bindings = this._bindings,
46297				propBinding = binding.binding,
46298				rootUuid = propBinding.rootNode.uuid,
46299				trackName = propBinding.path,
46300				bindingsByRoot = this._bindingsByRootAndName,
46301				bindingByName = bindingsByRoot[ rootUuid ],
46302
46303				lastInactiveBinding = bindings[ bindings.length - 1 ],
46304				cacheIndex = binding._cacheIndex;
46305
46306			lastInactiveBinding._cacheIndex = cacheIndex;
46307			bindings[ cacheIndex ] = lastInactiveBinding;
46308			bindings.pop();
46309
46310			delete bindingByName[ trackName ];
46311
46312			if ( Object.keys( bindingByName ).length === 0 ) {
46313
46314				delete bindingsByRoot[ rootUuid ];
46315
46316			}
46317
46318		},
46319
46320		_lendBinding: function ( binding ) {
46321
46322			var bindings = this._bindings,
46323				prevIndex = binding._cacheIndex,
46324
46325				lastActiveIndex = this._nActiveBindings ++,
46326
46327				firstInactiveBinding = bindings[ lastActiveIndex ];
46328
46329			binding._cacheIndex = lastActiveIndex;
46330			bindings[ lastActiveIndex ] = binding;
46331
46332			firstInactiveBinding._cacheIndex = prevIndex;
46333			bindings[ prevIndex ] = firstInactiveBinding;
46334
46335		},
46336
46337		_takeBackBinding: function ( binding ) {
46338
46339			var bindings = this._bindings,
46340				prevIndex = binding._cacheIndex,
46341
46342				firstInactiveIndex = -- this._nActiveBindings,
46343
46344				lastActiveBinding = bindings[ firstInactiveIndex ];
46345
46346			binding._cacheIndex = firstInactiveIndex;
46347			bindings[ firstInactiveIndex ] = binding;
46348
46349			lastActiveBinding._cacheIndex = prevIndex;
46350			bindings[ prevIndex ] = lastActiveBinding;
46351
46352		},
46353
46354
46355		// Memory management of Interpolants for weight and time scale
46356
46357		_lendControlInterpolant: function () {
46358
46359			var interpolants = this._controlInterpolants,
46360				lastActiveIndex = this._nActiveControlInterpolants ++;
46361
46362			var interpolant = interpolants[ lastActiveIndex ];
46363
46364			if ( interpolant === undefined ) {
46365
46366				interpolant = new LinearInterpolant(
46367					new Float32Array( 2 ), new Float32Array( 2 ),
46368					1, this._controlInterpolantsResultBuffer );
46369
46370				interpolant.__cacheIndex = lastActiveIndex;
46371				interpolants[ lastActiveIndex ] = interpolant;
46372
46373			}
46374
46375			return interpolant;
46376
46377		},
46378
46379		_takeBackControlInterpolant: function ( interpolant ) {
46380
46381			var interpolants = this._controlInterpolants,
46382				prevIndex = interpolant.__cacheIndex,
46383
46384				firstInactiveIndex = -- this._nActiveControlInterpolants,
46385
46386				lastActiveInterpolant = interpolants[ firstInactiveIndex ];
46387
46388			interpolant.__cacheIndex = firstInactiveIndex;
46389			interpolants[ firstInactiveIndex ] = interpolant;
46390
46391			lastActiveInterpolant.__cacheIndex = prevIndex;
46392			interpolants[ prevIndex ] = lastActiveInterpolant;
46393
46394		},
46395
46396		_controlInterpolantsResultBuffer: new Float32Array( 1 ),
46397
46398		// return an action for a clip optionally using a custom root target
46399		// object (this method allocates a lot of dynamic memory in case a
46400		// previously unknown clip/root combination is specified)
46401		clipAction: function ( clip, optionalRoot, blendMode ) {
46402
46403			var root = optionalRoot || this._root,
46404				rootUuid = root.uuid;
46405
46406			var clipObject = typeof clip === 'string' ? AnimationClip.findByName( root, clip ) : clip;
46407
46408			var clipUuid = clipObject !== null ? clipObject.uuid : clip;
46409
46410			var actionsForClip = this._actionsByClip[ clipUuid ],
46411				prototypeAction = null;
46412
46413			if ( blendMode === undefined ) {
46414
46415				if ( clipObject !== null ) {
46416
46417					blendMode = clipObject.blendMode;
46418
46419				} else {
46420
46421					blendMode = NormalAnimationBlendMode;
46422
46423				}
46424
46425			}
46426
46427			if ( actionsForClip !== undefined ) {
46428
46429				var existingAction = actionsForClip.actionByRoot[ rootUuid ];
46430
46431				if ( existingAction !== undefined && existingAction.blendMode === blendMode ) {
46432
46433					return existingAction;
46434
46435				}
46436
46437				// we know the clip, so we don't have to parse all
46438				// the bindings again but can just copy
46439				prototypeAction = actionsForClip.knownActions[ 0 ];
46440
46441				// also, take the clip from the prototype action
46442				if ( clipObject === null )
46443					{ clipObject = prototypeAction._clip; }
46444
46445			}
46446
46447			// clip must be known when specified via string
46448			if ( clipObject === null ) { return null; }
46449
46450			// allocate all resources required to run it
46451			var newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode );
46452
46453			this._bindAction( newAction, prototypeAction );
46454
46455			// and make the action known to the memory manager
46456			this._addInactiveAction( newAction, clipUuid, rootUuid );
46457
46458			return newAction;
46459
46460		},
46461
46462		// get an existing action
46463		existingAction: function ( clip, optionalRoot ) {
46464
46465			var root = optionalRoot || this._root,
46466				rootUuid = root.uuid,
46467
46468				clipObject = typeof clip === 'string' ?
46469					AnimationClip.findByName( root, clip ) : clip,
46470
46471				clipUuid = clipObject ? clipObject.uuid : clip,
46472
46473				actionsForClip = this._actionsByClip[ clipUuid ];
46474
46475			if ( actionsForClip !== undefined ) {
46476
46477				return actionsForClip.actionByRoot[ rootUuid ] || null;
46478
46479			}
46480
46481			return null;
46482
46483		},
46484
46485		// deactivates all previously scheduled actions
46486		stopAllAction: function () {
46487
46488			var actions = this._actions,
46489				nActions = this._nActiveActions;
46490
46491			for ( var i = nActions - 1; i >= 0; -- i ) {
46492
46493				actions[ i ].stop();
46494
46495			}
46496
46497			return this;
46498
46499		},
46500
46501		// advance the time and update apply the animation
46502		update: function ( deltaTime ) {
46503
46504			deltaTime *= this.timeScale;
46505
46506			var actions = this._actions,
46507				nActions = this._nActiveActions,
46508
46509				time = this.time += deltaTime,
46510				timeDirection = Math.sign( deltaTime ),
46511
46512				accuIndex = this._accuIndex ^= 1;
46513
46514			// run active actions
46515
46516			for ( var i = 0; i !== nActions; ++ i ) {
46517
46518				var action = actions[ i ];
46519
46520				action._update( time, deltaTime, timeDirection, accuIndex );
46521
46522			}
46523
46524			// update scene graph
46525
46526			var bindings = this._bindings,
46527				nBindings = this._nActiveBindings;
46528
46529			for ( var i$1 = 0; i$1 !== nBindings; ++ i$1 ) {
46530
46531				bindings[ i$1 ].apply( accuIndex );
46532
46533			}
46534
46535			return this;
46536
46537		},
46538
46539		// Allows you to seek to a specific time in an animation.
46540		setTime: function ( timeInSeconds ) {
46541
46542			this.time = 0; // Zero out time attribute for AnimationMixer object;
46543			for ( var i = 0; i < this._actions.length; i ++ ) {
46544
46545				this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects.
46546
46547			}
46548
46549			return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object.
46550
46551		},
46552
46553		// return this mixer's root target object
46554		getRoot: function () {
46555
46556			return this._root;
46557
46558		},
46559
46560		// free all resources specific to a particular clip
46561		uncacheClip: function ( clip ) {
46562
46563			var actions = this._actions,
46564				clipUuid = clip.uuid,
46565				actionsByClip = this._actionsByClip,
46566				actionsForClip = actionsByClip[ clipUuid ];
46567
46568			if ( actionsForClip !== undefined ) {
46569
46570				// note: just calling _removeInactiveAction would mess up the
46571				// iteration state and also require updating the state we can
46572				// just throw away
46573
46574				var actionsToRemove = actionsForClip.knownActions;
46575
46576				for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {
46577
46578					var action = actionsToRemove[ i ];
46579
46580					this._deactivateAction( action );
46581
46582					var cacheIndex = action._cacheIndex,
46583						lastInactiveAction = actions[ actions.length - 1 ];
46584
46585					action._cacheIndex = null;
46586					action._byClipCacheIndex = null;
46587
46588					lastInactiveAction._cacheIndex = cacheIndex;
46589					actions[ cacheIndex ] = lastInactiveAction;
46590					actions.pop();
46591
46592					this._removeInactiveBindingsForAction( action );
46593
46594				}
46595
46596				delete actionsByClip[ clipUuid ];
46597
46598			}
46599
46600		},
46601
46602		// free all resources specific to a particular root target object
46603		uncacheRoot: function ( root ) {
46604
46605			var rootUuid = root.uuid,
46606				actionsByClip = this._actionsByClip;
46607
46608			for ( var clipUuid in actionsByClip ) {
46609
46610				var actionByRoot = actionsByClip[ clipUuid ].actionByRoot,
46611					action = actionByRoot[ rootUuid ];
46612
46613				if ( action !== undefined ) {
46614
46615					this._deactivateAction( action );
46616					this._removeInactiveAction( action );
46617
46618				}
46619
46620			}
46621
46622			var bindingsByRoot = this._bindingsByRootAndName,
46623				bindingByName = bindingsByRoot[ rootUuid ];
46624
46625			if ( bindingByName !== undefined ) {
46626
46627				for ( var trackName in bindingByName ) {
46628
46629					var binding = bindingByName[ trackName ];
46630					binding.restoreOriginalState();
46631					this._removeInactiveBinding( binding );
46632
46633				}
46634
46635			}
46636
46637		},
46638
46639		// remove a targeted clip from the cache
46640		uncacheAction: function ( clip, optionalRoot ) {
46641
46642			var action = this.existingAction( clip, optionalRoot );
46643
46644			if ( action !== null ) {
46645
46646				this._deactivateAction( action );
46647				this._removeInactiveAction( action );
46648
46649			}
46650
46651		}
46652
46653	} );
46654
46655	/**
46656	 * @author mrdoob / http://mrdoob.com/
46657	 */
46658
46659	function Uniform( value ) {
46660
46661		if ( typeof value === 'string' ) {
46662
46663			console.warn( 'THREE.Uniform: Type parameter is no longer needed.' );
46664			value = arguments[ 1 ];
46665
46666		}
46667
46668		this.value = value;
46669
46670	}
46671
46672	Uniform.prototype.clone = function () {
46673
46674		return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );
46675
46676	};
46677
46678	/**
46679	 * @author benaadams / https://twitter.com/ben_a_adams
46680	 */
46681
46682	function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {
46683
46684		InterleavedBuffer.call( this, array, stride );
46685
46686		this.meshPerAttribute = meshPerAttribute || 1;
46687
46688	}
46689
46690	InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), {
46691
46692		constructor: InstancedInterleavedBuffer,
46693
46694		isInstancedInterleavedBuffer: true,
46695
46696		copy: function ( source ) {
46697
46698			InterleavedBuffer.prototype.copy.call( this, source );
46699
46700			this.meshPerAttribute = source.meshPerAttribute;
46701
46702			return this;
46703
46704		},
46705
46706		clone: function ( data ) {
46707
46708			var ib = InterleavedBuffer.prototype.clone.call( this, data );
46709
46710			ib.meshPerAttribute = this.meshPerAttribute;
46711
46712			return ib;
46713
46714		},
46715
46716		toJSON: function ( data ) {
46717
46718			var json = InterleavedBuffer.prototype.toJSON.call( this, data );
46719
46720			json.isInstancedInterleavedBuffer = true;
46721			json.meshPerAttribute = this.meshPerAttribute;
46722
46723			return json;
46724
46725		}
46726
46727	} );
46728
46729	/**
46730	 * @author mrdoob / http://mrdoob.com/
46731	 * @author bhouston / http://clara.io/
46732	 * @author stephomi / http://stephaneginier.com/
46733	 */
46734
46735	function Raycaster( origin, direction, near, far ) {
46736
46737		this.ray = new Ray( origin, direction );
46738		// direction is assumed to be normalized (for accurate distance calculations)
46739
46740		this.near = near || 0;
46741		this.far = far || Infinity;
46742		this.camera = null;
46743		this.layers = new Layers();
46744
46745		this.params = {
46746			Mesh: {},
46747			Line: { threshold: 1 },
46748			LOD: {},
46749			Points: { threshold: 1 },
46750			Sprite: {}
46751		};
46752
46753		Object.defineProperties( this.params, {
46754			PointCloud: {
46755				get: function () {
46756
46757					console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
46758					return this.Points;
46759
46760				}
46761			}
46762		} );
46763
46764	}
46765
46766	function ascSort( a, b ) {
46767
46768		return a.distance - b.distance;
46769
46770	}
46771
46772	function intersectObject( object, raycaster, intersects, recursive ) {
46773
46774		if ( object.layers.test( raycaster.layers ) ) {
46775
46776			object.raycast( raycaster, intersects );
46777
46778		}
46779
46780		if ( recursive === true ) {
46781
46782			var children = object.children;
46783
46784			for ( var i = 0, l = children.length; i < l; i ++ ) {
46785
46786				intersectObject( children[ i ], raycaster, intersects, true );
46787
46788			}
46789
46790		}
46791
46792	}
46793
46794	Object.assign( Raycaster.prototype, {
46795
46796		set: function ( origin, direction ) {
46797
46798			// direction is assumed to be normalized (for accurate distance calculations)
46799
46800			this.ray.set( origin, direction );
46801
46802		},
46803
46804		setFromCamera: function ( coords, camera ) {
46805
46806			if ( ( camera && camera.isPerspectiveCamera ) ) {
46807
46808				this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
46809				this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
46810				this.camera = camera;
46811
46812			} else if ( ( camera && camera.isOrthographicCamera ) ) {
46813
46814				this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
46815				this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
46816				this.camera = camera;
46817
46818			} else {
46819
46820				console.error( 'THREE.Raycaster: Unsupported camera type.' );
46821
46822			}
46823
46824		},
46825
46826		intersectObject: function ( object, recursive, optionalTarget ) {
46827
46828			var intersects = optionalTarget || [];
46829
46830			intersectObject( object, this, intersects, recursive );
46831
46832			intersects.sort( ascSort );
46833
46834			return intersects;
46835
46836		},
46837
46838		intersectObjects: function ( objects, recursive, optionalTarget ) {
46839
46840			var intersects = optionalTarget || [];
46841
46842			if ( Array.isArray( objects ) === false ) {
46843
46844				console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
46845				return intersects;
46846
46847			}
46848
46849			for ( var i = 0, l = objects.length; i < l; i ++ ) {
46850
46851				intersectObject( objects[ i ], this, intersects, recursive );
46852
46853			}
46854
46855			intersects.sort( ascSort );
46856
46857			return intersects;
46858
46859		}
46860
46861	} );
46862
46863	/**
46864	 * @author bhouston / http://clara.io
46865	 * @author WestLangley / http://github.com/WestLangley
46866	 *
46867	 * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system
46868	 *
46869	 * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up.
46870	 * The azimuthal angle (theta) is measured from the positive z-axis.
46871	 */
46872
46873	function Spherical( radius, phi, theta ) {
46874
46875		this.radius = ( radius !== undefined ) ? radius : 1.0;
46876		this.phi = ( phi !== undefined ) ? phi : 0; // polar angle
46877		this.theta = ( theta !== undefined ) ? theta : 0; // azimuthal angle
46878
46879		return this;
46880
46881	}
46882
46883	Object.assign( Spherical.prototype, {
46884
46885		set: function ( radius, phi, theta ) {
46886
46887			this.radius = radius;
46888			this.phi = phi;
46889			this.theta = theta;
46890
46891			return this;
46892
46893		},
46894
46895		clone: function () {
46896
46897			return new this.constructor().copy( this );
46898
46899		},
46900
46901		copy: function ( other ) {
46902
46903			this.radius = other.radius;
46904			this.phi = other.phi;
46905			this.theta = other.theta;
46906
46907			return this;
46908
46909		},
46910
46911		// restrict phi to be betwee EPS and PI-EPS
46912		makeSafe: function () {
46913
46914			var EPS = 0.000001;
46915			this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );
46916
46917			return this;
46918
46919		},
46920
46921		setFromVector3: function ( v ) {
46922
46923			return this.setFromCartesianCoords( v.x, v.y, v.z );
46924
46925		},
46926
46927		setFromCartesianCoords: function ( x, y, z ) {
46928
46929			this.radius = Math.sqrt( x * x + y * y + z * z );
46930
46931			if ( this.radius === 0 ) {
46932
46933				this.theta = 0;
46934				this.phi = 0;
46935
46936			} else {
46937
46938				this.theta = Math.atan2( x, z );
46939				this.phi = Math.acos( MathUtils.clamp( y / this.radius, - 1, 1 ) );
46940
46941			}
46942
46943			return this;
46944
46945		}
46946
46947	} );
46948
46949	/**
46950	 * @author Mugen87 / https://github.com/Mugen87
46951	 *
46952	 * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system
46953	 *
46954	 */
46955
46956	function Cylindrical( radius, theta, y ) {
46957
46958		this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane
46959		this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis
46960		this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane
46961
46962		return this;
46963
46964	}
46965
46966	Object.assign( Cylindrical.prototype, {
46967
46968		set: function ( radius, theta, y ) {
46969
46970			this.radius = radius;
46971			this.theta = theta;
46972			this.y = y;
46973
46974			return this;
46975
46976		},
46977
46978		clone: function () {
46979
46980			return new this.constructor().copy( this );
46981
46982		},
46983
46984		copy: function ( other ) {
46985
46986			this.radius = other.radius;
46987			this.theta = other.theta;
46988			this.y = other.y;
46989
46990			return this;
46991
46992		},
46993
46994		setFromVector3: function ( v ) {
46995
46996			return this.setFromCartesianCoords( v.x, v.y, v.z );
46997
46998		},
46999
47000		setFromCartesianCoords: function ( x, y, z ) {
47001
47002			this.radius = Math.sqrt( x * x + z * z );
47003			this.theta = Math.atan2( x, z );
47004			this.y = y;
47005
47006			return this;
47007
47008		}
47009
47010	} );
47011
47012	/**
47013	 * @author bhouston / http://clara.io
47014	 */
47015
47016	var _vector$7 = new Vector2();
47017
47018	function Box2( min, max ) {
47019
47020		this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );
47021		this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );
47022
47023	}
47024
47025	Object.assign( Box2.prototype, {
47026
47027		set: function ( min, max ) {
47028
47029			this.min.copy( min );
47030			this.max.copy( max );
47031
47032			return this;
47033
47034		},
47035
47036		setFromPoints: function ( points ) {
47037
47038			this.makeEmpty();
47039
47040			for ( var i = 0, il = points.length; i < il; i ++ ) {
47041
47042				this.expandByPoint( points[ i ] );
47043
47044			}
47045
47046			return this;
47047
47048		},
47049
47050		setFromCenterAndSize: function ( center, size ) {
47051
47052			var halfSize = _vector$7.copy( size ).multiplyScalar( 0.5 );
47053			this.min.copy( center ).sub( halfSize );
47054			this.max.copy( center ).add( halfSize );
47055
47056			return this;
47057
47058		},
47059
47060		clone: function () {
47061
47062			return new this.constructor().copy( this );
47063
47064		},
47065
47066		copy: function ( box ) {
47067
47068			this.min.copy( box.min );
47069			this.max.copy( box.max );
47070
47071			return this;
47072
47073		},
47074
47075		makeEmpty: function () {
47076
47077			this.min.x = this.min.y = + Infinity;
47078			this.max.x = this.max.y = - Infinity;
47079
47080			return this;
47081
47082		},
47083
47084		isEmpty: function () {
47085
47086			// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
47087
47088			return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
47089
47090		},
47091
47092		getCenter: function ( target ) {
47093
47094			if ( target === undefined ) {
47095
47096				console.warn( 'THREE.Box2: .getCenter() target is now required' );
47097				target = new Vector2();
47098
47099			}
47100
47101			return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
47102
47103		},
47104
47105		getSize: function ( target ) {
47106
47107			if ( target === undefined ) {
47108
47109				console.warn( 'THREE.Box2: .getSize() target is now required' );
47110				target = new Vector2();
47111
47112			}
47113
47114			return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min );
47115
47116		},
47117
47118		expandByPoint: function ( point ) {
47119
47120			this.min.min( point );
47121			this.max.max( point );
47122
47123			return this;
47124
47125		},
47126
47127		expandByVector: function ( vector ) {
47128
47129			this.min.sub( vector );
47130			this.max.add( vector );
47131
47132			return this;
47133
47134		},
47135
47136		expandByScalar: function ( scalar ) {
47137
47138			this.min.addScalar( - scalar );
47139			this.max.addScalar( scalar );
47140
47141			return this;
47142
47143		},
47144
47145		containsPoint: function ( point ) {
47146
47147			return point.x < this.min.x || point.x > this.max.x ||
47148				point.y < this.min.y || point.y > this.max.y ? false : true;
47149
47150		},
47151
47152		containsBox: function ( box ) {
47153
47154			return this.min.x <= box.min.x && box.max.x <= this.max.x &&
47155				this.min.y <= box.min.y && box.max.y <= this.max.y;
47156
47157		},
47158
47159		getParameter: function ( point, target ) {
47160
47161			// This can potentially have a divide by zero if the box
47162			// has a size dimension of 0.
47163
47164			if ( target === undefined ) {
47165
47166				console.warn( 'THREE.Box2: .getParameter() target is now required' );
47167				target = new Vector2();
47168
47169			}
47170
47171			return target.set(
47172				( point.x - this.min.x ) / ( this.max.x - this.min.x ),
47173				( point.y - this.min.y ) / ( this.max.y - this.min.y )
47174			);
47175
47176		},
47177
47178		intersectsBox: function ( box ) {
47179
47180			// using 4 splitting planes to rule out intersections
47181
47182			return box.max.x < this.min.x || box.min.x > this.max.x ||
47183				box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
47184
47185		},
47186
47187		clampPoint: function ( point, target ) {
47188
47189			if ( target === undefined ) {
47190
47191				console.warn( 'THREE.Box2: .clampPoint() target is now required' );
47192				target = new Vector2();
47193
47194			}
47195
47196			return target.copy( point ).clamp( this.min, this.max );
47197
47198		},
47199
47200		distanceToPoint: function ( point ) {
47201
47202			var clampedPoint = _vector$7.copy( point ).clamp( this.min, this.max );
47203			return clampedPoint.sub( point ).length();
47204
47205		},
47206
47207		intersect: function ( box ) {
47208
47209			this.min.max( box.min );
47210			this.max.min( box.max );
47211
47212			return this;
47213
47214		},
47215
47216		union: function ( box ) {
47217
47218			this.min.min( box.min );
47219			this.max.max( box.max );
47220
47221			return this;
47222
47223		},
47224
47225		translate: function ( offset ) {
47226
47227			this.min.add( offset );
47228			this.max.add( offset );
47229
47230			return this;
47231
47232		},
47233
47234		equals: function ( box ) {
47235
47236			return box.min.equals( this.min ) && box.max.equals( this.max );
47237
47238		}
47239
47240	} );
47241
47242	/**
47243	 * @author bhouston / http://clara.io
47244	 */
47245
47246	var _startP = new Vector3();
47247	var _startEnd = new Vector3();
47248
47249	function Line3( start, end ) {
47250
47251		this.start = ( start !== undefined ) ? start : new Vector3();
47252		this.end = ( end !== undefined ) ? end : new Vector3();
47253
47254	}
47255
47256	Object.assign( Line3.prototype, {
47257
47258		set: function ( start, end ) {
47259
47260			this.start.copy( start );
47261			this.end.copy( end );
47262
47263			return this;
47264
47265		},
47266
47267		clone: function () {
47268
47269			return new this.constructor().copy( this );
47270
47271		},
47272
47273		copy: function ( line ) {
47274
47275			this.start.copy( line.start );
47276			this.end.copy( line.end );
47277
47278			return this;
47279
47280		},
47281
47282		getCenter: function ( target ) {
47283
47284			if ( target === undefined ) {
47285
47286				console.warn( 'THREE.Line3: .getCenter() target is now required' );
47287				target = new Vector3();
47288
47289			}
47290
47291			return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
47292
47293		},
47294
47295		delta: function ( target ) {
47296
47297			if ( target === undefined ) {
47298
47299				console.warn( 'THREE.Line3: .delta() target is now required' );
47300				target = new Vector3();
47301
47302			}
47303
47304			return target.subVectors( this.end, this.start );
47305
47306		},
47307
47308		distanceSq: function () {
47309
47310			return this.start.distanceToSquared( this.end );
47311
47312		},
47313
47314		distance: function () {
47315
47316			return this.start.distanceTo( this.end );
47317
47318		},
47319
47320		at: function ( t, target ) {
47321
47322			if ( target === undefined ) {
47323
47324				console.warn( 'THREE.Line3: .at() target is now required' );
47325				target = new Vector3();
47326
47327			}
47328
47329			return this.delta( target ).multiplyScalar( t ).add( this.start );
47330
47331		},
47332
47333		closestPointToPointParameter: function ( point, clampToLine ) {
47334
47335			_startP.subVectors( point, this.start );
47336			_startEnd.subVectors( this.end, this.start );
47337
47338			var startEnd2 = _startEnd.dot( _startEnd );
47339			var startEnd_startP = _startEnd.dot( _startP );
47340
47341			var t = startEnd_startP / startEnd2;
47342
47343			if ( clampToLine ) {
47344
47345				t = MathUtils.clamp( t, 0, 1 );
47346
47347			}
47348
47349			return t;
47350
47351		},
47352
47353		closestPointToPoint: function ( point, clampToLine, target ) {
47354
47355			var t = this.closestPointToPointParameter( point, clampToLine );
47356
47357			if ( target === undefined ) {
47358
47359				console.warn( 'THREE.Line3: .closestPointToPoint() target is now required' );
47360				target = new Vector3();
47361
47362			}
47363
47364			return this.delta( target ).multiplyScalar( t ).add( this.start );
47365
47366		},
47367
47368		applyMatrix4: function ( matrix ) {
47369
47370			this.start.applyMatrix4( matrix );
47371			this.end.applyMatrix4( matrix );
47372
47373			return this;
47374
47375		},
47376
47377		equals: function ( line ) {
47378
47379			return line.start.equals( this.start ) && line.end.equals( this.end );
47380
47381		}
47382
47383	} );
47384
47385	/**
47386	 * @author alteredq / http://alteredqualia.com/
47387	 */
47388
47389	function ImmediateRenderObject( material ) {
47390
47391		Object3D.call( this );
47392
47393		this.material = material;
47394		this.render = function ( /* renderCallback */ ) {};
47395
47396		this.hasPositions = false;
47397		this.hasNormals = false;
47398		this.hasColors = false;
47399		this.hasUvs = false;
47400
47401		this.positionArray = null;
47402		this.normalArray = null;
47403		this.colorArray = null;
47404		this.uvArray = null;
47405
47406		this.count = 0;
47407
47408	}
47409
47410	ImmediateRenderObject.prototype = Object.create( Object3D.prototype );
47411	ImmediateRenderObject.prototype.constructor = ImmediateRenderObject;
47412
47413	ImmediateRenderObject.prototype.isImmediateRenderObject = true;
47414
47415	/**
47416	 * @author alteredq / http://alteredqualia.com/
47417	 * @author mrdoob / http://mrdoob.com/
47418	 * @author WestLangley / http://github.com/WestLangley
47419	 */
47420
47421	var _vector$8 = new Vector3();
47422
47423	function SpotLightHelper( light, color ) {
47424
47425		Object3D.call( this );
47426
47427		this.light = light;
47428		this.light.updateMatrixWorld();
47429
47430		this.matrix = light.matrixWorld;
47431		this.matrixAutoUpdate = false;
47432
47433		this.color = color;
47434
47435		var geometry = new BufferGeometry();
47436
47437		var positions = [
47438			0, 0, 0, 	0, 0, 1,
47439			0, 0, 0, 	1, 0, 1,
47440			0, 0, 0,	- 1, 0, 1,
47441			0, 0, 0, 	0, 1, 1,
47442			0, 0, 0, 	0, - 1, 1
47443		];
47444
47445		for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {
47446
47447			var p1 = ( i / l ) * Math.PI * 2;
47448			var p2 = ( j / l ) * Math.PI * 2;
47449
47450			positions.push(
47451				Math.cos( p1 ), Math.sin( p1 ), 1,
47452				Math.cos( p2 ), Math.sin( p2 ), 1
47453			);
47454
47455		}
47456
47457		geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
47458
47459		var material = new LineBasicMaterial( { fog: false, toneMapped: false } );
47460
47461		this.cone = new LineSegments( geometry, material );
47462		this.add( this.cone );
47463
47464		this.update();
47465
47466	}
47467
47468	SpotLightHelper.prototype = Object.create( Object3D.prototype );
47469	SpotLightHelper.prototype.constructor = SpotLightHelper;
47470
47471	SpotLightHelper.prototype.dispose = function () {
47472
47473		this.cone.geometry.dispose();
47474		this.cone.material.dispose();
47475
47476	};
47477
47478	SpotLightHelper.prototype.update = function () {
47479
47480		this.light.updateMatrixWorld();
47481
47482		var coneLength = this.light.distance ? this.light.distance : 1000;
47483		var coneWidth = coneLength * Math.tan( this.light.angle );
47484
47485		this.cone.scale.set( coneWidth, coneWidth, coneLength );
47486
47487		_vector$8.setFromMatrixPosition( this.light.target.matrixWorld );
47488
47489		this.cone.lookAt( _vector$8 );
47490
47491		if ( this.color !== undefined ) {
47492
47493			this.cone.material.color.set( this.color );
47494
47495		} else {
47496
47497			this.cone.material.color.copy( this.light.color );
47498
47499		}
47500
47501	};
47502
47503	/**
47504	 * @author Sean Griffin / http://twitter.com/sgrif
47505	 * @author Michael Guerrero / http://realitymeltdown.com
47506	 * @author mrdoob / http://mrdoob.com/
47507	 * @author ikerr / http://verold.com
47508	 * @author Mugen87 / https://github.com/Mugen87
47509	 */
47510
47511	var _vector$9 = new Vector3();
47512	var _boneMatrix = new Matrix4();
47513	var _matrixWorldInv = new Matrix4();
47514
47515	function getBoneList( object ) {
47516
47517		var boneList = [];
47518
47519		if ( object && object.isBone ) {
47520
47521			boneList.push( object );
47522
47523		}
47524
47525		for ( var i = 0; i < object.children.length; i ++ ) {
47526
47527			boneList.push.apply( boneList, getBoneList( object.children[ i ] ) );
47528
47529		}
47530
47531		return boneList;
47532
47533	}
47534
47535	function SkeletonHelper( object ) {
47536
47537		var bones = getBoneList( object );
47538
47539		var geometry = new BufferGeometry();
47540
47541		var vertices = [];
47542		var colors = [];
47543
47544		var color1 = new Color( 0, 0, 1 );
47545		var color2 = new Color( 0, 1, 0 );
47546
47547		for ( var i = 0; i < bones.length; i ++ ) {
47548
47549			var bone = bones[ i ];
47550
47551			if ( bone.parent && bone.parent.isBone ) {
47552
47553				vertices.push( 0, 0, 0 );
47554				vertices.push( 0, 0, 0 );
47555				colors.push( color1.r, color1.g, color1.b );
47556				colors.push( color2.r, color2.g, color2.b );
47557
47558			}
47559
47560		}
47561
47562		geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
47563		geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
47564
47565		var material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } );
47566
47567		LineSegments.call( this, geometry, material );
47568
47569		this.type = 'SkeletonHelper';
47570
47571		this.root = object;
47572		this.bones = bones;
47573
47574		this.matrix = object.matrixWorld;
47575		this.matrixAutoUpdate = false;
47576
47577	}
47578
47579	SkeletonHelper.prototype = Object.create( LineSegments.prototype );
47580	SkeletonHelper.prototype.constructor = SkeletonHelper;
47581
47582	SkeletonHelper.prototype.isSkeletonHelper = true;
47583
47584	SkeletonHelper.prototype.updateMatrixWorld = function ( force ) {
47585
47586		var bones = this.bones;
47587
47588		var geometry = this.geometry;
47589		var position = geometry.getAttribute( 'position' );
47590
47591		_matrixWorldInv.getInverse( this.root.matrixWorld );
47592
47593		for ( var i = 0, j = 0; i < bones.length; i ++ ) {
47594
47595			var bone = bones[ i ];
47596
47597			if ( bone.parent && bone.parent.isBone ) {
47598
47599				_boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld );
47600				_vector$9.setFromMatrixPosition( _boneMatrix );
47601				position.setXYZ( j, _vector$9.x, _vector$9.y, _vector$9.z );
47602
47603				_boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld );
47604				_vector$9.setFromMatrixPosition( _boneMatrix );
47605				position.setXYZ( j + 1, _vector$9.x, _vector$9.y, _vector$9.z );
47606
47607				j += 2;
47608
47609			}
47610
47611		}
47612
47613		geometry.getAttribute( 'position' ).needsUpdate = true;
47614
47615		Object3D.prototype.updateMatrixWorld.call( this, force );
47616
47617	};
47618
47619	/**
47620	 * @author alteredq / http://alteredqualia.com/
47621	 * @author mrdoob / http://mrdoob.com/
47622	 */
47623
47624	function PointLightHelper( light, sphereSize, color ) {
47625
47626		this.light = light;
47627		this.light.updateMatrixWorld();
47628
47629		this.color = color;
47630
47631		var geometry = new SphereBufferGeometry( sphereSize, 4, 2 );
47632		var material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
47633
47634		Mesh.call( this, geometry, material );
47635
47636		this.type = 'PointLightHelper';
47637
47638		this.matrix = this.light.matrixWorld;
47639		this.matrixAutoUpdate = false;
47640
47641		this.update();
47642
47643
47644		/*
47645		const distanceGeometry = new THREE.IcosahedronBufferGeometry( 1, 2 );
47646		const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );
47647
47648		this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
47649		this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );
47650
47651		const d = light.distance;
47652
47653		if ( d === 0.0 ) {
47654
47655			this.lightDistance.visible = false;
47656
47657		} else {
47658
47659			this.lightDistance.scale.set( d, d, d );
47660
47661		}
47662
47663		this.add( this.lightDistance );
47664		*/
47665
47666	}
47667
47668	PointLightHelper.prototype = Object.create( Mesh.prototype );
47669	PointLightHelper.prototype.constructor = PointLightHelper;
47670
47671	PointLightHelper.prototype.dispose = function () {
47672
47673		this.geometry.dispose();
47674		this.material.dispose();
47675
47676	};
47677
47678	PointLightHelper.prototype.update = function () {
47679
47680		if ( this.color !== undefined ) {
47681
47682			this.material.color.set( this.color );
47683
47684		} else {
47685
47686			this.material.color.copy( this.light.color );
47687
47688		}
47689
47690		/*
47691		const d = this.light.distance;
47692
47693		if ( d === 0.0 ) {
47694
47695			this.lightDistance.visible = false;
47696
47697		} else {
47698
47699			this.lightDistance.visible = true;
47700			this.lightDistance.scale.set( d, d, d );
47701
47702		}
47703		*/
47704
47705	};
47706
47707	/**
47708	 * @author alteredq / http://alteredqualia.com/
47709	 * @author mrdoob / http://mrdoob.com/
47710	 * @author Mugen87 / https://github.com/Mugen87
47711	 */
47712
47713	var _vector$a = new Vector3();
47714	var _color1 = new Color();
47715	var _color2 = new Color();
47716
47717	function HemisphereLightHelper( light, size, color ) {
47718
47719		Object3D.call( this );
47720
47721		this.light = light;
47722		this.light.updateMatrixWorld();
47723
47724		this.matrix = light.matrixWorld;
47725		this.matrixAutoUpdate = false;
47726
47727		this.color = color;
47728
47729		var geometry = new OctahedronBufferGeometry( size );
47730		geometry.rotateY( Math.PI * 0.5 );
47731
47732		this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
47733		if ( this.color === undefined ) { this.material.vertexColors = true; }
47734
47735		var position = geometry.getAttribute( 'position' );
47736		var colors = new Float32Array( position.count * 3 );
47737
47738		geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) );
47739
47740		this.add( new Mesh( geometry, this.material ) );
47741
47742		this.update();
47743
47744	}
47745
47746	HemisphereLightHelper.prototype = Object.create( Object3D.prototype );
47747	HemisphereLightHelper.prototype.constructor = HemisphereLightHelper;
47748
47749	HemisphereLightHelper.prototype.dispose = function () {
47750
47751		this.children[ 0 ].geometry.dispose();
47752		this.children[ 0 ].material.dispose();
47753
47754	};
47755
47756	HemisphereLightHelper.prototype.update = function () {
47757
47758		var mesh = this.children[ 0 ];
47759
47760		if ( this.color !== undefined ) {
47761
47762			this.material.color.set( this.color );
47763
47764		} else {
47765
47766			var colors = mesh.geometry.getAttribute( 'color' );
47767
47768			_color1.copy( this.light.color );
47769			_color2.copy( this.light.groundColor );
47770
47771			for ( var i = 0, l = colors.count; i < l; i ++ ) {
47772
47773				var color = ( i < ( l / 2 ) ) ? _color1 : _color2;
47774
47775				colors.setXYZ( i, color.r, color.g, color.b );
47776
47777			}
47778
47779			colors.needsUpdate = true;
47780
47781		}
47782
47783		mesh.lookAt( _vector$a.setFromMatrixPosition( this.light.matrixWorld ).negate() );
47784
47785	};
47786
47787	/**
47788	 * @author mrdoob / http://mrdoob.com/
47789	 */
47790
47791	function GridHelper( size, divisions, color1, color2 ) {
47792
47793		size = size || 10;
47794		divisions = divisions || 10;
47795		color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
47796		color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
47797
47798		var center = divisions / 2;
47799		var step = size / divisions;
47800		var halfSize = size / 2;
47801
47802		var vertices = [], colors = [];
47803
47804		for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {
47805
47806			vertices.push( - halfSize, 0, k, halfSize, 0, k );
47807			vertices.push( k, 0, - halfSize, k, 0, halfSize );
47808
47809			var color = i === center ? color1 : color2;
47810
47811			color.toArray( colors, j ); j += 3;
47812			color.toArray( colors, j ); j += 3;
47813			color.toArray( colors, j ); j += 3;
47814			color.toArray( colors, j ); j += 3;
47815
47816		}
47817
47818		var geometry = new BufferGeometry();
47819		geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
47820		geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
47821
47822		var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
47823
47824		LineSegments.call( this, geometry, material );
47825
47826		this.type = 'GridHelper';
47827
47828	}
47829
47830	GridHelper.prototype = Object.assign( Object.create( LineSegments.prototype ), {
47831
47832		constructor: GridHelper,
47833
47834		copy: function ( source ) {
47835
47836			LineSegments.prototype.copy.call( this, source );
47837
47838			this.geometry.copy( source.geometry );
47839			this.material.copy( source.material );
47840
47841			return this;
47842
47843		},
47844
47845		clone: function () {
47846
47847			return new this.constructor().copy( this );
47848
47849		}
47850
47851	} );
47852
47853	/**
47854	 * @author mrdoob / http://mrdoob.com/
47855	 * @author Mugen87 / http://github.com/Mugen87
47856	 * @author Hectate / http://www.github.com/Hectate
47857	 */
47858
47859	function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {
47860
47861		radius = radius || 10;
47862		radials = radials || 16;
47863		circles = circles || 8;
47864		divisions = divisions || 64;
47865		color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
47866		color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
47867
47868		var vertices = [];
47869		var colors = [];
47870
47871		// create the radials
47872
47873		for ( var i = 0; i <= radials; i ++ ) {
47874
47875			var v = ( i / radials ) * ( Math.PI * 2 );
47876
47877			var x = Math.sin( v ) * radius;
47878			var z = Math.cos( v ) * radius;
47879
47880			vertices.push( 0, 0, 0 );
47881			vertices.push( x, 0, z );
47882
47883			var color = ( i & 1 ) ? color1 : color2;
47884
47885			colors.push( color.r, color.g, color.b );
47886			colors.push( color.r, color.g, color.b );
47887
47888		}
47889
47890		// create the circles
47891
47892		for ( var i$1 = 0; i$1 <= circles; i$1 ++ ) {
47893
47894			var color$1 = ( i$1 & 1 ) ? color1 : color2;
47895
47896			var r = radius - ( radius / circles * i$1 );
47897
47898			for ( var j = 0; j < divisions; j ++ ) {
47899
47900				// first vertex
47901
47902				var v$1 = ( j / divisions ) * ( Math.PI * 2 );
47903
47904				var x$1 = Math.sin( v$1 ) * r;
47905				var z$1 = Math.cos( v$1 ) * r;
47906
47907				vertices.push( x$1, 0, z$1 );
47908				colors.push( color$1.r, color$1.g, color$1.b );
47909
47910				// second vertex
47911
47912				v$1 = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );
47913
47914				x$1 = Math.sin( v$1 ) * r;
47915				z$1 = Math.cos( v$1 ) * r;
47916
47917				vertices.push( x$1, 0, z$1 );
47918				colors.push( color$1.r, color$1.g, color$1.b );
47919
47920			}
47921
47922		}
47923
47924		var geometry = new BufferGeometry();
47925		geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
47926		geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
47927
47928		var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
47929
47930		LineSegments.call( this, geometry, material );
47931
47932		this.type = 'PolarGridHelper';
47933
47934	}
47935
47936	PolarGridHelper.prototype = Object.create( LineSegments.prototype );
47937	PolarGridHelper.prototype.constructor = PolarGridHelper;
47938
47939	/**
47940	 * @author alteredq / http://alteredqualia.com/
47941	 * @author mrdoob / http://mrdoob.com/
47942	 * @author WestLangley / http://github.com/WestLangley
47943	 */
47944
47945	var _v1$5 = new Vector3();
47946	var _v2$3 = new Vector3();
47947	var _v3$1 = new Vector3();
47948
47949	function DirectionalLightHelper( light, size, color ) {
47950
47951		Object3D.call( this );
47952
47953		this.light = light;
47954		this.light.updateMatrixWorld();
47955
47956		this.matrix = light.matrixWorld;
47957		this.matrixAutoUpdate = false;
47958
47959		this.color = color;
47960
47961		if ( size === undefined ) { size = 1; }
47962
47963		var geometry = new BufferGeometry();
47964		geometry.setAttribute( 'position', new Float32BufferAttribute( [
47965			- size, size, 0,
47966			size, size, 0,
47967			size, - size, 0,
47968			- size, - size, 0,
47969			- size, size, 0
47970		], 3 ) );
47971
47972		var material = new LineBasicMaterial( { fog: false, toneMapped: false } );
47973
47974		this.lightPlane = new Line( geometry, material );
47975		this.add( this.lightPlane );
47976
47977		geometry = new BufferGeometry();
47978		geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );
47979
47980		this.targetLine = new Line( geometry, material );
47981		this.add( this.targetLine );
47982
47983		this.update();
47984
47985	}
47986
47987	DirectionalLightHelper.prototype = Object.create( Object3D.prototype );
47988	DirectionalLightHelper.prototype.constructor = DirectionalLightHelper;
47989
47990	DirectionalLightHelper.prototype.dispose = function () {
47991
47992		this.lightPlane.geometry.dispose();
47993		this.lightPlane.material.dispose();
47994		this.targetLine.geometry.dispose();
47995		this.targetLine.material.dispose();
47996
47997	};
47998
47999	DirectionalLightHelper.prototype.update = function () {
48000
48001		_v1$5.setFromMatrixPosition( this.light.matrixWorld );
48002		_v2$3.setFromMatrixPosition( this.light.target.matrixWorld );
48003		_v3$1.subVectors( _v2$3, _v1$5 );
48004
48005		this.lightPlane.lookAt( _v2$3 );
48006
48007		if ( this.color !== undefined ) {
48008
48009			this.lightPlane.material.color.set( this.color );
48010			this.targetLine.material.color.set( this.color );
48011
48012		} else {
48013
48014			this.lightPlane.material.color.copy( this.light.color );
48015			this.targetLine.material.color.copy( this.light.color );
48016
48017		}
48018
48019		this.targetLine.lookAt( _v2$3 );
48020		this.targetLine.scale.z = _v3$1.length();
48021
48022	};
48023
48024	/**
48025	 * @author alteredq / http://alteredqualia.com/
48026	 * @author Mugen87 / https://github.com/Mugen87
48027	 *
48028	 *	- shows frustum, line of sight and up of the camera
48029	 *	- suitable for fast updates
48030	 * 	- based on frustum visualization in lightgl.js shadowmap example
48031	 *		http://evanw.github.com/lightgl.js/tests/shadowmap.html
48032	 */
48033
48034	var _vector$b = new Vector3();
48035	var _camera = new Camera();
48036
48037	function CameraHelper( camera ) {
48038
48039		var geometry = new BufferGeometry();
48040		var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } );
48041
48042		var vertices = [];
48043		var colors = [];
48044
48045		var pointMap = {};
48046
48047		// colors
48048
48049		var colorFrustum = new Color( 0xffaa00 );
48050		var colorCone = new Color( 0xff0000 );
48051		var colorUp = new Color( 0x00aaff );
48052		var colorTarget = new Color( 0xffffff );
48053		var colorCross = new Color( 0x333333 );
48054
48055		// near
48056
48057		addLine( 'n1', 'n2', colorFrustum );
48058		addLine( 'n2', 'n4', colorFrustum );
48059		addLine( 'n4', 'n3', colorFrustum );
48060		addLine( 'n3', 'n1', colorFrustum );
48061
48062		// far
48063
48064		addLine( 'f1', 'f2', colorFrustum );
48065		addLine( 'f2', 'f4', colorFrustum );
48066		addLine( 'f4', 'f3', colorFrustum );
48067		addLine( 'f3', 'f1', colorFrustum );
48068
48069		// sides
48070
48071		addLine( 'n1', 'f1', colorFrustum );
48072		addLine( 'n2', 'f2', colorFrustum );
48073		addLine( 'n3', 'f3', colorFrustum );
48074		addLine( 'n4', 'f4', colorFrustum );
48075
48076		// cone
48077
48078		addLine( 'p', 'n1', colorCone );
48079		addLine( 'p', 'n2', colorCone );
48080		addLine( 'p', 'n3', colorCone );
48081		addLine( 'p', 'n4', colorCone );
48082
48083		// up
48084
48085		addLine( 'u1', 'u2', colorUp );
48086		addLine( 'u2', 'u3', colorUp );
48087		addLine( 'u3', 'u1', colorUp );
48088
48089		// target
48090
48091		addLine( 'c', 't', colorTarget );
48092		addLine( 'p', 'c', colorCross );
48093
48094		// cross
48095
48096		addLine( 'cn1', 'cn2', colorCross );
48097		addLine( 'cn3', 'cn4', colorCross );
48098
48099		addLine( 'cf1', 'cf2', colorCross );
48100		addLine( 'cf3', 'cf4', colorCross );
48101
48102		function addLine( a, b, color ) {
48103
48104			addPoint( a, color );
48105			addPoint( b, color );
48106
48107		}
48108
48109		function addPoint( id, color ) {
48110
48111			vertices.push( 0, 0, 0 );
48112			colors.push( color.r, color.g, color.b );
48113
48114			if ( pointMap[ id ] === undefined ) {
48115
48116				pointMap[ id ] = [];
48117
48118			}
48119
48120			pointMap[ id ].push( ( vertices.length / 3 ) - 1 );
48121
48122		}
48123
48124		geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
48125		geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
48126
48127		LineSegments.call( this, geometry, material );
48128
48129		this.type = 'CameraHelper';
48130
48131		this.camera = camera;
48132		if ( this.camera.updateProjectionMatrix ) { this.camera.updateProjectionMatrix(); }
48133
48134		this.matrix = camera.matrixWorld;
48135		this.matrixAutoUpdate = false;
48136
48137		this.pointMap = pointMap;
48138
48139		this.update();
48140
48141	}
48142
48143	CameraHelper.prototype = Object.create( LineSegments.prototype );
48144	CameraHelper.prototype.constructor = CameraHelper;
48145
48146	CameraHelper.prototype.update = function () {
48147
48148		var geometry = this.geometry;
48149		var pointMap = this.pointMap;
48150
48151		var w = 1, h = 1;
48152
48153		// we need just camera projection matrix inverse
48154		// world matrix must be identity
48155
48156		_camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse );
48157
48158		// center / target
48159
48160		setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 );
48161		setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 );
48162
48163		// near
48164
48165		setPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 );
48166		setPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 );
48167		setPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 );
48168		setPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 );
48169
48170		// far
48171
48172		setPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 );
48173		setPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 );
48174		setPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 );
48175		setPoint( 'f4', pointMap, geometry, _camera, w, h, 1 );
48176
48177		// up
48178
48179		setPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 );
48180		setPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 );
48181		setPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 );
48182
48183		// cross
48184
48185		setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 );
48186		setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 );
48187		setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 );
48188		setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 );
48189
48190		setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 );
48191		setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 );
48192		setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 );
48193		setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 );
48194
48195		geometry.getAttribute( 'position' ).needsUpdate = true;
48196
48197	};
48198
48199	function setPoint( point, pointMap, geometry, camera, x, y, z ) {
48200
48201		_vector$b.set( x, y, z ).unproject( camera );
48202
48203		var points = pointMap[ point ];
48204
48205		if ( points !== undefined ) {
48206
48207			var position = geometry.getAttribute( 'position' );
48208
48209			for ( var i = 0, l = points.length; i < l; i ++ ) {
48210
48211				position.setXYZ( points[ i ], _vector$b.x, _vector$b.y, _vector$b.z );
48212
48213			}
48214
48215		}
48216
48217	}
48218
48219	/**
48220	 * @author mrdoob / http://mrdoob.com/
48221	 * @author Mugen87 / http://github.com/Mugen87
48222	 */
48223
48224	var _box$3 = new Box3();
48225
48226	function BoxHelper( object, color ) {
48227
48228		this.object = object;
48229
48230		if ( color === undefined ) { color = 0xffff00; }
48231
48232		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 ] );
48233		var positions = new Float32Array( 8 * 3 );
48234
48235		var geometry = new BufferGeometry();
48236		geometry.setIndex( new BufferAttribute( indices, 1 ) );
48237		geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
48238
48239		LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
48240
48241		this.type = 'BoxHelper';
48242
48243		this.matrixAutoUpdate = false;
48244
48245		this.update();
48246
48247	}
48248
48249	BoxHelper.prototype = Object.create( LineSegments.prototype );
48250	BoxHelper.prototype.constructor = BoxHelper;
48251
48252	BoxHelper.prototype.update = function ( object ) {
48253
48254		if ( object !== undefined ) {
48255
48256			console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' );
48257
48258		}
48259
48260		if ( this.object !== undefined ) {
48261
48262			_box$3.setFromObject( this.object );
48263
48264		}
48265
48266		if ( _box$3.isEmpty() ) { return; }
48267
48268		var min = _box$3.min;
48269		var max = _box$3.max;
48270
48271		/*
48272		  5____4
48273		1/___0/|
48274		| 6__|_7
48275		2/___3/
48276
48277		0: max.x, max.y, max.z
48278		1: min.x, max.y, max.z
48279		2: min.x, min.y, max.z
48280		3: max.x, min.y, max.z
48281		4: max.x, max.y, min.z
48282		5: min.x, max.y, min.z
48283		6: min.x, min.y, min.z
48284		7: max.x, min.y, min.z
48285		*/
48286
48287		var position = this.geometry.attributes.position;
48288		var array = position.array;
48289
48290		array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;
48291		array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;
48292		array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;
48293		array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;
48294		array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;
48295		array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;
48296		array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;
48297		array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;
48298
48299		position.needsUpdate = true;
48300
48301		this.geometry.computeBoundingSphere();
48302
48303
48304	};
48305
48306	BoxHelper.prototype.setFromObject = function ( object ) {
48307
48308		this.object = object;
48309		this.update();
48310
48311		return this;
48312
48313	};
48314
48315	BoxHelper.prototype.copy = function ( source ) {
48316
48317		LineSegments.prototype.copy.call( this, source );
48318
48319		this.object = source.object;
48320
48321		return this;
48322
48323	};
48324
48325	BoxHelper.prototype.clone = function () {
48326
48327		return new this.constructor().copy( this );
48328
48329	};
48330
48331	/**
48332	 * @author WestLangley / http://github.com/WestLangley
48333	 */
48334
48335	function Box3Helper( box, color ) {
48336
48337		this.type = 'Box3Helper';
48338
48339		this.box = box;
48340
48341		color = color || 0xffff00;
48342
48343		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 ] );
48344
48345		var positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ];
48346
48347		var geometry = new BufferGeometry();
48348
48349		geometry.setIndex( new BufferAttribute( indices, 1 ) );
48350
48351		geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
48352
48353		LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
48354
48355		this.type = 'Box3Helper';
48356
48357		this.geometry.computeBoundingSphere();
48358
48359	}
48360
48361	Box3Helper.prototype = Object.create( LineSegments.prototype );
48362	Box3Helper.prototype.constructor = Box3Helper;
48363
48364	Box3Helper.prototype.updateMatrixWorld = function ( force ) {
48365
48366		var box = this.box;
48367
48368		if ( box.isEmpty() ) { return; }
48369
48370		box.getCenter( this.position );
48371
48372		box.getSize( this.scale );
48373
48374		this.scale.multiplyScalar( 0.5 );
48375
48376		Object3D.prototype.updateMatrixWorld.call( this, force );
48377
48378	};
48379
48380	/**
48381	 * @author WestLangley / http://github.com/WestLangley
48382	 */
48383
48384	function PlaneHelper( plane, size, hex ) {
48385
48386		this.plane = plane;
48387
48388		this.size = ( size === undefined ) ? 1 : size;
48389
48390		var color = ( hex !== undefined ) ? hex : 0xffff00;
48391
48392		var positions = [ 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, 0, 1, 0, 0, 0 ];
48393
48394		var geometry = new BufferGeometry();
48395		geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
48396		geometry.computeBoundingSphere();
48397
48398		Line.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
48399
48400		this.type = 'PlaneHelper';
48401
48402		//
48403
48404		var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ];
48405
48406		var geometry2 = new BufferGeometry();
48407		geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );
48408		geometry2.computeBoundingSphere();
48409
48410		this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) );
48411
48412	}
48413
48414	PlaneHelper.prototype = Object.create( Line.prototype );
48415	PlaneHelper.prototype.constructor = PlaneHelper;
48416
48417	PlaneHelper.prototype.updateMatrixWorld = function ( force ) {
48418
48419		var scale = - this.plane.constant;
48420
48421		if ( Math.abs( scale ) < 1e-8 ) { scale = 1e-8; } // sign does not matter
48422
48423		this.scale.set( 0.5 * this.size, 0.5 * this.size, scale );
48424
48425		this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here
48426
48427		this.lookAt( this.plane.normal );
48428
48429		Object3D.prototype.updateMatrixWorld.call( this, force );
48430
48431	};
48432
48433	/**
48434	 * @author WestLangley / http://github.com/WestLangley
48435	 * @author zz85 / http://github.com/zz85
48436	 * @author bhouston / http://clara.io
48437	 *
48438	 * Creates an arrow for visualizing directions
48439	 *
48440	 * Parameters:
48441	 *  dir - Vector3
48442	 *  origin - Vector3
48443	 *  length - Number
48444	 *  color - color in hex value
48445	 *  headLength - Number
48446	 *  headWidth - Number
48447	 */
48448
48449	var _axis = new Vector3();
48450	var _lineGeometry, _coneGeometry;
48451
48452	function ArrowHelper( dir, origin, length, color, headLength, headWidth ) {
48453
48454		// dir is assumed to be normalized
48455
48456		Object3D.call( this );
48457
48458		this.type = 'ArrowHelper';
48459
48460		if ( dir === undefined ) { dir = new Vector3( 0, 0, 1 ); }
48461		if ( origin === undefined ) { origin = new Vector3( 0, 0, 0 ); }
48462		if ( length === undefined ) { length = 1; }
48463		if ( color === undefined ) { color = 0xffff00; }
48464		if ( headLength === undefined ) { headLength = 0.2 * length; }
48465		if ( headWidth === undefined ) { headWidth = 0.2 * headLength; }
48466
48467		if ( _lineGeometry === undefined ) {
48468
48469			_lineGeometry = new BufferGeometry();
48470			_lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );
48471
48472			_coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );
48473			_coneGeometry.translate( 0, - 0.5, 0 );
48474
48475		}
48476
48477		this.position.copy( origin );
48478
48479		this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
48480		this.line.matrixAutoUpdate = false;
48481		this.add( this.line );
48482
48483		this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) );
48484		this.cone.matrixAutoUpdate = false;
48485		this.add( this.cone );
48486
48487		this.setDirection( dir );
48488		this.setLength( length, headLength, headWidth );
48489
48490	}
48491
48492	ArrowHelper.prototype = Object.create( Object3D.prototype );
48493	ArrowHelper.prototype.constructor = ArrowHelper;
48494
48495	ArrowHelper.prototype.setDirection = function ( dir ) {
48496
48497		// dir is assumed to be normalized
48498
48499		if ( dir.y > 0.99999 ) {
48500
48501			this.quaternion.set( 0, 0, 0, 1 );
48502
48503		} else if ( dir.y < - 0.99999 ) {
48504
48505			this.quaternion.set( 1, 0, 0, 0 );
48506
48507		} else {
48508
48509			_axis.set( dir.z, 0, - dir.x ).normalize();
48510
48511			var radians = Math.acos( dir.y );
48512
48513			this.quaternion.setFromAxisAngle( _axis, radians );
48514
48515		}
48516
48517	};
48518
48519	ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {
48520
48521		if ( headLength === undefined ) { headLength = 0.2 * length; }
48522		if ( headWidth === undefined ) { headWidth = 0.2 * headLength; }
48523
48524		this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458
48525		this.line.updateMatrix();
48526
48527		this.cone.scale.set( headWidth, headLength, headWidth );
48528		this.cone.position.y = length;
48529		this.cone.updateMatrix();
48530
48531	};
48532
48533	ArrowHelper.prototype.setColor = function ( color ) {
48534
48535		this.line.material.color.set( color );
48536		this.cone.material.color.set( color );
48537
48538	};
48539
48540	ArrowHelper.prototype.copy = function ( source ) {
48541
48542		Object3D.prototype.copy.call( this, source, false );
48543
48544		this.line.copy( source.line );
48545		this.cone.copy( source.cone );
48546
48547		return this;
48548
48549	};
48550
48551	ArrowHelper.prototype.clone = function () {
48552
48553		return new this.constructor().copy( this );
48554
48555	};
48556
48557	/**
48558	 * @author sroucheray / http://sroucheray.org/
48559	 * @author mrdoob / http://mrdoob.com/
48560	 */
48561
48562	function AxesHelper( size ) {
48563
48564		size = size || 1;
48565
48566		var vertices = [
48567			0, 0, 0,	size, 0, 0,
48568			0, 0, 0,	0, size, 0,
48569			0, 0, 0,	0, 0, size
48570		];
48571
48572		var colors = [
48573			1, 0, 0,	1, 0.6, 0,
48574			0, 1, 0,	0.6, 1, 0,
48575			0, 0, 1,	0, 0.6, 1
48576		];
48577
48578		var geometry = new BufferGeometry();
48579		geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
48580		geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
48581
48582		var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
48583
48584		LineSegments.call( this, geometry, material );
48585
48586		this.type = 'AxesHelper';
48587
48588	}
48589
48590	AxesHelper.prototype = Object.create( LineSegments.prototype );
48591	AxesHelper.prototype.constructor = AxesHelper;
48592
48593	/**
48594	 * @author Emmett Lalish / elalish
48595	 *
48596	 * This class generates a Prefiltered, Mipmapped Radiance Environment Map
48597	 * (PMREM) from a cubeMap environment texture. This allows different levels of
48598	 * blur to be quickly accessed based on material roughness. It is packed into a
48599	 * special CubeUV format that allows us to perform custom interpolation so that
48600	 * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap
48601	 * chain, it only goes down to the LOD_MIN level (above), and then creates extra
48602	 * even more filtered 'mips' at the same LOD_MIN resolution, associated with
48603	 * higher roughness levels. In this way we maintain resolution to smoothly
48604	 * interpolate diffuse lighting while limiting sampling computation.
48605	 */
48606
48607	var LOD_MIN = 4;
48608	var LOD_MAX = 8;
48609	var SIZE_MAX = Math.pow( 2, LOD_MAX );
48610
48611	// The standard deviations (radians) associated with the extra mips. These are
48612	// chosen to approximate a Trowbridge-Reitz distribution function times the
48613	// geometric shadowing function. These sigma values squared must match the
48614	// variance #defines in cube_uv_reflection_fragment.glsl.js.
48615	var EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
48616
48617	var TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;
48618
48619	// The maximum length of the blur for loop. Smaller sigmas will use fewer
48620	// samples and exit early, but not recompile the shader.
48621	var MAX_SAMPLES = 20;
48622
48623	var ENCODINGS = {};
48624	ENCODINGS[ LinearEncoding ] = 0;
48625	ENCODINGS[ sRGBEncoding ] = 1;
48626	ENCODINGS[ RGBEEncoding ] = 2;
48627	ENCODINGS[ RGBM7Encoding ] = 3;
48628	ENCODINGS[ RGBM16Encoding ] = 4;
48629	ENCODINGS[ RGBDEncoding ] = 5;
48630	ENCODINGS[ GammaEncoding ] = 6;
48631
48632	var _flatCamera = new OrthographicCamera();
48633	var ref = _createPlanes();
48634	var _lodPlanes = ref._lodPlanes;
48635	var _sizeLods = ref._sizeLods;
48636	var _sigmas = ref._sigmas;
48637	var _oldTarget = null;
48638
48639	// Golden Ratio
48640	var PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
48641	var INV_PHI = 1 / PHI;
48642
48643	// Vertices of a dodecahedron (except the opposites, which represent the
48644	// same axis), used as axis directions evenly spread on a sphere.
48645	var _axisDirections = [
48646		new Vector3( 1, 1, 1 ),
48647		new Vector3( - 1, 1, 1 ),
48648		new Vector3( 1, 1, - 1 ),
48649		new Vector3( - 1, 1, - 1 ),
48650		new Vector3( 0, PHI, INV_PHI ),
48651		new Vector3( 0, PHI, - INV_PHI ),
48652		new Vector3( INV_PHI, 0, PHI ),
48653		new Vector3( - INV_PHI, 0, PHI ),
48654		new Vector3( PHI, INV_PHI, 0 ),
48655		new Vector3( - PHI, INV_PHI, 0 ) ];
48656
48657	function PMREMGenerator( renderer ) {
48658
48659		this._renderer = renderer;
48660		this._pingPongRenderTarget = null;
48661
48662		this._blurMaterial = _getBlurShader( MAX_SAMPLES );
48663		this._equirectShader = null;
48664		this._cubemapShader = null;
48665
48666		this._compileMaterial( this._blurMaterial );
48667
48668	}
48669
48670	PMREMGenerator.prototype = {
48671
48672		constructor: PMREMGenerator,
48673
48674		/**
48675		 * Generates a PMREM from a supplied Scene, which can be faster than using an
48676		 * image if networking bandwidth is low. Optional sigma specifies a blur radius
48677		 * in radians to be applied to the scene before PMREM generation. Optional near
48678		 * and far planes ensure the scene is rendered in its entirety (the cubeCamera
48679		 * is placed at the origin).
48680		 */
48681		fromScene: function ( scene, sigma, near, far ) {
48682			if ( sigma === void 0 ) sigma = 0;
48683			if ( near === void 0 ) near = 0.1;
48684			if ( far === void 0 ) far = 100;
48685
48686
48687			_oldTarget = this._renderer.getRenderTarget();
48688			var cubeUVRenderTarget = this._allocateTargets();
48689
48690			this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
48691			if ( sigma > 0 ) {
48692
48693				this._blur( cubeUVRenderTarget, 0, 0, sigma );
48694
48695			}
48696
48697			this._applyPMREM( cubeUVRenderTarget );
48698			this._cleanup( cubeUVRenderTarget );
48699
48700			return cubeUVRenderTarget;
48701
48702		},
48703
48704		/**
48705		 * Generates a PMREM from an equirectangular texture, which can be either LDR
48706		 * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512),
48707		 * as this matches best with the 256 x 256 cubemap output.
48708		 */
48709		fromEquirectangular: function ( equirectangular ) {
48710
48711			return this._fromTexture( equirectangular );
48712
48713		},
48714
48715		/**
48716		 * Generates a PMREM from an cubemap texture, which can be either LDR
48717		 * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256,
48718		 * as this matches best with the 256 x 256 cubemap output.
48719		 */
48720		fromCubemap: function ( cubemap ) {
48721
48722			return this._fromTexture( cubemap );
48723
48724		},
48725
48726		/**
48727		 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
48728		 * your texture's network fetch for increased concurrency.
48729		 */
48730		compileCubemapShader: function () {
48731
48732			if ( this._cubemapShader === null ) {
48733
48734				this._cubemapShader = _getCubemapShader();
48735				this._compileMaterial( this._cubemapShader );
48736
48737			}
48738
48739		},
48740
48741		/**
48742		 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
48743		 * your texture's network fetch for increased concurrency.
48744		 */
48745		compileEquirectangularShader: function () {
48746
48747			if ( this._equirectShader === null ) {
48748
48749				this._equirectShader = _getEquirectShader();
48750				this._compileMaterial( this._equirectShader );
48751
48752			}
48753
48754		},
48755
48756		/**
48757		 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
48758		 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
48759		 * one of them will cause any others to also become unusable.
48760		 */
48761		dispose: function () {
48762
48763			this._blurMaterial.dispose();
48764
48765			if ( this._cubemapShader !== null ) { this._cubemapShader.dispose(); }
48766			if ( this._equirectShader !== null ) { this._equirectShader.dispose(); }
48767
48768			for ( var i = 0; i < _lodPlanes.length; i ++ ) {
48769
48770				_lodPlanes[ i ].dispose();
48771
48772			}
48773
48774		},
48775
48776		// private interface
48777
48778		_cleanup: function ( outputTarget ) {
48779
48780			this._pingPongRenderTarget.dispose();
48781			this._renderer.setRenderTarget( _oldTarget );
48782			outputTarget.scissorTest = false;
48783			_setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
48784
48785		},
48786
48787		_fromTexture: function ( texture ) {
48788
48789			_oldTarget = this._renderer.getRenderTarget();
48790			var cubeUVRenderTarget = this._allocateTargets( texture );
48791			this._textureToCubeUV( texture, cubeUVRenderTarget );
48792			this._applyPMREM( cubeUVRenderTarget );
48793			this._cleanup( cubeUVRenderTarget );
48794
48795			return cubeUVRenderTarget;
48796
48797		},
48798
48799		_allocateTargets: function ( texture ) { // warning: null texture is valid
48800
48801			var params = {
48802				magFilter: NearestFilter,
48803				minFilter: NearestFilter,
48804				generateMipmaps: false,
48805				type: UnsignedByteType,
48806				format: RGBEFormat,
48807				encoding: _isLDR( texture ) ? texture.encoding : RGBEEncoding,
48808				depthBuffer: false,
48809				stencilBuffer: false
48810			};
48811
48812			var cubeUVRenderTarget = _createRenderTarget( params );
48813			cubeUVRenderTarget.depthBuffer = texture ? false : true;
48814			this._pingPongRenderTarget = _createRenderTarget( params );
48815			return cubeUVRenderTarget;
48816
48817		},
48818
48819		_compileMaterial: function ( material ) {
48820
48821			var tmpMesh = new Mesh( _lodPlanes[ 0 ], material );
48822			this._renderer.compile( tmpMesh, _flatCamera );
48823
48824		},
48825
48826		_sceneToCubeUV: function ( scene, near, far, cubeUVRenderTarget ) {
48827
48828			var fov = 90;
48829			var aspect = 1;
48830			var cubeCamera = new PerspectiveCamera( fov, aspect, near, far );
48831			var upSign = [ 1, - 1, 1, 1, 1, 1 ];
48832			var forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ];
48833			var renderer = this._renderer;
48834
48835			var outputEncoding = renderer.outputEncoding;
48836			var toneMapping = renderer.toneMapping;
48837			var clearColor = renderer.getClearColor();
48838			var clearAlpha = renderer.getClearAlpha();
48839
48840			renderer.toneMapping = NoToneMapping;
48841			renderer.outputEncoding = LinearEncoding;
48842
48843			var background = scene.background;
48844			if ( background && background.isColor ) {
48845
48846				background.convertSRGBToLinear();
48847				// Convert linear to RGBE
48848				var maxComponent = Math.max( background.r, background.g, background.b );
48849				var fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 );
48850				background = background.multiplyScalar( Math.pow( 2.0, - fExp ) );
48851				var alpha = ( fExp + 128.0 ) / 255.0;
48852				renderer.setClearColor( background, alpha );
48853				scene.background = null;
48854
48855			}
48856
48857			for ( var i = 0; i < 6; i ++ ) {
48858
48859				var col = i % 3;
48860				if ( col == 0 ) {
48861
48862					cubeCamera.up.set( 0, upSign[ i ], 0 );
48863					cubeCamera.lookAt( forwardSign[ i ], 0, 0 );
48864
48865				} else if ( col == 1 ) {
48866
48867					cubeCamera.up.set( 0, 0, upSign[ i ] );
48868					cubeCamera.lookAt( 0, forwardSign[ i ], 0 );
48869
48870				} else {
48871
48872					cubeCamera.up.set( 0, upSign[ i ], 0 );
48873					cubeCamera.lookAt( 0, 0, forwardSign[ i ] );
48874
48875				}
48876
48877				_setViewport( cubeUVRenderTarget,
48878					col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX );
48879				renderer.setRenderTarget( cubeUVRenderTarget );
48880				renderer.render( scene, cubeCamera );
48881
48882			}
48883
48884			renderer.toneMapping = toneMapping;
48885			renderer.outputEncoding = outputEncoding;
48886			renderer.setClearColor( clearColor, clearAlpha );
48887
48888		},
48889
48890		_textureToCubeUV: function ( texture, cubeUVRenderTarget ) {
48891
48892			var renderer = this._renderer;
48893
48894			if ( texture.isCubeTexture ) {
48895
48896				if ( this._cubemapShader == null ) {
48897
48898					this._cubemapShader = _getCubemapShader();
48899
48900				}
48901
48902			} else {
48903
48904				if ( this._equirectShader == null ) {
48905
48906					this._equirectShader = _getEquirectShader();
48907
48908				}
48909
48910			}
48911
48912			var material = texture.isCubeTexture ? this._cubemapShader : this._equirectShader;
48913			var mesh = new Mesh( _lodPlanes[ 0 ], material );
48914
48915			var uniforms = material.uniforms;
48916
48917			uniforms[ 'envMap' ].value = texture;
48918
48919			if ( ! texture.isCubeTexture ) {
48920
48921				uniforms[ 'texelSize' ].value.set( 1.0 / texture.image.width, 1.0 / texture.image.height );
48922
48923			}
48924
48925			uniforms[ 'inputEncoding' ].value = ENCODINGS[ texture.encoding ];
48926			uniforms[ 'outputEncoding' ].value = ENCODINGS[ cubeUVRenderTarget.texture.encoding ];
48927
48928			_setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX );
48929
48930			renderer.setRenderTarget( cubeUVRenderTarget );
48931			renderer.render( mesh, _flatCamera );
48932
48933		},
48934
48935		_applyPMREM: function ( cubeUVRenderTarget ) {
48936
48937			var renderer = this._renderer;
48938			var autoClear = renderer.autoClear;
48939			renderer.autoClear = false;
48940
48941			for ( var i = 1; i < TOTAL_LODS; i ++ ) {
48942
48943				var sigma = Math.sqrt( _sigmas[ i ] * _sigmas[ i ] - _sigmas[ i - 1 ] * _sigmas[ i - 1 ] );
48944
48945				var poleAxis = _axisDirections[ ( i - 1 ) % _axisDirections.length ];
48946
48947				this._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis );
48948
48949			}
48950
48951			renderer.autoClear = autoClear;
48952
48953		},
48954
48955		/**
48956		 * This is a two-pass Gaussian blur for a cubemap. Normally this is done
48957		 * vertically and horizontally, but this breaks down on a cube. Here we apply
48958		 * the blur latitudinally (around the poles), and then longitudinally (towards
48959		 * the poles) to approximate the orthogonally-separable blur. It is least
48960		 * accurate at the poles, but still does a decent job.
48961		 */
48962		_blur: function ( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) {
48963
48964			var pingPongRenderTarget = this._pingPongRenderTarget;
48965
48966			this._halfBlur(
48967				cubeUVRenderTarget,
48968				pingPongRenderTarget,
48969				lodIn,
48970				lodOut,
48971				sigma,
48972				'latitudinal',
48973				poleAxis );
48974
48975			this._halfBlur(
48976				pingPongRenderTarget,
48977				cubeUVRenderTarget,
48978				lodOut,
48979				lodOut,
48980				sigma,
48981				'longitudinal',
48982				poleAxis );
48983
48984		},
48985
48986		_halfBlur: function ( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) {
48987
48988			var renderer = this._renderer;
48989			var blurMaterial = this._blurMaterial;
48990
48991			if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) {
48992
48993				console.error(
48994					'blur direction must be either latitudinal or longitudinal!' );
48995
48996			}
48997
48998			// Number of standard deviations at which to cut off the discrete approximation.
48999			var STANDARD_DEVIATIONS = 3;
49000
49001			var blurMesh = new Mesh( _lodPlanes[ lodOut ], blurMaterial );
49002			var blurUniforms = blurMaterial.uniforms;
49003
49004			var pixels = _sizeLods[ lodIn ] - 1;
49005			var radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 );
49006			var sigmaPixels = sigmaRadians / radiansPerPixel;
49007			var samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES;
49008
49009			if ( samples > MAX_SAMPLES ) {
49010
49011				console.warn( ("sigmaRadians, " + sigmaRadians + ", is too large and will clip, as it requested " + samples + " samples when the maximum is set to " + MAX_SAMPLES) );
49012
49013			}
49014
49015			var weights = [];
49016			var sum = 0;
49017
49018			for ( var i = 0; i < MAX_SAMPLES; ++ i ) {
49019
49020				var x$1 = i / sigmaPixels;
49021				var weight = Math.exp( - x$1 * x$1 / 2 );
49022				weights.push( weight );
49023
49024				if ( i == 0 ) {
49025
49026					sum += weight;
49027
49028				} else if ( i < samples ) {
49029
49030					sum += 2 * weight;
49031
49032				}
49033
49034			}
49035
49036			for ( var i$1 = 0; i$1 < weights.length; i$1 ++ ) {
49037
49038				weights[ i$1 ] = weights[ i$1 ] / sum;
49039
49040			}
49041
49042			blurUniforms[ 'envMap' ].value = targetIn.texture;
49043			blurUniforms[ 'samples' ].value = samples;
49044			blurUniforms[ 'weights' ].value = weights;
49045			blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal';
49046
49047			if ( poleAxis ) {
49048
49049				blurUniforms[ 'poleAxis' ].value = poleAxis;
49050
49051			}
49052
49053			blurUniforms[ 'dTheta' ].value = radiansPerPixel;
49054			blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn;
49055			blurUniforms[ 'inputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
49056			blurUniforms[ 'outputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
49057
49058			var outputSize = _sizeLods[ lodOut ];
49059			var x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize );
49060			var y = ( lodOut === 0 ? 0 : 2 * SIZE_MAX ) + 2 * outputSize * ( lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0 );
49061
49062			_setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize );
49063			renderer.setRenderTarget( targetOut );
49064			renderer.render( blurMesh, _flatCamera );
49065
49066		}
49067
49068	};
49069
49070	function _isLDR( texture ) {
49071
49072		if ( texture === undefined || texture.type !== UnsignedByteType ) { return false; }
49073
49074		return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding;
49075
49076	}
49077
49078	function _createPlanes() {
49079
49080		var _lodPlanes = [];
49081		var _sizeLods = [];
49082		var _sigmas = [];
49083
49084		var lod = LOD_MAX;
49085
49086		for ( var i = 0; i < TOTAL_LODS; i ++ ) {
49087
49088			var sizeLod = Math.pow( 2, lod );
49089			_sizeLods.push( sizeLod );
49090			var sigma = 1.0 / sizeLod;
49091
49092			if ( i > LOD_MAX - LOD_MIN ) {
49093
49094				sigma = EXTRA_LOD_SIGMA[ i - LOD_MAX + LOD_MIN - 1 ];
49095
49096			} else if ( i == 0 ) {
49097
49098				sigma = 0;
49099
49100			}
49101
49102			_sigmas.push( sigma );
49103
49104			var texelSize = 1.0 / ( sizeLod - 1 );
49105			var min = - texelSize / 2;
49106			var max = 1 + texelSize / 2;
49107			var uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ];
49108
49109			var cubeFaces = 6;
49110			var vertices = 6;
49111			var positionSize = 3;
49112			var uvSize = 2;
49113			var faceIndexSize = 1;
49114
49115			var position = new Float32Array( positionSize * vertices * cubeFaces );
49116			var uv = new Float32Array( uvSize * vertices * cubeFaces );
49117			var faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces );
49118
49119			for ( var face = 0; face < cubeFaces; face ++ ) {
49120
49121				var x = ( face % 3 ) * 2 / 3 - 1;
49122				var y = face > 2 ? 0 : - 1;
49123				var coordinates = [
49124					x, y, 0,
49125					x + 2 / 3, y, 0,
49126					x + 2 / 3, y + 1, 0,
49127					x, y, 0,
49128					x + 2 / 3, y + 1, 0,
49129					x, y + 1, 0
49130				];
49131				position.set( coordinates, positionSize * vertices * face );
49132				uv.set( uv1, uvSize * vertices * face );
49133				var fill = [ face, face, face, face, face, face ];
49134				faceIndex.set( fill, faceIndexSize * vertices * face );
49135
49136			}
49137
49138			var planes = new BufferGeometry();
49139			planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );
49140			planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
49141			planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
49142			_lodPlanes.push( planes );
49143
49144			if ( lod > LOD_MIN ) {
49145
49146				lod --;
49147
49148			}
49149
49150		}
49151
49152		return { _lodPlanes: _lodPlanes, _sizeLods: _sizeLods, _sigmas: _sigmas };
49153
49154	}
49155
49156	function _createRenderTarget( params ) {
49157
49158		var cubeUVRenderTarget = new WebGLRenderTarget( 3 * SIZE_MAX, 3 * SIZE_MAX, params );
49159		cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
49160		cubeUVRenderTarget.texture.name = 'PMREM.cubeUv';
49161		cubeUVRenderTarget.scissorTest = true;
49162		return cubeUVRenderTarget;
49163
49164	}
49165
49166	function _setViewport( target, x, y, width, height ) {
49167
49168		target.viewport.set( x, y, width, height );
49169		target.scissor.set( x, y, width, height );
49170
49171	}
49172
49173	function _getBlurShader( maxSamples ) {
49174
49175		var weights = new Float32Array( maxSamples );
49176		var poleAxis = new Vector3( 0, 1, 0 );
49177		var shaderMaterial = new RawShaderMaterial( {
49178
49179			name: 'SphericalGaussianBlur',
49180
49181			defines: { 'n': maxSamples },
49182
49183			uniforms: {
49184				'envMap': { value: null },
49185				'samples': { value: 1 },
49186				'weights': { value: weights },
49187				'latitudinal': { value: false },
49188				'dTheta': { value: 0 },
49189				'mipInt': { value: 0 },
49190				'poleAxis': { value: poleAxis },
49191				'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
49192				'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
49193			},
49194
49195			vertexShader: _getCommonVertexShader(),
49196
49197			fragmentShader: ("\nprecision mediump float;\nprecision mediump int;\nvarying vec3 vOutputDirection;\nuniform sampler2D envMap;\nuniform int samples;\nuniform float weights[n];\nuniform bool latitudinal;\nuniform float dTheta;\nuniform float mipInt;\nuniform vec3 poleAxis;\n\n" + (_getEncodings()) + "\n\n#define ENVMAP_TYPE_CUBE_UV\n#include <cube_uv_reflection_fragment>\n\nvec3 getSample(float theta, vec3 axis) {\n\tfloat cosTheta = cos(theta);\n\t// Rodrigues' axis-angle rotation\n\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t+ cross(axis, vOutputDirection) * 
49197sin(theta)\n\t\t+ axis * dot(axis, vOutputDirection) * (1.0 - cosTheta);\n\treturn bilinearCubeUV(envMap, sampleDirection, mipInt);\n}\n\nvoid main() {\n\tvec3 axis = latitudinal ? poleAxis : cross(poleAxis, vOutputDirection);\n\tif (all(equal(axis, vec3(0.0))))\n\t\taxis = vec3(vOutputDirection.z, 0.0, - vOutputDirection.x);\n\taxis = normalize(axis);\n\tgl_FragColor = vec4(0.0);\n\tgl_FragColor.rgb += weights[0] * getSample(0.0, axis);\n\tfor (int i = 1; i < n; i++) {\n\t\tif (i >= samples)\n\t\t\tbreak;\n\t\tfloat theta = dTheta * float(i);\n\t\tgl_FragColor.rgb += weights[i] * getSample(-1.0 * theta, axis);\n\t\tgl_FragColor.rgb += weights[i] * getSample(theta, axis);\n\t}\n\tgl_FragColor = linearToOutputTexel(gl_FragColor);\n}\n\t\t"),
49198
49199			blending: NoBlending,
49200			depthTest: false,
49201			depthWrite: false
49202
49203		} );
49204
49205		return shaderMaterial;
49206
49207	}
49208
49209	function _getEquirectShader() {
49210
49211		var texelSize = new Vector2( 1, 1 );
49212		var shaderMaterial = new RawShaderMaterial( {
49213
49214			name: 'EquirectangularToCubeUV',
49215
49216			uniforms: {
49217				'envMap': { value: null },
49218				'texelSize': { value: texelSize },
49219				'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
49220				'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
49221			},
49222
49223			vertexShader: _getCommonVertexShader(),
49224
49225			fragmentShader: ("\nprecision mediump float;\nprecision mediump int;\nvarying vec3 vOutputDirection;\nuniform sampler2D envMap;\nuniform vec2 texelSize;\n\n" + (_getEncodings()) + "\n\n#include <common>\n\nvoid main() {\n\tgl_FragColor = vec4(0.0);\n\tvec3 outputDirection = normalize(vOutputDirection);\n\tvec2 uv = equirectUv( outputDirection );\n\tvec2 f = fract(uv / texelSize - 0.5);\n\tuv -= f * texelSize;\n\tvec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tuv.x += texelSize.x;\n\tvec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tuv.y += texelSize.y;\n\tvec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tuv.x -= texelSize.x;\n\tvec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n\tvec3 tm = mix(tl, tr, f.x);\n\tvec3 bm = mix(bl, br, f.x);\n\tgl_FragColor.rgb = mix(tm, bm, f.y);\n\tgl_FragColor = linearToOutputTexel(gl_FragColor);\n}\n\t\t"),
49226
49227			blending: NoBlending,
49228			depthTest: false,
49229			depthWrite: false
49230
49231		} );
49232
49233		return shaderMaterial;
49234
49235	}
49236
49237	function _getCubemapShader() {
49238
49239		var shaderMaterial = new RawShaderMaterial( {
49240
49241			name: 'CubemapToCubeUV',
49242
49243			uniforms: {
49244				'envMap': { value: null },
49245				'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
49246				'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
49247			},
49248
49249			vertexShader: _getCommonVertexShader(),
49250
49251			fragmentShader: ("\nprecision mediump float;\nprecision mediump int;\nvarying vec3 vOutputDirection;\nuniform samplerCube envMap;\n\n" + (_getEncodings()) + "\n\nvoid main() {\n\tgl_FragColor = vec4(0.0);\n\tgl_FragColor.rgb = envMapTexelToLinear(textureCube(envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ))).rgb;\n\tgl_FragColor = linearToOutputTexel(gl_FragColor);\n}\n\t\t"),
49252
49253			blending: NoBlending,
49254			depthTest: false,
49255			depthWrite: false
49256
49257		} );
49258
49259		return shaderMaterial;
49260
49261	}
49262
49263	function _getCommonVertexShader() {
49264
49265		return "\nprecision mediump float;\nprecision mediump int;\nattribute vec3 position;\nattribute vec2 uv;\nattribute float faceIndex;\nvarying vec3 vOutputDirection;\n\n// RH coordinate system; PMREM face-indexing convention\nvec3 getDirection(vec2 uv, float face) {\n\tuv = 2.0 * uv - 1.0;\n\tvec3 direction = vec3(uv, 1.0);\n\tif (face == 0.0) {\n\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\t} else if (face == 1.0) {\n\t\tdirection = direction.xzy;\n\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\t} else if (face == 2.0) {\n\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\t} else if (face == 3.0) {\n\t\tdirection = direction.zyx;\n\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\t} else if (face == 4.0) {\n\t\tdirection = direction.xzy;\n\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\t} else if (face == 5.0) {\n\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\t}\n\treturn direction;\n}\n\nvoid main() {\n\tvOutputDirection = getDirection(uv, faceIndex);\n\tgl_Position = vec4( position, 1.0 );\n}\n\t";
49266
49267	}
49268
49269	function _getEncodings() {
49270
49271		return "\nuniform int inputEncoding;\nuniform int outputEncoding;\n\n#include <encodings_pars_fragment>\n\nvec4 inputTexelToLinear(vec4 value){\n\tif(inputEncoding == 0){\n\t\treturn value;\n\t}else if(inputEncoding == 1){\n\t\treturn sRGBToLinear(value);\n\t}else if(inputEncoding == 2){\n\t\treturn RGBEToLinear(value);\n\t}else if(inputEncoding == 3){\n\t\treturn RGBMToLinear(value, 7.0);\n\t}else if(inputEncoding == 4){\n\t\treturn RGBMToLinear(value, 16.0);\n\t}else if(inputEncoding == 5){\n\t\treturn RGBDToLinear(value, 256.0);\n\t}else{\n\t\treturn GammaToLinear(value, 2.2);\n\t}\n}\n\nvec4 linearToOutputTexel(vec4 value){\n\tif(outputEncoding == 0){\n\t\treturn value;\n\t}else if(outputEncoding == 1){\n\t\treturn LinearTosRGB(value);\n\t}else if(outputEncoding == 2){\n\t\treturn LinearToRGBE(value);\n\t}else if(outputEncoding == 3){\n\t\treturn LinearToRGBM(value, 7.0);\n\t}else if(outputEncoding == 4){\n\t\treturn LinearToRGBM(value, 16.0);\n\t}else if(outputEncoding == 5){\n\t\treturn LinearToRGBD(value, 256.0);\n\t}else{\n\t\treturn LinearToGamma(value, 2.2);\n\t}\n}\n\nvec4 envMapTexelToLinear(vec4 color) {\n\treturn inputTexelToLinear(color);\n}\n\t";
49272
49273	}
49274
49275	/**
49276	 * @author mrdoob / http://mrdoob.com/
49277	 */
49278
49279	function Face4( a, b, c, d, normal, color, materialIndex ) {
49280
49281		console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );
49282		return new Face3( a, b, c, normal, color, materialIndex );
49283
49284	}
49285
49286	var LineStrip = 0;
49287	var LinePieces = 1;
49288	var NoColors = 0;
49289	var FaceColors = 1;
49290	var VertexColors = 2;
49291
49292	function MeshFaceMaterial( materials ) {
49293
49294		console.warn( 'THREE.MeshFaceMaterial has been removed. Use an Array instead.' );
49295		return materials;
49296
49297	}
49298
49299	function MultiMaterial( materials ) {
49300
49301		if ( materials === undefined ) { materials = []; }
49302
49303		console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' );
49304		materials.isMultiMaterial = true;
49305		materials.materials = materials;
49306		materials.clone = function () {
49307
49308			return materials.slice();
49309
49310		};
49311
49312		return materials;
49313
49314	}
49315
49316	function PointCloud( geometry, material ) {
49317
49318		console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );
49319		return new Points( geometry, material );
49320
49321	}
49322
49323	function Particle( material ) {
49324
49325		console.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );
49326		return new Sprite( material );
49327
49328	}
49329
49330	function ParticleSystem( geometry, material ) {
49331
49332		console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );
49333		return new Points( geometry, material );
49334
49335	}
49336
49337	function PointCloudMaterial( parameters ) {
49338
49339		console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );
49340		return new PointsMaterial( parameters );
49341
49342	}
49343
49344	function ParticleBasicMaterial( parameters ) {
49345
49346		console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );
49347		return new PointsMaterial( parameters );
49348
49349	}
49350
49351	function ParticleSystemMaterial( parameters ) {
49352
49353		console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );
49354		return new PointsMaterial( parameters );
49355
49356	}
49357
49358	function Vertex( x, y, z ) {
49359
49360		console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );
49361		return new Vector3( x, y, z );
49362
49363	}
49364
49365	//
49366
49367	function DynamicBufferAttribute( array, itemSize ) {
49368
49369		console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.' );
49370		return new BufferAttribute( array, itemSize ).setUsage( DynamicDrawUsage );
49371
49372	}
49373
49374	function Int8Attribute( array, itemSize ) {
49375
49376		console.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );
49377		return new Int8BufferAttribute( array, itemSize );
49378
49379	}
49380
49381	function Uint8Attribute( array, itemSize ) {
49382
49383		console.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );
49384		return new Uint8BufferAttribute( array, itemSize );
49385
49386	}
49387
49388	function Uint8ClampedAttribute( array, itemSize ) {
49389
49390		console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );
49391		return new Uint8ClampedBufferAttribute( array, itemSize );
49392
49393	}
49394
49395	function Int16Attribute( array, itemSize ) {
49396
49397		console.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );
49398		return new Int16BufferAttribute( array, itemSize );
49399
49400	}
49401
49402	function Uint16Attribute( array, itemSize ) {
49403
49404		console.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );
49405		return new Uint16BufferAttribute( array, itemSize );
49406
49407	}
49408
49409	function Int32Attribute( array, itemSize ) {
49410
49411		console.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );
49412		return new Int32BufferAttribute( array, itemSize );
49413
49414	}
49415
49416	function Uint32Attribute( array, itemSize ) {
49417
49418		console.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );
49419		return new Uint32BufferAttribute( array, itemSize );
49420
49421	}
49422
49423	function Float32Attribute( array, itemSize ) {
49424
49425		console.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );
49426		return new Float32BufferAttribute( array, itemSize );
49427
49428	}
49429
49430	function Float64Attribute( array, itemSize ) {
49431
49432		console.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );
49433		return new Float64BufferAttribute( array, itemSize );
49434
49435	}
49436
49437	//
49438
49439	Curve.create = function ( construct, getPoint ) {
49440
49441		console.log( 'THREE.Curve.create() has been deprecated' );
49442
49443		construct.prototype = Object.create( Curve.prototype );
49444		construct.prototype.constructor = construct;
49445		construct.prototype.getPoint = getPoint;
49446
49447		return construct;
49448
49449	};
49450
49451	//
49452
49453	Object.assign( CurvePath.prototype, {
49454
49455		createPointsGeometry: function ( divisions ) {
49456
49457			console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
49458
49459			// generate geometry from path points (for Line or Points objects)
49460
49461			var pts = this.getPoints( divisions );
49462			return this.createGeometry( pts );
49463
49464		},
49465
49466		createSpacedPointsGeometry: function ( divisions ) {
49467
49468			console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
49469
49470			// generate geometry from equidistant sampling along the path
49471
49472			var pts = this.getSpacedPoints( divisions );
49473			return this.createGeometry( pts );
49474
49475		},
49476
49477		createGeometry: function ( points ) {
49478
49479			console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
49480
49481			var geometry = new Geometry();
49482
49483			for ( var i = 0, l = points.length; i < l; i ++ ) {
49484
49485				var point = points[ i ];
49486				geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
49487
49488			}
49489
49490			return geometry;
49491
49492		}
49493
49494	} );
49495
49496	//
49497
49498	Object.assign( Path.prototype, {
49499
49500		fromPoints: function ( points ) {
49501
49502			console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' );
49503			return this.setFromPoints( points );
49504
49505		}
49506
49507	} );
49508
49509	//
49510
49511	function ClosedSplineCurve3( points ) {
49512
49513		console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
49514
49515		CatmullRomCurve3.call( this, points );
49516		this.type = 'catmullrom';
49517		this.closed = true;
49518
49519	}
49520
49521	ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
49522
49523	//
49524
49525	function SplineCurve3( points ) {
49526
49527		console.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
49528
49529		CatmullRomCurve3.call( this, points );
49530		this.type = 'catmullrom';
49531
49532	}
49533
49534	SplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
49535
49536	//
49537
49538	function Spline( points ) {
49539
49540		console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );
49541
49542		CatmullRomCurve3.call( this, points );
49543		this.type = 'catmullrom';
49544
49545	}
49546
49547	Spline.prototype = Object.create( CatmullRomCurve3.prototype );
49548
49549	Object.assign( Spline.prototype, {
49550
49551		initFromArray: function ( /* a */ ) {
49552
49553			console.error( 'THREE.Spline: .initFromArray() has been removed.' );
49554
49555		},
49556		getControlPointsArray: function ( /* optionalTarget */ ) {
49557
49558			console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );
49559
49560		},
49561		reparametrizeByArcLength: function ( /* samplingCoef */ ) {
49562
49563			console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );
49564
49565		}
49566
49567	} );
49568
49569	//
49570
49571	function AxisHelper( size ) {
49572
49573		console.warn( 'THREE.AxisHelper has been renamed to THREE.AxesHelper.' );
49574		return new AxesHelper( size );
49575
49576	}
49577
49578	function BoundingBoxHelper( object, color ) {
49579
49580		console.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );
49581		return new BoxHelper( object, color );
49582
49583	}
49584
49585	function EdgesHelper( object, hex ) {
49586
49587		console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );
49588		return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
49589
49590	}
49591
49592	GridHelper.prototype.setColors = function () {
49593
49594		console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );
49595
49596	};
49597
49598	SkeletonHelper.prototype.update = function () {
49599
49600		console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' );
49601
49602	};
49603
49604	function WireframeHelper( object, hex ) {
49605
49606		console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );
49607		return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
49608
49609	}
49610
49611	//
49612
49613	Object.assign( Loader.prototype, {
49614
49615		extractUrlBase: function ( url ) {
49616
49617			console.warn( 'THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.' );
49618			return LoaderUtils.extractUrlBase( url );
49619
49620		}
49621
49622	} );
49623
49624	Loader.Handlers = {
49625
49626		add: function ( /* regex, loader */ ) {
49627
49628			console.error( 'THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.' );
49629
49630		},
49631
49632		get: function ( /* file */ ) {
49633
49634			console.error( 'THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.' );
49635
49636		}
49637
49638	};
49639
49640	function XHRLoader( manager ) {
49641
49642		console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );
49643		return new FileLoader( manager );
49644
49645	}
49646
49647	function BinaryTextureLoader( manager ) {
49648
49649		console.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );
49650		return new DataTextureLoader( manager );
49651
49652	}
49653
49654	Object.assign( ObjectLoader.prototype, {
49655
49656		setTexturePath: function ( value ) {
49657
49658			console.warn( 'THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().' );
49659			return this.setResourcePath( value );
49660
49661		}
49662
49663	} );
49664
49665	//
49666
49667	Object.assign( Box2.prototype, {
49668
49669		center: function ( optionalTarget ) {
49670
49671			console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );
49672			return this.getCenter( optionalTarget );
49673
49674		},
49675		empty: function () {
49676
49677			console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );
49678			return this.isEmpty();
49679
49680		},
49681		isIntersectionBox: function ( box ) {
49682
49683			console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );
49684			return this.intersectsBox( box );
49685
49686		},
49687		size: function ( optionalTarget ) {
49688
49689			console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );
49690			return this.getSize( optionalTarget );
49691
49692		}
49693	} );
49694
49695	Object.assign( Box3.prototype, {
49696
49697		center: function ( optionalTarget ) {
49698
49699			console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );
49700			return this.getCenter( optionalTarget );
49701
49702		},
49703		empty: function () {
49704
49705			console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );
49706			return this.isEmpty();
49707
49708		},
49709		isIntersectionBox: function ( box ) {
49710
49711			console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );
49712			return this.intersectsBox( box );
49713
49714		},
49715		isIntersectionSphere: function ( sphere ) {
49716
49717			console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
49718			return this.intersectsSphere( sphere );
49719
49720		},
49721		size: function ( optionalTarget ) {
49722
49723			console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );
49724			return this.getSize( optionalTarget );
49725
49726		}
49727	} );
49728
49729	Object.assign( Sphere.prototype, {
49730
49731		empty: function () {
49732
49733			console.warn( 'THREE.Sphere: .empty() has been renamed to .isEmpty().' );
49734			return this.isEmpty();
49735
49736		},
49737
49738	} );
49739
49740	Frustum.prototype.setFromMatrix = function ( m ) {
49741
49742		console.warn( 'THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().' );
49743		return this.setFromProjectionMatrix( m );
49744
49745	};
49746
49747	Line3.prototype.center = function ( optionalTarget ) {
49748
49749		console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );
49750		return this.getCenter( optionalTarget );
49751
49752	};
49753
49754	Object.assign( MathUtils, {
49755
49756		random16: function () {
49757
49758			console.warn( 'THREE.Math: .random16() has been deprecated. Use Math.random() instead.' );
49759			return Math.random();
49760
49761		},
49762
49763		nearestPowerOfTwo: function ( value ) {
49764
49765			console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' );
49766			return MathUtils.floorPowerOfTwo( value );
49767
49768		},
49769
49770		nextPowerOfTwo: function ( value ) {
49771
49772			console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' );
49773			return MathUtils.ceilPowerOfTwo( value );
49774
49775		}
49776
49777	} );
49778
49779	Object.assign( Matrix3.prototype, {
49780
49781		flattenToArrayOffset: function ( array, offset ) {
49782
49783			console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
49784			return this.toArray( array, offset );
49785
49786		},
49787		multiplyVector3: function ( vector ) {
49788
49789			console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
49790			return vector.applyMatrix3( this );
49791
49792		},
49793		multiplyVector3Array: function ( /* a */ ) {
49794
49795			console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' );
49796
49797		},
49798		applyToBufferAttribute: function ( attribute ) {
49799
49800			console.warn( 'THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.' );
49801			return attribute.applyMatrix3( this );
49802
49803		},
49804		applyToVector3Array: function ( /* array, offset, length */ ) {
49805
49806			console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );
49807
49808		}
49809
49810	} );
49811
49812	Object.assign( Matrix4.prototype, {
49813
49814		extractPosition: function ( m ) {
49815
49816			console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );
49817			return this.copyPosition( m );
49818
49819		},
49820		flattenToArrayOffset: function ( array, offset ) {
49821
49822			console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
49823			return this.toArray( array, offset );
49824
49825		},
49826		getPosition: function () {
49827
49828			console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
49829			return new Vector3().setFromMatrixColumn( this, 3 );
49830
49831		},
49832		setRotationFromQuaternion: function ( q ) {
49833
49834			console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );
49835			return this.makeRotationFromQuaternion( q );
49836
49837		},
49838		multiplyToArray: function () {
49839
49840			console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' );
49841
49842		},
49843		multiplyVector3: function ( vector ) {
49844
49845			console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
49846			return vector.applyMatrix4( this );
49847
49848		},
49849		multiplyVector4: function ( vector ) {
49850
49851			console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
49852			return vector.applyMatrix4( this );
49853
49854		},
49855		multiplyVector3Array: function ( /* a */ ) {
49856
49857			console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' );
49858
49859		},
49860		rotateAxis: function ( v ) {
49861
49862			console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
49863			v.transformDirection( this );
49864
49865		},
49866		crossVector: function ( vector ) {
49867
49868			console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
49869			return vector.applyMatrix4( this );
49870
49871		},
49872		translate: function () {
49873
49874			console.error( 'THREE.Matrix4: .translate() has been removed.' );
49875
49876		},
49877		rotateX: function () {
49878
49879			console.error( 'THREE.Matrix4: .rotateX() has been removed.' );
49880
49881		},
49882		rotateY: function () {
49883
49884			console.error( 'THREE.Matrix4: .rotateY() has been removed.' );
49885
49886		},
49887		rotateZ: function () {
49888
49889			console.error( 'THREE.Matrix4: .rotateZ() has been removed.' );
49890
49891		},
49892		rotateByAxis: function () {
49893
49894			console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );
49895
49896		},
49897		applyToBufferAttribute: function ( attribute ) {
49898
49899			console.warn( 'THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.' );
49900			return attribute.applyMatrix4( this );
49901
49902		},
49903		applyToVector3Array: function ( /* array, offset, length */ ) {
49904
49905			console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );
49906
49907		},
49908		makeFrustum: function ( left, right, bottom, top, near, far ) {
49909
49910			console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );
49911			return this.makePerspective( left, right, top, bottom, near, far );
49912
49913		}
49914
49915	} );
49916
49917	Plane.prototype.isIntersectionLine = function ( line ) {
49918
49919		console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );
49920		return this.intersectsLine( line );
49921
49922	};
49923
49924	Quaternion.prototype.multiplyVector3 = function ( vector ) {
49925
49926		console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
49927		return vector.applyQuaternion( this );
49928
49929	};
49930
49931	Object.assign( Ray.prototype, {
49932
49933		isIntersectionBox: function ( box ) {
49934
49935			console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );
49936			return this.intersectsBox( box );
49937
49938		},
49939		isIntersectionPlane: function ( plane ) {
49940
49941			console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );
49942			return this.intersectsPlane( plane );
49943
49944		},
49945		isIntersectionSphere: function ( sphere ) {
49946
49947			console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
49948			return this.intersectsSphere( sphere );
49949
49950		}
49951
49952	} );
49953
49954	Object.assign( Triangle.prototype, {
49955
49956		area: function () {
49957
49958			console.warn( 'THREE.Triangle: .area() has been renamed to .getArea().' );
49959			return this.getArea();
49960
49961		},
49962		barycoordFromPoint: function ( point, target ) {
49963
49964			console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' );
49965			return this.getBarycoord( point, target );
49966
49967		},
49968		midpoint: function ( target ) {
49969
49970			console.warn( 'THREE.Triangle: .midpoint() has been renamed to .getMidpoint().' );
49971			return this.getMidpoint( target );
49972
49973		},
49974		normal: function ( target ) {
49975
49976			console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' );
49977			return this.getNormal( target );
49978
49979		},
49980		plane: function ( target ) {
49981
49982			console.warn( 'THREE.Triangle: .plane() has been renamed to .getPlane().' );
49983			return this.getPlane( target );
49984
49985		}
49986
49987	} );
49988
49989	Object.assign( Triangle, {
49990
49991		barycoordFromPoint: function ( point, a, b, c, target ) {
49992
49993			console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' );
49994			return Triangle.getBarycoord( point, a, b, c, target );
49995
49996		},
49997		normal: function ( a, b, c, target ) {
49998
49999			console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' );
50000			return Triangle.getNormal( a, b, c, target );
50001
50002		}
50003
50004	} );
50005
50006	Object.assign( Shape.prototype, {
50007
50008		extractAllPoints: function ( divisions ) {
50009
50010			console.warn( 'THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.' );
50011			return this.extractPoints( divisions );
50012
50013		},
50014		extrude: function ( options ) {
50015
50016			console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );
50017			return new ExtrudeGeometry( this, options );
50018
50019		},
50020		makeGeometry: function ( options ) {
50021
50022			console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );
50023			return new ShapeGeometry( this, options );
50024
50025		}
50026
50027	} );
50028
50029	Object.assign( Vector2.prototype, {
50030
50031		fromAttribute: function ( attribute, index, offset ) {
50032
50033			console.warn( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );
50034			return this.fromBufferAttribute( attribute, index, offset );
50035
50036		},
50037		distanceToManhattan: function ( v ) {
50038
50039			console.warn( 'THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' );
50040			return this.manhattanDistanceTo( v );
50041
50042		},
50043		lengthManhattan: function () {
50044
50045			console.warn( 'THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().' );
50046			return this.manhattanLength();
50047
50048		}
50049
50050	} );
50051
50052	Object.assign( Vector3.prototype, {
50053
50054		setEulerFromRotationMatrix: function () {
50055
50056			console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );
50057
50058		},
50059		setEulerFromQuaternion: function () {
50060
50061			console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );
50062
50063		},
50064		getPositionFromMatrix: function ( m ) {
50065
50066			console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );
50067			return this.setFromMatrixPosition( m );
50068
50069		},
50070		getScaleFromMatrix: function ( m ) {
50071
50072			console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );
50073			return this.setFromMatrixScale( m );
50074
50075		},
50076		getColumnFromMatrix: function ( index, matrix ) {
50077
50078			console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );
50079			return this.setFromMatrixColumn( matrix, index );
50080
50081		},
50082		applyProjection: function ( m ) {
50083
50084			console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );
50085			return this.applyMatrix4( m );
50086
50087		},
50088		fromAttribute: function ( attribute, index, offset ) {
50089
50090			console.warn( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );
50091			return this.fromBufferAttribute( attribute, index, offset );
50092
50093		},
50094		distanceToManhattan: function ( v ) {
50095
50096			console.warn( 'THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' );
50097			return this.manhattanDistanceTo( v );
50098
50099		},
50100		lengthManhattan: function () {
50101
50102			console.warn( 'THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().' );
50103			return this.manhattanLength();
50104
50105		}
50106
50107	} );
50108
50109	Object.assign( Vector4.prototype, {
50110
50111		fromAttribute: function ( attribute, index, offset ) {
50112
50113			console.warn( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );
50114			return this.fromBufferAttribute( attribute, index, offset );
50115
50116		},
50117		lengthManhattan: function () {
50118
50119			console.warn( 'THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().' );
50120			return this.manhattanLength();
50121
50122		}
50123
50124	} );
50125
50126	//
50127
50128	Object.assign( Geometry.prototype, {
50129
50130		computeTangents: function () {
50131
50132			console.error( 'THREE.Geometry: .computeTangents() has been removed.' );
50133
50134		},
50135		computeLineDistances: function () {
50136
50137			console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' );
50138
50139		},
50140		applyMatrix: function ( matrix ) {
50141
50142			console.warn( 'THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().' );
50143			return this.applyMatrix4( matrix );
50144
50145		}
50146
50147	} );
50148
50149	Object.assign( Object3D.prototype, {
50150
50151		getChildByName: function ( name ) {
50152
50153			console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
50154			return this.getObjectByName( name );
50155
50156		},
50157		renderDepth: function () {
50158
50159			console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );
50160
50161		},
50162		translate: function ( distance, axis ) {
50163
50164			console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
50165			return this.translateOnAxis( axis, distance );
50166
50167		},
50168		getWorldRotation: function () {
50169
50170			console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' );
50171
50172		},
50173		applyMatrix: function ( matrix ) {
50174
50175			console.warn( 'THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().' );
50176			return this.applyMatrix4( matrix );
50177
50178		}
50179
50180	} );
50181
50182	Object.defineProperties( Object3D.prototype, {
50183
50184		eulerOrder: {
50185			get: function () {
50186
50187				console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
50188				return this.rotation.order;
50189
50190			},
50191			set: function ( value ) {
50192
50193				console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
50194				this.rotation.order = value;
50195
50196			}
50197		},
50198		useQuaternion: {
50199			get: function () {
50200
50201				console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
50202
50203			},
50204			set: function () {
50205
50206				console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
50207
50208			}
50209		}
50210
50211	} );
50212
50213	Object.assign( Mesh.prototype, {
50214
50215		setDrawMode: function () {
50216
50217			console.error( 'THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' );
50218
50219		},
50220
50221	} );
50222
50223	Object.defineProperties( Mesh.prototype, {
50224
50225		drawMode: {
50226			get: function () {
50227
50228				console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.' );
50229				return TrianglesDrawMode;
50230
50231			},
50232			set: function () {
50233
50234				console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' );
50235
50236			}
50237		}
50238
50239	} );
50240
50241	Object.defineProperties( LOD.prototype, {
50242
50243		objects: {
50244			get: function () {
50245
50246				console.warn( 'THREE.LOD: .objects has been renamed to .levels.' );
50247				return this.levels;
50248
50249			}
50250		}
50251
50252	} );
50253
50254	Object.defineProperty( Skeleton.prototype, 'useVertexTexture', {
50255
50256		get: function () {
50257
50258			console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
50259
50260		},
50261		set: function () {
50262
50263			console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
50264
50265		}
50266
50267	} );
50268
50269	SkinnedMesh.prototype.initBones = function () {
50270
50271		console.error( 'THREE.SkinnedMesh: initBones() has been removed.' );
50272
50273	};
50274
50275	Object.defineProperty( Curve.prototype, '__arcLengthDivisions', {
50276
50277		get: function () {
50278
50279			console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
50280			return this.arcLengthDivisions;
50281
50282		},
50283		set: function ( value ) {
50284
50285			console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
50286			this.arcLengthDivisions = value;
50287
50288		}
50289
50290	} );
50291
50292	//
50293
50294	PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {
50295
50296		console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " +
50297				"Use .setFocalLength and .filmGauge for a photographic setup." );
50298
50299		if ( filmGauge !== undefined ) { this.filmGauge = filmGauge; }
50300		this.setFocalLength( focalLength );
50301
50302	};
50303
50304	//
50305
50306	Object.defineProperties( Light.prototype, {
50307		onlyShadow: {
50308			set: function () {
50309
50310				console.warn( 'THREE.Light: .onlyShadow has been removed.' );
50311
50312			}
50313		},
50314		shadowCameraFov: {
50315			set: function ( value ) {
50316
50317				console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );
50318				this.shadow.camera.fov = value;
50319
50320			}
50321		},
50322		shadowCameraLeft: {
50323			set: function ( value ) {
50324
50325				console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );
50326				this.shadow.camera.left = value;
50327
50328			}
50329		},
50330		shadowCameraRight: {
50331			set: function ( value ) {
50332
50333				console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );
50334				this.shadow.camera.right = value;
50335
50336			}
50337		},
50338		shadowCameraTop: {
50339			set: function ( value ) {
50340
50341				console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );
50342				this.shadow.camera.top = value;
50343
50344			}
50345		},
50346		shadowCameraBottom: {
50347			set: function ( value ) {
50348
50349				console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );
50350				this.shadow.camera.bottom = value;
50351
50352			}
50353		},
50354		shadowCameraNear: {
50355			set: function ( value ) {
50356
50357				console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );
50358				this.shadow.camera.near = value;
50359
50360			}
50361		},
50362		shadowCameraFar: {
50363			set: function ( value ) {
50364
50365				console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );
50366				this.shadow.camera.far = value;
50367
50368			}
50369		},
50370		shadowCameraVisible: {
50371			set: function () {
50372
50373				console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );
50374
50375			}
50376		},
50377		shadowBias: {
50378			set: function ( value ) {
50379
50380				console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );
50381				this.shadow.bias = value;
50382
50383			}
50384		},
50385		shadowDarkness: {
50386			set: function () {
50387
50388				console.warn( 'THREE.Light: .shadowDarkness has been removed.' );
50389
50390			}
50391		},
50392		shadowMapWidth: {
50393			set: function ( value ) {
50394
50395				console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );
50396				this.shadow.mapSize.width = value;
50397
50398			}
50399		},
50400		shadowMapHeight: {
50401			set: function ( value ) {
50402
50403				console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );
50404				this.shadow.mapSize.height = value;
50405
50406			}
50407		}
50408	} );
50409
50410	//
50411
50412	Object.defineProperties( BufferAttribute.prototype, {
50413
50414		length: {
50415			get: function () {
50416
50417				console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );
50418				return this.array.length;
50419
50420			}
50421		},
50422		dynamic: {
50423			get: function () {
50424
50425				console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' );
50426				return this.usage === DynamicDrawUsage;
50427
50428			},
50429			set: function ( /* value */ ) {
50430
50431				console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' );
50432				this.setUsage( DynamicDrawUsage );
50433
50434			}
50435		}
50436
50437	} );
50438
50439	Object.assign( BufferAttribute.prototype, {
50440		setDynamic: function ( value ) {
50441
50442			console.warn( 'THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.' );
50443			this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage );
50444			return this;
50445
50446		},
50447		copyIndicesArray: function ( /* indices */ ) {
50448
50449			console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' );
50450
50451		},
50452		setArray: function ( /* array */ ) {
50453
50454			console.error( 'THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' );
50455
50456		}
50457	} );
50458
50459	Object.assign( BufferGeometry.prototype, {
50460
50461		addIndex: function ( index ) {
50462
50463			console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );
50464			this.setIndex( index );
50465
50466		},
50467		addAttribute: function ( name, attribute ) {
50468
50469			console.warn( 'THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().' );
50470
50471			if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) {
50472
50473				console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
50474
50475				return this.setAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
50476
50477			}
50478
50479			if ( name === 'index' ) {
50480
50481				console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
50482				this.setIndex( attribute );
50483
50484				return this;
50485
50486			}
50487
50488			return this.setAttribute( name, attribute );
50489
50490		},
50491		addDrawCall: function ( start, count, indexOffset ) {
50492
50493			if ( indexOffset !== undefined ) {
50494
50495				console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );
50496
50497			}
50498
50499			console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );
50500			this.addGroup( start, count );
50501
50502		},
50503		clearDrawCalls: function () {
50504
50505			console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
50506			this.clearGroups();
50507
50508		},
50509		computeTangents: function () {
50510
50511			console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
50512
50513		},
50514		computeOffsets: function () {
50515
50516			console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );
50517
50518		},
50519		removeAttribute: function ( name ) {
50520
50521			console.warn( 'THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().' );
50522
50523			return this.deleteAttribute( name );
50524
50525		},
50526		applyMatrix: function ( matrix ) {
50527
50528			console.warn( 'THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().' );
50529			return this.applyMatrix4( matrix );
50530
50531		}
50532
50533	} );
50534
50535	Object.defineProperties( BufferGeometry.prototype, {
50536
50537		drawcalls: {
50538			get: function () {
50539
50540				console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );
50541				return this.groups;
50542
50543			}
50544		},
50545		offsets: {
50546			get: function () {
50547
50548				console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );
50549				return this.groups;
50550
50551			}
50552		}
50553
50554	} );
50555
50556	Object.defineProperties( InstancedBufferGeometry.prototype, {
50557
50558		maxInstancedCount: {
50559			get: function () {
50560
50561				console.warn( 'THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.' );
50562				return this.instanceCount;
50563
50564			},
50565			set: function ( value ) {
50566
50567				console.warn( 'THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.' );
50568				this.instanceCount = value;
50569
50570			}
50571		}
50572
50573	} );
50574
50575	Object.defineProperties( Raycaster.prototype, {
50576
50577		linePrecision: {
50578			get: function () {
50579
50580				console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' );
50581				return this.params.Line.threshold;
50582
50583			},
50584			set: function ( value ) {
50585
50586				console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' );
50587				this.params.Line.threshold = value;
50588
50589			}
50590		}
50591
50592	} );
50593
50594	Object.defineProperties( InterleavedBuffer.prototype, {
50595
50596		dynamic: {
50597			get: function () {
50598
50599				console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' );
50600				return this.usage === DynamicDrawUsage;
50601
50602			},
50603			set: function ( value ) {
50604
50605				console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' );
50606				this.setUsage( value );
50607
50608			}
50609		}
50610
50611	} );
50612
50613	Object.assign( InterleavedBuffer.prototype, {
50614		setDynamic: function ( value ) {
50615
50616			console.warn( 'THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.' );
50617			this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage );
50618			return this;
50619
50620		},
50621		setArray: function ( /* array */ ) {
50622
50623			console.error( 'THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' );
50624
50625		}
50626	} );
50627
50628	//
50629
50630	Object.assign( ExtrudeBufferGeometry.prototype, {
50631
50632		getArrays: function () {
50633
50634			console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' );
50635
50636		},
50637
50638		addShapeList: function () {
50639
50640			console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' );
50641
50642		},
50643
50644		addShape: function () {
50645
50646			console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' );
50647
50648		}
50649
50650	} );
50651
50652	//
50653
50654	Object.defineProperties( Uniform.prototype, {
50655
50656		dynamic: {
50657			set: function () {
50658
50659				console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );
50660
50661			}
50662		},
50663		onUpdate: {
50664			value: function () {
50665
50666				console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );
50667				return this;
50668
50669			}
50670		}
50671
50672	} );
50673
50674	//
50675
50676	Object.defineProperties( Material.prototype, {
50677
50678		wrapAround: {
50679			get: function () {
50680
50681				console.warn( 'THREE.Material: .wrapAround has been removed.' );
50682
50683			},
50684			set: function () {
50685
50686				console.warn( 'THREE.Material: .wrapAround has been removed.' );
50687
50688			}
50689		},
50690
50691		overdraw: {
50692			get: function () {
50693
50694				console.warn( 'THREE.Material: .overdraw has been removed.' );
50695
50696			},
50697			set: function () {
50698
50699				console.warn( 'THREE.Material: .overdraw has been removed.' );
50700
50701			}
50702		},
50703
50704		wrapRGB: {
50705			get: function () {
50706
50707				console.warn( 'THREE.Material: .wrapRGB has been removed.' );
50708				return new Color();
50709
50710			}
50711		},
50712
50713		shading: {
50714			get: function () {
50715
50716				console.error( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
50717
50718			},
50719			set: function ( value ) {
50720
50721				console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
50722				this.flatShading = ( value === FlatShading );
50723
50724			}
50725		},
50726
50727		stencilMask: {
50728			get: function () {
50729
50730				console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' );
50731				return this.stencilFuncMask;
50732
50733			},
50734			set: function ( value ) {
50735
50736				console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' );
50737				this.stencilFuncMask = value;
50738
50739			}
50740		}
50741
50742	} );
50743
50744	Object.defineProperties( MeshPhongMaterial.prototype, {
50745
50746		metal: {
50747			get: function () {
50748
50749				console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );
50750				return false;
50751
50752			},
50753			set: function () {
50754
50755				console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );
50756
50757			}
50758		}
50759
50760	} );
50761
50762	Object.defineProperties( ShaderMaterial.prototype, {
50763
50764		derivatives: {
50765			get: function () {
50766
50767				console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
50768				return this.extensions.derivatives;
50769
50770			},
50771			set: function ( value ) {
50772
50773				console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
50774				this.extensions.derivatives = value;
50775
50776			}
50777		}
50778
50779	} );
50780
50781	//
50782
50783	Object.assign( WebGLRenderer.prototype, {
50784
50785		clearTarget: function ( renderTarget, color, depth, stencil ) {
50786
50787			console.warn( 'THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead.' );
50788			this.setRenderTarget( renderTarget );
50789			this.clear( color, depth, stencil );
50790
50791		},
50792		animate: function ( callback ) {
50793
50794			console.warn( 'THREE.WebGLRenderer: .animate() is now .setAnimationLoop().' );
50795			this.setAnimationLoop( callback );
50796
50797		},
50798		getCurrentRenderTarget: function () {
50799
50800			console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' );
50801			return this.getRenderTarget();
50802
50803		},
50804		getMaxAnisotropy: function () {
50805
50806			console.warn( 'THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().' );
50807			return this.capabilities.getMaxAnisotropy();
50808
50809		},
50810		getPrecision: function () {
50811
50812			console.warn( 'THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.' );
50813			return this.capabilities.precision;
50814
50815		},
50816		resetGLState: function () {
50817
50818			console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' );
50819			return this.state.reset();
50820
50821		},
50822		supportsFloatTextures: function () {
50823
50824			console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );
50825			return this.extensions.get( 'OES_texture_float' );
50826
50827		},
50828		supportsHalfFloatTextures: function () {
50829
50830			console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' );
50831			return this.extensions.get( 'OES_texture_half_float' );
50832
50833		},
50834		supportsStandardDerivatives: function () {
50835
50836			console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' );
50837			return this.extensions.get( 'OES_standard_derivatives' );
50838
50839		},
50840		supportsCompressedTextureS3TC: function () {
50841
50842			console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' );
50843			return this.extensions.get( 'WEBGL_compressed_texture_s3tc' );
50844
50845		},
50846		supportsCompressedTexturePVRTC: function () {
50847
50848			console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' );
50849			return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );
50850
50851		},
50852		supportsBlendMinMax: function () {
50853
50854			console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' );
50855			return this.extensions.get( 'EXT_blend_minmax' );
50856
50857		},
50858		supportsVertexTextures: function () {
50859
50860			console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );
50861			return this.capabilities.vertexTextures;
50862
50863		},
50864		supportsInstancedArrays: function () {
50865
50866			console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_
50866instanced_arrays\' ).' );
50867			return this.extensions.get( 'ANGLE_instanced_arrays' );
50868
50869		},
50870		enableScissorTest: function ( boolean ) {
50871
50872			console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );
50873			this.setScissorTest( boolean );
50874
50875		},
50876		initMaterial: function () {
50877
50878			console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
50879
50880		},
50881		addPrePlugin: function () {
50882
50883			console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );
50884
50885		},
50886		addPostPlugin: function () {
50887
50888			console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );
50889
50890		},
50891		updateShadowMap: function () {
50892
50893			console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );
50894
50895		},
50896		setFaceCulling: function () {
50897
50898			console.warn( 'THREE.WebGLRenderer: .setFaceCulling() has been removed.' );
50899
50900		},
50901		allocTextureUnit: function () {
50902
50903			console.warn( 'THREE.WebGLRenderer: .allocTextureUnit() has been removed.' );
50904
50905		},
50906		setTexture: function () {
50907
50908			console.warn( 'THREE.WebGLRenderer: .setTexture() has been removed.' );
50909
50910		},
50911		setTexture2D: function () {
50912
50913			console.warn( 'THREE.WebGLRenderer: .setTexture2D() has been removed.' );
50914
50915		},
50916		setTextureCube: function () {
50917
50918			console.warn( 'THREE.WebGLRenderer: .setTextureCube() has been removed.' );
50919
50920		},
50921		getActiveMipMapLevel: function () {
50922
50923			console.warn( 'THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel().' );
50924			return this.getActiveMipmapLevel();
50925
50926		}
50927
50928	} );
50929
50930	Object.defineProperties( WebGLRenderer.prototype, {
50931
50932		shadowMapEnabled: {
50933			get: function () {
50934
50935				return this.shadowMap.enabled;
50936
50937			},
50938			set: function ( value ) {
50939
50940				console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );
50941				this.shadowMap.enabled = value;
50942
50943			}
50944		},
50945		shadowMapType: {
50946			get: function () {
50947
50948				return this.shadowMap.type;
50949
50950			},
50951			set: function ( value ) {
50952
50953				console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );
50954				this.shadowMap.type = value;
50955
50956			}
50957		},
50958		shadowMapCullFace: {
50959			get: function () {
50960
50961				console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' );
50962				return undefined;
50963
50964			},
50965			set: function ( /* value */ ) {
50966
50967				console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' );
50968
50969			}
50970		},
50971		context: {
50972			get: function () {
50973
50974				console.warn( 'THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.' );
50975				return this.getContext();
50976
50977			}
50978		},
50979		vr: {
50980			get: function () {
50981
50982				console.warn( 'THREE.WebGLRenderer: .vr has been renamed to .xr' );
50983				return this.xr;
50984
50985			}
50986		},
50987		gammaInput: {
50988			get: function () {
50989
50990				console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' );
50991				return false;
50992
50993			},
50994			set: function () {
50995
50996				console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' );
50997
50998			}
50999		},
51000		gammaOutput: {
51001			get: function () {
51002
51003				console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' );
51004				return false;
51005
51006			},
51007			set: function ( value ) {
51008
51009				console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' );
51010				this.outputEncoding = ( value === true ) ? sRGBEncoding : LinearEncoding;
51011
51012			}
51013		},
51014		toneMappingWhitePoint: {
51015			get: function () {
51016
51017				console.warn( 'THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.' );
51018				return 1.0;
51019
51020			},
51021			set: function () {
51022
51023				console.warn( 'THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.' );
51024
51025			}
51026		},
51027
51028	} );
51029
51030	Object.defineProperties( WebGLShadowMap.prototype, {
51031
51032		cullFace: {
51033			get: function () {
51034
51035				console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' );
51036				return undefined;
51037
51038			},
51039			set: function ( /* cullFace */ ) {
51040
51041				console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' );
51042
51043			}
51044		},
51045		renderReverseSided: {
51046			get: function () {
51047
51048				console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' );
51049				return undefined;
51050
51051			},
51052			set: function () {
51053
51054				console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' );
51055
51056			}
51057		},
51058		renderSingleSided: {
51059			get: function () {
51060
51061				console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' );
51062				return undefined;
51063
51064			},
51065			set: function () {
51066
51067				console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' );
51068
51069			}
51070		}
51071
51072	} );
51073
51074	function WebGLRenderTargetCube( width, height, options ) {
51075
51076		console.warn( 'THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).' );
51077		return new WebGLCubeRenderTarget( width, options );
51078
51079	}
51080
51081	//
51082
51083	Object.defineProperties( WebGLRenderTarget.prototype, {
51084
51085		wrapS: {
51086			get: function () {
51087
51088				console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
51089				return this.texture.wrapS;
51090
51091			},
51092			set: function ( value ) {
51093
51094				console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
51095				this.texture.wrapS = value;
51096
51097			}
51098		},
51099		wrapT: {
51100			get: function () {
51101
51102				console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
51103				return this.texture.wrapT;
51104
51105			},
51106			set: function ( value ) {
51107
51108				console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
51109				this.texture.wrapT = value;
51110
51111			}
51112		},
51113		magFilter: {
51114			get: function () {
51115
51116				console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
51117				return this.texture.magFilter;
51118
51119			},
51120			set: function ( value ) {
51121
51122				console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
51123				this.texture.magFilter = value;
51124
51125			}
51126		},
51127		minFilter: {
51128			get: function () {
51129
51130				console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
51131				return this.texture.minFilter;
51132
51133			},
51134			set: function ( value ) {
51135
51136				console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
51137				this.texture.minFilter = value;
51138
51139			}
51140		},
51141		anisotropy: {
51142			get: function () {
51143
51144				console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
51145				return this.texture.anisotropy;
51146
51147			},
51148			set: function ( value ) {
51149
51150				console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
51151				this.texture.anisotropy = value;
51152
51153			}
51154		},
51155		offset: {
51156			get: function () {
51157
51158				console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
51159				return this.texture.offset;
51160
51161			},
51162			set: function ( value ) {
51163
51164				console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
51165				this.texture.offset = value;
51166
51167			}
51168		},
51169		repeat: {
51170			get: function () {
51171
51172				console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
51173				return this.texture.repeat;
51174
51175			},
51176			set: function ( value ) {
51177
51178				console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
51179				this.texture.repeat = value;
51180
51181			}
51182		},
51183		format: {
51184			get: function () {
51185
51186				console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
51187				return this.texture.format;
51188
51189			},
51190			set: function ( value ) {
51191
51192				console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
51193				this.texture.format = value;
51194
51195			}
51196		},
51197		type: {
51198			get: function () {
51199
51200				console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
51201				return this.texture.type;
51202
51203			},
51204			set: function ( value ) {
51205
51206				console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
51207				this.texture.type = value;
51208
51209			}
51210		},
51211		generateMipmaps: {
51212			get: function () {
51213
51214				console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
51215				return this.texture.generateMipmaps;
51216
51217			},
51218			set: function ( value ) {
51219
51220				console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
51221				this.texture.generateMipmaps = value;
51222
51223			}
51224		}
51225
51226	} );
51227
51228	//
51229
51230	Object.defineProperties( Audio.prototype, {
51231
51232		load: {
51233			value: function ( file ) {
51234
51235				console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );
51236				var scope = this;
51237				var audioLoader = new AudioLoader();
51238				audioLoader.load( file, function ( buffer ) {
51239
51240					scope.setBuffer( buffer );
51241
51242				} );
51243				return this;
51244
51245			}
51246		},
51247		startTime: {
51248			set: function () {
51249
51250				console.warn( 'THREE.Audio: .startTime is now .play( delay ).' );
51251
51252			}
51253		}
51254
51255	} );
51256
51257	AudioAnalyser.prototype.getData = function () {
51258
51259		console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );
51260		return this.getFrequencyData();
51261
51262	};
51263
51264	//
51265
51266	CubeCamera.prototype.updateCubeMap = function ( renderer, scene ) {
51267
51268		console.warn( 'THREE.CubeCamera: .updateCubeMap() is now .update().' );
51269		return this.update( renderer, scene );
51270
51271	};
51272
51273	//
51274
51275	var GeometryUtils = {
51276
51277		merge: function ( geometry1, geometry2, materialIndexOffset ) {
51278
51279			console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
51280			var matrix;
51281
51282			if ( geometry2.isMesh ) {
51283
51284				geometry2.matrixAutoUpdate && geometry2.updateMatrix();
51285
51286				matrix = geometry2.matrix;
51287				geometry2 = geometry2.geometry;
51288
51289			}
51290
51291			geometry1.merge( geometry2, matrix, materialIndexOffset );
51292
51293		},
51294
51295		center: function ( geometry ) {
51296
51297			console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );
51298			return geometry.center();
51299
51300		}
51301
51302	};
51303
51304	ImageUtils.crossOrigin = undefined;
51305
51306	ImageUtils.loadTexture = function ( url, mapping, onLoad, onError ) {
51307
51308		console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );
51309
51310		var loader = new TextureLoader();
51311		loader.setCrossOrigin( this.crossOrigin );
51312
51313		var texture = loader.load( url, onLoad, undefined, onError );
51314
51315		if ( mapping ) { texture.mapping = mapping; }
51316
51317		return texture;
51318
51319	};
51320
51321	ImageUtils.loadTextureCube = function ( urls, mapping, onLoad, onError ) {
51322
51323		console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );
51324
51325		var loader = new CubeTextureLoader();
51326		loader.setCrossOrigin( this.crossOrigin );
51327
51328		var texture = loader.load( urls, onLoad, undefined, onError );
51329
51330		if ( mapping ) { texture.mapping = mapping; }
51331
51332		return texture;
51333
51334	};
51335
51336	ImageUtils.loadCompressedTexture = function () {
51337
51338		console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );
51339
51340	};
51341
51342	ImageUtils.loadCompressedTextureCube = function () {
51343
51344		console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );
51345
51346	};
51347
51348	//
51349
51350	function CanvasRenderer() {
51351
51352		console.error( 'THREE.CanvasRenderer has been removed' );
51353
51354	}
51355
51356	//
51357
51358	function JSONLoader() {
51359
51360		console.error( 'THREE.JSONLoader has been removed.' );
51361
51362	}
51363
51364	//
51365
51366	var SceneUtils = {
51367
51368		createMultiMaterialObject: function ( /* geometry, materials */ ) {
51369
51370			console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
51371
51372		},
51373
51374		detach: function ( /* child, parent, scene */ ) {
51375
51376			console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
51377
51378		},
51379
51380		attach: function ( /* child, scene, parent */ ) {
51381
51382			console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
51383
51384		}
51385
51386	};
51387
51388	//
51389
51390	function LensFlare() {
51391
51392		console.error( 'THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js' );
51393
51394	}
51395
51396	if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
51397
51398		/* eslint-disable no-undef */
51399		__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: {
51400			revision: REVISION,
51401		} } ) );
51402		/* eslint-enable no-undef */
51403
51404	}
51405
51406	exports.ACESFilmicToneMapping = ACESFilmicToneMapping;
51407	exports.AddEquation = AddEquation;
51408	exports.AddOperation = AddOperation;
51409	exports.AdditiveAnimationBlendMode = AdditiveAnimationBlendMode;
51410	exports.AdditiveBlending = AdditiveBlending;
51411	exports.AlphaFormat = AlphaFormat;
51412	exports.AlwaysDepth = AlwaysDepth;
51413	exports.AlwaysStencilFunc = AlwaysStencilFunc;
51414	exports.AmbientLight = AmbientLight;
51415	exports.AmbientLightProbe = AmbientLightProbe;
51416	exports.AnimationClip = AnimationClip;
51417	exports.AnimationLoader = AnimationLoader;
51418	exports.AnimationMixer = AnimationMixer;
51419	exports.AnimationObjectGroup = AnimationObjectGroup;
51420	exports.AnimationUtils = AnimationUtils;
51421	exports.ArcCurve = ArcCurve;
51422	exports.ArrayCamera = ArrayCamera;
51423	exports.ArrowHelper = ArrowHelper;
51424	exports.Audio = Audio;
51425	exports.AudioAnalyser = AudioAnalyser;
51426	exports.AudioContext = AudioContext;
51427	exports.AudioListener = AudioListener;
51428	exports.AudioLoader = AudioLoader;
51429	exports.AxesHelper = AxesHelper;
51430	exports.AxisHelper = AxisHelper;
51431	exports.BackSide = BackSide;
51432	exports.BasicDepthPacking = BasicDepthPacking;
51433	exports.BasicShadowMap = BasicShadowMap;
51434	exports.BinaryTextureLoader = BinaryTextureLoader;
51435	exports.Bone = Bone;
51436	exports.BooleanKeyframeTrack = BooleanKeyframeTrack;
51437	exports.BoundingBoxHelper = BoundingBoxHelper;
51438	exports.Box2 = Box2;
51439	exports.Box3 = Box3;
51440	exports.Box3Helper = Box3Helper;
51441	exports.BoxBufferGeometry = BoxBufferGeometry;
51442	exports.BoxGeometry = BoxGeometry;
51443	exports.BoxHelper = BoxHelper;
51444	exports.BufferAttribute = BufferAttribute;
51445	exports.BufferGeometry = BufferGeometry;
51446	exports.BufferGeometryLoader = BufferGeometryLoader;
51447	exports.ByteType = ByteType;
51448	exports.Cache = Cache;
51449	exports.Camera = Camera;
51450	exports.CameraHelper = CameraHelper;
51451	exports.CanvasRenderer = CanvasRenderer;
51452	exports.CanvasTexture = CanvasTexture;
51453	exports.CatmullRomCurve3 = CatmullRomCurve3;
51454	exports.CineonToneMapping = CineonToneMapping;
51455	exports.CircleBufferGeometry = CircleBufferGeometry;
51456	exports.CircleGeometry = CircleGeometry;
51457	exports.ClampToEdgeWrapping = ClampToEdgeWrapping;
51458	exports.Clock = Clock;
51459	exports.ClosedSplineCurve3 = ClosedSplineCurve3;
51460	exports.Color = Color;
51461	exports.ColorKeyframeTrack = ColorKeyframeTrack;
51462	exports.CompressedTexture = CompressedTexture;
51463	exports.CompressedTextureLoader = CompressedTextureLoader;
51464	exports.ConeBufferGeometry = ConeBufferGeometry;
51465	exports.ConeGeometry = ConeGeometry;
51466	exports.CubeCamera = CubeCamera;
51467	exports.CubeGeometry = BoxGeometry;
51468	exports.CubeReflectionMapping = CubeReflectionMapping;
51469	exports.CubeRefractionMapping = CubeRefractionMapping;
51470	exports.CubeTexture = CubeTexture;
51471	exports.CubeTextureLoader = CubeTextureLoader;
51472	exports.CubeUVReflectionMapping = CubeUVReflectionMapping;
51473	exports.CubeUVRefractionMapping = CubeUVRefractionMapping;
51474	exports.CubicBezierCurve = CubicBezierCurve;
51475	exports.CubicBezierCurve3 = CubicBezierCurve3;
51476	exports.CubicInterpolant = CubicInterpolant;
51477	exports.CullFaceBack = CullFaceBack;
51478	exports.CullFaceFront = CullFaceFront;
51479	exports.CullFaceFrontBack = CullFaceFrontBack;
51480	exports.CullFaceNone = CullFaceNone;
51481	exports.Curve = Curve;
51482	exports.CurvePath = CurvePath;
51483	exports.CustomBlending = CustomBlending;
51484	exports.CustomToneMapping = CustomToneMapping;
51485	exports.CylinderBufferGeometry = CylinderBufferGeometry;
51486	exports.CylinderGeometry = CylinderGeometry;
51487	exports.Cylindrical = Cylindrical;
51488	exports.DataTexture = DataTexture;
51489	exports.DataTexture2DArray = DataTexture2DArray;
51490	exports.DataTexture3D = DataTexture3D;
51491	exports.DataTextureLoader = DataTextureLoader;
51492	exports.DecrementStencilOp = DecrementStencilOp;
51493	exports.DecrementWrapStencilOp = DecrementWrapStencilOp;
51494	exports.DefaultLoadingManager = DefaultLoadingManager;
51495	exports.DepthFormat = DepthFormat;
51496	exports.DepthStencilFormat = DepthStencilFormat;
51497	exports.DepthTexture = DepthTexture;
51498	exports.DirectionalLight = DirectionalLight;
51499	exports.DirectionalLightHelper = DirectionalLightHelper;
51500	exports.DirectionalLightShadow = DirectionalLightShadow;
51501	exports.DiscreteInterpolant = DiscreteInterpolant;
51502	exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;
51503	exports.DodecahedronGeometry = DodecahedronGeometry;
51504	exports.DoubleSide = DoubleSide;
51505	exports.DstAlphaFactor = DstAlphaFactor;
51506	exports.DstColorFactor = DstColorFactor;
51507	exports.DynamicBufferAttribute = DynamicBufferAttribute;
51508	exports.DynamicCopyUsage = DynamicCopyUsage;
51509	exports.DynamicDrawUsage = DynamicDrawUsage;
51510	exports.DynamicReadUsage = DynamicReadUsage;
51511	exports.EdgesGeometry = EdgesGeometry;
51512	exports.EdgesHelper = EdgesHelper;
51513	exports.EllipseCurve = EllipseCurve;
51514	exports.EqualDepth = EqualDepth;
51515	exports.EqualStencilFunc = EqualStencilFunc;
51516	exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;
51517	exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;
51518	exports.Euler = Euler;
51519	exports.EventDispatcher = EventDispatcher;
51520	exports.ExtrudeBufferGeometry = ExtrudeBufferGeometry;
51521	exports.ExtrudeGeometry = ExtrudeGeometry;
51522	exports.Face3 = Face3;
51523	exports.Face4 = Face4;
51524	exports.FaceColors = FaceColors;
51525	exports.FileLoader = FileLoader;
51526	exports.FlatShading = FlatShading;
51527	exports.Float32Attribute = Float32Attribute;
51528	exports.Float32BufferAttribute = Float32BufferAttribute;
51529	exports.Float64Attribute = Float64Attribute;
51530	exports.Float64BufferAttribute = Float64BufferAttribute;
51531	exports.FloatType = FloatType;
51532	exports.Fog = Fog;
51533	exports.FogExp2 = FogExp2;
51534	exports.Font = Font;
51535	exports.FontLoader = FontLoader;
51536	exports.FrontFaceDirectionCCW = FrontFaceDirectionCCW;
51537	exports.FrontFaceDirectionCW = FrontFaceDirectionCW;
51538	exports.FrontSide = FrontSide;
51539	exports.Frustum = Frustum;
51540	exports.GammaEncoding = GammaEncoding;
51541	exports.Geometry = Geometry;
51542	exports.GeometryUtils = GeometryUtils;
51543	exports.GreaterDepth = GreaterDepth;
51544	exports.GreaterEqualDepth = GreaterEqualDepth;
51545	exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc;
51546	exports.GreaterStencilFunc = GreaterStencilFunc;
51547	exports.GridHelper = GridHelper;
51548	exports.Group = Group;
51549	exports.HalfFloatType = HalfFloatType;
51550	exports.HemisphereLight = HemisphereLight;
51551	exports.HemisphereLightHelper = HemisphereLightHelper;
51552	exports.HemisphereLightProbe = HemisphereLightProbe;
51553	exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;
51554	exports.IcosahedronGeometry = IcosahedronGeometry;
51555	exports.ImageBitmapLoader = ImageBitmapLoader;
51556	exports.ImageLoader = ImageLoader;
51557	exports.ImageUtils = ImageUtils;
51558	exports.ImmediateRenderObject = ImmediateRenderObject;
51559	exports.IncrementStencilOp = IncrementStencilOp;
51560	exports.IncrementWrapStencilOp = IncrementWrapStencilOp;
51561	exports.InstancedBufferAttribute = InstancedBufferAttribute;
51562	exports.InstancedBufferGeometry = InstancedBufferGeometry;
51563	exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;
51564	exports.InstancedMesh = InstancedMesh;
51565	exports.Int16Attribute = Int16Attribute;
51566	exports.Int16BufferAttribute = Int16BufferAttribute;
51567	exports.Int32Attribute = Int32Attribute;
51568	exports.Int32BufferAttribute = Int32BufferAttribute;
51569	exports.Int8Attribute = Int8Attribute;
51570	exports.Int8BufferAttribute = Int8BufferAttribute;
51571	exports.IntType = IntType;
51572	exports.InterleavedBuffer = InterleavedBuffer;
51573	exports.InterleavedBufferAttribute = InterleavedBufferAttribute;
51574	exports.Interpolant = Interpolant;
51575	exports.InterpolateDiscrete = InterpolateDiscrete;
51576	exports.InterpolateLinear = InterpolateLinear;
51577	exports.InterpolateSmooth = InterpolateSmooth;
51578	exports.InvertStencilOp = InvertStencilOp;
51579	exports.JSONLoader = JSONLoader;
51580	exports.KeepStencilOp = KeepStencilOp;
51581	exports.KeyframeTrack = KeyframeTrack;
51582	exports.LOD = LOD;
51583	exports.LatheBufferGeometry = LatheBufferGeometry;
51584	exports.LatheGeometry = LatheGeometry;
51585	exports.Layers = Layers;
51586	exports.LensFlare = LensFlare;
51587	exports.LessDepth = LessDepth;
51588	exports.LessEqualDepth = LessEqualDepth;
51589	exports.LessEqualStencilFunc = LessEqualStencilFunc;
51590	exports.LessStencilFunc = LessStencilFunc;
51591	exports.Light = Light;
51592	exports.LightProbe = LightProbe;
51593	exports.LightShadow = LightShadow;
51594	exports.Line = Line;
51595	exports.Line3 = Line3;
51596	exports.LineBasicMaterial = LineBasicMaterial;
51597	exports.LineCurve = LineCurve;
51598	exports.LineCurve3 = LineCurve3;
51599	exports.LineDashedMaterial = LineDashedMaterial;
51600	exports.LineLoop = LineLoop;
51601	exports.LinePieces = LinePieces;
51602	exports.LineSegments = LineSegments;
51603	exports.LineStrip = LineStrip;
51604	exports.LinearEncoding = LinearEncoding;
51605	exports.LinearFilter = LinearFilter;
51606	exports.LinearInterpolant = LinearInterpolant;
51607	exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;
51608	exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;
51609	exports.LinearMipmapLinearFilter = LinearMipmapLinearFilter;
51610	exports.LinearMipmapNearestFilter = LinearMipmapNearestFilter;
51611	exports.LinearToneMapping = LinearToneMapping;
51612	exports.Loader = Loader;
51613	exports.LoaderUtils = LoaderUtils;
51614	exports.LoadingManager = LoadingManager;
51615	exports.LogLuvEncoding = LogLuvEncoding;
51616	exports.LoopOnce = LoopOnce;
51617	exports.LoopPingPong = LoopPingPong;
51618	exports.LoopRepeat = LoopRepeat;
51619	exports.LuminanceAlphaFormat = LuminanceAlphaFormat;
51620	exports.LuminanceFormat = LuminanceFormat;
51621	exports.MOUSE = MOUSE;
51622	exports.Material = Material;
51623	exports.MaterialLoader = MaterialLoader;
51624	exports.Math = MathUtils;
51625	exports.MathUtils = MathUtils;
51626	exports.Matrix3 = Matrix3;
51627	exports.Matrix4 = Matrix4;
51628	exports.MaxEquation = MaxEquation;
51629	exports.Mesh = Mesh;
51630	exports.MeshBasicMaterial = MeshBasicMaterial;
51631	exports.MeshDepthMaterial = MeshDepthMaterial;
51632	exports.MeshDistanceMaterial = MeshDistanceMaterial;
51633	exports.MeshFaceMaterial = MeshFaceMaterial;
51634	exports.MeshLambertMaterial = MeshLambertMaterial;
51635	exports.MeshMatcapMaterial = MeshMatcapMaterial;
51636	exports.MeshNormalMaterial = MeshNormalMaterial;
51637	exports.MeshPhongMaterial = MeshPhongMaterial;
51638	exports.MeshPhysicalMaterial = MeshPhysicalMaterial;
51639	exports.MeshStandardMaterial = MeshStandardMaterial;
51640	exports.MeshToonMaterial = MeshToonMaterial;
51641	exports.MinEquation = MinEquation;
51642	exports.MirroredRepeatWrapping = MirroredRepeatWrapping;
51643	exports.MixOperation = MixOperation;
51644	exports.MultiMaterial = MultiMaterial;
51645	exports.MultiplyBlending = MultiplyBlending;
51646	exports.MultiplyOperation = MultiplyOperation;
51647	exports.NearestFilter = NearestFilter;
51648	exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;
51649	exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;
51650	exports.NearestMipmapLinearFilter = NearestMipmapLinearFilter;
51651	exports.NearestMipmapNearestFilter = NearestMipmapNearestFilter;
51652	exports.NeverDepth = NeverDepth;
51653	exports.NeverStencilFunc = NeverStencilFunc;
51654	exports.NoBlending = NoBlending;
51655	exports.NoColors = NoColors;
51656	exports.NoToneMapping = NoToneMapping;
51657	exports.NormalAnimationBlendMode = NormalAnimationBlendMode;
51658	exports.NormalBlending = NormalBlending;
51659	exports.NotEqualDepth = NotEqualDepth;
51660	exports.NotEqualStencilFunc = NotEqualStencilFunc;
51661	exports.NumberKeyframeTrack = NumberKeyframeTrack;
51662	exports.Object3D = Object3D;
51663	exports.ObjectLoader = ObjectLoader;
51664	exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap;
51665	exports.OctahedronBufferGeometry = OctahedronBufferGeometry;
51666	exports.OctahedronGeometry = OctahedronGeometry;
51667	exports.OneFactor = OneFactor;
51668	exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;
51669	exports.OneMinusDstColorFactor = OneMinusDstColorFactor;
51670	exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;
51671	exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;
51672	exports.OrthographicCamera = OrthographicCamera;
51673	exports.PCFShadowMap = PCFShadowMap;
51674	exports.PCFSoftShadowMap = PCFSoftShadowMap;
51675	exports.PMREMGenerator = PMREMGenerator;
51676	exports.ParametricBufferGeometry = ParametricBufferGeometry;
51677	exports.ParametricGeometry = ParametricGeometry;
51678	exports.Particle = Particle;
51679	exports.ParticleBasicMaterial = ParticleBasicMaterial;
51680	exports.ParticleSystem = ParticleSystem;
51681	exports.ParticleSystemMaterial = ParticleSystemMaterial;
51682	exports.Path = Path;
51683	exports.PerspectiveCamera = PerspectiveCamera;
51684	exports.Plane = Plane;
51685	exports.PlaneBufferGeometry = PlaneBufferGeometry;
51686	exports.PlaneGeometry = PlaneGeometry;
51687	exports.PlaneHelper = PlaneHelper;
51688	exports.PointCloud = PointCloud;
51689	exports.PointCloudMaterial = PointCloudMaterial;
51690	exports.PointLight = PointLight;
51691	exports.PointLightHelper = PointLightHelper;
51692	exports.Points = Points;
51693	exports.PointsMaterial = PointsMaterial;
51694	exports.PolarGridHelper = PolarGridHelper;
51695	exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;
51696	exports.PolyhedronGeometry = PolyhedronGeometry;
51697	exports.PositionalAudio = PositionalAudio;
51698	exports.PropertyBinding = PropertyBinding;
51699	exports.PropertyMixer = PropertyMixer;
51700	exports.QuadraticBezierCurve = QuadraticBezierCurve;
51701	exports.QuadraticBezierCurve3 = QuadraticBezierCurve3;
51702	exports.Quaternion = Quaternion;
51703	exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;
51704	exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;
51705	exports.REVISION = REVISION;
51706	exports.RGBADepthPacking = RGBADepthPacking;
51707	exports.RGBAFormat = RGBAFormat;
51708	exports.RGBAIntegerFormat = RGBAIntegerFormat;
51709	exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format;
51710	exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format;
51711	exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format;
51712	exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format;
51713	exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format;
51714	exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format;
51715	exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format;
51716	exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format;
51717	exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format;
51718	exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format;
51719	exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format;
51720	exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format;
51721	exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format;
51722	exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format;
51723	exports.RGBA_BPTC_Format = RGBA_BPTC_Format;
51724	exports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format;
51725	exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;
51726	exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;
51727	exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;
51728	exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;
51729	exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;
51730	exports.RGBDEncoding = RGBDEncoding;
51731	exports.RGBEEncoding = RGBEEncoding;
51732	exports.RGBEFormat = RGBEFormat;
51733	exports.RGBFormat = RGBFormat;
51734	exports.RGBIntegerFormat = RGBIntegerFormat;
51735	exports.RGBM16Encoding = RGBM16Encoding;
51736	exports.RGBM7Encoding = RGBM7Encoding;
51737	exports.RGB_ETC1_Format = RGB_ETC1_Format;
51738	exports.RGB_ETC2_Format = RGB_ETC2_Format;
51739	exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;
51740	exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;
51741	exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;
51742	exports.RGFormat = RGFormat;
51743	exports.RGIntegerFormat = RGIntegerFormat;
51744	exports.RawShaderMaterial = RawShaderMaterial;
51745	exports.Ray = Ray;
51746	exports.Raycaster = Raycaster;
51747	exports.RectAreaLight = RectAreaLight;
51748	exports.RedFormat = RedFormat;
51749	exports.RedIntegerFormat = RedIntegerFormat;
51750	exports.ReinhardToneMapping = ReinhardToneMapping;
51751	exports.RepeatWrapping = RepeatWrapping;
51752	exports.ReplaceStencilOp = ReplaceStencilOp;
51753	exports.ReverseSubtractEquation = ReverseSubtractEquation;
51754	exports.RingBufferGeometry = RingBufferGeometry;
51755	exports.RingGeometry = RingGeometry;
51756	exports.SRGB8_ALPHA8_ASTC_10x10_Format = SRGB8_ALPHA8_ASTC_10x10_Format;
51757	exports.SRGB8_ALPHA8_ASTC_10x5_Format = SRGB8_ALPHA8_ASTC_10x5_Format;
51758	exports.SRGB8_ALPHA8_ASTC_10x6_Format = SRGB8_ALPHA8_ASTC_10x6_Format;
51759	exports.SRGB8_ALPHA8_ASTC_10x8_Format = SRGB8_ALPHA8_ASTC_10x8_Format;
51760	exports.SRGB8_ALPHA8_ASTC_12x10_Format = SRGB8_ALPHA8_ASTC_12x10_Format;
51761	exports.SRGB8_ALPHA8_ASTC_12x12_Format = SRGB8_ALPHA8_ASTC_12x12_Format;
51762	exports.SRGB8_ALPHA8_ASTC_4x4_Format = SRGB8_ALPHA8_ASTC_4x4_Format;
51763	exports.SRGB8_ALPHA8_ASTC_5x4_Format = SRGB8_ALPHA8_ASTC_5x4_Format;
51764	exports.SRGB8_ALPHA8_ASTC_5x5_Format = SRGB8_ALPHA8_ASTC_5x5_Format;
51765	exports.SRGB8_ALPHA8_ASTC_6x5_Format = SRGB8_ALPHA8_ASTC_6x5_Format;
51766	exports.SRGB8_ALPHA8_ASTC_6x6_Format = SRGB8_ALPHA8_ASTC_6x6_Format;
51767	exports.SRGB8_ALPHA8_ASTC_8x5_Format = SRGB8_ALPHA8_ASTC_8x5_Format;
51768	exports.SRGB8_ALPHA8_ASTC_8x6_Format = SRGB8_ALPHA8_ASTC_8x6_Format;
51769	exports.SRGB8_ALPHA8_ASTC_8x8_Format = SRGB8_ALPHA8_ASTC_8x8_Format;
51770	exports.Scene = Scene;
51771	exports.SceneUtils = SceneUtils;
51772	exports.ShaderChunk = ShaderChunk;
51773	exports.ShaderLib = ShaderLib;
51774	exports.ShaderMaterial = ShaderMaterial;
51775	exports.ShadowMaterial = ShadowMaterial;
51776	exports.Shape = Shape;
51777	exports.ShapeBufferGeometry = ShapeBufferGeometry;
51778	exports.ShapeGeometry = ShapeGeometry;
51779	exports.ShapePath = ShapePath;
51780	exports.ShapeUtils = ShapeUtils;
51781	exports.ShortType = ShortType;
51782	exports.Skeleton = Skeleton;
51783	exports.SkeletonHelper = SkeletonHelper;
51784	exports.SkinnedMesh = SkinnedMesh;
51785	exports.SmoothShading = SmoothShading;
51786	exports.Sphere = Sphere;
51787	exports.SphereBufferGeometry = SphereBufferGeometry;
51788	exports.SphereGeometry = SphereGeometry;
51789	exports.Spherical = Spherical;
51790	exports.SphericalHarmonics3 = SphericalHarmonics3;
51791	exports.Spline = Spline;
51792	exports.SplineCurve = SplineCurve;
51793	exports.SplineCurve3 = SplineCurve3;
51794	exports.SpotLight = SpotLight;
51795	exports.SpotLightHelper = SpotLightHelper;
51796	exports.SpotLightShadow = SpotLightShadow;
51797	exports.Sprite = Sprite;
51798	exports.SpriteMaterial = SpriteMaterial;
51799	exports.SrcAlphaFactor = SrcAlphaFactor;
51800	exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;
51801	exports.SrcColorFactor = SrcColorFactor;
51802	exports.StaticCopyUsage = StaticCopyUsage;
51803	exports.StaticDrawUsage = StaticDrawUsage;
51804	exports.StaticReadUsage = StaticReadUsage;
51805	exports.StereoCamera = StereoCamera;
51806	exports.StreamCopyUsage = StreamCopyUsage;
51807	exports.StreamDrawUsage = StreamDrawUsage;
51808	exports.StreamReadUsage = StreamReadUsage;
51809	exports.StringKeyframeTrack = StringKeyframeTrack;
51810	exports.SubtractEquation = SubtractEquation;
51811	exports.SubtractiveBlending = SubtractiveBlending;
51812	exports.TOUCH = TOUCH;
51813	exports.TangentSpaceNormalMap = TangentSpaceNormalMap;
51814	exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;
51815	exports.TetrahedronGeometry = TetrahedronGeometry;
51816	exports.TextBufferGeometry = TextBufferGeometry;
51817	exports.TextGeometry = TextGeometry;
51818	exports.Texture = Texture;
51819	exports.TextureLoader = TextureLoader;
51820	exports.TorusBufferGeometry = TorusBufferGeometry;
51821	exports.TorusGeometry = TorusGeometry;
51822	exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;
51823	exports.TorusKnotGeometry = TorusKnotGeometry;
51824	exports.Triangle = Triangle;
51825	exports.TriangleFanDrawMode = TriangleFanDrawMode;
51826	exports.TriangleStripDrawMode = TriangleStripDrawMode;
51827	exports.TrianglesDrawMode = TrianglesDrawMode;
51828	exports.TubeBufferGeometry = TubeBufferGeometry;
51829	exports.TubeGeometry = TubeGeometry;
51830	exports.UVMapping = UVMapping;
51831	exports.Uint16Attribute = Uint16Attribute;
51832	exports.Uint16BufferAttribute = Uint16BufferAttribute;
51833	exports.Uint32Attribute = Uint32Attribute;
51834	exports.Uint32BufferAttribute = Uint32BufferAttribute;
51835	exports.Uint8Attribute = Uint8Attribute;
51836	exports.Uint8BufferAttribute = Uint8BufferAttribute;
51837	exports.Uint8ClampedAttribute = Uint8ClampedAttribute;
51838	exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;
51839	exports.Uniform = Uniform;
51840	exports.UniformsLib = UniformsLib;
51841	exports.UniformsUtils = UniformsUtils;
51842	exports.UnsignedByteType = UnsignedByteType;
51843	exports.UnsignedInt248Type = UnsignedInt248Type;
51844	exports.UnsignedIntType = UnsignedIntType;
51845	exports.UnsignedShort4444Type = UnsignedShort4444Type;
51846	exports.UnsignedShort5551Type = UnsignedShort5551Type;
51847	exports.UnsignedShort565Type = UnsignedShort565Type;
51848	exports.UnsignedShortType = UnsignedShortType;
51849	exports.VSMShadowMap = VSMShadowMap;
51850	exports.Vector2 = Vector2;
51851	exports.Vector3 = Vector3;
51852	exports.Vector4 = Vector4;
51853	exports.VectorKeyframeTrack = VectorKeyframeTrack;
51854	exports.Vertex = Vertex;
51855	exports.VertexColors = VertexColors;
51856	exports.VideoTexture = VideoTexture;
51857	exports.WebGL1Renderer = WebGL1Renderer;
51858	exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget;
51859	exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget;
51860	exports.WebGLRenderTarget = WebGLRenderTarget;
51861	exports.WebGLRenderTargetCube = WebGLRenderTargetCube;
51862	exports.WebGLRenderer = WebGLRenderer;
51863	exports.WebGLUtils = WebGLUtils;
51864	exports.WireframeGeometry = WireframeGeometry;
51865	exports.WireframeHelper = WireframeHelper;
51866	exports.WrapAroundEnding = WrapAroundEnding;
51867	exports.XHRLoader = XHRLoader;
51868	exports.ZeroCurvatureEnding = ZeroCurvatureEnding;
51869	exports.ZeroFactor = ZeroFactor;
51870	exports.ZeroSlopeEnding = ZeroSlopeEnding;
51871	exports.ZeroStencilOp = ZeroStencilOp;
51872	exports.sRGBEncoding = sRGBEncoding;
51873
51874	Object.defineProperty(exports, '__esModule', { value: true });
51875
51876})));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.