PageSourceSearch

https://www.laserboost.com/img/3d/three.js

js laserboost.com collected 2026-10-02 05:36:06 UTC 1,176,383 bytes, 36,678 lines download raw bytes

1/**
2 * @license
3 * Copyright 2010-2021 Three.js Authors
4 * SPDX-License-Identifier: MIT
5 */
6(function (global, factory) {
7	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
8	typeof define === 'function' && define.amd ? define(['exports'], factory) :
9	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {}));
10})(this, (function (exports) { 'use strict';
11
12	const REVISION = '136';
13	const MOUSE = {
14		LEFT: 0,
15		MIDDLE: 1,
16		RIGHT: 2,
17		ROTATE: 0,
18		DOLLY: 1,
19		PAN: 2
20	};
21	const TOUCH = {
22		ROTATE: 0,
23		PAN: 1,
24		DOLLY_PAN: 2,
25		DOLLY_ROTATE: 3
26	};
27	const CullFaceNone = 0;
28	const CullFaceBack = 1;
29	const CullFaceFront = 2;
30	const CullFaceFrontBack = 3;
31	const BasicShadowMap = 0;
32	const PCFShadowMap = 1;
33	const PCFSoftShadowMap = 2;
34	const VSMShadowMap = 3;
35	const FrontSide = 0;
36	const BackSide = 1;
37	const DoubleSide = 2;
38	const FlatShading = 1;
39	const SmoothShading = 2;
40	const NoBlending = 0;
41	const NormalBlending = 1;
42	const AdditiveBlending = 2;
43	const SubtractiveBlending = 3;
44	const MultiplyBlending = 4;
45	const CustomBlending = 5;
46	const AddEquation = 100;
47	const SubtractEquation = 101;
48	const ReverseSubtractEquation = 102;
49	const MinEquation = 103;
50	const MaxEquation = 104;
51	const ZeroFactor = 200;
52	const OneFactor = 201;
53	const SrcColorFactor = 202;
54	const OneMinusSrcColorFactor = 203;
55	const SrcAlphaFactor = 204;
56	const OneMinusSrcAlphaFactor = 205;
57	const DstAlphaFactor = 206;
58	const OneMinusDstAlphaFactor = 207;
59	const DstColorFactor = 208;
60	const OneMinusDstColorFactor = 209;
61	const SrcAlphaSaturateFactor = 210;
62	const NeverDepth = 0;
63	const AlwaysDepth = 1;
64	const LessDepth = 2;
65	const LessEqualDepth = 3;
66	const EqualDepth = 4;
67	const GreaterEqualDepth = 5;
68	const GreaterDepth = 6;
69	const NotEqualDepth = 7;
70	const MultiplyOperation = 0;
71	const MixOperation = 1;
72	const AddOperation = 2;
73	const NoToneMapping = 0;
74	const LinearToneMapping = 1;
75	const ReinhardToneMapping = 2;
76	const CineonToneMapping = 3;
77	const ACESFilmicToneMapping = 4;
78	const CustomToneMapping = 5;
79	const UVMapping = 300;
80	const CubeReflectionMapping = 301;
81	const CubeRefractionMapping = 302;
82	const EquirectangularReflectionMapping = 303;
83	const EquirectangularRefractionMapping = 304;
84	const CubeUVReflectionMapping = 306;
85	const CubeUVRefractionMapping = 307;
86	const RepeatWrapping = 1000;
87	const ClampToEdgeWrapping = 1001;
88	const MirroredRepeatWrapping = 1002;
89	const NearestFilter = 1003;
90	const NearestMipmapNearestFilter = 1004;
91	const NearestMipMapNearestFilter = 1004;
92	const NearestMipmapLinearFilter = 1005;
93	const NearestMipMapLinearFilter = 1005;
94	const LinearFilter = 1006;
95	const LinearMipmapNearestFilter = 1007;
96	const LinearMipMapNearestFilter = 1007;
97	const LinearMipmapLinearFilter = 1008;
98	const LinearMipMapLinearFilter = 1008;
99	const UnsignedByteType = 1009;
100	const ByteType = 1010;
101	const ShortType = 1011;
102	const UnsignedShortType = 1012;
103	const IntType = 1013;
104	const UnsignedIntType = 1014;
105	const FloatType = 1015;
106	const HalfFloatType = 1016;
107	const UnsignedShort4444Type = 1017;
108	const UnsignedShort5551Type = 1018;
109	const UnsignedShort565Type = 1019;
110	const UnsignedInt248Type = 1020;
111	const AlphaFormat = 1021;
112	const RGBFormat = 1022;
113	const RGBAFormat = 1023;
114	const LuminanceFormat = 1024;
115	const LuminanceAlphaFormat = 1025;
116	const DepthFormat = 1026;
117	const DepthStencilFormat = 1027;
118	const RedFormat = 1028;
119	const RedIntegerFormat = 1029;
120	const RGFormat = 1030;
121	const RGIntegerFormat = 1031;
122	const RGBIntegerFormat = 1032;
123	const RGBAIntegerFormat = 1033;
124	const RGB_S3TC_DXT1_Format = 33776;
125	const RGBA_S3TC_DXT1_Format = 33777;
126	const RGBA_S3TC_DXT3_Format = 33778;
127	const RGBA_S3TC_DXT5_Format = 33779;
128	const RGB_PVRTC_4BPPV1_Format = 35840;
129	const RGB_PVRTC_2BPPV1_Format = 35841;
130	const RGBA_PVRTC_4BPPV1_Format = 35842;
131	const RGBA_PVRTC_2BPPV1_Format = 35843;
132	const RGB_ETC1_Format = 36196;
133	const RGB_ETC2_Format = 37492;
134	const RGBA_ETC2_EAC_Format = 37496;
135	const RGBA_ASTC_4x4_Format = 37808;
136	const RGBA_ASTC_5x4_Format = 37809;
137	const RGBA_ASTC_5x5_Format = 37810;
138	const RGBA_ASTC_6x5_Format = 37811;
139	const RGBA_ASTC_6x6_Format = 37812;
140	const RGBA_ASTC_8x5_Format = 37813;
141	const RGBA_ASTC_8x6_Format = 37814;
142	const RGBA_ASTC_8x8_Format = 37815;
143	const RGBA_ASTC_10x5_Format = 37816;
144	const RGBA_ASTC_10x6_Format = 37817;
145	const RGBA_ASTC_10x8_Format = 37818;
146	const RGBA_ASTC_10x10_Format = 37819;
147	const RGBA_ASTC_12x10_Format = 37820;
148	const RGBA_ASTC_12x12_Format = 37821;
149	const RGBA_BPTC_Format = 36492;
150	const SRGB8_ALPHA8_ASTC_4x4_Format = 37840;
151	const SRGB8_ALPHA8_ASTC_5x4_Format = 37841;
152	const SRGB8_ALPHA8_ASTC_5x5_Format = 37842;
153	const SRGB8_ALPHA8_ASTC_6x5_Format = 37843;
154	const SRGB8_ALPHA8_ASTC_6x6_Format = 37844;
155	const SRGB8_ALPHA8_ASTC_8x5_Format = 37845;
156	const SRGB8_ALPHA8_ASTC_8x6_Format = 37846;
157	const SRGB8_ALPHA8_ASTC_8x8_Format = 37847;
158	const SRGB8_ALPHA8_ASTC_10x5_Format = 37848;
159	const SRGB8_ALPHA8_ASTC_10x6_Format = 37849;
160	const SRGB8_ALPHA8_ASTC_10x8_Format = 37850;
161	const SRGB8_ALPHA8_ASTC_10x10_Format = 37851;
162	const SRGB8_ALPHA8_ASTC_12x10_Format = 37852;
163	const SRGB8_ALPHA8_ASTC_12x12_Format = 37853;
164	const LoopOnce = 2200;
165	const LoopRepeat = 2201;
166	const LoopPingPong = 2202;
167	const InterpolateDiscrete = 2300;
168	const InterpolateLinear = 2301;
169	const InterpolateSmooth = 2302;
170	const ZeroCurvatureEnding = 2400;
171	const ZeroSlopeEnding = 2401;
172	const WrapAroundEnding = 2402;
173	const NormalAnimationBlendMode = 2500;
174	const AdditiveAnimationBlendMode = 2501;
175	const TrianglesDrawMode = 0;
176	const TriangleStripDrawMode = 1;
177	const TriangleFanDrawMode = 2;
178	const LinearEncoding = 3000;
179	const sRGBEncoding = 3001;
180	const BasicDepthPacking = 3200;
181	const RGBADepthPacking = 3201;
182	const TangentSpaceNormalMap = 0;
vendor: 5,189 bytes, lines 183-356
183	const ObjectSpaceNormalMap = 1;
184	const ZeroStencilOp = 0;
185	const KeepStencilOp = 7680;
186	const ReplaceStencilOp = 7681;
187	const IncrementStencilOp = 7682;
188	const DecrementStencilOp = 7683;
189	const IncrementWrapStencilOp = 34055;
190	const DecrementWrapStencilOp = 34056;
191	const InvertStencilOp = 5386;
192	const NeverStencilFunc = 512;
193	const LessStencilFunc = 513;
194	const EqualStencilFunc = 514;
195	const LessEqualStencilFunc = 515;
196	const GreaterStencilFunc = 516;
197	const NotEqualStencilFunc = 517;
198	const GreaterEqualStencilFunc = 518;
199	const AlwaysStencilFunc = 519;
200	const StaticDrawUsage = 35044;
201	const DynamicDrawUsage = 35048;
202	const StreamDrawUsage = 35040;
203	const StaticReadUsage = 35045;
204	const DynamicReadUsage = 35049;
205	const StreamReadUsage = 35041;
206	const StaticCopyUsage = 35046;
207	const DynamicCopyUsage = 35050;
208	const StreamCopyUsage = 35042;
209	const GLSL1 = '100';
210	const GLSL3 = '300 es';
211
212	/**
213	 * https://github.com/mrdoob/eventdispatcher.js/
214	 */
215	class EventDispatcher {
216		addEventListener(type, listener) {
217			if (this._listeners === undefined) this._listeners = {};
218			const listeners = this._listeners;
219
220			if (listeners[type] === undefined) {
221				listeners[type] = [];
222			}
223
224			if (listeners[type].indexOf(listener) === -1) {
225				listeners[type].push(listener);
226			}
227		}
228
229		hasEventListener(type, listener) {
230			if (this._listeners === undefined) return false;
231			const listeners = this._listeners;
232			return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1;
233		}
234
235		removeEventListener(type, listener) {
236			if (this._listeners === undefined) return;
237			const listeners = this._listeners;
238			const listenerArray = listeners[type];
239
240			if (listenerArray !== undefined) {
241				const index = listenerArray.indexOf(listener);
242
243				if (index !== -1) {
244					listenerArray.splice(index, 1);
245				}
246			}
247		}
248
249		dispatchEvent(event) {
250			if (this._listeners === undefined) return;
251			const listeners = this._listeners;
252			const listenerArray = listeners[event.type];
253
254			if (listenerArray !== undefined) {
255				event.target = this; // Make a copy, in case listeners are removed while iterating.
256
257				const array = listenerArray.slice(0);
258
259				for (let i = 0, l = array.length; i < l; i++) {
260					array[i].call(this, event);
261				}
262
263				event.target = null;
264			}
265		}
266
267	}
268
269	const _lut = [];
270
271	for (let i = 0; i < 256; i++) {
272		_lut[i] = (i < 16 ? '0' : '') + i.toString(16);
273	}
274
275	let _seed = 1234567;
276	const DEG2RAD = Math.PI / 180;
277	const RAD2DEG = 180 / Math.PI; // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136
278
279	function generateUUID() {
280		const d0 = Math.random() * 0xffffffff | 0;
281		const d1 = Math.random() * 0xffffffff | 0;
282		const d2 = Math.random() * 0xffffffff | 0;
283		const d3 = Math.random() * 0xffffffff | 0;
284		const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff]; // .toUpperCase() here flattens concatenated strings to save heap memory space.
285
286		return uuid.toUpperCase();
287	}
288
289	function clamp(value, min, max) {
290		return Math.max(min, Math.min(max, value));
291	} // compute euclidian modulo of m % n
292	// https://en.wikipedia.org/wiki/Modulo_operation
293
294
295	function euclideanModulo(n, m) {
296		return (n % m + m) % m;
297	} // Linear mapping from range <a1, a2> to range <b1, b2>
298
299
300	function mapLinear(x, a1, a2, b1, b2) {
301		return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
302	} // https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/
303
304
305	function inverseLerp(x, y, value) {
306		if (x !== y) {
307			return (value - x) / (y - x);
308		} else {
309			return 0;
310		}
311	} // https://en.wikipedia.org/wiki/Linear_interpolation
312
313
314	function lerp(x, y, t) {
315		return (1 - t) * x + t * y;
316	} // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
317
318
319	function damp(x, y, lambda, dt) {
320		return lerp(x, y, 1 - Math.exp(-lambda * dt));
321	} // https://www.desmos.com/calculator/vcsjnyz7x4
322
323
324	function pingpong(x, length = 1) {
325		return length - Math.abs(euclideanModulo(x, length * 2) - length);
326	} // http://en.wikipedia.org/wiki/Smoothstep
327
328
329	function smoothstep(x, min, max) {
330		if (x <= min) return 0;
331		if (x >= max) return 1;
332		x = (x - min) / (max - min);
333		return x * x * (3 - 2 * x);
334	}
335
336	function smootherstep(x, min, max) {
337		if (x <= min) return 0;
338		if (x >= max) return 1;
339		x = (x - min) / (max - min);
340		return x * x * x * (x * (x * 6 - 15) + 10);
341	} // Random integer from <low, high> interval
342
343
344	function randInt(low, high) {
345		return low + Math.floor(Math.random() * (high - low + 1));
346	} // Random float from <low, high> interval
347
348
349	function randFloat(low, high) {
350		return low + Math.random() * (high - low);
351	} // Random float from <-range/2, range/2> interval
352
353
354	function randFloatSpread(range) {
355		return range * (0.5 - Math.random());
356	}
356 // Deterministic pseudo-random float in the interval [ 0, 1 ]
357
358
359	function seededRandom(s) {
360		if (s !== undefined) _seed = s % 2147483647; // Park-Miller algorithm
361
362		_seed = _seed * 16807 % 2147483647;
363		return (_seed - 1) / 2147483646;
364	}
365
366	function degToRad(degrees) {
367		return degrees * DEG2RAD;
368	}
369
370	function radToDeg(radians) {
371		return radians * RAD2DEG;
372	}
373
374	function isPowerOfTwo(value) {
375		return (value & value - 1) === 0 && value !== 0;
376	}
377
378	function ceilPowerOfTwo(value) {
379		return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
380	}
381
382	function floorPowerOfTwo(value) {
383		return Math.pow(2, Math.floor(Math.log(value) / Math.LN2));
384	}
385
386	function setQuaternionFromProperEuler(q, a, b, c, order) {
387		// Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles
388		// rotations are applied to the axes in the order specified by 'order'
389		// rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c'
390		// angles are in radians
391		const cos = Math.cos;
392		const sin = Math.sin;
vendor: 11,516 bytes, lines 393-986
393		const c2 = cos(b / 2);
394		const s2 = sin(b / 2);
395		const c13 = cos((a + c) / 2);
396		const s13 = sin((a + c) / 2);
397		const c1_3 = cos((a - c) / 2);
398		const s1_3 = sin((a - c) / 2);
399		const c3_1 = cos((c - a) / 2);
400		const s3_1 = sin((c - a) / 2);
401
402		switch (order) {
403			case 'XYX':
404				q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13);
405				break;
406
407			case 'YZY':
408				q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13);
409				break;
410
411			case 'ZXZ':
412				q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13);
413				break;
414
415			case 'XZX':
416				q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13);
417				break;
418
419			case 'YXY':
420				q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13);
421				break;
422
423			case 'ZYZ':
424				q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13);
425				break;
426
427			default:
428				console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order);
429		}
430	}
431
432	var MathUtils = /*#__PURE__*/Object.freeze({
433		__proto__: null,
434		DEG2RAD: DEG2RAD,
435		RAD2DEG: RAD2DEG,
436		generateUUID: generateUUID,
437		clamp: clamp,
438		euclideanModulo: euclideanModulo,
439		mapLinear: mapLinear,
440		inverseLerp: inverseLerp,
441		lerp: lerp,
442		damp: damp,
443		pingpong: pingpong,
444		smoothstep: smoothstep,
445		smootherstep: smootherstep,
446		randInt: randInt,
447		randFloat: randFloat,
448		randFloatSpread: randFloatSpread,
449		seededRandom: seededRandom,
450		degToRad: degToRad,
451		radToDeg: radToDeg,
452		isPowerOfTwo: isPowerOfTwo,
453		ceilPowerOfTwo: ceilPowerOfTwo,
454		floorPowerOfTwo: floorPowerOfTwo,
455		setQuaternionFromProperEuler: setQuaternionFromProperEuler
456	});
457
458	class Vector2 {
459		constructor(x = 0, y = 0) {
460			this.x = x;
461			this.y = y;
462		}
463
464		get width() {
465			return this.x;
466		}
467
468		set width(value) {
469			this.x = value;
470		}
471
472		get height() {
473			return this.y;
474		}
475
476		set height(value) {
477			this.y = value;
478		}
479
480		set(x, y) {
481			this.x = x;
482			this.y = y;
483			return this;
484		}
485
486		setScalar(scalar) {
487			this.x = scalar;
488			this.y = scalar;
489			return this;
490		}
491
492		setX(x) {
493			this.x = x;
494			return this;
495		}
496
497		setY(y) {
498			this.y = y;
499			return this;
500		}
501
502		setComponent(index, value) {
503			switch (index) {
504				case 0:
505					this.x = value;
506					break;
507
508				case 1:
509					this.y = value;
510					break;
511
512				default:
513					throw new Error('index is out of range: ' + index);
514			}
515
516			return this;
517		}
518
519		getComponent(index) {
520			switch (index) {
521				case 0:
522					return this.x;
523
524				case 1:
525					return this.y;
526
527				default:
528					throw new Error('index is out of range: ' + index);
529			}
530		}
531
532		clone() {
533			return new this.constructor(this.x, this.y);
534		}
535
536		copy(v) {
537			this.x = v.x;
538			this.y = v.y;
539			return this;
540		}
541
542		add(v, w) {
543			if (w !== undefined) {
544				console.warn('THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.');
545				return this.addVectors(v, w);
546			}
547
548			this.x += v.x;
549			this.y += v.y;
550			return this;
551		}
552
553		addScalar(s) {
554			this.x += s;
555			this.y += s;
556			return this;
557		}
558
559		addVectors(a, b) {
560			this.x = a.x + b.x;
561			this.y = a.y + b.y;
562			return this;
563		}
564
565		addScaledVector(v, s) {
566			this.x += v.x * s;
567			this.y += v.y * s;
568			return this;
569		}
570
571		sub(v, w) {
572			if (w !== undefined) {
573				console.warn('THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.');
574				return this.subVectors(v, w);
575			}
576
577			this.x -= v.x;
578			this.y -= v.y;
579			return this;
580		}
581
582		subScalar(s) {
583			this.x -= s;
584			this.y -= s;
585			return this;
586		}
587
588		subVectors(a, b) {
589			this.x = a.x - b.x;
590			this.y = a.y - b.y;
591			return this;
592		}
593
594		multiply(v) {
595			this.x *= v.x;
596			this.y *= v.y;
597			return this;
598		}
599
600		multiplyScalar(scalar) {
601			this.x *= scalar;
602			this.y *= scalar;
603			return this;
604		}
605
606		divide(v) {
607			this.x /= v.x;
608			this.y /= v.y;
609			return this;
610		}
611
612		divideScalar(scalar) {
613			return this.multiplyScalar(1 / scalar);
614		}
615
616		applyMatrix3(m) {
617			const x = this.x,
618						y = this.y;
619			const e = m.elements;
620			this.x = e[0] * x + e[3] * y + e[6];
621			this.y = e[1] * x + e[4] * y + e[7];
622			return this;
623		}
624
625		min(v) {
626			this.x = Math.min(this.x, v.x);
627			this.y = Math.min(this.y, v.y);
628			return this;
629		}
630
631		max(v) {
632			this.x = Math.max(this.x, v.x);
633			this.y = Math.max(this.y, v.y);
634			return this;
635		}
636
637		clamp(min, max) {
638			// assumes min < max, componentwise
639			this.x = Math.max(min.x, Math.min(max.x, this.x));
640			this.y = Math.max(min.y, Math.min(max.y, this.y));
641			return this;
642		}
643
644		clampScalar(minVal, maxVal) {
645			this.x = Math.max(minVal, Math.min(maxVal, this.x));
646			this.y = Math.max(minVal, Math.min(maxVal, this.y));
647			return this;
648		}
649
650		clampLength(min, max) {
651			const length = this.length();
652			return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
653		}
654
655		floor() {
656			this.x = Math.floor(this.x);
657			this.y = Math.floor(this.y);
658			return this;
659		}
660
661		ceil() {
662			this.x = Math.ceil(this.x);
663			this.y = Math.ceil(this.y);
664			return this;
665		}
666
667		round() {
668			this.x = Math.round(this.x);
669			this.y = Math.round(this.y);
670			return this;
671		}
672
673		roundToZero() {
674			this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
675			this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
676			return this;
677		}
678
679		negate() {
680			this.x = -this.x;
681			this.y = -this.y;
682			return this;
683		}
684
685		dot(v) {
686			return this.x * v.x + this.y * v.y;
687		}
688
689		cross(v) {
690			return this.x * v.y - this.y * v.x;
691		}
692
693		lengthSq() {
694			return this.x * this.x + this.y * this.y;
695		}
696
697		length() {
698			return Math.sqrt(this.x * this.x + this.y * this.y);
699		}
700
701		manhattanLength() {
702			return Math.abs(this.x) + Math.abs(this.y);
703		}
704
705		normalize() {
706			return this.divideScalar(this.length() || 1);
707		}
708
709		angle() {
710			// computes the angle in radians with respect to the positive x-axis
711			const angle = Math.atan2(-this.y, -this.x) + Math.PI;
712			return angle;
713		}
714
715		distanceTo(v) {
716			return Math.sqrt(this.distanceToSquared(v));
717		}
718
719		distanceToSquared(v) {
720			const dx = this.x - v.x,
721						dy = this.y - v.y;
722			return dx * dx + dy * dy;
723		}
724
725		manhattanDistanceTo(v) {
726			return Math.abs(this.x - v.x) + Math.abs(this.y - v.y);
727		}
728
729		setLength(length) {
730			return this.normalize().multiplyScalar(length);
731		}
732
733		lerp(v, alpha) {
734			this.x += (v.x - this.x) * alpha;
735			this.y += (v.y - this.y) * alpha;
736			return this;
737		}
738
739		lerpVectors(v1, v2, alpha) {
740			this.x = v1.x + (v2.x - v1.x) * alpha;
741			this.y = v1.y + (v2.y - v1.y) * alpha;
742			return this;
743		}
744
745		equals(v) {
746			return v.x === this.x && v.y === this.y;
747		}
748
749		fromArray(array, offset = 0) {
750			this.x = array[offset];
751			this.y = array[offset + 1];
752			return this;
753		}
754
755		toArray(array = [], offset = 0) {
756			array[offset] = this.x;
757			array[offset + 1] = this.y;
758			return array;
759		}
760
761		fromBufferAttribute(attribute, index, offset) {
762			if (offset !== undefined) {
763				console.warn('THREE.Vector2: offset has been removed from .fromBufferAttribute().');
764			}
765
766			this.x = attribute.getX(index);
767			this.y = attribute.getY(index);
768			return this;
769		}
770
771		rotateAround(center, angle) {
772			const c = Math.cos(angle),
773						s = Math.sin(angle);
774			const x = this.x - center.x;
775			const y = this.y - center.y;
776			this.x = x * c - y * s + center.x;
777			this.y = x * s + y * c + center.y;
778			return this;
779		}
780
781		random() {
782			this.x = Math.random();
783			this.y = Math.random();
784			return this;
785		}
786
787		*[Symbol.iterator]() {
788			yield this.x;
789			yield this.y;
790		}
791
792	}
793
794	Vector2.prototype.isVector2 = true;
795
796	class Matrix3 {
797		constructor() {
798			this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1];
799
800			if (arguments.length > 0) {
801				console.error('THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.');
802			}
803		}
804
805		set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
806			const te = this.elements;
807			te[0] = n11;
808			te[1] = n21;
809			te[2] = n31;
810			te[3] = n12;
811			te[4] = n22;
812			te[5] = n32;
813			te[6] = n13;
814			te[7] = n23;
815			te[8] = n33;
816			return this;
817		}
818
819		identity() {
820			this.set(1, 0, 0, 0, 1, 0, 0, 0, 1);
821			return this;
822		}
823
824		copy(m) {
825			const te = this.elements;
826			const me = m.elements;
827			te[0] = me[0];
828			te[1] = me[1];
829			te[2] = me[2];
830			te[3] = me[3];
831			te[4] = me[4];
832			te[5] = me[5];
833			te[6] = me[6];
834			te[7] = me[7];
835			te[8] = me[8];
836			return this;
837		}
838
839		extractBasis(xAxis, yAxis, zAxis) {
840			xAxis.setFromMatrix3Column(this, 0);
841			yAxis.setFromMatrix3Column(this, 1);
842			zAxis.setFromMatrix3Column(this, 2);
843			return this;
844		}
845
846		setFromMatrix4(m) {
847			const me = m.elements;
848			this.set(me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10]);
849			return this;
850		}
851
852		multiply(m) {
853			return this.multiplyMatrices(this, m);
854		}
855
856		premultiply(m) {
857			return this.multiplyMatrices(m, this);
858		}
859
860		multiplyMatrices(a, b) {
861			const ae = a.elements;
862			const be = b.elements;
863			const te = this.elements;
864			const a11 = ae[0],
865						a12 = ae[3],
866						a13 = ae[6];
867			const a21 = ae[1],
868						a22 = ae[4],
869						a23 = ae[7];
870			const a31 = ae[2],
871						a32 = ae[5],
872						a33 = ae[8];
873			const b11 = be[0],
874						b12 = be[3],
875						b13 = be[6];
876			const b21 = be[1],
877						b22 = be[4],
878						b23 = be[7];
879			const b31 = be[2],
880						b32 = be[5],
881						b33 = be[8];
882			te[0] = a11 * b11 + a12 * b21 + a13 * b31;
883			te[3] = a11 * b12 + a12 * b22 + a13 * b32;
884			te[6] = a11 * b13 + a12 * b23 + a13 * b33;
885			te[1] = a21 * b11 + a22 * b21 + a23 * b31;
886			te[4] = a21 * b12 + a22 * b22 + a23 * b32;
887			te[7] = a21 * b13 + a22 * b23 + a23 * b33;
888			te[2] = a31 * b11 + a32 * b21 + a33 * b31;
889			te[5] = a31 * b12 + a32 * b22 + a33 * b32;
890			te[8] = a31 * b13 + a32 * b23 + a33 * b33;
891			return this;
892		}
893
894		multiplyScalar(s) {
895			const te = this.elements;
896			te[0] *= s;
897			te[3] *= s;
898			te[6] *= s;
899			te[1] *= s;
900			te[4] *= s;
901			te[7] *= s;
902			te[2] *= s;
903			te[5] *= s;
904			te[8] *= s;
905			return this;
906		}
907
908		determinant() {
909			const te = this.elements;
910			const a = te[0],
911						b = te[1],
912						c = te[2],
913						d = te[3],
914						e = te[4],
915						f = te[5],
916						g = te[6],
917						h = te[7],
918						i = te[8];
919			return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
920		}
921
922		invert() {
923			const te = this.elements,
924						n11 = te[0],
925						n21 = te[1],
926						n31 = te[2],
927						n12 = te[3],
928						n22 = te[4],
929						n32 = te[5],
930						n13 = te[6],
931						n23 = te[7],
932						n33 = te[8],
933						t11 = n33 * n22 - n32 * n23,
934						t12 = n32 * n13 - n33 * n12,
935						t13 = n23 * n12 - n22 * n13,
936						det = n11 * t11 + n21 * t12 + n31 * t13;
937			if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
938			const detInv = 1 / det;
939			te[0] = t11 * detInv;
940			te[1] = (n31 * n23 - n33 * n21) * detInv;
941			te[2] = (n32 * n21 - n31 * n22) * detInv;
942			te[3] = t12 * detInv;
943			te[4] = (n33 * n11 - n31 * n13) * detInv;
944			te[5] = (n31 * n12 - n32 * n11) * detInv;
945			te[6] = t13 * detInv;
946			te[7] = (n21 * n13 - n23 * n11) * detInv;
947			te[8] = (n22 * n11 - n21 * n12) * detInv;
948			return this;
949		}
950
951		transpose() {
952			let tmp;
953			const m = this.elements;
954			tmp = m[1];
955			m[1] = m[3];
956			m[3] = tmp;
957			tmp = m[2];
958			m[2] = m[6];
959			m[6] = tmp;
960			tmp = m[5];
961			m[5] = m[7];
962			m[7] = tmp;
963			return this;
964		}
965
966		getNormalMatrix(matrix4) {
967			return this.setFromMatrix4(matrix4).invert().transpose();
968		}
969
970		transposeIntoArray(r) {
971			const m = this.elements;
972			r[0] = m[0];
973			r[1] = m[3];
974			r[2] = m[6];
975			r[3] = m[1];
976			r[4] = m[4];
977			r[5] = m[7];
978			r[6] = m[2];
979			r[7] = m[5];
980			r[8] = m[8];
981			return this;
982		}
983
984		setUvTransform(tx, ty, sx, sy, rotation, cx, cy) {
985			const c = Math.cos(rotation);
986			const s = Math.sin(rotation);
987			this.set(sx * c, sx * s, -sx * (c * cx + s * cy) + cx + tx, -sy * s, sy * c, -sy * (-s * cx + c * cy) + cy + ty, 0, 0, 1);
988			return this;
989		}
990
991		scale(sx, sy) {
992			const te = this.elements;
993			te[0] *= sx;
994			te[3] *= sx;
995			te[6] *= sx;
996			te[1] *= sy;
997			te[4] *= sy;
998			te[7] *= sy;
999			return this;
1000		}
1001
1002		rotate(theta) {
1003			const c = Math.cos(theta);
1004			const s = Math.sin(theta);
1005			const te = this.elements;
1006			const a11 = te[0],
1007						a12 = te[3],
1008						a13 = te[6];
1009			const a21 = te[1],
1010						a22 = te[4],
1011						a23 = te[7];
1012			te[0] = c * a11 + s * a21;
1013			te[3] = c * a12 + s * a22;
1014			te[6] = c * a13 + s * a23;
1015			te[1] = -s * a11 + c * a21;
1016			te[4] = -s * a12 + c * a22;
1017			te[7] = -s * a13 + c * a23;
1018			return this;
1019		}
1020
1021		translate(tx, ty) {
1022			const te = this.elements;
1023			te[0] += tx * te[2];
1024			te[3] += tx * te[5];
1025			te[6] += tx * te[8];
1026			te[1] += ty * te[2];
1027			te[4] += ty * te[5];
1028			te[7] += ty * te[8];
1029			return this;
1030		}
1031
1032		equals(matrix) {
1033			const te = this.elements;
1034			const me = matrix.elements;
1035
1036			for (let i = 0; i < 9; i++) {
1037				if (te[i] !== me[i]) return false;
1038			}
1039
1040			return true;
1041		}
1042
1043		fromArray(array, offset = 0) {
1044			for (let i = 0; i < 9; i++) {
1045				this.elements[i] = array[i + offset];
1046			}
1047
1048			return this;
1049		}
1050
1051		toArray(array = [], offset = 0) {
1052			const te = this.elements;
1053			array[offset] = te[0];
1054			array[offset + 1] = te[1];
1055			array[offset + 2] = te[2];
1056			array[offset + 3] = te[3];
1057			array[offset + 4] = te[4];
1058			array[offset + 5] = te[5];
1059			array[offset + 6] = te[6];
1060			array[offset + 7] = te[7];
1061			array[offset + 8] = te[8];
1062			return array;
1063		}
1064
1065		clone() {
1066			return new this.constructor().fromArray(this.elements);
1067		}
1068
1069	}
1070
1071	Matrix3.prototype.isMatrix3 = true;
1072
1073	function arrayMax(array) {
1074		if (array.length === 0) return -Infinity;
1075		let max = array[0];
1076
1077		for (let i = 1, l = array.length; i < l; ++i) {
1078			if (array[i] > max) max = array[i];
1079		}
1080
1081		return max;
1082	}
1083
1084	const TYPED_ARRAYS = {
1085		Int8Array: Int8Array,
1086		Uint8Array: Uint8Array,
1087		Uint8ClampedArray: Uint8ClampedArray,
1088		Int16Array: Int16Array,
1089		Uint16Array: Uint16Array,
1090		Int32Array: Int32Array,
1091		Uint32Array: Uint32Array,
1092		Float32Array: Float32Array,
1093		Float64Array: Float64Array
1094	};
1095
1096	function getTypedArray(type, buffer) {
1097		return new TYPED_ARRAYS[type](buffer);
1098	}
1099
1100	function createElementNS(name) {
1101		return document.createElementNS('http://www.w3.org/1999/xhtml', name);
1102	}
1103
1104	let _canvas;
1105
1106	class ImageUtils {
1107		static getDataURL(image) {
1108			if (/^data:/i.test(image.src)) {
1109				return image.src;
1110			}
1111
1112			if (typeof HTMLCanvasElement == 'undefined') {
1113				return image.src;
1114			}
1115
1116			let canvas;
1117
1118			if (image instanceof HTMLCanvasElement) {
1119				canvas = image;
1120			} else {
1121				if (_canvas === undefined) _canvas = createElementNS('canvas');
1122				_canvas.width = image.width;
1123				_canvas.height = image.height;
1124
1125				const context = _canvas.getContext('2d');
1126
1127				if (image instanceof ImageData) {
1128					context.putImageData(image, 0, 0);
1129				} else {
1130					context.drawImage(image, 0, 0, image.width, image.height);
1131				}
1132
1133				canvas = _canvas;
1134			}
1135
1136			if (canvas.width > 2048 || canvas.height > 2048) {
1137				console.warn('THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image);
1138				return canvas.toDataURL('image/jpeg', 0.6);
1139			} else {
1140				return canvas.toDataURL('image/png');
1141			}
1142		}
1143
1144	}
1145
1146	let textureId = 0;
1147
1148	class Texture extends EventDispatcher {
1149		constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding) {
1150			super();
1151			Object.defineProperty(this, 'id', {
1152				value: textureId++
1153			});
1154			this.uuid = generateUUID();
1155			this.name = '';
1156			this.image = image;
1157			this.mipmaps = [];
1158			this.mapping = mapping;
1159			this.wrapS = wrapS;
1160			this.wrapT = wrapT;
1161			this.magFilter = magFilter;
1162			this.minFilter = minFilter;
1163			this.anisotropy = anisotropy;
1164			this.format = format;
1165			this.internalFormat = null;
1166			this.type = type;
1167			this.offset = new Vector2(0, 0);
1168			this.repeat = new Vector2(1, 1);
1169			this.center = new Vector2(0, 0);
1170			this.rotation = 0;
1171			this.matrixAutoUpdate = true;
1172			this.matrix = new Matrix3();
1173			this.generateMipmaps = true;
1174			this.premultiplyAlpha = false;
vendor: 13,438 bytes, lines 1175-1765
1175			this.flipY = true;
1176			this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
1177			// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
1178			//
1179			// Also changing the encoding after already used by a Material will not automatically make the Material
1180			// update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
1181
1182			this.encoding = encoding;
1183			this.userData = {};
1184			this.version = 0;
1185			this.onUpdate = null;
1186			this.isRenderTargetTexture = false;
1187		}
1188
1189		updateMatrix() {
1190			this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y);
1191		}
1192
1193		clone() {
1194			return new this.constructor().copy(this);
1195		}
1196
1197		copy(source) {
1198			this.name = source.name;
1199			this.image = source.image;
1200			this.mipmaps = source.mipmaps.slice(0);
1201			this.mapping = source.mapping;
1202			this.wrapS = source.wrapS;
1203			this.wrapT = source.wrapT;
1204			this.magFilter = source.magFilter;
1205			this.minFilter = source.minFilter;
1206			this.anisotropy = source.anisotropy;
1207			this.format = source.format;
1208			this.internalFormat = source.internalFormat;
1209			this.type = source.type;
1210			this.offset.copy(source.offset);
1211			this.repeat.copy(source.repeat);
1212			this.center.copy(source.center);
1213			this.rotation = source.rotation;
1214			this.matrixAutoUpdate = source.matrixAutoUpdate;
1215			this.matrix.copy(source.matrix);
1216			this.generateMipmaps = source.generateMipmaps;
1217			this.premultiplyAlpha = source.premultiplyAlpha;
1218			this.flipY = source.flipY;
1219			this.unpackAlignment = source.unpackAlignment;
1220			this.encoding = source.encoding;
1221			this.userData = JSON.parse(JSON.stringify(source.userData));
1222			return this;
1223		}
1224
1225		toJSON(meta) {
1226			const isRootObject = meta === undefined || typeof meta === 'string';
1227
1228			if (!isRootObject && meta.textures[this.uuid] !== undefined) {
1229				return meta.textures[this.uuid];
1230			}
1231
1232			const output = {
1233				metadata: {
1234					version: 4.5,
1235					type: 'Texture',
1236					generator: 'Texture.toJSON'
1237				},
1238				uuid: this.uuid,
1239				name: this.name,
1240				mapping: this.mapping,
1241				repeat: [this.repeat.x, this.repeat.y],
1242				offset: [this.offset.x, this.offset.y],
1243				center: [this.center.x, this.center.y],
1244				rotation: this.rotation,
1245				wrap: [this.wrapS, this.wrapT],
1246				format: this.format,
1247				type: this.type,
1248				encoding: this.encoding,
1249				minFilter: this.minFilter,
1250				magFilter: this.magFilter,
1251				anisotropy: this.anisotropy,
1252				flipY: this.flipY,
1253				premultiplyAlpha: this.premultiplyAlpha,
1254				unpackAlignment: this.unpackAlignment
1255			};
1256
1257			if (this.image !== undefined) {
1258				// TODO: Move to THREE.Image
1259				const image = this.image;
1260
1261				if (image.uuid === undefined) {
1262					image.uuid = generateUUID(); // UGH
1263				}
1264
1265				if (!isRootObject && meta.images[image.uuid] === undefined) {
1266					let url;
1267
1268					if (Array.isArray(image)) {
1269						// process array of images e.g. CubeTexture
1270						url = [];
1271
1272						for (let i = 0, l = image.length; i < l; i++) {
1273							// check cube texture with data textures
1274							if (image[i].isDataTexture) {
1275								url.push(serializeImage(image[i].image));
1276							} else {
1277								url.push(serializeImage(image[i]));
1278							}
1279						}
1280					} else {
1281						// process single image
1282						url = serializeImage(image);
1283					}
1284
1285					meta.images[image.uuid] = {
1286						uuid: image.uuid,
1287						url: url
1288					};
1289				}
1290
1291				output.image = image.uuid;
1292			}
1293
1294			if (JSON.stringify(this.userData) !== '{}') output.userData = this.userData;
1295
1296			if (!isRootObject) {
1297				meta.textures[this.uuid] = output;
1298			}
1299
1300			return output;
1301		}
1302
1303		dispose() {
1304			this.dispatchEvent({
1305				type: 'dispose'
1306			});
1307		}
1308
1309		transformUv(uv) {
1310			if (this.mapping !== UVMapping) return uv;
1311			uv.applyMatrix3(this.matrix);
1312
1313			if (uv.x < 0 || uv.x > 1) {
1314				switch (this.wrapS) {
1315					case RepeatWrapping:
1316						uv.x = uv.x - Math.floor(uv.x);
1317						break;
1318
1319					case ClampToEdgeWrapping:
1320						uv.x = uv.x < 0 ? 0 : 1;
1321						break;
1322
1323					case MirroredRepeatWrapping:
1324						if (Math.abs(Math.floor(uv.x) % 2) === 1) {
1325							uv.x = Math.ceil(uv.x) - uv.x;
1326						} else {
1327							uv.x = uv.x - Math.floor(uv.x);
1328						}
1329
1330						break;
1331				}
1332			}
1333
1334			if (uv.y < 0 || uv.y > 1) {
1335				switch (this.wrapT) {
1336					case RepeatWrapping:
1337						uv.y = uv.y - Math.floor(uv.y);
1338						break;
1339
1340					case ClampToEdgeWrapping:
1341						uv.y = uv.y < 0 ? 0 : 1;
1342						break;
1343
1344					case MirroredRepeatWrapping:
1345						if (Math.abs(Math.floor(uv.y) % 2) === 1) {
1346							uv.y = Math.ceil(uv.y) - uv.y;
1347						} else {
1348							uv.y = uv.y - Math.floor(uv.y);
1349						}
1350
1351						break;
1352				}
1353			}
1354
1355			if (this.flipY) {
1356				uv.y = 1 - uv.y;
1357			}
1358
1359			return uv;
1360		}
1361
1362		set needsUpdate(value) {
1363			if (value === true) this.version++;
1364		}
1365
1366	}
1367
1368	Texture.DEFAULT_IMAGE = undefined;
1369	Texture.DEFAULT_MAPPING = UVMapping;
1370	Texture.prototype.isTexture = true;
1371
1372	function serializeImage(image) {
1373		if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
1374			// default images
1375			return ImageUtils.getDataURL(image);
1376		} else {
1377			if (image.data) {
1378				// images of DataTexture
1379				return {
1380					data: Array.prototype.slice.call(image.data),
1381					width: image.width,
1382					height: image.height,
1383					type: image.data.constructor.name
1384				};
1385			} else {
1386				console.warn('THREE.Texture: Unable to serialize Texture.');
1387				return {};
1388			}
1389		}
1390	}
1391
1392	class Vector4 {
1393		constructor(x = 0, y = 0, z = 0, w = 1) {
1394			this.x = x;
1395			this.y = y;
1396			this.z = z;
1397			this.w = w;
1398		}
1399
1400		get width() {
1401			return this.z;
1402		}
1403
1404		set width(value) {
1405			this.z = value;
1406		}
1407
1408		get height() {
1409			return this.w;
1410		}
1411
1412		set height(value) {
1413			this.w = value;
1414		}
1415
1416		set(x, y, z, w) {
1417			this.x = x;
1418			this.y = y;
1419			this.z = z;
1420			this.w = w;
1421			return this;
1422		}
1423
1424		setScalar(scalar) {
1425			this.x = scalar;
1426			this.y = scalar;
1427			this.z = scalar;
1428			this.w = scalar;
1429			return this;
1430		}
1431
1432		setX(x) {
1433			this.x = x;
1434			return this;
1435		}
1436
1437		setY(y) {
1438			this.y = y;
1439			return this;
1440		}
1441
1442		setZ(z) {
1443			this.z = z;
1444			return this;
1445		}
1446
1447		setW(w) {
1448			this.w = w;
1449			return this;
1450		}
1451
1452		setComponent(index, value) {
1453			switch (index) {
1454				case 0:
1455					this.x = value;
1456					break;
1457
1458				case 1:
1459					this.y = value;
1460					break;
1461
1462				case 2:
1463					this.z = value;
1464					break;
1465
1466				case 3:
1467					this.w = value;
1468					break;
1469
1470				default:
1471					throw new Error('index is out of range: ' + index);
1472			}
1473
1474			return this;
1475		}
1476
1477		getComponent(index) {
1478			switch (index) {
1479				case 0:
1480					return this.x;
1481
1482				case 1:
1483					return this.y;
1484
1485				case 2:
1486					return this.z;
1487
1488				case 3:
1489					return this.w;
1490
1491				default:
1492					throw new Error('index is out of range: ' + index);
1493			}
1494		}
1495
1496		clone() {
1497			return new this.constructor(this.x, this.y, this.z, this.w);
1498		}
1499
1500		copy(v) {
1501			this.x = v.x;
1502			this.y = v.y;
1503			this.z = v.z;
1504			this.w = v.w !== undefined ? v.w : 1;
1505			return this;
1506		}
1507
1508		add(v, w) {
1509			if (w !== undefined) {
1510				console.warn('THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.');
1511				return this.addVectors(v, w);
1512			}
1513
1514			this.x += v.x;
1515			this.y += v.y;
1516			this.z += v.z;
1517			this.w += v.w;
1518			return this;
1519		}
1520
1521		addScalar(s) {
1522			this.x += s;
1523			this.y += s;
1524			this.z += s;
1525			this.w += s;
1526			return this;
1527		}
1528
1529		addVectors(a, b) {
1530			this.x = a.x + b.x;
1531			this.y = a.y + b.y;
1532			this.z = a.z + b.z;
1533			this.w = a.w + b.w;
1534			return this;
1535		}
1536
1537		addScaledVector(v, s) {
1538			this.x += v.x * s;
1539			this.y += v.y * s;
1540			this.z += v.z * s;
1541			this.w += v.w * s;
1542			return this;
1543		}
1544
1545		sub(v, w) {
1546			if (w !== undefined) {
1547				console.warn('THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.');
1548				return this.subVectors(v, w);
1549			}
1550
1551			this.x -= v.x;
1552			this.y -= v.y;
1553			this.z -= v.z;
1554			this.w -= v.w;
1555			return this;
1556		}
1557
1558		subScalar(s) {
1559			this.x -= s;
1560			this.y -= s;
1561			this.z -= s;
1562			this.w -= s;
1563			return this;
1564		}
1565
1566		subVectors(a, b) {
1567			this.x = a.x - b.x;
1568			this.y = a.y - b.y;
1569			this.z = a.z - b.z;
1570			this.w = a.w - b.w;
1571			return this;
1572		}
1573
1574		multiply(v) {
1575			this.x *= v.x;
1576			this.y *= v.y;
1577			this.z *= v.z;
1578			this.w *= v.w;
1579			return this;
1580		}
1581
1582		multiplyScalar(scalar) {
1583			this.x *= scalar;
1584			this.y *= scalar;
1585			this.z *= scalar;
1586			this.w *= scalar;
1587			return this;
1588		}
1589
1590		applyMatrix4(m) {
1591			const x = this.x,
1592						y = this.y,
1593						z = this.z,
1594						w = this.w;
1595			const e = m.elements;
1596			this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w;
1597			this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w;
1598			this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w;
1599			this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w;
1600			return this;
1601		}
1602
1603		divideScalar(scalar) {
1604			return this.multiplyScalar(1 / scalar);
1605		}
1606
1607		setAxisAngleFromQuaternion(q) {
1608			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
1609			// q is assumed to be normalized
1610			this.w = 2 * Math.acos(q.w);
1611			const s = Math.sqrt(1 - q.w * q.w);
1612
1613			if (s < 0.0001) {
1614				this.x = 1;
1615				this.y = 0;
1616				this.z = 0;
1617			} else {
1618				this.x = q.x / s;
1619				this.y = q.y / s;
1620				this.z = q.z / s;
1621			}
1622
1623			return this;
1624		}
1625
1626		setAxisAngleFromRotationMatrix(m) {
1627			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
1628			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
1629			let angle, x, y, z; // variables for result
1630
1631			const epsilon = 0.01,
1632						// margin to allow for rounding errors
1633			epsilon2 = 0.1,
1634						// margin to distinguish between 0 and 180 degrees
1635			te = m.elements,
1636						m11 = te[0],
1637						m12 = te[4],
1638						m13 = te[8],
1639						m21 = te[1],
1640						m22 = te[5],
1641						m23 = te[9],
1642						m31 = te[2],
1643						m32 = te[6],
1644						m33 = te[10];
1645
1646			if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) {
1647				// singularity found
1648				// first check for identity matrix which must have +1 for all terms
1649				// in leading diagonal and zero in other terms
1650				if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) {
1651					// this singularity is identity matrix so angle = 0
1652					this.set(1, 0, 0, 0);
1653					return this; // zero angle, arbitrary axis
1654				} // otherwise this singularity is angle = 180
1655
1656
1657				angle = Math.PI;
1658				const xx = (m11 + 1) / 2;
1659				const yy = (m22 + 1) / 2;
1660				const zz = (m33 + 1) / 2;
1661				const xy = (m12 + m21) / 4;
1662				const xz = (m13 + m31) / 4;
1663				const yz = (m23 + m32) / 4;
1664
1665				if (xx > yy && xx > zz) {
1666					// m11 is the largest diagonal term
1667					if (xx < epsilon) {
1668						x = 0;
1669						y = 0.707106781;
1670						z = 0.707106781;
1671					} else {
1672						x = Math.sqrt(xx);
1673						y = xy / x;
1674						z = xz / x;
1675					}
1676				} else if (yy > zz) {
1677					// m22 is the largest diagonal term
1678					if (yy < epsilon) {
1679						x = 0.707106781;
1680						y = 0;
1681						z = 0.707106781;
1682					} else {
1683						y = Math.sqrt(yy);
1684						x = xy / y;
1685						z = yz / y;
1686					}
1687				} else {
1688					// m33 is the largest diagonal term so base result on this
1689					if (zz < epsilon) {
1690						x = 0.707106781;
1691						y = 0.707106781;
1692						z = 0;
1693					} else {
1694						z = Math.sqrt(zz);
1695						x = xz / z;
1696						y = yz / z;
1697					}
1698				}
1699
1700				this.set(x, y, z, angle);
1701				return this; // return 180 deg rotation
1702			} // as we have reached here there are no singularities so we can handle normally
1703
1704
1705			let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); // used to normalize
1706
1707			if (Math.abs(s) < 0.001) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be
1708			// caught by singularity test above, but I've left it in just in case
1709
1710			this.x = (m32 - m23) / s;
1711			this.y = (m13 - m31) / s;
1712			this.z = (m21 - m12) / s;
1713			this.w = Math.acos((m11 + m22 + m33 - 1) / 2);
1714			return this;
1715		}
1716
1717		min(v) {
1718			this.x = Math.min(this.x, v.x);
1719			this.y = Math.min(this.y, v.y);
1720			this.z = Math.min(this.z, v.z);
1721			this.w = Math.min(this.w, v.w);
1722			return this;
1723		}
1724
1725		max(v) {
1726			this.x = Math.max(this.x, v.x);
1727			this.y = Math.max(this.y, v.y);
1728			this.z = Math.max(this.z, v.z);
1729			this.w = Math.max(this.w, v.w);
1730			return this;
1731		}
1732
1733		clamp(min, max) {
1734			// assumes min < max, componentwise
1735			this.x = Math.max(min.x, Math.min(max.x, this.x));
1736			this.y = Math.max(min.y, Math.min(max.y, this.y));
1737			this.z = Math.max(min.z, Math.min(max.z, this.z));
1738			this.w = Math.max(min.w, Math.min(max.w, this.w));
1739			return this;
1740		}
1741
1742		clampScalar(minVal, maxVal) {
1743			this.x = Math.max(minVal, Math.min(maxVal, this.x));
1744			this.y = Math.max(minVal, Math.min(maxVal, this.y));
1745			this.z = Math.max(minVal, Math.min(maxVal, this.z));
1746			this.w = Math.max(minVal, Math.min(maxVal, this.w));
1747			return this;
1748		}
1749
1750		clampLength(min, max) {
1751			const length = this.length();
1752			return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
1753		}
1754
1755		floor() {
1756			this.x = Math.floor(this.x);
1757			this.y = Math.floor(this.y);
1758			this.z = Math.floor(this.z);
1759			this.w = Math.floor(this.w);
1760			return this;
1761		}
1762
1763		ceil() {
1764			this.x = Math.ceil(this.x);
1765			this.y = Math.ceil(this.y);
1766			this.z = Math.ceil(this.z);
1767			this.w = Math.ceil(this.w);
1768			return this;
1769		}
1770
1771		round() {
1772			this.x = Math.round(this.x);
1773			this.y = Math.round(this.y);
1774			this.z = Math.round(this.z);
1775			this.w = Math.round(this.w);
1776			return this;
1777		}
1778
1779		roundToZero() {
1780			this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
1781			this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
1782			this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z);
1783			this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w);
1784			return this;
1785		}
1786
1787		negate() {
1788			this.x = -this.x;
1789			this.y = -this.y;
1790			this.z = -this.z;
1791			this.w = -this.w;
1792			return this;
1793		}
1794
1795		dot(v) {
1796			return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
1797		}
1798
1799		lengthSq() {
1800			return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
1801		}
1802
1803		length() {
1804			return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
1805		}
1806
1807		manhattanLength() {
1808			return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w);
1809		}
1810
1811		normalize() {
1812			return this.divideScalar(this.length() || 1);
1813		}
1814
1815		setLength(length) {
1816			return this.normalize().multiplyScalar(length);
1817		}
1818
1819		lerp(v, alpha) {
1820			this.x += (v.x - this.x) * alpha;
1821			this.y += (v.y - this.y) * alpha;
1822			this.z += (v.z - this.z) * alpha;
1823			this.w += (v.w - this.w) * alpha;
1824			return this;
1825		}
1826
1827		lerpVectors(v1, v2, alpha) {
1828			this.x = v1.x + (v2.x - v1.x) * alpha;
1829			this.y = v1.y + (v2.y - v1.y) * alpha;
1830			this.z = v1.z + (v2.z - v1.z) * alpha;
1831			this.w = v1.w + (v2.w - v1.w) * alpha;
1832			return this;
1833		}
1834
1835		equals(v) {
1836			return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w;
1837		}
1838
1839		fromArray(array, offset = 0) {
1840			this.x = array[offset];
1841			this.y = array[offset + 1];
1842			this.z = array[offset + 2];
1843			this.w = array[offset + 3];
1844			return this;
1845		}
1846
1847		toArray(array = [], offset = 0) {
1848			array[offset] = this.x;
1849			array[offset + 1] = this.y;
1850			array[offset + 2] = this.z;
1851			array[offset + 3] = this.w;
1852			return array;
1853		}
1854
1855		fromBufferAttribute(attribute, index, offset) {
1856			if (offset !== undefined) {
1857				console.warn('THREE.Vector4: offset has been removed from .fromBufferAttribute().');
1858			}
1859
1860			this.x = attribute.getX(index);
1861			this.y = attribute.getY(index);
1862			this.z = attribute.getZ(index);
1863			this.w = attribute.getW(index);
1864			return this;
1865		}
1866
1867		random() {
1868			this.x = Math.random();
1869			this.y = Math.random();
1870			this.z = Math.random();
1871			this.w = Math.random();
1872			return this;
1873		}
1874
1875		*[Symbol.iterator]() {
1876			yield this.x;
1877			yield this.y;
1878			yield this.z;
1879			yield this.w;
1880		}
1881
1882	}
1883
1884	Vector4.prototype.isVector4 = true;
1885
1886	/*
1887	 In options, we can specify:
1888	 * Texture parameters for an auto-generated target texture
1889	 * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
1890	*/
1891
1892	class WebGLRenderTarget extends EventDispatcher {
1893		constructor(width, height, options = {}) {
1894			super();
1895			this.width = width;
1896			this.height = height;
1897			this.depth = 1;
1898			this.scissor = new Vector4(0, 0, width, height);
1899			this.scissorTest = false;
1900			this.viewport = new Vector4(0, 0, width, height);
1901			this.texture = new Texture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding);
1902			this.texture.isRenderTargetTexture = true;
1903			this.texture.image = {
1904				width: width,
1905				height: height,
1906				depth: 1
1907			};
1908			this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
1909			this.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null;
1910			this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
1911			this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
1912			this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;
1913			this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
1914		}
1915
1916		setTexture(texture) {
1917			texture.image = {
1918				width: this.width,
1919				height: this.height,
1920				depth: this.depth
1921			};
1922			this.texture = texture;
1923		}
1924
1925		setSize(width, height, depth = 1) {
1926			if (this.width !== width || this.height !== height || this.depth !== depth) {
1927				this.width = width;
1928				this.height = height;
1929				this.depth = depth;
1930				this.texture.image.width = width;
1931				this.texture.image.height = height;
1932				this.texture.image.depth = depth;
1933				this.dispose();
1934			}
1935
1936			this.viewport.set(0, 0, width, height);
1937			this.scissor.set(0, 0, width, height);
1938		}
1939
1940		clone() {
1941			return new this.constructor().copy(this);
1942		}
1943
1944		copy(source) {
1945			this.width = source.width;
1946			this.height = source.height;
1947			this.depth = source.depth;
1948			this.viewport.copy(source.viewport);
1949			this.texture = source.texture.clone();
1950			this.texture.image = { ...this.texture.image
1951			}; // See #20328.
1952
1953			this.depthBuffer = source.depthBuffer;
1954			this.stencilBuffer = source.stencilBuffer;
1955			this.depthTexture = source.depthTexture;
1956			return this;
1957		}
1958
1959		dispose() {
1960			this.dispatchEvent({
1961				type: 'dispose'
1962			});
1963		}
1964
1965	}
1966
1967	WebGLRenderTarget.prototype.isWebGLRenderTarget = true;
1968
1969	class WebGLMultipleRenderTargets extends WebGLRenderTarget {
1970		constructor(width, height, count) {
1971			super(width, height);
1972			const texture = this.texture;
1973			this.texture = [];
1974
1975			for (let i = 0; i < count; i++) {
1976				this.texture[i] = texture.clone();
1977			}
1978		}
1979
1980		setSize(width, height, depth = 1) {
1981			if (this.width !== width || this.height !== height || this.depth !== depth) {
1982				this.width = width;
1983				this.height = height;
1984				this.depth = depth;
1985
1986				for (let i = 0, il = this.texture.length; i < il; i++) {
1987					this.texture[i].image.width = width;
1988					this.texture[i].image.height = height;
1989					this.texture[i].image.depth = depth;
1990				}
1991
1992				this.dispose();
1993			}
1994
1995			this.viewport.set(0, 0, width, height);
1996			this.scissor.set(0, 0, width, height);
1997			return this;
1998		}
1999
2000		copy(source) {
2001			this.dispose();
2002			this.width = source.width;
2003			this.height = source.height;
2004			this.depth = source.depth;
2005			this.viewport.set(0, 0, this.width, this.height);
2006			this.scissor.set(0, 0, this.width, this.height);
2007			this.depthBuffer = source.depthBuffer;
2008			this.stencilBuffer = source.stencilBuffer;
2009			this.depthTexture = source.depthTexture;
2010			this.texture.length = 0;
2011
2012			for (let i = 0, il = source.texture.length; i < il; i++) {
2013				this.texture[i] = source.texture[i].clone();
2014			}
2015
2016			return this;
2017		}
2018
2019	}
2020
2021	WebGLMultipleRenderTargets.prototype.isWebGLMultipleRenderTargets = true;
2022
2023	class WebGLMultisampleRenderTarget extends WebGLRenderTarget {
2024		constructor(width, height, options = {}) {
2025			super(width, height, options);
2026			this.samples = 4;
2027			this.ignoreDepthForMultisampleCopy = options.ignoreDepth !== undefined ? options.ignoreDepth : true;
2028			this.useRenderToTexture = options.useRenderToTexture !== undefined ? options.useRenderToTexture : false;
vendor: 31,738 bytes, lines 2029-3366
2029			this.useRenderbuffer = this.useRenderToTexture === false;
2030		}
2031
2032		copy(source) {
2033			super.copy.call(this, source);
2034			this.samples = source.samples;
2035			this.useRenderToTexture = source.useRenderToTexture;
2036			this.useRenderbuffer = source.useRenderbuffer;
2037			return this;
2038		}
2039
2040	}
2041
2042	WebGLMultisampleRenderTarget.prototype.isWebGLMultisampleRenderTarget = true;
2043
2044	class Quaternion {
2045		constructor(x = 0, y = 0, z = 0, w = 1) {
2046			this._x = x;
2047			this._y = y;
2048			this._z = z;
2049			this._w = w;
2050		}
2051
2052		static slerp(qa, qb, qm, t) {
2053			console.warn('THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.');
2054			return qm.slerpQuaternions(qa, qb, t);
2055		}
2056
2057		static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {
2058			// fuzz-free, array-based Quaternion SLERP operation
2059			let x0 = src0[srcOffset0 + 0],
2060					y0 = src0[srcOffset0 + 1],
2061					z0 = src0[srcOffset0 + 2],
2062					w0 = src0[srcOffset0 + 3];
2063			const x1 = src1[srcOffset1 + 0],
2064						y1 = src1[srcOffset1 + 1],
2065						z1 = src1[srcOffset1 + 2],
2066						w1 = src1[srcOffset1 + 3];
2067
2068			if (t === 0) {
2069				dst[dstOffset + 0] = x0;
2070				dst[dstOffset + 1] = y0;
2071				dst[dstOffset + 2] = z0;
2072				dst[dstOffset + 3] = w0;
2073				return;
2074			}
2075
2076			if (t === 1) {
2077				dst[dstOffset + 0] = x1;
2078				dst[dstOffset + 1] = y1;
2079				dst[dstOffset + 2] = z1;
2080				dst[dstOffset + 3] = w1;
2081				return;
2082			}
2083
2084			if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {
2085				let s = 1 - t;
2086				const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
2087							dir = cos >= 0 ? 1 : -1,
2088							sqrSin = 1 - cos * cos; // Skip the Slerp for tiny steps to avoid numeric problems:
2089
2090				if (sqrSin > Number.EPSILON) {
2091					const sin = Math.sqrt(sqrSin),
2092								len = Math.atan2(sin, cos * dir);
2093					s = Math.sin(s * len) / sin;
2094					t = Math.sin(t * len) / sin;
2095				}
2096
2097				const tDir = t * dir;
2098				x0 = x0 * s + x1 * tDir;
2099				y0 = y0 * s + y1 * tDir;
2100				z0 = z0 * s + z1 * tDir;
2101				w0 = w0 * s + w1 * tDir; // Normalize in case we just did a lerp:
2102
2103				if (s === 1 - t) {
2104					const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);
2105					x0 *= f;
2106					y0 *= f;
2107					z0 *= f;
2108					w0 *= f;
2109				}
2110			}
2111
2112			dst[dstOffset] = x0;
2113			dst[dstOffset + 1] = y0;
2114			dst[dstOffset + 2] = z0;
2115			dst[dstOffset + 3] = w0;
2116		}
2117
2118		static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {
2119			const x0 = src0[srcOffset0];
2120			const y0 = src0[srcOffset0 + 1];
2121			const z0 = src0[srcOffset0 + 2];
2122			const w0 = src0[srcOffset0 + 3];
2123			const x1 = src1[srcOffset1];
2124			const y1 = src1[srcOffset1 + 1];
2125			const z1 = src1[srcOffset1 + 2];
2126			const w1 = src1[srcOffset1 + 3];
2127			dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
2128			dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
2129			dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
2130			dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
2131			return dst;
2132		}
2133
2134		get x() {
2135			return this._x;
2136		}
2137
2138		set x(value) {
2139			this._x = value;
2140
2141			this._onChangeCallback();
2142		}
2143
2144		get y() {
2145			return this._y;
2146		}
2147
2148		set y(value) {
2149			this._y = value;
2150
2151			this._onChangeCallback();
2152		}
2153
2154		get z() {
2155			return this._z;
2156		}
2157
2158		set z(value) {
2159			this._z = value;
2160
2161			this._onChangeCallback();
2162		}
2163
2164		get w() {
2165			return this._w;
2166		}
2167
2168		set w(value) {
2169			this._w = value;
2170
2171			this._onChangeCallback();
2172		}
2173
2174		set(x, y, z, w) {
2175			this._x = x;
2176			this._y = y;
2177			this._z = z;
2178			this._w = w;
2179
2180			this._onChangeCallback();
2181
2182			return this;
2183		}
2184
2185		clone() {
2186			return new this.constructor(this._x, this._y, this._z, this._w);
2187		}
2188
2189		copy(quaternion) {
2190			this._x = quaternion.x;
2191			this._y = quaternion.y;
2192			this._z = quaternion.z;
2193			this._w = quaternion.w;
2194
2195			this._onChangeCallback();
2196
2197			return this;
2198		}
2199
2200		setFromEuler(euler, update) {
2201			if (!(euler && euler.isEuler)) {
2202				throw new Error('THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.');
2203			}
2204
2205			const x = euler._x,
2206						y = euler._y,
2207						z = euler._z,
2208						order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/
2209			// 	20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
2210			//	content/SpinCalc.m
2211
2212			const cos = Math.cos;
2213			const sin = Math.sin;
2214			const c1 = cos(x / 2);
2215			const c2 = cos(y / 2);
2216			const c3 = cos(z / 2);
2217			const s1 = sin(x / 2);
2218			const s2 = sin(y / 2);
2219			const s3 = sin(z / 2);
2220
2221			switch (order) {
2222				case 'XYZ':
2223					this._x = s1 * c2 * c3 + c1 * s2 * s3;
2224					this._y = c1 * s2 * c3 - s1 * c2 * s3;
2225					this._z = c1 * c2 * s3 + s1 * s2 * c3;
2226					this._w = c1 * c2 * c3 - s1 * s2 * s3;
2227					break;
2228
2229				case 'YXZ':
2230					this._x = s1 * c2 * c3 + c1 * s2 * s3;
2231					this._y = c1 * s2 * c3 - s1 * c2 * s3;
2232					this._z = c1 * c2 * s3 - s1 * s2 * c3;
2233					this._w = c1 * c2 * c3 + s1 * s2 * s3;
2234					break;
2235
2236				case 'ZXY':
2237					this._x = s1 * c2 * c3 - c1 * s2 * s3;
2238					this._y = c1 * s2 * c3 + s1 * c2 * s3;
2239					this._z = c1 * c2 * s3 + s1 * s2 * c3;
2240					this._w = c1 * c2 * c3 - s1 * s2 * s3;
2241					break;
2242
2243				case 'ZYX':
2244					this._x = s1 * c2 * c3 - c1 * s2 * s3;
2245					this._y = c1 * s2 * c3 + s1 * c2 * s3;
2246					this._z = c1 * c2 * s3 - s1 * s2 * c3;
2247					this._w = c1 * c2 * c3 + s1 * s2 * s3;
2248					break;
2249
2250				case 'YZX':
2251					this._x = s1 * c2 * c3 + c1 * s2 * s3;
2252					this._y = c1 * s2 * c3 + s1 * c2 * s3;
2253					this._z = c1 * c2 * s3 - s1 * s2 * c3;
2254					this._w = c1 * c2 * c3 - s1 * s2 * s3;
2255					break;
2256
2257				case 'XZY':
2258					this._x = s1 * c2 * c3 - c1 * s2 * s3;
2259					this._y = c1 * s2 * c3 - s1 * c2 * s3;
2260					this._z = c1 * c2 * s3 + s1 * s2 * c3;
2261					this._w = c1 * c2 * c3 + s1 * s2 * s3;
2262					break;
2263
2264				default:
2265					console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order);
2266			}
2267
2268			if (update !== false) this._onChangeCallback();
2269			return this;
2270		}
2271
2272		setFromAxisAngle(axis, angle) {
2273			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
2274			// assumes axis is normalized
2275			const halfAngle = angle / 2,
2276						s = Math.sin(halfAngle);
2277			this._x = axis.x * s;
2278			this._y = axis.y * s;
2279			this._z = axis.z * s;
2280			this._w = Math.cos(halfAngle);
2281
2282			this._onChangeCallback();
2283
2284			return this;
2285		}
2286
2287		setFromRotationMatrix(m) {
2288			// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
2289			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
2290			const te = m.elements,
2291						m11 = te[0],
2292						m12 = te[4],
2293						m13 = te[8],
2294						m21 = te[1],
2295						m22 = te[5],
2296						m23 = te[9],
2297						m31 = te[2],
2298						m32 = te[6],
2299						m33 = te[10],
2300						trace = m11 + m22 + m33;
2301
2302			if (trace > 0) {
2303				const s = 0.5 / Math.sqrt(trace + 1.0);
2304				this._w = 0.25 / s;
2305				this._x = (m32 - m23) * s;
2306				this._y = (m13 - m31) * s;
2307				this._z = (m21 - m12) * s;
2308			} else if (m11 > m22 && m11 > m33) {
2309				const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
2310				this._w = (m32 - m23) / s;
2311				this._x = 0.25 * s;
2312				this._y = (m12 + m21) / s;
2313				this._z = (m13 + m31) / s;
2314			} else if (m22 > m33) {
2315				const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
2316				this._w = (m13 - m31) / s;
2317				this._x = (m12 + m21) / s;
2318				this._y = 0.25 * s;
2319				this._z = (m23 + m32) / s;
2320			} else {
2321				const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
2322				this._w = (m21 - m12) / s;
2323				this._x = (m13 + m31) / s;
2324				this._y = (m23 + m32) / s;
2325				this._z = 0.25 * s;
2326			}
2327
2328			this._onChangeCallback();
2329
2330			return this;
2331		}
2332
2333		setFromUnitVectors(vFrom, vTo) {
2334			// assumes direction vectors vFrom and vTo are normalized
2335			let r = vFrom.dot(vTo) + 1;
2336
2337			if (r < Number.EPSILON) {
2338				// vFrom and vTo point in opposite directions
2339				r = 0;
2340
2341				if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {
2342					this._x = -vFrom.y;
2343					this._y = vFrom.x;
2344					this._z = 0;
2345					this._w = r;
2346				} else {
2347					this._x = 0;
2348					this._y = -vFrom.z;
2349					this._z = vFrom.y;
2350					this._w = r;
2351				}
2352			} else {
2353				// crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3
2354				this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
2355				this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
2356				this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
2357				this._w = r;
2358			}
2359
2360			return this.normalize();
2361		}
2362
2363		angleTo(q) {
2364			return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));
2365		}
2366
2367		rotateTowards(q, step) {
2368			const angle = this.angleTo(q);
2369			if (angle === 0) return this;
2370			const t = Math.min(1, step / angle);
2371			this.slerp(q, t);
2372			return this;
2373		}
2374
2375		identity() {
2376			return this.set(0, 0, 0, 1);
2377		}
2378
2379		invert() {
2380			// quaternion is assumed to have unit length
2381			return this.conjugate();
2382		}
2383
2384		conjugate() {
2385			this._x *= -1;
2386			this._y *= -1;
2387			this._z *= -1;
2388
2389			this._onChangeCallback();
2390
2391			return this;
2392		}
2393
2394		dot(v) {
2395			return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
2396		}
2397
2398		lengthSq() {
2399			return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
2400		}
2401
2402		length() {
2403			return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
2404		}
2405
2406		normalize() {
2407			let l = this.length();
2408
2409			if (l === 0) {
2410				this._x = 0;
2411				this._y = 0;
2412				this._z = 0;
2413				this._w = 1;
2414			} else {
2415				l = 1 / l;
2416				this._x = this._x * l;
2417				this._y = this._y * l;
2418				this._z = this._z * l;
2419				this._w = this._w * l;
2420			}
2421
2422			this._onChangeCallback();
2423
2424			return this;
2425		}
2426
2427		multiply(q, p) {
2428			if (p !== undefined) {
2429				console.warn('THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.');
2430				return this.multiplyQuaternions(q, p);
2431			}
2432
2433			return this.multiplyQuaternions(this, q);
2434		}
2435
2436		premultiply(q) {
2437			return this.multiplyQuaternions(q, this);
2438		}
2439
2440		multiplyQuaternions(a, b) {
2441			// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
2442			const qax = a._x,
2443						qay = a._y,
2444						qaz = a._z,
2445						qaw = a._w;
2446			const qbx = b._x,
2447						qby = b._y,
2448						qbz = b._z,
2449						qbw = b._w;
2450			this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
2451			this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
2452			this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
2453			this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
2454
2455			this._onChangeCallback();
2456
2457			return this;
2458		}
2459
2460		slerp(qb, t) {
2461			if (t === 0) return this;
2462			if (t === 1) return this.copy(qb);
2463			const x = this._x,
2464						y = this._y,
2465						z = this._z,
2466						w = this._w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
2467
2468			let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
2469
2470			if (cosHalfTheta < 0) {
2471				this._w = -qb._w;
2472				this._x = -qb._x;
2473				this._y = -qb._y;
2474				this._z = -qb._z;
2475				cosHalfTheta = -cosHalfTheta;
2476			} else {
2477				this.copy(qb);
2478			}
2479
2480			if (cosHalfTheta >= 1.0) {
2481				this._w = w;
2482				this._x = x;
2483				this._y = y;
2484				this._z = z;
2485				return this;
2486			}
2487
2488			const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
2489
2490			if (sqrSinHalfTheta <= Number.EPSILON) {
2491				const s = 1 - t;
2492				this._w = s * w + t * this._w;
2493				this._x = s * x + t * this._x;
2494				this._y = s * y + t * this._y;
2495				this._z = s * z + t * this._z;
2496				this.normalize();
2497
2498				this._onChangeCallback();
2499
2500				return this;
2501			}
2502
2503			const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);
2504			const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);
2505			const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta,
2506						ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
2507			this._w = w * ratioA + this._w * ratioB;
2508			this._x = x * ratioA + this._x * ratioB;
2509			this._y = y * ratioA + this._y * ratioB;
2510			this._z = z * ratioA + this._z * ratioB;
2511
2512			this._onChangeCallback();
2513
2514			return this;
2515		}
2516
2517		slerpQuaternions(qa, qb, t) {
2518			this.copy(qa).slerp(qb, t);
2519		}
2520
2521		random() {
2522			// Derived from http://planning.cs.uiuc.edu/node198.html
2523			// Note, this source uses w, x, y, z ordering,
2524			// so we swap the order below.
2525			const u1 = Math.random();
2526			const sqrt1u1 = Math.sqrt(1 - u1);
2527			const sqrtu1 = Math.sqrt(u1);
2528			const u2 = 2 * Math.PI * Math.random();
2529			const u3 = 2 * Math.PI * Math.random();
2530			return this.set(sqrt1u1 * Math.cos(u2), sqrtu1 * Math.sin(u3), sqrtu1 * Math.cos(u3), sqrt1u1 * Math.sin(u2));
2531		}
2532
2533		equals(quaternion) {
2534			return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;
2535		}
2536
2537		fromArray(array, offset = 0) {
2538			this._x = array[offset];
2539			this._y = array[offset + 1];
2540			this._z = array[offset + 2];
2541			this._w = array[offset + 3];
2542
2543			this._onChangeCallback();
2544
2545			return this;
2546		}
2547
2548		toArray(array = [], offset = 0) {
2549			array[offset] = this._x;
2550			array[offset + 1] = this._y;
2551			array[offset + 2] = this._z;
2552			array[offset + 3] = this._w;
2553			return array;
2554		}
2555
2556		fromBufferAttribute(attribute, index) {
2557			this._x = attribute.getX(index);
2558			this._y = attribute.getY(index);
2559			this._z = attribute.getZ(index);
2560			this._w = attribute.getW(index);
2561			return this;
2562		}
2563
2564		_onChange(callback) {
2565			this._onChangeCallback = callback;
2566			return this;
2567		}
2568
2569		_onChangeCallback() {}
2570
2571	}
2572
2573	Quaternion.prototype.isQuaternion = true;
2574
2575	class Vector3 {
2576		constructor(x = 0, y = 0, z = 0) {
2577			this.x = x;
2578			this.y = y;
2579			this.z = z;
2580		}
2581
2582		set(x, y, z) {
2583			if (z === undefined) z = this.z; // sprite.scale.set(x,y)
2584
2585			this.x = x;
2586			this.y = y;
2587			this.z = z;
2588			return this;
2589		}
2590
2591		setScalar(scalar) {
2592			this.x = scalar;
2593			this.y = scalar;
2594			this.z = scalar;
2595			return this;
2596		}
2597
2598		setX(x) {
2599			this.x = x;
2600			return this;
2601		}
2602
2603		setY(y) {
2604			this.y = y;
2605			return this;
2606		}
2607
2608		setZ(z) {
2609			this.z = z;
2610			return this;
2611		}
2612
2613		setComponent(index, value) {
2614			switch (index) {
2615				case 0:
2616					this.x = value;
2617					break;
2618
2619				case 1:
2620					this.y = value;
2621					break;
2622
2623				case 2:
2624					this.z = value;
2625					break;
2626
2627				default:
2628					throw new Error('index is out of range: ' + index);
2629			}
2630
2631			return this;
2632		}
2633
2634		getComponent(index) {
2635			switch (index) {
2636				case 0:
2637					return this.x;
2638
2639				case 1:
2640					return this.y;
2641
2642				case 2:
2643					return this.z;
2644
2645				default:
2646					throw new Error('index is out of range: ' + index);
2647			}
2648		}
2649
2650		clone() {
2651			return new this.constructor(this.x, this.y, this.z);
2652		}
2653
2654		copy(v) {
2655			this.x = v.x;
2656			this.y = v.y;
2657			this.z = v.z;
2658			return this;
2659		}
2660
2661		add(v, w) {
2662			if (w !== undefined) {
2663				console.warn('THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.');
2664				return this.addVectors(v, w);
2665			}
2666
2667			this.x += v.x;
2668			this.y += v.y;
2669			this.z += v.z;
2670			return this;
2671		}
2672
2673		addScalar(s) {
2674			this.x += s;
2675			this.y += s;
2676			this.z += s;
2677			return this;
2678		}
2679
2680		addVectors(a, b) {
2681			this.x = a.x + b.x;
2682			this.y = a.y + b.y;
2683			this.z = a.z + b.z;
2684			return this;
2685		}
2686
2687		addScaledVector(v, s) {
2688			this.x += v.x * s;
2689			this.y += v.y * s;
2690			this.z += v.z * s;
2691			return this;
2692		}
2693
2694		sub(v, w) {
2695			if (w !== undefined) {
2696				console.warn('THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.');
2697				return this.subVectors(v, w);
2698			}
2699
2700			this.x -= v.x;
2701			this.y -= v.y;
2702			this.z -= v.z;
2703			return this;
2704		}
2705
2706		subScalar(s) {
2707			this.x -= s;
2708			this.y -= s;
2709			this.z -= s;
2710			return this;
2711		}
2712
2713		subVectors(a, b) {
2714			this.x = a.x - b.x;
2715			this.y = a.y - b.y;
2716			this.z = a.z - b.z;
2717			return this;
2718		}
2719
2720		multiply(v, w) {
2721			if (w !== undefined) {
2722				console.warn('THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.');
2723				return this.multiplyVectors(v, w);
2724			}
2725
2726			this.x *= v.x;
2727			this.y *= v.y;
2728			this.z *= v.z;
2729			return this;
2730		}
2731
2732		multiplyScalar(scalar) {
2733			this.x *= scalar;
2734			this.y *= scalar;
2735			this.z *= scalar;
2736			return this;
2737		}
2738
2739		multiplyVectors(a, b) {
2740			this.x = a.x * b.x;
2741			this.y = a.y * b.y;
2742			this.z = a.z * b.z;
2743			return this;
2744		}
2745
2746		applyEuler(euler) {
2747			if (!(euler && euler.isEuler)) {
2748				console.error('THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.');
2749			}
2750
2751			return this.applyQuaternion(_quaternion$4.setFromEuler(euler));
2752		}
2753
2754		applyAxisAngle(axis, angle) {
2755			return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle));
2756		}
2757
2758		applyMatrix3(m) {
2759			const x = this.x,
2760						y = this.y,
2761						z = this.z;
2762			const e = m.elements;
2763			this.x = e[0] * x + e[3] * y + e[6] * z;
2764			this.y = e[1] * x + e[4] * y + e[7] * z;
2765			this.z = e[2] * x + e[5] * y + e[8] * z;
2766			return this;
2767		}
2768
2769		applyNormalMatrix(m) {
2770			return this.applyMatrix3(m).normalize();
2771		}
2772
2773		applyMatrix4(m) {
2774			const x = this.x,
2775						y = this.y,
2776						z = this.z;
2777			const e = m.elements;
2778			const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]);
2779			this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w;
2780			this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w;
2781			this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w;
2782			return this;
2783		}
2784
2785		applyQuaternion(q) {
2786			const x = this.x,
2787						y = this.y,
2788						z = this.z;
2789			const qx = q.x,
2790						qy = q.y,
2791						qz = q.z,
2792						qw = q.w; // calculate quat * vector
2793
2794			const ix = qw * x + qy * z - qz * y;
2795			const iy = qw * y + qz * x - qx * z;
2796			const iz = qw * z + qx * y - qy * x;
2797			const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat
2798
2799			this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
2800			this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
2801			this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
2802			return this;
2803		}
2804
2805		project(camera) {
2806			return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);
2807		}
2808
2809		unproject(camera) {
2810			return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);
2811		}
2812
2813		transformDirection(m) {
2814			// input: THREE.Matrix4 affine matrix
2815			// vector interpreted as a direction
2816			const x = this.x,
2817						y = this.y,
2818						z = this.z;
2819			const e = m.elements;
2820			this.x = e[0] * x + e[4] * y + e[8] * z;
2821			this.y = e[1] * x + e[5] * y + e[9] * z;
2822			this.z = e[2] * x + e[6] * y + e[10] * z;
2823			return this.normalize();
2824		}
2825
2826		divide(v) {
2827			this.x /= v.x;
2828			this.y /= v.y;
2829			this.z /= v.z;
2830			return this;
2831		}
2832
2833		divideScalar(scalar) {
2834			return this.multiplyScalar(1 / scalar);
2835		}
2836
2837		min(v) {
2838			this.x = Math.min(this.x, v.x);
2839			this.y = Math.min(this.y, v.y);
2840			this.z = Math.min(this.z, v.z);
2841			return this;
2842		}
2843
2844		max(v) {
2845			this.x = Math.max(this.x, v.x);
2846			this.y = Math.max(this.y, v.y);
2847			this.z = Math.max(this.z, v.z);
2848			return this;
2849		}
2850
2851		clamp(min, max) {
2852			// assumes min < max, componentwise
2853			this.x = Math.max(min.x, Math.min(max.x, this.x));
2854			this.y = Math.max(min.y, Math.min(max.y, this.y));
2855			this.z = Math.max(min.z, Math.min(max.z, this.z));
2856			return this;
2857		}
2858
2859		clampScalar(minVal, maxVal) {
2860			this.x = Math.max(minVal, Math.min(maxVal, this.x));
2861			this.y = Math.max(minVal, Math.min(maxVal, this.y));
2862			this.z = Math.max(minVal, Math.min(maxVal, this.z));
2863			return this;
2864		}
2865
2866		clampLength(min, max) {
2867			const length = this.length();
2868			return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
2869		}
2870
2871		floor() {
2872			this.x = Math.floor(this.x);
2873			this.y = Math.floor(this.y);
2874			this.z = Math.floor(this.z);
2875			return this;
2876		}
2877
2878		ceil() {
2879			this.x = Math.ceil(this.x);
2880			this.y = Math.ceil(this.y);
2881			this.z = Math.ceil(this.z);
2882			return this;
2883		}
2884
2885		round() {
2886			this.x = Math.round(this.x);
2887			this.y = Math.round(this.y);
2888			this.z = Math.round(this.z);
2889			return this;
2890		}
2891
2892		roundToZero() {
2893			this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
2894			this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
2895			this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z);
2896			return this;
2897		}
2898
2899		negate() {
2900			this.x = -this.x;
2901			this.y = -this.y;
2902			this.z = -this.z;
2903			return this;
2904		}
2905
2906		dot(v) {
2907			return this.x * v.x + this.y * v.y + this.z * v.z;
2908		} // TODO lengthSquared?
2909
2910
2911		lengthSq() {
2912			return this.x * this.x + this.y * this.y + this.z * this.z;
2913		}
2914
2915		length() {
2916			return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
2917		}
2918
2919		manhattanLength() {
2920			return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
2921		}
2922
2923		normalize() {
2924			return this.divideScalar(this.length() || 1);
2925		}
2926
2927		setLength(length) {
2928			return this.normalize().multiplyScalar(length);
2929		}
2930
2931		lerp(v, alpha) {
2932			this.x += (v.x - this.x) * alpha;
2933			this.y += (v.y - this.y) * alpha;
2934			this.z += (v.z - this.z) * alpha;
2935			return this;
2936		}
2937
2938		lerpVectors(v1, v2, alpha) {
2939			this.x = v1.x + (v2.x - v1.x) * alpha;
2940			this.y = v1.y + (v2.y - v1.y) * alpha;
2941			this.z = v1.z + (v2.z - v1.z) * alpha;
2942			return this;
2943		}
2944
2945		cross(v, w) {
2946			if (w !== undefined) {
2947				console.warn('THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.');
2948				return this.crossVectors(v, w);
2949			}
2950
2951			return this.crossVectors(this, v);
2952		}
2953
2954		crossVectors(a, b) {
2955			const ax = a.x,
2956						ay = a.y,
2957						az = a.z;
2958			const bx = b.x,
2959						by = b.y,
2960						bz = b.z;
2961			this.x = ay * bz - az * by;
2962			this.y = az * bx - ax * bz;
2963			this.z = ax * by - ay * bx;
2964			return this;
2965		}
2966
2967		projectOnVector(v) {
2968			const denominator = v.lengthSq();
2969			if (denominator === 0) return this.set(0, 0, 0);
2970			const scalar = v.dot(this) / denominator;
2971			return this.copy(v).multiplyScalar(scalar);
2972		}
2973
2974		projectOnPlane(planeNormal) {
2975			_vector$c.copy(this).projectOnVector(planeNormal);
2976
2977			return this.sub(_vector$c);
2978		}
2979
2980		reflect(normal) {
2981			// reflect incident vector off plane orthogonal to normal
2982			// normal is assumed to have unit length
2983			return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal)));
2984		}
2985
2986		angleTo(v) {
2987			const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
2988			if (denominator === 0) return Math.PI / 2;
2989			const theta = this.dot(v) / denominator; // clamp, to handle numerical problems
2990
2991			return Math.acos(clamp(theta, -1, 1));
2992		}
2993
2994		distanceTo(v) {
2995			return Math.sqrt(this.distanceToSquared(v));
2996		}
2997
2998		distanceToSquared(v) {
2999			const dx = this.x - v.x,
3000						dy = this.y - v.y,
3001						dz = this.z - v.z;
3002			return dx * dx + dy * dy + dz * dz;
3003		}
3004
3005		manhattanDistanceTo(v) {
3006			return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z);
3007		}
3008
3009		setFromSpherical(s) {
3010			return this.setFromSphericalCoords(s.radius, s.phi, s.theta);
3011		}
3012
3013		setFromSphericalCoords(radius, phi, theta) {
3014			const sinPhiRadius = Math.sin(phi) * radius;
3015			this.x = sinPhiRadius * Math.sin(theta);
3016			this.y = Math.cos(phi) * radius;
3017			this.z = sinPhiRadius * Math.cos(theta);
3018			return this;
3019		}
3020
3021		setFromCylindrical(c) {
3022			return this.setFromCylindricalCoords(c.radius, c.theta, c.y);
3023		}
3024
3025		setFromCylindricalCoords(radius, theta, y) {
3026			this.x = radius * Math.sin(theta);
3027			this.y = y;
3028			this.z = radius * Math.cos(theta);
3029			return this;
3030		}
3031
3032		setFromMatrixPosition(m) {
3033			const e = m.elements;
3034			this.x = e[12];
3035			this.y = e[13];
3036			this.z = e[14];
3037			return this;
3038		}
3039
3040		setFromMatrixScale(m) {
3041			const sx = this.setFromMatrixColumn(m, 0).length();
3042			const sy = this.setFromMatrixColumn(m, 1).length();
3043			const sz = this.setFromMatrixColumn(m, 2).length();
3044			this.x = sx;
3045			this.y = sy;
3046			this.z = sz;
3047			return this;
3048		}
3049
3050		setFromMatrixColumn(m, index) {
3051			return this.fromArray(m.elements, index * 4);
3052		}
3053
3054		setFromMatrix3Column(m, index) {
3055			return this.fromArray(m.elements, index * 3);
3056		}
3057
3058		equals(v) {
3059			return v.x === this.x && v.y === this.y && v.z === this.z;
3060		}
3061
3062		fromArray(array, offset = 0) {
3063			this.x = array[offset];
3064			this.y = array[offset + 1];
3065			this.z = array[offset + 2];
3066			return this;
3067		}
3068
3069		toArray(array = [], offset = 0) {
3070			array[offset] = this.x;
3071			array[offset + 1] = this.y;
3072			array[offset + 2] = this.z;
3073			return array;
3074		}
3075
3076		fromBufferAttribute(attribute, index, offset) {
3077			if (offset !== undefined) {
3078				console.warn('THREE.Vector3: offset has been removed from .fromBufferAttribute().');
3079			}
3080
3081			this.x = attribute.getX(index);
3082			this.y = attribute.getY(index);
3083			this.z = attribute.getZ(index);
3084			return this;
3085		}
3086
3087		random() {
3088			this.x = Math.random();
3089			this.y = Math.random();
3090			this.z = Math.random();
3091			return this;
3092		}
3093
3094		randomDirection() {
3095			// Derived from https://mathworld.wolfram.com/SpherePointPicking.html
3096			const u = (Math.random() - 0.5) * 2;
3097			const t = Math.random() * Math.PI * 2;
3098			const f = Math.sqrt(1 - u ** 2);
3099			this.x = f * Math.cos(t);
3100			this.y = f * Math.sin(t);
3101			this.z = u;
3102			return this;
3103		}
3104
3105		*[Symbol.iterator]() {
3106			yield this.x;
3107			yield this.y;
3108			yield this.z;
3109		}
3110
3111	}
3112
3113	Vector3.prototype.isVector3 = true;
3114
3115	const _vector$c = /*@__PURE__*/new Vector3();
3116
3117	const _quaternion$4 = /*@__PURE__*/new Quaternion();
3118
3119	class Box3 {
3120		constructor(min = new Vector3(+Infinity, +Infinity, +Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) {
3121			this.min = min;
3122			this.max = max;
3123		}
3124
3125		set(min, max) {
3126			this.min.copy(min);
3127			this.max.copy(max);
3128			return this;
3129		}
3130
3131		setFromArray(array) {
3132			let minX = +Infinity;
3133			let minY = +Infinity;
3134			let minZ = +Infinity;
3135			let maxX = -Infinity;
3136			let maxY = -Infinity;
3137			let maxZ = -Infinity;
3138
3139			for (let i = 0, l = array.length; i < l; i += 3) {
3140				const x = array[i];
3141				const y = array[i + 1];
3142				const z = array[i + 2];
3143				if (x < minX) minX = x;
3144				if (y < minY) minY = y;
3145				if (z < minZ) minZ = z;
3146				if (x > maxX) maxX = x;
3147				if (y > maxY) maxY = y;
3148				if (z > maxZ) maxZ = z;
3149			}
3150
3151			this.min.set(minX, minY, minZ);
3152			this.max.set(maxX, maxY, maxZ);
3153			return this;
3154		}
3155
3156		setFromBufferAttribute(attribute) {
3157			let minX = +Infinity;
3158			let minY = +Infinity;
3159			let minZ = +Infinity;
3160			let maxX = -Infinity;
3161			let maxY = -Infinity;
3162			let maxZ = -Infinity;
3163
3164			for (let i = 0, l = attribute.count; i < l; i++) {
3165				const x = attribute.getX(i);
3166				const y = attribute.getY(i);
3167				const z = attribute.getZ(i);
3168				if (x < minX) minX = x;
3169				if (y < minY) minY = y;
3170				if (z < minZ) minZ = z;
3171				if (x > maxX) maxX = x;
3172				if (y > maxY) maxY = y;
3173				if (z > maxZ) maxZ = z;
3174			}
3175
3176			this.min.set(minX, minY, minZ);
3177			this.max.set(maxX, maxY, maxZ);
3178			return this;
3179		}
3180
3181		setFromPoints(points) {
3182			this.makeEmpty();
3183
3184			for (let i = 0, il = points.length; i < il; i++) {
3185				this.expandByPoint(points[i]);
3186			}
3187
3188			return this;
3189		}
3190
3191		setFromCenterAndSize(center, size) {
3192			const halfSize = _vector$b.copy(size).multiplyScalar(0.5);
3193
3194			this.min.copy(center).sub(halfSize);
3195			this.max.copy(center).add(halfSize);
3196			return this;
3197		}
3198
3199		setFromObject(object) {
3200			this.makeEmpty();
3201			return this.expandByObject(object);
3202		}
3203
3204		clone() {
3205			return new this.constructor().copy(this);
3206		}
3207
3208		copy(box) {
3209			this.min.copy(box.min);
3210			this.max.copy(box.max);
3211			return this;
3212		}
3213
3214		makeEmpty() {
3215			this.min.x = this.min.y = this.min.z = +Infinity;
3216			this.max.x = this.max.y = this.max.z = -Infinity;
3217			return this;
3218		}
3219
3220		isEmpty() {
3221			// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
3222			return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;
3223		}
3224
3225		getCenter(target) {
3226			return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);
3227		}
3228
3229		getSize(target) {
3230			return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min);
3231		}
3232
3233		expandByPoint(point) {
3234			this.min.min(point);
3235			this.max.max(point);
3236			return this;
3237		}
3238
3239		expandByVector(vector) {
3240			this.min.sub(vector);
3241			this.max.add(vector);
3242			return this;
3243		}
3244
3245		expandByScalar(scalar) {
3246			this.min.addScalar(-scalar);
3247			this.max.addScalar(scalar);
3248			return this;
3249		}
3250
3251		expandByObject(object) {
3252			// Computes the world-axis-aligned bounding box of an object (including its children),
3253			// accounting for both the object's, and children's, world transforms
3254			object.updateWorldMatrix(false, false);
3255			const geometry = object.geometry;
3256
3257			if (geometry !== undefined) {
3258				if (geometry.boundingBox === null) {
3259					geometry.computeBoundingBox();
3260				}
3261
3262				_box$3.copy(geometry.boundingBox);
3263
3264				_box$3.applyMatrix4(object.matrixWorld);
3265
3266				this.union(_box$3);
3267			}
3268
3269			const children = object.children;
3270
3271			for (let i = 0, l = children.length; i < l; i++) {
3272				this.expandByObject(children[i]);
3273			}
3274
3275			return this;
3276		}
3277
3278		containsPoint(point) {
3279			return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y || point.z < this.min.z || point.z > this.max.z ? false : true;
3280		}
3281
3282		containsBox(box) {
3283			return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z;
3284		}
3285
3286		getParameter(point, target) {
3287			// This can potentially have a divide by zero if the box
3288			// has a size dimension of 0.
3289			return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y), (point.z - this.min.z) / (this.max.z - this.min.z));
3290		}
3291
3292		intersectsBox(box) {
3293			// using 6 splitting planes to rule out intersections.
3294			return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y || box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
3295		}
3296
3297		intersectsSphere(sphere) {
3298			// Find the point on the AABB closest to the sphere center.
3299			this.clampPoint(sphere.center, _vector$b); // If that point is inside the sphere, the AABB and sphere intersect.
3300
3301			return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;
3302		}
3303
3304		intersectsPlane(plane) {
3305			// We compute the minimum and maximum dot product values. If those values
3306			// are on the same side (back or front) of the plane, then there is no intersection.
3307			let min, max;
3308
3309			if (plane.normal.x > 0) {
3310				min = plane.normal.x * this.min.x;
3311				max = plane.normal.x * this.max.x;
3312			} else {
3313				min = plane.normal.x * this.max.x;
3314				max = plane.normal.x * this.min.x;
3315			}
3316
3317			if (plane.normal.y > 0) {
3318				min += plane.normal.y * this.min.y;
3319				max += plane.normal.y * this.max.y;
3320			} else {
3321				min += plane.normal.y * this.max.y;
3322				max += plane.normal.y * this.min.y;
3323			}
3324
3325			if (plane.normal.z > 0) {
3326				min += plane.normal.z * this.min.z;
3327				max += plane.normal.z * this.max.z;
3328			} else {
3329				min += plane.normal.z * this.max.z;
3330				max += plane.normal.z * this.min.z;
3331			}
3332
3333			return min <= -plane.constant && max >= -plane.constant;
3334		}
3335
3336		intersectsTriangle(triangle) {
3337			if (this.isEmpty()) {
3338				return false;
3339			} // compute box center and extents
3340
3341
3342			this.getCenter(_center);
3343
3344			_extents.subVectors(this.max, _center); // translate triangle to aabb origin
3345
3346
3347			_v0$2.subVectors(triangle.a, _center);
3348
3349			_v1$7.subVectors(triangle.b, _center);
3350
3351			_v2$3.subVectors(triangle.c, _center); // compute edge vectors for triangle
3352
3353
3354			_f0.subVectors(_v1$7, _v0$2);
3355
3356			_f1.subVectors(_v2$3, _v1$7);
3357
3358			_f2.subVectors(_v0$2, _v2$3); // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb
3359			// 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
3360			// axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned)
3361
3362
3363			let axes = [0, -_f0.z, _f0.y, 0, -_f1.z, _f1.y, 0, -_f2.z, _f2.y, _f0.z, 0, -_f0.x, _f1.z, 0, -_f1.x, _f2.z, 0, -_f2.x, -_f0.y, _f0.x, 0, -_f1.y, _f1.x, 0, -_f2.y, _f2.x, 0];
3364
3365			if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) {
3366				return false;
vendor: 4,321 bytes, lines 3367-3518
3367			} // test 3 face normals from the aabb
3368
3369
3370			axes = [1, 0, 0, 0, 1, 0, 0, 0, 1];
3371
3372			if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) {
3373				return false;
3374			} // finally testing the face normal of the triangle
3375			// use already existing triangle edge vectors here
3376
3377
3378			_triangleNormal.crossVectors(_f0, _f1);
3379
3380			axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z];
3381			return satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents);
3382		}
3383
3384		clampPoint(point, target) {
3385			return target.copy(point).clamp(this.min, this.max);
3386		}
3387
3388		distanceToPoint(point) {
3389			const clampedPoint = _vector$b.copy(point).clamp(this.min, this.max);
3390
3391			return clampedPoint.sub(point).length();
3392		}
3393
3394		getBoundingSphere(target) {
3395			this.getCenter(target.center);
3396			target.radius = this.getSize(_vector$b).length() * 0.5;
3397			return target;
3398		}
3399
3400		intersect(box) {
3401			this.min.max(box.min);
3402			this.max.min(box.max); // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.
3403
3404			if (this.isEmpty()) this.makeEmpty();
3405			return this;
3406		}
3407
3408		union(box) {
3409			this.min.min(box.min);
3410			this.max.max(box.max);
3411			return this;
3412		}
3413
3414		applyMatrix4(matrix) {
3415			// transform of empty box is an empty box.
3416			if (this.isEmpty()) return this; // NOTE: I am using a binary pattern to specify all 2^3 combinations below
3417
3418			_points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000
3419
3420
3421			_points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001
3422
3423
3424			_points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010
3425
3426
3427			_points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011
3428
3429
3430			_points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100
3431
3432
3433			_points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101
3434
3435
3436			_points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110
3437
3438
3439			_points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111
3440
3441
3442			this.setFromPoints(_points);
3443			return this;
3444		}
3445
3446		translate(offset) {
3447			this.min.add(offset);
3448			this.max.add(offset);
3449			return this;
3450		}
3451
3452		equals(box) {
3453			return box.min.equals(this.min) && box.max.equals(this.max);
3454		}
3455
3456	}
3457
3458	Box3.prototype.isBox3 = true;
3459	const _points = [/*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3()];
3460
3461	const _vector$b = /*@__PURE__*/new Vector3();
3462
3463	const _box$3 = /*@__PURE__*/new Box3(); // triangle centered vertices
3464
3465
3466	const _v0$2 = /*@__PURE__*/new Vector3();
3467
3468	const _v1$7 = /*@__PURE__*/new Vector3();
3469
3470	const _v2$3 = /*@__PURE__*/new Vector3(); // triangle edge vectors
3471
3472
3473	const _f0 = /*@__PURE__*/new Vector3();
3474
3475	const _f1 = /*@__PURE__*/new Vector3();
3476
3477	const _f2 = /*@__PURE__*/new Vector3();
3478
3479	const _center = /*@__PURE__*/new Vector3();
3480
3481	const _extents = /*@__PURE__*/new Vector3();
3482
3483	const _triangleNormal = /*@__PURE__*/new Vector3();
3484
3485	const _testAxis = /*@__PURE__*/new Vector3();
3486
3487	function satForAxes(axes, v0, v1, v2, extents) {
3488		for (let i = 0, j = axes.length - 3; i <= j; i += 3) {
3489			_testAxis.fromArray(axes, i); // project the aabb onto the seperating axis
3490
3491
3492			const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z); // project all 3 vertices of the triangle onto the seperating axis
3493
3494			const p0 = v0.dot(_testAxis);
3495			const p1 = v1.dot(_testAxis);
3496			const p2 = v2.dot(_testAxis); // actual test, basically see if either of the most extreme of the triangle points intersects r
3497
3498			if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) {
3499				// points of the projected triangle are outside the projected half-length of the aabb
3500				// the axis is seperating and we can exit
3501				return false;
3502			}
3503		}
3504
3505		return true;
3506	}
3507
3508	const _box$2 = /*@__PURE__*/new Box3();
3509
3510	const _v1$6 = /*@__PURE__*/new Vector3();
3511
3512	const _toFarthestPoint = /*@__PURE__*/new Vector3();
3513
3514	const _toPoint = /*@__PURE__*/new Vector3();
3515
3516	class Sphere {
3517		constructor(center = new Vector3(), radius = -1) {
3518			this.center = center;
vendor: 4,848 bytes, lines 3519-3711
3519			this.radius = radius;
3520		}
3521
3522		set(center, radius) {
3523			this.center.copy(center);
3524			this.radius = radius;
3525			return this;
3526		}
3527
3528		setFromPoints(points, optionalCenter) {
3529			const center = this.center;
3530
3531			if (optionalCenter !== undefined) {
3532				center.copy(optionalCenter);
3533			} else {
3534				_box$2.setFromPoints(points).getCenter(center);
3535			}
3536
3537			let maxRadiusSq = 0;
3538
3539			for (let i = 0, il = points.length; i < il; i++) {
3540				maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i]));
3541			}
3542
3543			this.radius = Math.sqrt(maxRadiusSq);
3544			return this;
3545		}
3546
3547		copy(sphere) {
3548			this.center.copy(sphere.center);
3549			this.radius = sphere.radius;
3550			return this;
3551		}
3552
3553		isEmpty() {
3554			return this.radius < 0;
3555		}
3556
3557		makeEmpty() {
3558			this.center.set(0, 0, 0);
3559			this.radius = -1;
3560			return this;
3561		}
3562
3563		containsPoint(point) {
3564			return point.distanceToSquared(this.center) <= this.radius * this.radius;
3565		}
3566
3567		distanceToPoint(point) {
3568			return point.distanceTo(this.center) - this.radius;
3569		}
3570
3571		intersectsSphere(sphere) {
3572			const radiusSum = this.radius + sphere.radius;
3573			return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum;
3574		}
3575
3576		intersectsBox(box) {
3577			return box.intersectsSphere(this);
3578		}
3579
3580		intersectsPlane(plane) {
3581			return Math.abs(plane.distanceToPoint(this.center)) <= this.radius;
3582		}
3583
3584		clampPoint(point, target) {
3585			const deltaLengthSq = this.center.distanceToSquared(point);
3586			target.copy(point);
3587
3588			if (deltaLengthSq > this.radius * this.radius) {
3589				target.sub(this.center).normalize();
3590				target.multiplyScalar(this.radius).add(this.center);
3591			}
3592
3593			return target;
3594		}
3595
3596		getBoundingBox(target) {
3597			if (this.isEmpty()) {
3598				// Empty sphere produces empty bounding box
3599				target.makeEmpty();
3600				return target;
3601			}
3602
3603			target.set(this.center, this.center);
3604			target.expandByScalar(this.radius);
3605			return target;
3606		}
3607
3608		applyMatrix4(matrix) {
3609			this.center.applyMatrix4(matrix);
3610			this.radius = this.radius * matrix.getMaxScaleOnAxis();
3611			return this;
3612		}
3613
3614		translate(offset) {
3615			this.center.add(offset);
3616			return this;
3617		}
3618
3619		expandByPoint(point) {
3620			// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671
3621			_toPoint.subVectors(point, this.center);
3622
3623			const lengthSq = _toPoint.lengthSq();
3624
3625			if (lengthSq > this.radius * this.radius) {
3626				const length = Math.sqrt(lengthSq);
3627				const missingRadiusHalf = (length - this.radius) * 0.5; // Nudge this sphere towards the target point. Add half the missing distance to radius,
3628				// and the other half to position. This gives a tighter enclosure, instead of if
3629				// the whole missing distance were just added to radius.
3630
3631				this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length));
3632				this.radius += missingRadiusHalf;
3633			}
3634
3635			return this;
3636		}
3637
3638		union(sphere) {
3639			// from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769
3640			// To enclose another sphere into this sphere, we only need to enclose two points:
3641			// 1) Enclose the farthest point on the other sphere into this sphere.
3642			// 2) Enclose the opposite point of the farthest point into this sphere.
3643			if (this.center.equals(sphere.center) === true) {
3644				_toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius);
3645			} else {
3646				_toFarthestPoint.subVectors(sphere.center, this.center).normalize().multiplyScalar(sphere.radius);
3647			}
3648
3649			this.expandByPoint(_v1$6.copy(sphere.center).add(_toFarthestPoint));
3650			this.expandByPoint(_v1$6.copy(sphere.center).sub(_toFarthestPoint));
3651			return this;
3652		}
3653
3654		equals(sphere) {
3655			return sphere.center.equals(this.center) && sphere.radius === this.radius;
3656		}
3657
3658		clone() {
3659			return new this.constructor().copy(this);
3660		}
3661
3662	}
3663
3664	const _vector$a = /*@__PURE__*/new Vector3();
3665
3666	const _segCenter = /*@__PURE__*/new Vector3();
3667
3668	const _segDir = /*@__PURE__*/new Vector3();
3669
3670	const _diff = /*@__PURE__*/new Vector3();
3671
3672	const _edge1 = /*@__PURE__*/new Vector3();
3673
3674	const _edge2 = /*@__PURE__*/new Vector3();
3675
3676	const _normal$1 = /*@__PURE__*/new Vector3();
3677
3678	class Ray {
3679		constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) {
3680			this.origin = origin;
3681			this.direction = direction;
3682		}
3683
3684		set(origin, direction) {
3685			this.origin.copy(origin);
3686			this.direction.copy(direction);
3687			return this;
3688		}
3689
3690		copy(ray) {
3691			this.origin.copy(ray.origin);
3692			this.direction.copy(ray.direction);
3693			return this;
3694		}
3695
3696		at(t, target) {
3697			return target.copy(this.direction).multiplyScalar(t).add(this.origin);
3698		}
3699
3700		lookAt(v) {
3701			this.direction.copy(v).sub(this.origin).normalize();
3702			return this;
3703		}
3704
3705		recast(t) {
3706			this.origin.copy(this.at(t, _vector$a));
3707			return this;
3708		}
3709
3710		closestPointToPoint(point, target) {
3711			target.subVectors(point, this.origin);
vendor: 28,216 bytes, lines 3712-4812
3712			const directionDistance = target.dot(this.direction);
3713
3714			if (directionDistance < 0) {
3715				return target.copy(this.origin);
3716			}
3717
3718			return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin);
3719		}
3720
3721		distanceToPoint(point) {
3722			return Math.sqrt(this.distanceSqToPoint(point));
3723		}
3724
3725		distanceSqToPoint(point) {
3726			const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); // point behind the ray
3727
3728
3729			if (directionDistance < 0) {
3730				return this.origin.distanceToSquared(point);
3731			}
3732
3733			_vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin);
3734
3735			return _vector$a.distanceToSquared(point);
3736		}
3737
3738		distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) {
3739			// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h
3740			// It returns the min distance between the ray and the segment
3741			// defined by v0 and v1
3742			// It can also set two optional targets :
3743			// - The closest point on the ray
3744			// - The closest point on the segment
3745			_segCenter.copy(v0).add(v1).multiplyScalar(0.5);
3746
3747			_segDir.copy(v1).sub(v0).normalize();
3748
3749			_diff.copy(this.origin).sub(_segCenter);
3750
3751			const segExtent = v0.distanceTo(v1) * 0.5;
3752			const a01 = -this.direction.dot(_segDir);
3753
3754			const b0 = _diff.dot(this.direction);
3755
3756			const b1 = -_diff.dot(_segDir);
3757
3758			const c = _diff.lengthSq();
3759
3760			const det = Math.abs(1 - a01 * a01);
3761			let s0, s1, sqrDist, extDet;
3762
3763			if (det > 0) {
3764				// The ray and segment are not parallel.
3765				s0 = a01 * b1 - b0;
3766				s1 = a01 * b0 - b1;
3767				extDet = segExtent * det;
3768
3769				if (s0 >= 0) {
3770					if (s1 >= -extDet) {
3771						if (s1 <= extDet) {
3772							// region 0
3773							// Minimum at interior points of ray and segment.
3774							const invDet = 1 / det;
3775							s0 *= invDet;
3776							s1 *= invDet;
3777							sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c;
3778						} else {
3779							// region 1
3780							s1 = segExtent;
3781							s0 = Math.max(0, -(a01 * s1 + b0));
3782							sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
3783						}
3784					} else {
3785						// region 5
3786						s1 = -segExtent;
3787						s0 = Math.max(0, -(a01 * s1 + b0));
3788						sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
3789					}
3790				} else {
3791					if (s1 <= -extDet) {
3792						// region 4
3793						s0 = Math.max(0, -(-a01 * segExtent + b0));
3794						s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
3795						sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
3796					} else if (s1 <= extDet) {
3797						// region 3
3798						s0 = 0;
3799						s1 = Math.min(Math.max(-segExtent, -b1), segExtent);
3800						sqrDist = s1 * (s1 + 2 * b1) + c;
3801					} else {
3802						// region 2
3803						s0 = Math.max(0, -(a01 * segExtent + b0));
3804						s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
3805						sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
3806					}
3807				}
3808			} else {
3809				// Ray and segment are parallel.
3810				s1 = a01 > 0 ? -segExtent : segExtent;
3811				s0 = Math.max(0, -(a01 * s1 + b0));
3812				sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
3813			}
3814
3815			if (optionalPointOnRay) {
3816				optionalPointOnRay.copy(this.direction).multiplyScalar(s0).add(this.origin);
3817			}
3818
3819			if (optionalPointOnSegment) {
3820				optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter);
3821			}
3822
3823			return sqrDist;
3824		}
3825
3826		intersectSphere(sphere, target) {
3827			_vector$a.subVectors(sphere.center, this.origin);
3828
3829			const tca = _vector$a.dot(this.direction);
3830
3831			const d2 = _vector$a.dot(_vector$a) - tca * tca;
3832			const radius2 = sphere.radius * sphere.radius;
3833			if (d2 > radius2) return null;
3834			const thc = Math.sqrt(radius2 - d2); // t0 = first intersect point - entrance on front of sphere
3835
3836			const t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere
3837
3838			const t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null
3839
3840			if (t0 < 0 && t1 < 0) return null; // test to see if t0 is behind the ray:
3841			// if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
3842			// in order to always return an intersect point that is in front of the ray.
3843
3844			if (t0 < 0) return this.at(t1, target); // else t0 is in front of the ray, so return the first collision point scaled by t0
3845
3846			return this.at(t0, target);
3847		}
3848
3849		intersectsSphere(sphere) {
3850			return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius;
3851		}
3852
3853		distanceToPlane(plane) {
3854			const denominator = plane.normal.dot(this.direction);
3855
3856			if (denominator === 0) {
3857				// line is coplanar, return origin
3858				if (plane.distanceToPoint(this.origin) === 0) {
3859					return 0;
3860				} // Null is preferable to undefined since undefined means.... it is undefined
3861
3862
3863				return null;
3864			}
3865
3866			const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; // Return if the ray never intersects the plane
3867
3868			return t >= 0 ? t : null;
3869		}
3870
3871		intersectPlane(plane, target) {
3872			const t = this.distanceToPlane(plane);
3873
3874			if (t === null) {
3875				return null;
3876			}
3877
3878			return this.at(t, target);
3879		}
3880
3881		intersectsPlane(plane) {
3882			// check if the ray lies on the plane first
3883			const distToPoint = plane.distanceToPoint(this.origin);
3884
3885			if (distToPoint === 0) {
3886				return true;
3887			}
3888
3889			const denominator = plane.normal.dot(this.direction);
3890
3891			if (denominator * distToPoint < 0) {
3892				return true;
3893			} // ray origin is behind the plane (and is pointing behind it)
3894
3895
3896			return false;
3897		}
3898
3899		intersectBox(box, target) {
3900			let tmin, tmax, tymin, tymax, tzmin, tzmax;
3901			const invdirx = 1 / this.direction.x,
3902						invdiry = 1 / this.direction.y,
3903						invdirz = 1 / this.direction.z;
3904			const origin = this.origin;
3905
3906			if (invdirx >= 0) {
3907				tmin = (box.min.x - origin.x) * invdirx;
3908				tmax = (box.max.x - origin.x) * invdirx;
3909			} else {
3910				tmin = (box.max.x - origin.x) * invdirx;
3911				tmax = (box.min.x - origin.x) * invdirx;
3912			}
3913
3914			if (invdiry >= 0) {
3915				tymin = (box.min.y - origin.y) * invdiry;
3916				tymax = (box.max.y - origin.y) * invdiry;
3917			} else {
3918				tymin = (box.max.y - origin.y) * invdiry;
3919				tymax = (box.min.y - origin.y) * invdiry;
3920			}
3921
3922			if (tmin > tymax || tymin > tmax) return null; // These lines also handle the case where tmin or tmax is NaN
3923			// (result of 0 * Infinity). x !== x returns true if x is NaN
3924
3925			if (tymin > tmin || tmin !== tmin) tmin = tymin;
3926			if (tymax < tmax || tmax !== tmax) tmax = tymax;
3927
3928			if (invdirz >= 0) {
3929				tzmin = (box.min.z - origin.z) * invdirz;
3930				tzmax = (box.max.z - origin.z) * invdirz;
3931			} else {
3932				tzmin = (box.max.z - origin.z) * invdirz;
3933				tzmax = (box.min.z - origin.z) * invdirz;
3934			}
3935
3936			if (tmin > tzmax || tzmin > tmax) return null;
3937			if (tzmin > tmin || tmin !== tmin) tmin = tzmin;
3938			if (tzmax < tmax || tmax !== tmax) tmax = tzmax; //return point closest to the ray (positive side)
3939
3940			if (tmax < 0) return null;
3941			return this.at(tmin >= 0 ? tmin : tmax, target);
3942		}
3943
3944		intersectsBox(box) {
3945			return this.intersectBox(box, _vector$a) !== null;
3946		}
3947
3948		intersectTriangle(a, b, c, backfaceCulling, target) {
3949			// Compute the offset origin, edges, and normal.
3950			// from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
3951			_edge1.subVectors(b, a);
3952
3953			_edge2.subVectors(c, a);
3954
3955			_normal$1.crossVectors(_edge1, _edge2); // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
3956			// E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
3957			//	 |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
3958			//	 |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
3959			//	 |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
3960
3961
3962			let DdN = this.direction.dot(_normal$1);
3963			let sign;
3964
3965			if (DdN > 0) {
3966				if (backfaceCulling) return null;
3967				sign = 1;
3968			} else if (DdN < 0) {
3969				sign = -1;
3970				DdN = -DdN;
3971			} else {
3972				return null;
3973			}
3974
3975			_diff.subVectors(this.origin, a);
3976
3977			const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); // b1 < 0, no intersection
3978
3979			if (DdQxE2 < 0) {
3980				return null;
3981			}
3982
3983			const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection
3984
3985			if (DdE1xQ < 0) {
3986				return null;
3987			} // b1+b2 > 1, no intersection
3988
3989
3990			if (DdQxE2 + DdE1xQ > DdN) {
3991				return null;
3992			} // Line intersects triangle, check if ray does.
3993
3994
3995			const QdN = -sign * _diff.dot(_normal$1); // t < 0, no intersection
3996
3997
3998			if (QdN < 0) {
3999				return null;
4000			} // Ray intersects triangle.
4001
4002
4003			return this.at(QdN / DdN, target);
4004		}
4005
4006		applyMatrix4(matrix4) {
4007			this.origin.applyMatrix4(matrix4);
4008			this.direction.transformDirection(matrix4);
4009			return this;
4010		}
4011
4012		equals(ray) {
4013			return ray.origin.equals(this.origin) && ray.direction.equals(this.direction);
4014		}
4015
4016		clone() {
4017			return new this.constructor().copy(this);
4018		}
4019
4020	}
4021
4022	class Matrix4 {
4023		constructor() {
4024			this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
4025
4026			if (arguments.length > 0) {
4027				console.error('THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.');
4028			}
4029		}
4030
4031		set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
4032			const te = this.elements;
4033			te[0] = n11;
4034			te[4] = n12;
4035			te[8] = n13;
4036			te[12] = n14;
4037			te[1] = n21;
4038			te[5] = n22;
4039			te[9] = n23;
4040			te[13] = n24;
4041			te[2] = n31;
4042			te[6] = n32;
4043			te[10] = n33;
4044			te[14] = n34;
4045			te[3] = n41;
4046			te[7] = n42;
4047			te[11] = n43;
4048			te[15] = n44;
4049			return this;
4050		}
4051
4052		identity() {
4053			this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
4054			return this;
4055		}
4056
4057		clone() {
4058			return new Matrix4().fromArray(this.elements);
4059		}
4060
4061		copy(m) {
4062			const te = this.elements;
4063			const me = m.elements;
4064			te[0] = me[0];
4065			te[1] = me[1];
4066			te[2] = me[2];
4067			te[3] = me[3];
4068			te[4] = me[4];
4069			te[5] = me[5];
4070			te[6] = me[6];
4071			te[7] = me[7];
4072			te[8] = me[8];
4073			te[9] = me[9];
4074			te[10] = me[10];
4075			te[11] = me[11];
4076			te[12] = me[12];
4077			te[13] = me[13];
4078			te[14] = me[14];
4079			te[15] = me[15];
4080			return this;
4081		}
4082
4083		copyPosition(m) {
4084			const te = this.elements,
4085						me = m.elements;
4086			te[12] = me[12];
4087			te[13] = me[13];
4088			te[14] = me[14];
4089			return this;
4090		}
4091
4092		setFromMatrix3(m) {
4093			const me = m.elements;
4094			this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1);
4095			return this;
4096		}
4097
4098		extractBasis(xAxis, yAxis, zAxis) {
4099			xAxis.setFromMatrixColumn(this, 0);
4100			yAxis.setFromMatrixColumn(this, 1);
4101			zAxis.setFromMatrixColumn(this, 2);
4102			return this;
4103		}
4104
4105		makeBasis(xAxis, yAxis, zAxis) {
4106			this.set(xAxis.x, yAxis.x, zAxis.x, 0, xAxis.y, yAxis.y, zAxis.y, 0, xAxis.z, yAxis.z, zAxis.z, 0, 0, 0, 0, 1);
4107			return this;
4108		}
4109
4110		extractRotation(m) {
4111			// this method does not support reflection matrices
4112			const te = this.elements;
4113			const me = m.elements;
4114
4115			const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length();
4116
4117			const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length();
4118
4119			const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length();
4120
4121			te[0] = me[0] * scaleX;
4122			te[1] = me[1] * scaleX;
4123			te[2] = me[2] * scaleX;
4124			te[3] = 0;
4125			te[4] = me[4] * scaleY;
4126			te[5] = me[5] * scaleY;
4127			te[6] = me[6] * scaleY;
4128			te[7] = 0;
4129			te[8] = me[8] * scaleZ;
4130			te[9] = me[9] * scaleZ;
4131			te[10] = me[10] * scaleZ;
4132			te[11] = 0;
4133			te[12] = 0;
4134			te[13] = 0;
4135			te[14] = 0;
4136			te[15] = 1;
4137			return this;
4138		}
4139
4140		makeRotationFromEuler(euler) {
4141			if (!(euler && euler.isEuler)) {
4142				console.error('THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.');
4143			}
4144
4145			const te = this.elements;
4146			const x = euler.x,
4147						y = euler.y,
4148						z = euler.z;
4149			const a = Math.cos(x),
4150						b = Math.sin(x);
4151			const c = Math.cos(y),
4152						d = Math.sin(y);
4153			const e = Math.cos(z),
4154						f = Math.sin(z);
4155
4156			if (euler.order === 'XYZ') {
4157				const ae = a * e,
4158							af = a * f,
4159							be = b * e,
4160							bf = b * f;
4161				te[0] = c * e;
4162				te[4] = -c * f;
4163				te[8] = d;
4164				te[1] = af + be * d;
4165				te[5] = ae - bf * d;
4166				te[9] = -b * c;
4167				te[2] = bf - ae * d;
4168				te[6] = be + af * d;
4169				te[10] = a * c;
4170			} else if (euler.order === 'YXZ') {
4171				const ce = c * e,
4172							cf = c * f,
4173							de = d * e,
4174							df = d * f;
4175				te[0] = ce + df * b;
4176				te[4] = de * b - cf;
4177				te[8] = a * d;
4178				te[1] = a * f;
4179				te[5] = a * e;
4180				te[9] = -b;
4181				te[2] = cf * b - de;
4182				te[6] = df + ce * b;
4183				te[10] = a * c;
4184			} else if (euler.order === 'ZXY') {
4185				const ce = c * e,
4186							cf = c * f,
4187							de = d * e,
4188							df = d * f;
4189				te[0] = ce - df * b;
4190				te[4] = -a * f;
4191				te[8] = de + cf * b;
4192				te[1] = cf + de * b;
4193				te[5] = a * e;
4194				te[9] = df - ce * b;
4195				te[2] = -a * d;
4196				te[6] = b;
4197				te[10] = a * c;
4198			} else if (euler.order === 'ZYX') {
4199				const ae = a * e,
4200							af = a * f,
4201							be = b * e,
4202							bf = b * f;
4203				te[0] = c * e;
4204				te[4] = be * d - af;
4205				te[8] = ae * d + bf;
4206				te[1] = c * f;
4207				te[5] = bf * d + ae;
4208				te[9] = af * d - be;
4209				te[2] = -d;
4210				te[6] = b * c;
4211				te[10] = a * c;
4212			} else if (euler.order === 'YZX') {
4213				const ac = a * c,
4214							ad = a * d,
4215							bc = b * c,
4216							bd = b * d;
4217				te[0] = c * e;
4218				te[4] = bd - ac * f;
4219				te[8] = bc * f + ad;
4220				te[1] = f;
4221				te[5] = a * e;
4222				te[9] = -b * e;
4223				te[2] = -d * e;
4224				te[6] = ad * f + bc;
4225				te[10] = ac - bd * f;
4226			} else if (euler.order === 'XZY') {
4227				const ac = a * c,
4228							ad = a * d,
4229							bc = b * c,
4230							bd = b * d;
4231				te[0] = c * e;
4232				te[4] = -f;
4233				te[8] = d * e;
4234				te[1] = ac * f + bd;
4235				te[5] = a * e;
4236				te[9] = ad * f - bc;
4237				te[2] = bc * f - ad;
4238				te[6] = b * e;
4239				te[10] = bd * f + ac;
4240			} // bottom row
4241
4242
4243			te[3] = 0;
4244			te[7] = 0;
4245			te[11] = 0; // last column
4246
4247			te[12] = 0;
4248			te[13] = 0;
4249			te[14] = 0;
4250			te[15] = 1;
4251			return this;
4252		}
4253
4254		makeRotationFromQuaternion(q) {
4255			return this.compose(_zero, q, _one);
4256		}
4257
4258		lookAt(eye, target, up) {
4259			const te = this.elements;
4260
4261			_z.subVectors(eye, target);
4262
4263			if (_z.lengthSq() === 0) {
4264				// eye and target are in the same position
4265				_z.z = 1;
4266			}
4267
4268			_z.normalize();
4269
4270			_x.crossVectors(up, _z);
4271
4272			if (_x.lengthSq() === 0) {
4273				// up and z are parallel
4274				if (Math.abs(up.z) === 1) {
4275					_z.x += 0.0001;
4276				} else {
4277					_z.z += 0.0001;
4278				}
4279
4280				_z.normalize();
4281
4282				_x.crossVectors(up, _z);
4283			}
4284
4285			_x.normalize();
4286
4287			_y.crossVectors(_z, _x);
4288
4289			te[0] = _x.x;
4290			te[4] = _y.x;
4291			te[8] = _z.x;
4292			te[1] = _x.y;
4293			te[5] = _y.y;
4294			te[9] = _z.y;
4295			te[2] = _x.z;
4296			te[6] = _y.z;
4297			te[10] = _z.z;
4298			return this;
4299		}
4300
4301		multiply(m, n) {
4302			if (n !== undefined) {
4303				console.warn('THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.');
4304				return this.multiplyMatrices(m, n);
4305			}
4306
4307			return this.multiplyMatrices(this, m);
4308		}
4309
4310		premultiply(m) {
4311			return this.multiplyMatrices(m, this);
4312		}
4313
4314		multiplyMatrices(a, b) {
4315			const ae = a.elements;
4316			const be = b.elements;
4317			const te = this.elements;
4318			const a11 = ae[0],
4319						a12 = ae[4],
4320						a13 = ae[8],
4321						a14 = ae[12];
4322			const a21 = ae[1],
4323						a22 = ae[5],
4324						a23 = ae[9],
4325						a24 = ae[13];
4326			const a31 = ae[2],
4327						a32 = ae[6],
4328						a33 = ae[10],
4329						a34 = ae[14];
4330			const a41 = ae[3],
4331						a42 = ae[7],
4332						a43 = ae[11],
4333						a44 = ae[15];
4334			const b11 = be[0],
4335						b12 = be[4],
4336						b13 = be[8],
4337						b14 = be[12];
4338			const b21 = be[1],
4339						b22 = be[5],
4340						b23 = be[9],
4341						b24 = be[13];
4342			const b31 = be[2],
4343						b32 = be[6],
4344						b33 = be[10],
4345						b34 = be[14];
4346			const b41 = be[3],
4347						b42 = be[7],
4348						b43 = be[11],
4349						b44 = be[15];
4350			te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
4351			te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
4352			te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
4353			te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
4354			te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
4355			te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
4356			te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
4357			te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
4358			te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
4359			te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
4360			te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
4361			te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
4362			te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
4363			te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
4364			te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
4365			te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
4366			return this;
4367		}
4368
4369		multiplyScalar(s) {
4370			const te = this.elements;
4371			te[0] *= s;
4372			te[4] *= s;
4373			te[8] *= s;
4374			te[12] *= s;
4375			te[1] *= s;
4376			te[5] *= s;
4377			te[9] *= s;
4378			te[13] *= s;
4379			te[2] *= s;
4380			te[6] *= s;
4381			te[10] *= s;
4382			te[14] *= s;
4383			te[3] *= s;
4384			te[7] *= s;
4385			te[11] *= s;
4386			te[15] *= s;
4387			return this;
4388		}
4389
4390		determinant() {
4391			const te = this.elements;
4392			const n11 = te[0],
4393						n12 = te[4],
4394						n13 = te[8],
4395						n14 = te[12];
4396			const n21 = te[1],
4397						n22 = te[5],
4398						n23 = te[9],
4399						n24 = te[13];
4400			const n31 = te[2],
4401						n32 = te[6],
4402						n33 = te[10],
4403						n34 = te[14];
4404			const n41 = te[3],
4405						n42 = te[7],
4406						n43 = te[11],
4407						n44 = te[15]; //TODO: make this more efficient
4408			//( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
4409
4410			return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31);
4411		}
4412
4413		transpose() {
4414			const te = this.elements;
4415			let tmp;
4416			tmp = te[1];
4417			te[1] = te[4];
4418			te[4] = tmp;
4419			tmp = te[2];
4420			te[2] = te[8];
4421			te[8] = tmp;
4422			tmp = te[6];
4423			te[6] = te[9];
4424			te[9] = tmp;
4425			tmp = te[3];
4426			te[3] = te[12];
4427			te[12] = tmp;
4428			tmp = te[7];
4429			te[7] = te[13];
4430			te[13] = tmp;
4431			tmp = te[11];
4432			te[11] = te[14];
4433			te[14] = tmp;
4434			return this;
4435		}
4436
4437		setPosition(x, y, z) {
4438			const te = this.elements;
4439
4440			if (x.isVector3) {
4441				te[12] = x.x;
4442				te[13] = x.y;
4443				te[14] = x.z;
4444			} else {
4445				te[12] = x;
4446				te[13] = y;
4447				te[14] = z;
4448			}
4449
4450			return this;
4451		}
4452
4453		invert() {
4454			// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
4455			const te = this.elements,
4456						n11 = te[0],
4457						n21 = te[1],
4458						n31 = te[2],
4459						n41 = te[3],
4460						n12 = te[4],
4461						n22 = te[5],
4462						n32 = te[6],
4463						n42 = te[7],
4464						n13 = te[8],
4465						n23 = te[9],
4466						n33 = te[10],
4467						n43 = te[11],
4468						n14 = te[12],
4469						n24 = te[13],
4470						n34 = te[14],
4471						n44 = te[15],
4472						t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
4473						t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
4474						t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
4475						t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
4476			const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
4477			if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4478			const detInv = 1 / det;
4479			te[0] = t11 * detInv;
4480			te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv;
4481			te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv;
4482			te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv;
4483			te[4] = t12 * detInv;
4484			te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv;
4485			te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv;
4486			te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv;
4487			te[8] = t13 * detInv;
4488			te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv;
4489			te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv;
4490			te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv;
4491			te[12] = t14 * detInv;
4492			te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv;
4493			te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv;
4494			te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv;
4495			return this;
4496		}
4497
4498		scale(v) {
4499			const te = this.elements;
4500			const x = v.x,
4501						y = v.y,
4502						z = v.z;
4503			te[0] *= x;
4504			te[4] *= y;
4505			te[8] *= z;
4506			te[1] *= x;
4507			te[5] *= y;
4508			te[9] *= z;
4509			te[2] *= x;
4510			te[6] *= y;
4511			te[10] *= z;
4512			te[3] *= x;
4513			te[7] *= y;
4514			te[11] *= z;
4515			return this;
4516		}
4517
4518		getMaxScaleOnAxis() {
4519			const te = this.elements;
4520			const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
4521			const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
4522			const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
4523			return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
4524		}
4525
4526		makeTranslation(x, y, z) {
4527			this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
4528			return this;
4529		}
4530
4531		makeRotationX(theta) {
4532			const c = Math.cos(theta),
4533						s = Math.sin(theta);
4534			this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1);
4535			return this;
4536		}
4537
4538		makeRotationY(theta) {
4539			const c = Math.cos(theta),
4540						s = Math.sin(theta);
4541			this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
4542			return this;
4543		}
4544
4545		makeRotationZ(theta) {
4546			const c = Math.cos(theta),
4547						s = Math.sin(theta);
4548			this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
4549			return this;
4550		}
4551
4552		makeRotationAxis(axis, angle) {
4553			// Based on http://www.gamedev.net/reference/articles/article1199.asp
4554			const c = Math.cos(angle);
4555			const s = Math.sin(angle);
4556			const t = 1 - c;
4557			const x = axis.x,
4558						y = axis.y,
4559						z = axis.z;
4560			const tx = t * x,
4561						ty = t * y;
4562			this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1);
4563			return this;
4564		}
4565
4566		makeScale(x, y, z) {
4567			this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1);
4568			return this;
4569		}
4570
4571		makeShear(xy, xz, yx, yz, zx, zy) {
4572			this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1);
4573			return this;
4574		}
4575
4576		compose(position, quaternion, scale) {
4577			const te = this.elements;
4578			const x = quaternion._x,
4579						y = quaternion._y,
4580						z = quaternion._z,
4581						w = quaternion._w;
4582			const x2 = x + x,
4583						y2 = y + y,
4584						z2 = z + z;
4585			const xx = x * x2,
4586						xy = x * y2,
4587						xz = x * z2;
4588			const yy = y * y2,
4589						yz = y * z2,
4590						zz = z * z2;
4591			const wx = w * x2,
4592						wy = w * y2,
4593						wz = w * z2;
4594			const sx = scale.x,
4595						sy = scale.y,
4596						sz = scale.z;
4597			te[0] = (1 - (yy + zz)) * sx;
4598			te[1] = (xy + wz) * sx;
4599			te[2] = (xz - wy) * sx;
4600			te[3] = 0;
4601			te[4] = (xy - wz) * sy;
4602			te[5] = (1 - (xx + zz)) * sy;
4603			te[6] = (yz + wx) * sy;
4604			te[7] = 0;
4605			te[8] = (xz + wy) * sz;
4606			te[9] = (yz - wx) * sz;
4607			te[10] = (1 - (xx + yy)) * sz;
4608			te[11] = 0;
4609			te[12] = position.x;
4610			te[13] = position.y;
4611			te[14] = position.z;
4612			te[15] = 1;
4613			return this;
4614		}
4615
4616		decompose(position, quaternion, scale) {
4617			const te = this.elements;
4618
4619			let sx = _v1$5.set(te[0], te[1], te[2]).length();
4620
4621			const sy = _v1$5.set(te[4], te[5], te[6]).length();
4622
4623			const sz = _v1$5.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale
4624
4625
4626			const det = this.determinant();
4627			if (det < 0) sx = -sx;
4628			position.x = te[12];
4629			position.y = te[13];
4630			position.z = te[14]; // scale the rotation part
4631
4632			_m1$2.copy(this);
4633
4634			const invSX = 1 / sx;
4635			const invSY = 1 / sy;
4636			const invSZ = 1 / sz;
4637			_m1$2.elements[0] *= invSX;
4638			_m1$2.elements[1] *= invSX;
4639			_m1$2.elements[2] *= invSX;
4640			_m1$2.elements[4] *= invSY;
4641			_m1$2.elements[5] *= invSY;
4642			_m1$2.elements[6] *= invSY;
4643			_m1$2.elements[8] *= invSZ;
4644			_m1$2.elements[9] *= invSZ;
4645			_m1$2.elements[10] *= invSZ;
4646			quaternion.setFromRotationMatrix(_m1$2);
4647			scale.x = sx;
4648			scale.y = sy;
4649			scale.z = sz;
4650			return this;
4651		}
4652
4653		makePerspective(left, right, top, bottom, near, far) {
4654			if (far === undefined) {
4655				console.warn('THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.');
4656			}
4657
4658			const te = this.elements;
4659			const x = 2 * near / (right - left);
4660			const y = 2 * near / (top - bottom);
4661			const a = (right + left) / (right - left);
4662			const b = (top + bottom) / (top - bottom);
4663			const c = -(far + near) / (far - near);
4664			const d = -2 * far * near / (far - near);
4665			te[0] = x;
4666			te[4] = 0;
4667			te[8] = a;
4668			te[12] = 0;
4669			te[1] = 0;
4670			te[5] = y;
4671			te[9] = b;
4672			te[13] = 0;
4673			te[2] = 0;
4674			te[6] = 0;
4675			te[10] = c;
4676			te[14] = d;
4677			te[3] = 0;
4678			te[7] = 0;
4679			te[11] = -1;
4680			te[15] = 0;
4681			return this;
4682		}
4683
4684		makeOrthographic(left, right, top, bottom, near, far) {
4685			const te = this.elements;
4686			const w = 1.0 / (right - left);
4687			const h = 1.0 / (top - bottom);
4688			const p = 1.0 / (far - near);
4689			const x = (right + left) * w;
4690			const y = (top + bottom) * h;
4691			const z = (far + near) * p;
4692			te[0] = 2 * w;
4693			te[4] = 0;
4694			te[8] = 0;
4695			te[12] = -x;
4696			te[1] = 0;
4697			te[5] = 2 * h;
4698			te[9] = 0;
4699			te[13] = -y;
4700			te[2] = 0;
4701			te[6] = 0;
4702			te[10] = -2 * p;
4703			te[14] = -z;
4704			te[3] = 0;
4705			te[7] = 0;
4706			te[11] = 0;
4707			te[15] = 1;
4708			return this;
4709		}
4710
4711		equals(matrix) {
4712			const te = this.elements;
4713			const me = matrix.elements;
4714
4715			for (let i = 0; i < 16; i++) {
4716				if (te[i] !== me[i]) return false;
4717			}
4718
4719			return true;
4720		}
4721
4722		fromArray(array, offset = 0) {
4723			for (let i = 0; i < 16; i++) {
4724				this.elements[i] = array[i + offset];
4725			}
4726
4727			return this;
4728		}
4729
4730		toArray(array = [], offset = 0) {
4731			const te = this.elements;
4732			array[offset] = te[0];
4733			array[offset + 1] = te[1];
4734			array[offset + 2] = te[2];
4735			array[offset + 3] = te[3];
4736			array[offset + 4] = te[4];
4737			array[offset + 5] = te[5];
4738			array[offset + 6] = te[6];
4739			array[offset + 7] = te[7];
4740			array[offset + 8] = te[8];
4741			array[offset + 9] = te[9];
4742			array[offset + 10] = te[10];
4743			array[offset + 11] = te[11];
4744			array[offset + 12] = te[12];
4745			array[offset + 13] = te[13];
4746			array[offset + 14] = te[14];
4747			array[offset + 15] = te[15];
4748			return array;
4749		}
4750
4751	}
4752
4753	Matrix4.prototype.isMatrix4 = true;
4754
4755	const _v1$5 = /*@__PURE__*/new Vector3();
4756
4757	const _m1$2 = /*@__PURE__*/new Matrix4();
4758
4759	const _zero = /*@__PURE__*/new Vector3(0, 0, 0);
4760
4761	const _one = /*@__PURE__*/new Vector3(1, 1, 1);
4762
4763	const _x = /*@__PURE__*/new Vector3();
4764
4765	const _y = /*@__PURE__*/new Vector3();
4766
4767	const _z = /*@__PURE__*/new Vector3();
4768
4769	const _matrix$1 = /*@__PURE__*/new Matrix4();
4770
4771	const _quaternion$3 = /*@__PURE__*/new Quaternion();
4772
4773	class Euler {
4774		constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) {
4775			this._x = x;
4776			this._y = y;
4777			this._z = z;
4778			this._order = order;
4779		}
4780
4781		get x() {
4782			return this._x;
4783		}
4784
4785		set x(value) {
4786			this._x = value;
4787
4788			this._onChangeCallback();
4789		}
4790
4791		get y() {
4792			return this._y;
4793		}
4794
4795		set y(value) {
4796			this._y = value;
4797
4798			this._onChangeCallback();
4799		}
4800
4801		get z() {
4802			return this._z;
4803		}
4804
4805		set z(value) {
4806			this._z = value;
4807
4808			this._onChangeCallback();
4809		}
4810
4811		get order() {
4812			return this._order;
vendor: 4,161 bytes, lines 4813-5014
4813		}
4814
4815		set order(value) {
4816			this._order = value;
4817
4818			this._onChangeCallback();
4819		}
4820
4821		set(x, y, z, order = this._order) {
4822			this._x = x;
4823			this._y = y;
4824			this._z = z;
4825			this._order = order;
4826
4827			this._onChangeCallback();
4828
4829			return this;
4830		}
4831
4832		clone() {
4833			return new this.constructor(this._x, this._y, this._z, this._order);
4834		}
4835
4836		copy(euler) {
4837			this._x = euler._x;
4838			this._y = euler._y;
4839			this._z = euler._z;
4840			this._order = euler._order;
4841
4842			this._onChangeCallback();
4843
4844			return this;
4845		}
4846
4847		setFromRotationMatrix(m, order = this._order, update = true) {
4848			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
4849			const te = m.elements;
4850			const m11 = te[0],
4851						m12 = te[4],
4852						m13 = te[8];
4853			const m21 = te[1],
4854						m22 = te[5],
4855						m23 = te[9];
4856			const m31 = te[2],
4857						m32 = te[6],
4858						m33 = te[10];
4859
4860			switch (order) {
4861				case 'XYZ':
4862					this._y = Math.asin(clamp(m13, -1, 1));
4863
4864					if (Math.abs(m13) < 0.9999999) {
4865						this._x = Math.atan2(-m23, m33);
4866						this._z = Math.atan2(-m12, m11);
4867					} else {
4868						this._x = Math.atan2(m32, m22);
4869						this._z = 0;
4870					}
4871
4872					break;
4873
4874				case 'YXZ':
4875					this._x = Math.asin(-clamp(m23, -1, 1));
4876
4877					if (Math.abs(m23) < 0.9999999) {
4878						this._y = Math.atan2(m13, m33);
4879						this._z = Math.atan2(m21, m22);
4880					} else {
4881						this._y = Math.atan2(-m31, m11);
4882						this._z = 0;
4883					}
4884
4885					break;
4886
4887				case 'ZXY':
4888					this._x = Math.asin(clamp(m32, -1, 1));
4889
4890					if (Math.abs(m32) < 0.9999999) {
4891						this._y = Math.atan2(-m31, m33);
4892						this._z = Math.atan2(-m12, m22);
4893					} else {
4894						this._y = 0;
4895						this._z = Math.atan2(m21, m11);
4896					}
4897
4898					break;
4899
4900				case 'ZYX':
4901					this._y = Math.asin(-clamp(m31, -1, 1));
4902
4903					if (Math.abs(m31) < 0.9999999) {
4904						this._x = Math.atan2(m32, m33);
4905						this._z = Math.atan2(m21, m11);
4906					} else {
4907						this._x = 0;
4908						this._z = Math.atan2(-m12, m22);
4909					}
4910
4911					break;
4912
4913				case 'YZX':
4914					this._z = Math.asin(clamp(m21, -1, 1));
4915
4916					if (Math.abs(m21) < 0.9999999) {
4917						this._x = Math.atan2(-m23, m22);
4918						this._y = Math.atan2(-m31, m11);
4919					} else {
4920						this._x = 0;
4921						this._y = Math.atan2(m13, m33);
4922					}
4923
4924					break;
4925
4926				case 'XZY':
4927					this._z = Math.asin(-clamp(m12, -1, 1));
4928
4929					if (Math.abs(m12) < 0.9999999) {
4930						this._x = Math.atan2(m32, m22);
4931						this._y = Math.atan2(m13, m11);
4932					} else {
4933						this._x = Math.atan2(-m23, m33);
4934						this._y = 0;
4935					}
4936
4937					break;
4938
4939				default:
4940					console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order);
4941			}
4942
4943			this._order = order;
4944			if (update === true) this._onChangeCallback();
4945			return this;
4946		}
4947
4948		setFromQuaternion(q, order, update) {
4949			_matrix$1.makeRotationFromQuaternion(q);
4950
4951			return this.setFromRotationMatrix(_matrix$1, order, update);
4952		}
4953
4954		setFromVector3(v, order = this._order) {
4955			return this.set(v.x, v.y, v.z, order);
4956		}
4957
4958		reorder(newOrder) {
4959			// WARNING: this discards revolution information -bhouston
4960			_quaternion$3.setFromEuler(this);
4961
4962			return this.setFromQuaternion(_quaternion$3, newOrder);
4963		}
4964
4965		equals(euler) {
4966			return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order;
4967		}
4968
4969		fromArray(array) {
4970			this._x = array[0];
4971			this._y = array[1];
4972			this._z = array[2];
4973			if (array[3] !== undefined) this._order = array[3];
4974
4975			this._onChangeCallback();
4976
4977			return this;
4978		}
4979
4980		toArray(array = [], offset = 0) {
4981			array[offset] = this._x;
4982			array[offset + 1] = this._y;
4983			array[offset + 2] = this._z;
4984			array[offset + 3] = this._order;
4985			return array;
4986		}
4987
4988		toVector3(optionalResult) {
4989			if (optionalResult) {
4990				return optionalResult.set(this._x, this._y, this._z);
4991			} else {
4992				return new Vector3(this._x, this._y, this._z);
4993			}
4994		}
4995
4996		_onChange(callback) {
4997			this._onChangeCallback = callback;
4998			return this;
4999		}
5000
5001		_onChangeCallback() {}
5002
5003	}
5004
5005	Euler.prototype.isEuler = true;
5006	Euler.DefaultOrder = 'XYZ';
5007	Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX'];
5008
5009	class Layers {
5010		constructor() {
5011			this.mask = 1 | 0;
5012		}
5013
5014		set(channel) {
vendor: 1,067 bytes, lines 5015-5076
5015			this.mask = (1 << channel | 0) >>> 0;
5016		}
5017
5018		enable(channel) {
5019			this.mask |= 1 << channel | 0;
5020		}
5021
5022		enableAll() {
5023			this.mask = 0xffffffff | 0;
5024		}
5025
5026		toggle(channel) {
5027			this.mask ^= 1 << channel | 0;
5028		}
5029
5030		disable(channel) {
5031			this.mask &= ~(1 << channel | 0);
5032		}
5033
5034		disableAll() {
5035			this.mask = 0;
5036		}
5037
5038		test(layers) {
5039			return (this.mask & layers.mask) !== 0;
5040		}
5041
5042		isEnabled(channel) {
5043			return (this.mask & (1 << channel | 0)) !== 0;
5044		}
5045
5046	}
5047
5048	let _object3DId = 0;
5049
5050	const _v1$4 = /*@__PURE__*/new Vector3();
5051
5052	const _q1 = /*@__PURE__*/new Quaternion();
5053
5054	const _m1$1 = /*@__PURE__*/new Matrix4();
5055
5056	const _target = /*@__PURE__*/new Vector3();
5057
5058	const _position$3 = /*@__PURE__*/new Vector3();
5059
5060	const _scale$2 = /*@__PURE__*/new Vector3();
5061
5062	const _quaternion$2 = /*@__PURE__*/new Quaternion();
5063
5064	const _xAxis = /*@__PURE__*/new Vector3(1, 0, 0);
5065
5066	const _yAxis = /*@__PURE__*/new Vector3(0, 1, 0);
5067
5068	const _zAxis = /*@__PURE__*/new Vector3(0, 0, 1);
5069
5070	const _addedEvent = {
5071		type: 'added'
5072	};
5073	const _removedEvent = {
5074		type: 'removed'
5075	};
5076
vendor: 16,537 bytes, lines 5077-5742
5077	class Object3D extends EventDispatcher {
5078		constructor() {
5079			super();
5080			Object.defineProperty(this, 'id', {
5081				value: _object3DId++
5082			});
5083			this.uuid = generateUUID();
5084			this.name = '';
5085			this.type = 'Object3D';
5086			this.parent = null;
5087			this.children = [];
5088			this.up = Object3D.DefaultUp.clone();
5089			const position = new Vector3();
5090			const rotation = new Euler();
5091			const quaternion = new Quaternion();
5092			const scale = new Vector3(1, 1, 1);
5093
5094			function onRotationChange() {
5095				quaternion.setFromEuler(rotation, false);
5096			}
5097
5098			function onQuaternionChange() {
5099				rotation.setFromQuaternion(quaternion, undefined, false);
5100			}
5101
5102			rotation._onChange(onRotationChange);
5103
5104			quaternion._onChange(onQuaternionChange);
5105
5106			Object.defineProperties(this, {
5107				position: {
5108					configurable: true,
5109					enumerable: true,
5110					value: position
5111				},
5112				rotation: {
5113					configurable: true,
5114					enumerable: true,
5115					value: rotation
5116				},
5117				quaternion: {
5118					configurable: true,
5119					enumerable: true,
5120					value: quaternion
5121				},
5122				scale: {
5123					configurable: true,
5124					enumerable: true,
5125					value: scale
5126				},
5127				modelViewMatrix: {
5128					value: new Matrix4()
5129				},
5130				normalMatrix: {
5131					value: new Matrix3()
5132				}
5133			});
5134			this.matrix = new Matrix4();
5135			this.matrixWorld = new Matrix4();
5136			this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
5137			this.matrixWorldNeedsUpdate = false;
5138			this.layers = new Layers();
5139			this.visible = true;
5140			this.castShadow = false;
5141			this.receiveShadow = false;
5142			this.frustumCulled = true;
5143			this.renderOrder = 0;
5144			this.animations = [];
5145			this.userData = {};
5146		}
5147
5148		onBeforeRender() {}
5149
5150		onAfterRender() {}
5151
5152		applyMatrix4(matrix) {
5153			if (this.matrixAutoUpdate) this.updateMatrix();
5154			this.matrix.premultiply(matrix);
5155			this.matrix.decompose(this.position, this.quaternion, this.scale);
5156		}
5157
5158		applyQuaternion(q) {
5159			this.quaternion.premultiply(q);
5160			return this;
5161		}
5162
5163		setRotationFromAxisAngle(axis, angle) {
5164			// assumes axis is normalized
5165			this.quaternion.setFromAxisAngle(axis, angle);
5166		}
5167
5168		setRotationFromEuler(euler) {
5169			this.quaternion.setFromEuler(euler, true);
5170		}
5171
5172		setRotationFromMatrix(m) {
5173			// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
5174			this.quaternion.setFromRotationMatrix(m);
5175		}
5176
5177		setRotationFromQuaternion(q) {
5178			// assumes q is normalized
5179			this.quaternion.copy(q);
5180		}
5181
5182		rotateOnAxis(axis, angle) {
5183			// rotate object on axis in object space
5184			// axis is assumed to be normalized
5185			_q1.setFromAxisAngle(axis, angle);
5186
5187			this.quaternion.multiply(_q1);
5188			return this;
5189		}
5190
5191		rotateOnWorldAxis(axis, angle) {
5192			// rotate object on axis in world space
5193			// axis is assumed to be normalized
5194			// method assumes no rotated parent
5195			_q1.setFromAxisAngle(axis, angle);
5196
5197			this.quaternion.premultiply(_q1);
5198			return this;
5199		}
5200
5201		rotateX(angle) {
5202			return this.rotateOnAxis(_xAxis, angle);
5203		}
5204
5205		rotateY(angle) {
5206			return this.rotateOnAxis(_yAxis, angle);
5207		}
5208
5209		rotateZ(angle) {
5210			return this.rotateOnAxis(_zAxis, angle);
5211		}
5212
5213		translateOnAxis(axis, distance) {
5214			// translate object by distance along axis in object space
5215			// axis is assumed to be normalized
5216			_v1$4.copy(axis).applyQuaternion(this.quaternion);
5217
5218			this.position.add(_v1$4.multiplyScalar(distance));
5219			return this;
5220		}
5221
5222		translateX(distance) {
5223			return this.translateOnAxis(_xAxis, distance);
5224		}
5225
5226		translateY(distance) {
5227			return this.translateOnAxis(_yAxis, distance);
5228		}
5229
5230		translateZ(distance) {
5231			return this.translateOnAxis(_zAxis, distance);
5232		}
5233
5234		localToWorld(vector) {
5235			return vector.applyMatrix4(this.matrixWorld);
5236		}
5237
5238		worldToLocal(vector) {
5239			return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert());
5240		}
5241
5242		lookAt(x, y, z) {
5243			// This method does not support objects having non-uniformly-scaled parent(s)
5244			if (x.isVector3) {
5245				_target.copy(x);
5246			} else {
5247				_target.set(x, y, z);
5248			}
5249
5250			const parent = this.parent;
5251			this.updateWorldMatrix(true, false);
5252
5253			_position$3.setFromMatrixPosition(this.matrixWorld);
5254
5255			if (this.isCamera || this.isLight) {
5256				_m1$1.lookAt(_position$3, _target, this.up);
5257			} else {
5258				_m1$1.lookAt(_target, _position$3, this.up);
5259			}
5260
5261			this.quaternion.setFromRotationMatrix(_m1$1);
5262
5263			if (parent) {
5264				_m1$1.extractRotation(parent.matrixWorld);
5265
5266				_q1.setFromRotationMatrix(_m1$1);
5267
5268				this.quaternion.premultiply(_q1.invert());
5269			}
5270		}
5271
5272		add(object) {
5273			if (arguments.length > 1) {
5274				for (let i = 0; i < arguments.length; i++) {
5275					this.add(arguments[i]);
5276				}
5277
5278				return this;
5279			}
5280
5281			if (object === this) {
5282				console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object);
5283				return this;
5284			}
5285
5286			if (object && object.isObject3D) {
5287				if (object.parent !== null) {
5288					object.parent.remove(object);
5289				}
5290
5291				object.parent = this;
5292				this.children.push(object);
5293				object.dispatchEvent(_addedEvent);
5294			} else {
5295				console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object);
5296			}
5297
5298			return this;
5299		}
5300
5301		remove(object) {
5302			if (arguments.length > 1) {
5303				for (let i = 0; i < arguments.length; i++) {
5304					this.remove(arguments[i]);
5305				}
5306
5307				return this;
5308			}
5309
5310			const index = this.children.indexOf(object);
5311
5312			if (index !== -1) {
5313				object.parent = null;
5314				this.children.splice(index, 1);
5315				object.dispatchEvent(_removedEvent);
5316			}
5317
5318			return this;
5319		}
5320
5321		removeFromParent() {
5322			const parent = this.parent;
5323
5324			if (parent !== null) {
5325				parent.remove(this);
5326			}
5327
5328			return this;
5329		}
5330
5331		clear() {
5332			for (let i = 0; i < this.children.length; i++) {
5333				const object = this.children[i];
5334				object.parent = null;
5335				object.dispatchEvent(_removedEvent);
5336			}
5337
5338			this.children.length = 0;
5339			return this;
5340		}
5341
5342		attach(object) {
5343			// adds object as a child of this, while maintaining the object's world transform
5344			// Note: This method does not support scene graphs having non-uniformly-scaled nodes(s)
5345			this.updateWorldMatrix(true, false);
5346
5347			_m1$1.copy(this.matrixWorld).invert();
5348
5349			if (object.parent !== null) {
5350				object.parent.updateWorldMatrix(true, false);
5351
5352				_m1$1.multiply(object.parent.matrixWorld);
5353			}
5354
5355			object.applyMatrix4(_m1$1);
5356			this.add(object);
5357			object.updateWorldMatrix(false, true);
5358			return this;
5359		}
5360
5361		getObjectById(id) {
5362			return this.getObjectByProperty('id', id);
5363		}
5364
5365		getObjectByName(name) {
5366			return this.getObjectByProperty('name', name);
5367		}
5368
5369		getObjectByProperty(name, value) {
5370			if (this[name] === value) return this;
5371
5372			for (let i = 0, l = this.children.length; i < l; i++) {
5373				const child = this.children[i];
5374				const object = child.getObjectByProperty(name, value);
5375
5376				if (object !== undefined) {
5377					return object;
5378				}
5379			}
5380
5381			return undefined;
5382		}
5383
5384		getWorldPosition(target) {
5385			this.updateWorldMatrix(true, false);
5386			return target.setFromMatrixPosition(this.matrixWorld);
5387		}
5388
5389		getWorldQuaternion(target) {
5390			this.updateWorldMatrix(true, false);
5391			this.matrixWorld.decompose(_position$3, target, _scale$2);
5392			return target;
5393		}
5394
5395		getWorldScale(target) {
5396			this.updateWorldMatrix(true, false);
5397			this.matrixWorld.decompose(_position$3, _quaternion$2, target);
5398			return target;
5399		}
5400
5401		getWorldDirection(target) {
5402			this.updateWorldMatrix(true, false);
5403			const e = this.matrixWorld.elements;
5404			return target.set(e[8], e[9], e[10]).normalize();
5405		}
5406
5407		raycast() {}
5408
5409		traverse(callback) {
5410			callback(this);
5411			const children = this.children;
5412
5413			for (let i = 0, l = children.length; i < l; i++) {
5414				children[i].traverse(callback);
5415			}
5416		}
5417
5418		traverseVisible(callback) {
5419			if (this.visible === false) return;
5420			callback(this);
5421			const children = this.children;
5422
5423			for (let i = 0, l = children.length; i < l; i++) {
5424				children[i].traverseVisible(callback);
5425			}
5426		}
5427
5428		traverseAncestors(callback) {
5429			const parent = this.parent;
5430
5431			if (parent !== null) {
5432				callback(parent);
5433				parent.traverseAncestors(callback);
5434			}
5435		}
5436
5437		updateMatrix() {
5438			this.matrix.compose(this.position, this.quaternion, this.scale);
5439			this.matrixWorldNeedsUpdate = true;
5440		}
5441
5442		updateMatrixWorld(force) {
5443			if (this.matrixAutoUpdate) this.updateMatrix();
5444
5445			if (this.matrixWorldNeedsUpdate || force) {
5446				if (this.parent === null) {
5447					this.matrixWorld.copy(this.matrix);
5448				} else {
5449					this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
5450				}
5451
5452				this.matrixWorldNeedsUpdate = false;
5453				force = true;
5454			} // update children
5455
5456
5457			const children = this.children;
5458
5459			for (let i = 0, l = children.length; i < l; i++) {
5460				children[i].updateMatrixWorld(force);
5461			}
5462		}
5463
5464		updateWorldMatrix(updateParents, updateChildren) {
5465			const parent = this.parent;
5466
5467			if (updateParents === true && parent !== null) {
5468				parent.updateWorldMatrix(true, false);
5469			}
5470
5471			if (this.matrixAutoUpdate) this.updateMatrix();
5472
5473			if (this.parent === null) {
5474				this.matrixWorld.copy(this.matrix);
5475			} else {
5476				this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
5477			} // update children
5478
5479
5480			if (updateChildren === true) {
5481				const children = this.children;
5482
5483				for (let i = 0, l = children.length; i < l; i++) {
5484					children[i].updateWorldMatrix(false, true);
5485				}
5486			}
5487		}
5488
5489		toJSON(meta) {
5490			// meta is a string when called from JSON.stringify
5491			const isRootObject = meta === undefined || typeof meta === 'string';
5492			const output = {}; // meta is a hash used to collect geometries, materials.
5493			// not providing it implies that this is the root object
5494			// being serialized.
5495
5496			if (isRootObject) {
5497				// initialize meta obj
5498				meta = {
5499					geometries: {},
5500					materials: {},
5501					textures: {},
5502					images: {},
5503					shapes: {},
5504					skeletons: {},
5505					animations: {}
5506				};
5507				output.metadata = {
5508					version: 4.5,
5509					type: 'Object',
5510					generator: 'Object3D.toJSON'
5511				};
5512			} // standard Object3D serialization
5513
5514
5515			const object = {};
5516			object.uuid = this.uuid;
5517			object.type = this.type;
5518			if (this.name !== '') object.name = this.name;
5519			if (this.castShadow === true) object.castShadow = true;
5520			if (this.receiveShadow === true) object.receiveShadow = true;
5521			if (this.visible === false) object.visible = false;
5522			if (this.frustumCulled === false) object.frustumCulled = false;
5523			if (this.renderOrder !== 0) object.renderOrder = this.renderOrder;
5524			if (JSON.stringify(this.userData) !== '{}') object.userData = this.userData;
5525			object.layers = this.layers.mask;
5526			object.matrix = this.matrix.toArray();
5527			if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false; // object specific properties
5528
5529			if (this.isInstancedMesh) {
5530				object.type = 'InstancedMesh';
5531				object.count = this.count;
5532				object.instanceMatrix = this.instanceMatrix.toJSON();
5533				if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON();
5534			} //
5535
5536
5537			function serialize(library, element) {
5538				if (library[element.uuid] === undefined) {
5539					library[element.uuid] = element.toJSON(meta);
5540				}
5541
5542				return element.uuid;
5543			}
5544
5545			if (this.isScene) {
5546				if (this.background) {
5547					if (this.background.isColor) {
5548						object.background = this.background.toJSON();
5549					} else if (this.background.isTexture) {
5550						object.background = this.background.toJSON(meta).uuid;
5551					}
5552				}
5553
5554				if (this.environment && this.environment.isTexture) {
5555					object.environment = this.environment.toJSON(meta).uuid;
5556				}
5557			} else if (this.isMesh || this.isLine || this.isPoints) {
5558				object.geometry = serialize(meta.geometries, this.geometry);
5559				const parameters = this.geometry.parameters;
5560
5561				if (parameters !== undefined && parameters.shapes !== undefined) {
5562					const shapes = parameters.shapes;
5563
5564					if (Array.isArray(shapes)) {
5565						for (let i = 0, l = shapes.length; i < l; i++) {
5566							const shape = shapes[i];
5567							serialize(meta.shapes, shape);
5568						}
5569					} else {
5570						serialize(meta.shapes, shapes);
5571					}
5572				}
5573			}
5574
5575			if (this.isSkinnedMesh) {
5576				object.bindMode = this.bindMode;
5577				object.bindMatrix = this.bindMatrix.toArray();
5578
5579				if (this.skeleton !== undefined) {
5580					serialize(meta.skeletons, this.skeleton);
5581					object.skeleton = this.skeleton.uuid;
5582				}
5583			}
5584
5585			if (this.material !== undefined) {
5586				if (Array.isArray(this.material)) {
5587					const uuids = [];
5588
5589					for (let i = 0, l = this.material.length; i < l; i++) {
5590						uuids.push(serialize(meta.materials, this.material[i]));
5591					}
5592
5593					object.material = uuids;
5594				} else {
5595					object.material = serialize(meta.materials, this.material);
5596				}
5597			} //
5598
5599
5600			if (this.children.length > 0) {
5601				object.children = [];
5602
5603				for (let i = 0; i < this.children.length; i++) {
5604					object.children.push(this.children[i].toJSON(meta).object);
5605				}
5606			} //
5607
5608
5609			if (this.animations.length > 0) {
5610				object.animations = [];
5611
5612				for (let i = 0; i < this.animations.length; i++) {
5613					const animation = this.animations[i];
5614					object.animations.push(serialize(meta.animations, animation));
5615				}
5616			}
5617
5618			if (isRootObject) {
5619				const geometries = extractFromCache(meta.geometries);
5620				const materials = extractFromCache(meta.materials);
5621				const textures = extractFromCache(meta.textures);
5622				const images = extractFromCache(meta.images);
5623				const shapes = extractFromCache(meta.shapes);
5624				const skeletons = extractFromCache(meta.skeletons);
5625				const animations = extractFromCache(meta.animations);
5626				if (geometries.length > 0) output.geometries = geometries;
5627				if (materials.length > 0) output.materials = materials;
5628				if (textures.length > 0) output.textures = textures;
5629				if (images.length > 0) output.images = images;
5630				if (shapes.length > 0) output.shapes = shapes;
5631				if (skeletons.length > 0) output.skeletons = skeletons;
5632				if (animations.length > 0) output.animations = animations;
5633			}
5634
5635			output.object = object;
5636			return output; // extract data from the cache hash
5637			// remove metadata on each item
5638			// and return as array
5639
5640			function extractFromCache(cache) {
5641				const values = [];
5642
5643				for (const key in cache) {
5644					const data = cache[key];
5645					delete data.metadata;
5646					values.push(data);
5647				}
5648
5649				return values;
5650			}
5651		}
5652
5653		clone(recursive) {
5654			return new this.constructor().copy(this, recursive);
5655		}
5656
5657		copy(source, recursive = true) {
5658			this.name = source.name;
5659			this.up.copy(source.up);
5660			this.position.copy(source.position);
5661			this.rotation.order = source.rotation.order;
5662			this.quaternion.copy(source.quaternion);
5663			this.scale.copy(source.scale);
5664			this.matrix.copy(source.matrix);
5665			this.matrixWorld.copy(source.matrixWorld);
5666			this.matrixAutoUpdate = source.matrixAutoUpdate;
5667			this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
5668			this.layers.mask = source.layers.mask;
5669			this.visible = source.visible;
5670			this.castShadow = source.castShadow;
5671			this.receiveShadow = source.receiveShadow;
5672			this.frustumCulled = source.frustumCulled;
5673			this.renderOrder = source.renderOrder;
5674			this.userData = JSON.parse(JSON.stringify(source.userData));
5675
5676			if (recursive === true) {
5677				for (let i = 0; i < source.children.length; i++) {
5678					const child = source.children[i];
5679					this.add(child.clone());
5680				}
5681			}
5682
5683			return this;
5684		}
5685
5686	}
5687
5688	Object3D.DefaultUp = new Vector3(0, 1, 0);
5689	Object3D.DefaultMatrixAutoUpdate = true;
5690	Object3D.prototype.isObject3D = true;
5691
5692	const _v0$1 = /*@__PURE__*/new Vector3();
5693
5694	const _v1$3 = /*@__PURE__*/new Vector3();
5695
5696	const _v2$2 = /*@__PURE__*/new Vector3();
5697
5698	const _v3$1 = /*@__PURE__*/new Vector3();
5699
5700	const _vab = /*@__PURE__*/new Vector3();
5701
5702	const _vac = /*@__PURE__*/new Vector3();
5703
5704	const _vbc = /*@__PURE__*/new Vector3();
5705
5706	const _vap = /*@__PURE__*/new Vector3();
5707
5708	const _vbp = /*@__PURE__*/new Vector3();
5709
5710	const _vcp = /*@__PURE__*/new Vector3();
5711
5712	class Triangle {
5713		constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()) {
5714			this.a = a;
5715			this.b = b;
5716			this.c = c;
5717		}
5718
5719		static getNormal(a, b, c, target) {
5720			target.subVectors(c, b);
5721
5722			_v0$1.subVectors(a, b);
5723
5724			target.cross(_v0$1);
5725			const targetLengthSq = target.lengthSq();
5726
5727			if (targetLengthSq > 0) {
5728				return target.multiplyScalar(1 / Math.sqrt(targetLengthSq));
5729			}
5730
5731			return target.set(0, 0, 0);
5732		} // static/instance method to calculate barycentric coordinates
5733		// based on: http://www.blackpawn.com/texts/pointinpoly/default.html
5734
5735
5736		static getBarycoord(point, a, b, c, target) {
5737			_v0$1.subVectors(c, a);
5738
5739			_v1$3.subVectors(b, a);
5740
5741			_v2$2.subVectors(point, a);
5742
vendor: 15,538 bytes, lines 5743-6207
5743			const dot00 = _v0$1.dot(_v0$1);
5744
5745			const dot01 = _v0$1.dot(_v1$3);
5746
5747			const dot02 = _v0$1.dot(_v2$2);
5748
5749			const dot11 = _v1$3.dot(_v1$3);
5750
5751			const dot12 = _v1$3.dot(_v2$2);
5752
5753			const denom = dot00 * dot11 - dot01 * dot01; // collinear or singular triangle
5754
5755			if (denom === 0) {
5756				// arbitrary location outside of triangle?
5757				// not sure if this is the best idea, maybe should be returning undefined
5758				return target.set(-2, -1, -1);
5759			}
5760
5761			const invDenom = 1 / denom;
5762			const u = (dot11 * dot02 - dot01 * dot12) * invDenom;
5763			const v = (dot00 * dot12 - dot01 * dot02) * invDenom; // barycentric coordinates must always sum to 1
5764
5765			return target.set(1 - u - v, v, u);
5766		}
5767
5768		static containsPoint(point, a, b, c) {
5769			this.getBarycoord(point, a, b, c, _v3$1);
5770			return _v3$1.x >= 0 && _v3$1.y >= 0 && _v3$1.x + _v3$1.y <= 1;
5771		}
5772
5773		static getUV(point, p1, p2, p3, uv1, uv2, uv3, target) {
5774			this.getBarycoord(point, p1, p2, p3, _v3$1);
5775			target.set(0, 0);
5776			target.addScaledVector(uv1, _v3$1.x);
5777			target.addScaledVector(uv2, _v3$1.y);
5778			target.addScaledVector(uv3, _v3$1.z);
5779			return target;
5780		}
5781
5782		static isFrontFacing(a, b, c, direction) {
5783			_v0$1.subVectors(c, b);
5784
5785			_v1$3.subVectors(a, b); // strictly front facing
5786
5787
5788			return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false;
5789		}
5790
5791		set(a, b, c) {
5792			this.a.copy(a);
5793			this.b.copy(b);
5794			this.c.copy(c);
5795			return this;
5796		}
5797
5798		setFromPointsAndIndices(points, i0, i1, i2) {
5799			this.a.copy(points[i0]);
5800			this.b.copy(points[i1]);
5801			this.c.copy(points[i2]);
5802			return this;
5803		}
5804
5805		setFromAttributeAndIndices(attribute, i0, i1, i2) {
5806			this.a.fromBufferAttribute(attribute, i0);
5807			this.b.fromBufferAttribute(attribute, i1);
5808			this.c.fromBufferAttribute(attribute, i2);
5809			return this;
5810		}
5811
5812		clone() {
5813			return new this.constructor().copy(this);
5814		}
5815
5816		copy(triangle) {
5817			this.a.copy(triangle.a);
5818			this.b.copy(triangle.b);
5819			this.c.copy(triangle.c);
5820			return this;
5821		}
5822
5823		getArea() {
5824			_v0$1.subVectors(this.c, this.b);
5825
5826			_v1$3.subVectors(this.a, this.b);
5827
5828			return _v0$1.cross(_v1$3).length() * 0.5;
5829		}
5830
5831		getMidpoint(target) {
5832			return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3);
5833		}
5834
5835		getNormal(target) {
5836			return Triangle.getNormal(this.a, this.b, this.c, target);
5837		}
5838
5839		getPlane(target) {
5840			return target.setFromCoplanarPoints(this.a, this.b, this.c);
5841		}
5842
5843		getBarycoord(point, target) {
5844			return Triangle.getBarycoord(point, this.a, this.b, this.c, target);
5845		}
5846
5847		getUV(point, uv1, uv2, uv3, target) {
5848			return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target);
5849		}
5850
5851		containsPoint(point) {
5852			return Triangle.containsPoint(point, this.a, this.b, this.c);
5853		}
5854
5855		isFrontFacing(direction) {
5856			return Triangle.isFrontFacing(this.a, this.b, this.c, direction);
5857		}
5858
5859		intersectsBox(box) {
5860			return box.intersectsTriangle(this);
5861		}
5862
5863		closestPointToPoint(p, target) {
5864			const a = this.a,
5865						b = this.b,
5866						c = this.c;
5867			let v, w; // algorithm thanks to Real-Time Collision Detection by Christer Ericson,
5868			// published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,
5869			// under the accompanying license; see chapter 5.1.5 for detailed explanation.
5870			// basically, we're distinguishing which of the voronoi regions of the triangle
5871			// the point lies in with the minimum amount of redundant computation.
5872
5873			_vab.subVectors(b, a);
5874
5875			_vac.subVectors(c, a);
5876
5877			_vap.subVectors(p, a);
5878
5879			const d1 = _vab.dot(_vap);
5880
5881			const d2 = _vac.dot(_vap);
5882
5883			if (d1 <= 0 && d2 <= 0) {
5884				// vertex region of A; barycentric coords (1, 0, 0)
5885				return target.copy(a);
5886			}
5887
5888			_vbp.subVectors(p, b);
5889
5890			const d3 = _vab.dot(_vbp);
5891
5892			const d4 = _vac.dot(_vbp);
5893
5894			if (d3 >= 0 && d4 <= d3) {
5895				// vertex region of B; barycentric coords (0, 1, 0)
5896				return target.copy(b);
5897			}
5898
5899			const vc = d1 * d4 - d3 * d2;
5900
5901			if (vc <= 0 && d1 >= 0 && d3 <= 0) {
5902				v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0)
5903
5904				return target.copy(a).addScaledVector(_vab, v);
5905			}
5906
5907			_vcp.subVectors(p, c);
5908
5909			const d5 = _vab.dot(_vcp);
5910
5911			const d6 = _vac.dot(_vcp);
5912
5913			if (d6 >= 0 && d5 <= d6) {
5914				// vertex region of C; barycentric coords (0, 0, 1)
5915				return target.copy(c);
5916			}
5917
5918			const vb = d5 * d2 - d1 * d6;
5919
5920			if (vb <= 0 && d2 >= 0 && d6 <= 0) {
5921				w = d2 / (d2 - d6); // edge region of AC; barycentric coords (1-w, 0, w)
5922
5923				return target.copy(a).addScaledVector(_vac, w);
5924			}
5925
5926			const va = d3 * d6 - d5 * d4;
5927
5928			if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) {
5929				_vbc.subVectors(c, b);
5930
5931				w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w)
5932
5933				return target.copy(b).addScaledVector(_vbc, w); // edge region of BC
5934			} // face region
5935
5936
5937			const denom = 1 / (va + vb + vc); // u = va * denom
5938
5939			v = vb * denom;
5940			w = vc * denom;
5941			return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w);
5942		}
5943
5944		equals(triangle) {
5945			return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c);
5946		}
5947
5948	}
5949
5950	let materialId = 0;
5951
5952	class Material extends EventDispatcher {
5953		constructor() {
5954			super();
5955			Object.defineProperty(this, 'id', {
5956				value: materialId++
5957			});
5958			this.uuid = generateUUID();
5959			this.name = '';
5960			this.type = 'Material';
5961			this.fog = true;
5962			this.blending = NormalBlending;
5963			this.side = FrontSide;
5964			this.vertexColors = false;
5965			this.opacity = 1;
5966			this.format = RGBAFormat;
5967			this.transparent = false;
5968			this.blendSrc = SrcAlphaFactor;
5969			this.blendDst = OneMinusSrcAlphaFactor;
5970			this.blendEquation = AddEquation;
5971			this.blendSrcAlpha = null;
5972			this.blendDstAlpha = null;
5973			this.blendEquationAlpha = null;
5974			this.depthFunc = LessEqualDepth;
5975			this.depthTest = true;
5976			this.depthWrite = true;
5977			this.stencilWriteMask = 0xff;
5978			this.stencilFunc = AlwaysStencilFunc;
5979			this.stencilRef = 0;
5980			this.stencilFuncMask = 0xff;
5981			this.stencilFail = KeepStencilOp;
5982			this.stencilZFail = KeepStencilOp;
5983			this.stencilZPass = KeepStencilOp;
5984			this.stencilWrite = false;
5985			this.clippingPlanes = null;
5986			this.clipIntersection = false;
5987			this.clipShadows = false;
5988			this.shadowSide = null;
5989			this.colorWrite = true;
5990			this.precision = null; // override the renderer's default precision for this material
5991
5992			this.polygonOffset = false;
5993			this.polygonOffsetFactor = 0;
5994			this.polygonOffsetUnits = 0;
5995			this.dithering = false;
5996			this.alphaToCoverage = false;
5997			this.premultipliedAlpha = false;
5998			this.visible = true;
5999			this.toneMapped = true;
6000			this.userData = {};
6001			this.version = 0;
6002			this._alphaTest = 0;
6003		}
6004
6005		get alphaTest() {
6006			return this._alphaTest;
6007		}
6008
6009		set alphaTest(value) {
6010			if (this._alphaTest > 0 !== value > 0) {
6011				this.version++;
6012			}
6013
6014			this._alphaTest = value;
6015		}
6016
6017		onBuild() {}
6018
6019		onBeforeRender() {}
6020
6021		onBeforeCompile() {}
6022
6023		customProgramCacheKey() {
6024			return this.onBeforeCompile.toString();
6025		}
6026
6027		setValues(values) {
6028			if (values === undefined) return;
6029
6030			for (const key in values) {
6031				const newValue = values[key];
6032
6033				if (newValue === undefined) {
6034					console.warn('THREE.Material: \'' + key + '\' parameter is undefined.');
6035					continue;
6036				} // for backward compatability if shading is set in the constructor
6037
6038
6039				if (key === 'shading') {
6040					console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.');
6041					this.flatShading = newValue === FlatShading ? true : false;
6042					continue;
6043				}
6044
6045				const currentValue = this[key];
6046
6047				if (currentValue === undefined) {
6048					console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.');
6049					continue;
6050				}
6051
6052				if (currentValue && currentValue.isColor) {
6053					currentValue.set(newValue);
6054				} else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) {
6055					currentValue.copy(newValue);
6056				} else {
6057					this[key] = newValue;
6058				}
6059			}
6060		}
6061
6062		toJSON(meta) {
6063			const isRoot = meta === undefined || typeof meta === 'string';
6064
6065			if (isRoot) {
6066				meta = {
6067					textures: {},
6068					images: {}
6069				};
6070			}
6071
6072			const data = {
6073				metadata: {
6074					version: 4.5,
6075					type: 'Material',
6076					generator: 'Material.toJSON'
6077				}
6078			}; // standard Material serialization
6079
6080			data.uuid = this.uuid;
6081			data.type = this.type;
6082			if (this.name !== '') data.name = this.name;
6083			if (this.color && this.color.isColor) data.color = this.color.getHex();
6084			if (this.roughness !== undefined) data.roughness = this.roughness;
6085			if (this.metalness !== undefined) data.metalness = this.metalness;
6086			if (this.sheen !== undefined) data.sheen = this.sheen;
6087			if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex();
6088			if (this.sheenRoughness !== undefined) data.sheenRoughness = this.sheenRoughness;
6089			if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex();
6090			if (this.emissiveIntensity && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity;
6091			if (this.specular && this.specular.isColor) data.specular = this.specular.getHex();
6092			if (this.specularIntensity !== undefined) data.specularIntensity = this.specularIntensity;
6093			if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex();
6094			if (this.shininess !== undefined) data.shininess = this.shininess;
6095			if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat;
6096			if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness;
6097
6098			if (this.clearcoatMap && this.clearcoatMap.isTexture) {
6099				data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid;
6100			}
6101
6102			if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) {
6103				data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid;
6104			}
6105
6106			if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) {
6107				data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid;
6108				data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
6109			}
6110
6111			if (this.map && this.map.isTexture) data.map = this.map.toJSON(meta).uuid;
6112			if (this.matcap && this.matcap.isTexture) data.matcap = this.matcap.toJSON(meta).uuid;
6113			if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON(meta).uuid;
6114
6115			if (this.lightMap && this.lightMap.isTexture) {
6116				data.lightMap = this.lightMap.toJSON(meta).uuid;
6117				data.lightMapIntensity = this.lightMapIntensity;
6118			}
6119
6120			if (this.aoMap && this.aoMap.isTexture) {
6121				data.aoMap = this.aoMap.toJSON(meta).uuid;
6122				data.aoMapIntensity = this.aoMapIntensity;
6123			}
6124
6125			if (this.bumpMap && this.bumpMap.isTexture) {
6126				data.bumpMap = this.bumpMap.toJSON(meta).uuid;
6127				data.bumpScale = this.bumpScale;
6128			}
6129
6130			if (this.normalMap && this.normalMap.isTexture) {
6131				data.normalMap = this.normalMap.toJSON(meta).uuid;
6132				data.normalMapType = this.normalMapType;
6133				data.normalScale = this.normalScale.toArray();
6134			}
6135
6136			if (this.displacementMap && this.displacementMap.isTexture) {
6137				data.displacementMap = this.displacementMap.toJSON(meta).uuid;
6138				data.displacementScale = this.displacementScale;
6139				data.displacementBias = this.displacementBias;
6140			}
6141
6142			if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON(meta).uuid;
6143			if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON(meta).uuid;
6144			if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON(meta).uuid;
6145			if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON(meta).uuid;
6146			if (this.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid;
6147			if (this.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.toJSON(meta).uuid;
6148
6149			if (this.envMap && this.envMap.isTexture) {
6150				data.envMap = this.envMap.toJSON(meta).uuid;
6151				if (this.combine !== undefined) data.combine = this.combine;
6152			}
6153
6154			if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity;
6155			if (this.reflectivity !== undefined) data.reflectivity = this.reflectivity;
6156			if (this.refractionRatio !== undefined) data.refractionRatio = this.refractionRatio;
6157
6158			if (this.gradientMap && this.gradientMap.isTexture) {
6159				data.gradientMap = this.gradientMap.toJSON(meta).uuid;
6160			}
6161
6162			if (this.transmission !== undefined) data.transmission = this.transmission;
6163			if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid;
6164			if (this.thickness !== undefined) data.thickness = this.thickness;
6165			if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid;
6166			if (this.attenuationDistance !== undefined) data.attenuationDistance = this.attenuationDistance;
6167			if (this.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex();
6168			if (this.size !== undefined) data.size = this.size;
6169			if (this.shadowSide !== null) data.shadowSide = this.shadowSide;
6170			if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation;
6171			if (this.blending !== NormalBlending) data.blending = this.blending;
6172			if (this.side !== FrontSide) data.side = this.side;
6173			if (this.vertexColors) data.vertexColors = true;
6174			if (this.opacity < 1) data.opacity = this.opacity;
6175			if (this.format !== RGBAFormat) data.format = this.format;
6176			if (this.transparent === true) data.transparent = this.transparent;
6177			data.depthFunc = this.depthFunc;
6178			data.depthTest = this.depthTest;
6179			data.depthWrite = this.depthWrite;
6180			data.colorWrite = this.colorWrite;
6181			data.stencilWrite = this.stencilWrite;
6182			data.stencilWriteMask = this.stencilWriteMask;
6183			data.stencilFunc = this.stencilFunc;
6184			data.stencilRef = this.stencilRef;
6185			data.stencilFuncMask = this.stencilFuncMask;
6186			data.stencilFail = this.stencilFail;
6187			data.stencilZFail = this.stencilZFail;
6188			data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial)
6189
6190			if (this.rotation && this.rotation !== 0) data.rotation = this.rotation;
6191			if (this.polygonOffset === true) data.polygonOffset = true;
6192			if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor;
6193			if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits;
6194			if (this.linewidth && this.linewidth !== 1) data.linewidth = this.linewidth;
6195			if (this.dashSize !== undefined) data.dashSize = this.dashSize;
6196			if (this.gapSize !== undefined) data.gapSize = this.gapSize;
6197			if (this.scale !== undefined) data.scale = this.scale;
6198			if (this.dithering === true) data.dithering = true;
6199			if (this.alphaTest > 0) data.alphaTest = this.alphaTest;
6200			if (this.alphaToCoverage === true) data.alphaToCoverage = this.alphaToCoverage;
6201			if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha;
6202			if (this.wireframe === true) data.wireframe = this.wireframe;
6203			if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth;
6204			if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap;
6205			if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin;
6206			if (this.flatShading === true) data.flatShading = this.flatShading;
6207			if (this.visible === false) data.visible = false;
6208			if (this.toneMapped === false) data.toneMapped = false;
6209			if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; // TODO: Copied from Object3D.toJSON
6210
6211			function extractFromCache(cache) {
6212				const values = [];
6213
6214				for (const key in cache) {
6215					const data = cache[key];
6216					delete data.metadata;
6217					values.push(data);
6218				}
6219
6220				return values;
6221			}
6222
6223			if (isRoot) {
6224				const textures = extractFromCache(meta.textures);
6225				const images = extractFromCache(meta.images);
6226				if (textures.length > 0) data.textures = textures;
6227				if (images.length > 0) data.images = images;
6228			}
6229
6230			return data;
6231		}
6232
6233		clone() {
6234			return new this.constructor().copy(this);
6235		}
6236
6237		copy(source) {
6238			this.name = source.name;
6239			this.fog = source.fog;
6240			this.blending = source.blending;
6241			this.side = source.side;
6242			this.vertexColors = source.vertexColors;
6243			this.opacity = source.opacity;
6244			this.format = source.format;
6245			this.transparent = source.transparent;
6246			this.blendSrc = source.blendSrc;
6247			this.blendDst = source.blendDst;
6248			this.blendEquation = source.blendEquation;
6249			this.blendSrcAlpha = source.blendSrcAlpha;
6250			this.blendDstAlpha = source.blendDstAlpha;
6251			this.blendEquationAlpha = source.blendEquationAlpha;
6252			this.depthFunc = source.depthFunc;
6253			this.depthTest = source.depthTest;
6254			this.depthWrite = source.depthWrite;
6255			this.stencilWriteMask = source.stencilWriteMask;
6256			this.stencilFunc = source.stencilFunc;
6257			this.stencilRef = source.stencilRef;
6258			this.stencilFuncMask = source.stencilFuncMask;
6259			this.stencilFail = source.stencilFail;
6260			this.stencilZFail = source.stencilZFail;
6261			this.stencilZPass = source.stencilZPass;
6262			this.stencilWrite = source.stencilWrite;
6263			const srcPlanes = source.clippingPlanes;
6264			let dstPlanes = null;
6265
6266			if (srcPlanes !== null) {
6267				const n = srcPlanes.length;
6268				dstPlanes = new Array(n);
6269
6270				for (let i = 0; i !== n; ++i) {
6271					dstPlanes[i] = srcPlanes[i].clone();
6272				}
6273			}
6274
6275			this.clippingPlanes = dstPlanes;
6276			this.clipIntersection = source.clipIntersection;
6277			this.clipShadows = source.clipShadows;
6278			this.shadowSide = source.shadowSide;
6279			this.colorWrite = source.colorWrite;
6280			this.precision = source.precision;
6281			this.polygonOffset = source.polygonOffset;
6282			this.polygonOffsetFactor = source.polygonOffsetFactor;
6283			this.polygonOffsetUnits = source.polygonOffsetUnits;
6284			this.dithering = source.dithering;
6285			this.alphaTest = source.alphaTest;
6286			this.alphaToCoverage = source.alphaToCoverage;
6287			this.premultipliedAlpha = source.premultipliedAlpha;
6288			this.visible = source.visible;
6289			this.toneMapped = source.toneMapped;
6290			this.userData = JSON.parse(JSON.stringify(source.userData));
6291			return this;
6292		}
6293
6294		dispose() {
6295			this.dispatchEvent({
6296				type: 'dispose'
6297			});
6298		}
6299
6300		set needsUpdate(value) {
6301			if (value === true) this.version++;
6302		}
6303
6304	}
6305
6306	Material.prototype.isMaterial = true;
6307
6308	const _colorKeywords = {
6309		'aliceblue': 0xF0F8FF,
6310		'antiquewhite': 0xFAEBD7,
6311		'aqua': 0x00FFFF,
6312		'aquamarine': 0x7FFFD4,
6313		'azure': 0xF0FFFF,
6314		'beige': 0xF5F5DC,
6315		'bisque': 0xFFE4C4,
6316		'black': 0x000000,
6317		'blanchedalmond': 0xFFEBCD,
6318		'blue': 0x0000FF,
6319		'blueviolet': 0x8A2BE2,
6320		'brown': 0xA52A2A,
6321		'burlywood': 0xDEB887,
6322		'cadetblue': 0x5F9EA0,
6323		'chartreuse': 0x7FFF00,
6324		'chocolate': 0xD2691E,
6325		'coral': 0xFF7F50,
6326		'cornflowerblue': 0x6495ED,
6327		'cornsilk': 0xFFF8DC,
6328		'crimson': 0xDC143C,
6329		'cyan': 0x00FFFF,
6330		'darkblue': 0x00008B,
6331		'darkcyan': 0x008B8B,
6332		'darkgoldenrod': 0xB8860B,
6333		'darkgray': 0xA9A9A9,
6334		'darkgreen': 0x006400,
6335		'darkgrey': 0xA9A9A9,
6336		'darkkhaki': 0xBDB76B,
6337		'darkmagenta': 0x8B008B,
6338		'darkolivegreen': 0x556B2F,
6339		'darkorange': 0xFF8C00,
6340		'darkorchid': 0x9932CC,
6341		'darkred': 0x8B0000,
6342		'darksalmon': 0xE9967A,
6343		'darkseagreen': 0x8FBC8F,
6344		'darkslateblue': 0x483D8B,
6345		'darkslategray': 0x2F4F4F,
6346		'darkslategrey': 0x2F4F4F,
6347		'darkturquoise': 0x00CED1,
6348		'darkviolet': 0x9400D3,
6349		'deeppink': 0xFF1493,
6350		'deepskyblue': 0x00BFFF,
6351		'dimgray': 0x696969,
6352		'dimgrey': 0x696969,
6353		'dodgerblue': 0x1E90FF,
6354		'firebrick': 0xB22222,
6355		'floralwhite': 0xFFFAF0,
6356		'forestgreen': 0x228B22,
6357		'fuchsia': 0xFF00FF,
6358		'gainsboro': 0xDCDCDC,
6359		'ghostwhite': 0xF8F8FF,
6360		'gold': 0xFFD700,
6361		'goldenrod': 0xDAA520,
6362		'gray': 0x808080,
6363		'green': 0x008000,
6364		'greenyellow': 0xADFF2F,
6365		'grey': 0x808080,
6366		'honeydew': 0xF0FFF0,
6367		'hotpink': 0xFF69B4,
6368		'indianred': 0xCD5C5C,
6369		'indigo': 0x4B0082,
6370		'ivory': 0xFFFFF0,
6371		'khaki': 0xF0E68C,
6372		'lavender': 0xE6E6FA,
6373		'lavenderblush': 0xFFF0F5,
6374		'lawngreen': 0x7CFC00,
6375		'lemonchiffon': 0xFFFACD,
6376		'lightblue': 0xADD8E6,
6377		'lightcoral': 0xF08080,
6378		'lightcyan': 0xE0FFFF,
6379		'lightgoldenrodyellow': 0xFAFAD2,
6380		'lightgray': 0xD3D3D3,
6381		'lightgreen': 0x90EE90,
6382		'lightgrey': 0xD3D3D3,
6383		'lightpink': 0xFFB6C1,
6384		'lightsalmon': 0xFFA07A,
6385		'lightseagreen': 0x20B2AA,
6386		'lightskyblue': 0x87CEFA,
6387		'lightslategray': 0x778899,
6388		'lightslategrey': 0x778899,
6389		'lightsteelblue': 0xB0C4DE,
6390		'lightyellow': 0xFFFFE0,
6391		'lime': 0x00FF00,
6392		'limegreen': 0x32CD32,
6393		'linen': 0xFAF0E6,
6394		'magenta': 0xFF00FF,
6395		'maroon': 0x800000,
6396		'mediumaquamarine': 0x66CDAA,
6397		'mediumblue': 0x0000CD,
6398		'mediumorchid': 0xBA55D3,
6399		'mediumpurple': 0x9370DB,
6400		'mediumseagreen': 0x3CB371,
6401		'mediumslateblue': 0x7B68EE,
6402		'mediumspringgreen': 0x00FA9A,
6403		'mediumturquoise': 0x48D1CC,
6404		'mediumvioletred': 0xC71585,
6405		'midnightblue': 0x191970,
6406		'mintcream': 0xF5FFFA,
6407		'mistyrose': 0xFFE4E1,
6408		'moccasin': 0xFFE4B5,
6409		'navajowhite': 0xFFDEAD,
6410		'navy': 0x000080,
6411		'oldlace': 0xFDF5E6,
6412		'olive': 0x808000,
6413		'olivedrab': 0x6B8E23,
6414		'orange': 0xFFA500,
6415		'orangered': 0xFF4500,
6416		'orchid': 0xDA70D6,
6417		'palegoldenrod': 0xEEE8AA,
6418		'palegreen': 0x98FB98,
6419		'paleturquoise': 0xAFEEEE,
6420		'palevioletred': 0xDB7093,
6421		'papayawhip': 0xFFEFD5,
6422		'peachpuff': 0xFFDAB9,
6423		'peru': 0xCD853F,
6424		'pink': 0xFFC0CB,
6425		'plum': 0xDDA0DD,
6426		'powderblue': 0xB0E0E6,
6427		'purple': 0x800080,
vendor: 8,788 bytes, lines 6428-6828
6428		'rebeccapurple': 0x663399,
6429		'red': 0xFF0000,
6430		'rosybrown': 0xBC8F8F,
6431		'royalblue': 0x4169E1,
6432		'saddlebrown': 0x8B4513,
6433		'salmon': 0xFA8072,
6434		'sandybrown': 0xF4A460,
6435		'seagreen': 0x2E8B57,
6436		'seashell': 0xFFF5EE,
6437		'sienna': 0xA0522D,
6438		'silver': 0xC0C0C0,
6439		'skyblue': 0x87CEEB,
6440		'slateblue': 0x6A5ACD,
6441		'slategray': 0x708090,
6442		'slategrey': 0x708090,
6443		'snow': 0xFFFAFA,
6444		'springgreen': 0x00FF7F,
6445		'steelblue': 0x4682B4,
6446		'tan': 0xD2B48C,
6447		'teal': 0x008080,
6448		'thistle': 0xD8BFD8,
6449		'tomato': 0xFF6347,
6450		'turquoise': 0x40E0D0,
6451		'violet': 0xEE82EE,
6452		'wheat': 0xF5DEB3,
6453		'white': 0xFFFFFF,
6454		'whitesmoke': 0xF5F5F5,
6455		'yellow': 0xFFFF00,
6456		'yellowgreen': 0x9ACD32
6457	};
6458	const _hslA = {
6459		h: 0,
6460		s: 0,
6461		l: 0
6462	};
6463	const _hslB = {
6464		h: 0,
6465		s: 0,
6466		l: 0
6467	};
6468
6469	function hue2rgb(p, q, t) {
6470		if (t < 0) t += 1;
6471		if (t > 1) t -= 1;
6472		if (t < 1 / 6) return p + (q - p) * 6 * t;
6473		if (t < 1 / 2) return q;
6474		if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t);
6475		return p;
6476	}
6477
6478	function SRGBToLinear(c) {
6479		return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
6480	}
6481
6482	function LinearToSRGB(c) {
6483		return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055;
6484	}
6485
6486	class Color {
6487		constructor(r, g, b) {
6488			if (g === undefined && b === undefined) {
6489				// r is THREE.Color, hex or string
6490				return this.set(r);
6491			}
6492
6493			return this.setRGB(r, g, b);
6494		}
6495
6496		set(value) {
6497			if (value && value.isColor) {
6498				this.copy(value);
6499			} else if (typeof value === 'number') {
6500				this.setHex(value);
6501			} else if (typeof value === 'string') {
6502				this.setStyle(value);
6503			}
6504
6505			return this;
6506		}
6507
6508		setScalar(scalar) {
6509			this.r = scalar;
6510			this.g = scalar;
6511			this.b = scalar;
6512			return this;
6513		}
6514
6515		setHex(hex) {
6516			hex = Math.floor(hex);
6517			this.r = (hex >> 16 & 255) / 255;
6518			this.g = (hex >> 8 & 255) / 255;
6519			this.b = (hex & 255) / 255;
6520			return this;
6521		}
6522
6523		setRGB(r, g, b) {
6524			this.r = r;
6525			this.g = g;
6526			this.b = b;
6527			return this;
6528		}
6529
6530		setHSL(h, s, l) {
6531			// h,s,l ranges are in 0.0 - 1.0
6532			h = euclideanModulo(h, 1);
6533			s = clamp(s, 0, 1);
6534			l = clamp(l, 0, 1);
6535
6536			if (s === 0) {
6537				this.r = this.g = this.b = l;
6538			} else {
6539				const p = l <= 0.5 ? l * (1 + s) : l + s - l * s;
6540				const q = 2 * l - p;
6541				this.r = hue2rgb(q, p, h + 1 / 3);
6542				this.g = hue2rgb(q, p, h);
6543				this.b = hue2rgb(q, p, h - 1 / 3);
6544			}
6545
6546			return this;
6547		}
6548
6549		setStyle(style) {
6550			function handleAlpha(string) {
6551				if (string === undefined) return;
6552
6553				if (parseFloat(string) < 1) {
6554					console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.');
6555				}
6556			}
6557
6558			let m;
6559
6560			if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) {
6561				// rgb / hsl
6562				let color;
6563				const name = m[1];
6564				const components = m[2];
6565
6566				switch (name) {
6567					case 'rgb':
6568					case 'rgba':
6569						if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
6570							// rgb(255,0,0) rgba(255,0,0,0.5)
6571							this.r = Math.min(255, parseInt(color[1], 10)) / 255;
6572							this.g = Math.min(255, parseInt(color[2], 10)) / 255;
6573							this.b = Math.min(255, parseInt(color[3], 10)) / 255;
6574							handleAlpha(color[4]);
6575							return this;
6576						}
6577
6578						if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
6579							// rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
6580							this.r = Math.min(100, parseInt(color[1], 10)) / 100;
6581							this.g = Math.min(100, parseInt(color[2], 10)) / 100;
6582							this.b = Math.min(100, parseInt(color[3], 10)) / 100;
6583							handleAlpha(color[4]);
6584							return this;
6585						}
6586
6587						break;
6588
6589					case 'hsl':
6590					case 'hsla':
6591						if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
6592							// hsl(120,50%,50%) hsla(120,50%,50%,0.5)
6593							const h = parseFloat(color[1]) / 360;
6594							const s = parseInt(color[2], 10) / 100;
6595							const l = parseInt(color[3], 10) / 100;
6596							handleAlpha(color[4]);
6597							return this.setHSL(h, s, l);
6598						}
6599
6600						break;
6601				}
6602			} else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) {
6603				// hex color
6604				const hex = m[1];
6605				const size = hex.length;
6606
6607				if (size === 3) {
6608					// #ff0
6609					this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255;
6610					this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255;
6611					this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255;
6612					return this;
6613				} else if (size === 6) {
6614					// #ff0000
6615					this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255;
6616					this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255;
6617					this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255;
6618					return this;
6619				}
6620			}
6621
6622			if (style && style.length > 0) {
6623				return this.setColorName(style);
6624			}
6625
6626			return this;
6627		}
6628
6629		setColorName(style) {
6630			// color keywords
6631			const hex = _colorKeywords[style.toLowerCase()];
6632
6633			if (hex !== undefined) {
6634				// red
6635				this.setHex(hex);
6636			} else {
6637				// unknown color
6638				console.warn('THREE.Color: Unknown color ' + style);
6639			}
6640
6641			return this;
6642		}
6643
6644		clone() {
6645			return new this.constructor(this.r, this.g, this.b);
6646		}
6647
6648		copy(color) {
6649			this.r = color.r;
6650			this.g = color.g;
6651			this.b = color.b;
6652			return this;
6653		}
6654
6655		copySRGBToLinear(color) {
6656			this.r = SRGBToLinear(color.r);
6657			this.g = SRGBToLinear(color.g);
6658			this.b = SRGBToLinear(color.b);
6659			return this;
6660		}
6661
6662		copyLinearToSRGB(color) {
6663			this.r = LinearToSRGB(color.r);
6664			this.g = LinearToSRGB(color.g);
6665			this.b = LinearToSRGB(color.b);
6666			return this;
6667		}
6668
6669		convertSRGBToLinear() {
6670			this.copySRGBToLinear(this);
6671			return this;
6672		}
6673
6674		convertLinearToSRGB() {
6675			this.copyLinearToSRGB(this);
6676			return this;
6677		}
6678
6679		getHex() {
6680			return this.r * 255 << 16 ^ this.g * 255 << 8 ^ this.b * 255 << 0;
6681		}
6682
6683		getHexString() {
6684			return ('000000' + this.getHex().toString(16)).slice(-6);
6685		}
6686
6687		getHSL(target) {
6688			// h,s,l ranges are in 0.0 - 1.0
6689			const r = this.r,
6690						g = this.g,
6691						b = this.b;
6692			const max = Math.max(r, g, b);
6693			const min = Math.min(r, g, b);
6694			let hue, saturation;
6695			const lightness = (min + max) / 2.0;
6696
6697			if (min === max) {
6698				hue = 0;
6699				saturation = 0;
6700			} else {
6701				const delta = max - min;
6702				saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
6703
6704				switch (max) {
6705					case r:
6706						hue = (g - b) / delta + (g < b ? 6 : 0);
6707						break;
6708
6709					case g:
6710						hue = (b - r) / delta + 2;
6711						break;
6712
6713					case b:
6714						hue = (r - g) / delta + 4;
6715						break;
6716				}
6717
6718				hue /= 6;
6719			}
6720
6721			target.h = hue;
6722			target.s = saturation;
6723			target.l = lightness;
6724			return target;
6725		}
6726
6727		getStyle() {
6728			return 'rgb(' + (this.r * 255 | 0) + ',' + (this.g * 255 | 0) + ',' + (this.b * 255 | 0) + ')';
6729		}
6730
6731		offsetHSL(h, s, l) {
6732			this.getHSL(_hslA);
6733			_hslA.h += h;
6734			_hslA.s += s;
6735			_hslA.l += l;
6736			this.setHSL(_hslA.h, _hslA.s, _hslA.l);
6737			return this;
6738		}
6739
6740		add(color) {
6741			this.r += color.r;
6742			this.g += color.g;
6743			this.b += color.b;
6744			return this;
6745		}
6746
6747		addColors(color1, color2) {
6748			this.r = color1.r + color2.r;
6749			this.g = color1.g + color2.g;
6750			this.b = color1.b + color2.b;
6751			return this;
6752		}
6753
6754		addScalar(s) {
6755			this.r += s;
6756			this.g += s;
6757			this.b += s;
6758			return this;
6759		}
6760
6761		sub(color) {
6762			this.r = Math.max(0, this.r - color.r);
6763			this.g = Math.max(0, this.g - color.g);
6764			this.b = Math.max(0, this.b - color.b);
6765			return this;
6766		}
6767
6768		multiply(color) {
6769			this.r *= color.r;
6770			this.g *= color.g;
6771			this.b *= color.b;
6772			return this;
6773		}
6774
6775		multiplyScalar(s) {
6776			this.r *= s;
6777			this.g *= s;
6778			this.b *= s;
6779			return this;
6780		}
6781
6782		lerp(color, alpha) {
6783			this.r += (color.r - this.r) * alpha;
6784			this.g += (color.g - this.g) * alpha;
6785			this.b += (color.b - this.b) * alpha;
6786			return this;
6787		}
6788
6789		lerpColors(color1, color2, alpha) {
6790			this.r = color1.r + (color2.r - color1.r) * alpha;
6791			this.g = color1.g + (color2.g - color1.g) * alpha;
6792			this.b = color1.b + (color2.b - color1.b) * alpha;
6793			return this;
6794		}
6795
6796		lerpHSL(color, alpha) {
6797			this.getHSL(_hslA);
6798			color.getHSL(_hslB);
6799			const h = lerp(_hslA.h, _hslB.h, alpha);
6800			const s = lerp(_hslA.s, _hslB.s, alpha);
6801			const l = lerp(_hslA.l, _hslB.l, alpha);
6802			this.setHSL(h, s, l);
6803			return this;
6804		}
6805
6806		equals(c) {
6807			return c.r === this.r && c.g === this.g && c.b === this.b;
6808		}
6809
6810		fromArray(array, offset = 0) {
6811			this.r = array[offset];
6812			this.g = array[offset + 1];
6813			this.b = array[offset + 2];
6814			return this;
6815		}
6816
6817		toArray(array = [], offset = 0) {
6818			array[offset] = this.r;
6819			array[offset + 1] = this.g;
6820			array[offset + 2] = this.b;
6821			return array;
6822		}
6823
6824		fromBufferAttribute(attribute, index) {
6825			this.r = attribute.getX(index);
6826			this.g = attribute.getY(index);
6827			this.b = attribute.getZ(index);
6828
6829			if (attribute.normalized === true) {
6830				// assuming Uint8Array
6831				this.r /= 255;
6832				this.g /= 255;
6833				this.b /= 255;
6834			}
6835
6836			return this;
6837		}
6838
6839		toJSON() {
6840			return this.getHex();
6841		}
6842
6843	}
6844
6845	Color.NAMES = _colorKeywords;
6846	Color.prototype.isColor = true;
6847	Color.prototype.r = 1;
6848	Color.prototype.g = 1;
6849	Color.prototype.b = 1;
6850
6851	/**
6852	 * parameters = {
6853	 *	color: <hex>,
6854	 *	opacity: <float>,
6855	 *	map: new THREE.Texture( <Image> ),
6856	 *
6857	 *	lightMap: new THREE.Texture( <Image> ),
6858	 *	lightMapIntensity: <float>
6859	 *
6860	 *	aoMap: new THREE.Texture( <Image> ),
6861	 *	aoMapIntensity: <float>
6862	 *
6863	 *	specularMap: new THREE.Texture( <Image> ),
6864	 *
6865	 *	alphaMap: new THREE.Texture( <Image> ),
6866	 *
6867	 *	envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
6868	 *	combine: THREE.Multiply,
6869	 *	reflectivity: <float>,
6870	 *	refractionRatio: <float>,
6871	 *
6872	 *	depthTest: <bool>,
6873	 *	depthWrite: <bool>,
6874	 *
6875	 *	wireframe: <boolean>,
6876	 *	wireframeLinewidth: <float>,
6877	 * }
6878	 */
6879
6880	class MeshBasicMaterial extends Material {
6881		constructor(parameters) {
6882			super();
6883			this.type = 'MeshBasicMaterial';
6884			this.color = new Color(0xffffff); // emissive
6885
6886			this.map = null;
6887			this.lightMap = null;
6888			this.lightMapIntensity = 1.0;
6889			this.aoMap = null;
6890			this.aoMapIntensity = 1.0;
6891			this.specularMap = null;
6892			this.alphaMap = null;
6893			this.envMap = null;
6894			this.combine = MultiplyOperation;
6895			this.reflectivity = 1;
6896			this.refractionRatio = 0.98;
6897			this.wireframe = false;
6898			this.wireframeLinewidth = 1;
6899			this.wireframeLinecap = 'round';
6900			this.wireframeLinejoin = 'round';
6901			this.setValues(parameters);
6902		}
6903
6904		copy(source) {
6905			super.copy(source);
6906			this.color.copy(source.color);
6907			this.map = source.map;
6908			this.lightMap = source.lightMap;
6909			this.lightMapIntensity = source.lightMapIntensity;
6910			this.aoMap = source.aoMap;
6911			this.aoMapIntensity = source.aoMapIntensity;
6912			this.specularMap = source.specularMap;
6913			this.alphaMap = source.alphaMap;
6914			this.envMap = source.envMap;
6915			this.combine = source.combine;
6916			this.reflectivity = source.reflectivity;
6917			this.refractionRatio = source.refractionRatio;
6918			this.wireframe = source.wireframe;
6919			this.wireframeLinewidth = source.wireframeLinewidth;
6920			this.wireframeLinecap = source.wireframeLinecap;
6921			this.wireframeLinejoin = source.wireframeLinejoin;
6922			return this;
6923		}
6924
6925	}
6926
6927	MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
6928
6929	const _vector$9 = /*@__PURE__*/new Vector3();
6930
6931	const _vector2$1 = /*@__PURE__*/new Vector2();
6932
6933	class BufferAttribute {
6934		constructor(array, itemSize, normalized) {
6935			if (Array.isArray(array)) {
6936				throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.');
6937			}
6938
6939			this.name = '';
6940			this.array = array;
6941			this.itemSize = itemSize;
6942			this.count = array !== undefined ? array.length / itemSize : 0;
6943			this.normalized = normalized === true;
6944			this.usage = StaticDrawUsage;
6945			this.updateRange = {
6946				offset: 0,
6947				count: -1
6948			};
6949			this.version = 0;
6950		}
6951
6952		onUploadCallback() {}
6953
6954		set needsUpdate(value) {
6955			if (value === true) this.version++;
6956		}
6957
6958		setUsage(value) {
6959			this.usage = value;
6960			return this;
6961		}
6962
6963		copy(source) {
6964			this.name = source.name;
6965			this.array = new source.array.constructor(source.array);
6966			this.itemSize = source.itemSize;
6967			this.count = source.count;
6968			this.normalized = source.normalized;
6969			this.usage = source.usage;
6970			return this;
6971		}
6972
6973		copyAt(index1, attribute, index2) {
6974			index1 *= this.itemSize;
6975			index2 *= attribute.itemSize;
6976
6977			for (let i = 0, l = this.itemSize; i < l; i++) {
6978				this.array[index1 + i] = attribute.array[index2 + i];
6979			}
6980
6981			return this;
6982		}
6983
6984		copyArray(array) {
6985			this.array.set(array);
6986			return this;
6987		}
6988
6989		copyColorsArray(colors) {
6990			const array = this.array;
6991			let offset = 0;
6992
6993			for (let i = 0, l = colors.length; i < l; i++) {
6994				let color = colors[i];
6995
6996				if (color === undefined) {
6997					console.warn('THREE.BufferAttribute.copyColorsArray(): color is undefined', i);
6998					color = new Color();
6999				}
7000
7001				array[offset++] = color.r;
7002				array[offset++] = color.g;
7003				array[offset++] = color.b;
7004			}
7005
7006			return this;
7007		}
7008
7009		copyVector2sArray(vectors) {
7010			const array = this.array;
7011			let offset = 0;
7012
7013			for (let i = 0, l = vectors.length; i < l; i++) {
7014				let vector = vectors[i];
7015
7016				if (vector === undefined) {
7017					console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i);
7018					vector = new Vector2();
7019				}
7020
7021				array[offset++] = vector.x;
7022				array[offset++] = vector.y;
7023			}
7024
7025			return this;
7026		}
7027
7028		copyVector3sArray(vectors) {
7029			const array = this.array;
7030			let offset = 0;
7031
7032			for (let i = 0, l = vectors.length; i < l; i++) {
7033				let vector = vectors[i];
7034
7035				if (vector === undefined) {
7036					console.warn('THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i);
7037					vector = new Vector3();
7038				}
7039
7040				array[offset++] = vector.x;
7041				array[offset++] = vector.y;
7042				array[offset++] = vector.z;
7043			}
7044
7045			return this;
7046		}
7047
7048		copyVector4sArray(vectors) {
7049			const array = this.array;
7050			let offset = 0;
7051
7052			for (let i = 0, l = vectors.length; i < l; i++) {
7053				let vector = vectors[i];
7054
7055				if (vector === undefined) {
7056					console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i);
7057					vector = new Vector4();
7058				}
7059
7060				array[offset++] = vector.x;
7061				array[offset++] = vector.y;
7062				array[offset++] = vector.z;
7063				array[offset++] = vector.w;
7064			}
7065
7066			return this;
7067		}
7068
7069		applyMatrix3(m) {
7070			if (this.itemSize === 2) {
7071				for (let i = 0, l = this.count; i < l; i++) {
7072					_vector2$1.fromBufferAttribute(this, i);
7073
7074					_vector2$1.applyMatrix3(m);
7075
7076					this.setXY(i, _vector2$1.x, _vector2$1.y);
7077				}
7078			} else if (this.itemSize === 3) {
7079				for (let i = 0, l = this.count; i < l; i++) {
7080					_vector$9.fromBufferAttribute(this, i);
7081
7082					_vector$9.applyMatrix3(m);
7083
7084					this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
7085				}
7086			}
7087
7088			return this;
7089		}
7090
7091		applyMatrix4(m) {
7092			for (let i = 0, l = this.count; i < l; i++) {
7093				_vector$9.x = this.getX(i);
7094				_vector$9.y = this.getY(i);
7095				_vector$9.z = this.getZ(i);
7096
7097				_vector$9.applyMatrix4(m);
7098
7099				this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
7100			}
7101
7102			return this;
7103		}
7104
7105		applyNormalMatrix(m) {
7106			for (let i = 0, l = this.count; i < l; i++) {
7107				_vector$9.x = this.getX(i);
7108				_vector$9.y = this.getY(i);
7109				_vector$9.z = this.getZ(i);
7110
7111				_vector$9.applyNormalMatrix(m);
7112
7113				this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
7114			}
7115
7116			return this;
7117		}
7118
7119		transformDirection(m) {
7120			for (let i = 0, l = this.count; i < l; i++) {
7121				_vector$9.x = this.getX(i);
7122				_vector$9.y = this.getY(i);
7123				_vector$9.z = this.getZ(i);
7124
7125				_vector$9.transformDirection(m);
7126
7127				this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
7128			}
7129
7130			return this;
7131		}
7132
7133		set(value, offset = 0) {
7134			this.array.set(value, offset);
7135			return this;
7136		}
7137
7138		getX(index) {
7139			return this.array[index * this.itemSize];
7140		}
7141
7142		setX(index, x) {
7143			this.array[index * this.itemSize] = x;
7144			return this;
7145		}
7146
7147		getY(index) {
7148			return this.array[index * this.itemSize + 1];
7149		}
7150
7151		setY(index, y) {
7152			this.array[index * this.itemSize + 1] = y;
7153			return this;
7154		}
7155
7156		getZ(index) {
7157			return this.array[index * this.itemSize + 2];
7158		}
7159
7160		setZ(index, z) {
7161			this.array[index * this.itemSize + 2] = z;
7162			return this;
7163		}
7164
7165		getW(index) {
7166			return this.array[index * this.itemSize + 3];
7167		}
7168
7169		setW(index, w) {
7170			this.array[index * this.itemSize + 3] = w;
7171			return this;
7172		}
7173
7174		setXY(index, x, y) {
7175			index *= this.itemSize;
7176			this.array[index + 0] = x;
7177			this.array[index + 1] = y;
7178			return this;
7179		}
7180
7181		setXYZ(index, x, y, z) {
7182			index *= this.itemSize;
7183			this.array[index + 0] = x;
7184			this.array[index + 1] = y;
7185			this.array[index + 2] = z;
7186			return this;
7187		}
7188
7189		setXYZW(index, x, y, z, w) {
7190			index *= this.itemSize;
7191			this.array[index + 0] = x;
7192			this.array[index + 1] = y;
7193			this.array[index + 2] = z;
7194			this.array[index + 3] = w;
7195			return this;
7196		}
7197
7198		onUpload(callback) {
7199			this.onUploadCallback = callback;
7200			return this;
7201		}
7202
7203		clone() {
7204			return new this.constructor(this.array, this.itemSize).copy(this);
7205		}
7206
7207		toJSON() {
7208			const data = {
7209				itemSize: this.itemSize,
7210				type: this.array.constructor.name,
7211				array: Array.prototype.slice.call(this.array),
7212				normalized: this.normalized
7213			};
7214			if (this.name !== '') data.name = this.name;
7215			if (this.usage !== StaticDrawUsage) data.usage = this.usage;
7216			if (this.updateRange.offset !== 0 || this.updateRange.count !== -1) data.updateRange = this.updateRange;
7217			return data;
7218		}
7219
7220	}
7221
7222	BufferAttribute.prototype.isBufferAttribute = true; //
7223
7224	class Int8BufferAttribute extends BufferAttribute {
7225		constructor(array, itemSize, normalized) {
7226			super(new Int8Array(array), itemSize, normalized);
7227		}
7228
7229	}
7230
7231	class Uint8BufferAttribute extends BufferAttribute {
7232		constructor(array, itemSize, normalized) {
7233			super(new Uint8Array(array), itemSize, normalized);
7234		}
7235
7236	}
7237
7238	class Uint8ClampedBufferAttribute extends BufferAttribute {
7239		constructor(array, itemSize, normalized) {
7240			super(new Uint8ClampedArray(array), itemSize, normalized);
7241		}
7242
7243	}
7244
7245	class Int16BufferAttribute extends BufferAttribute {
7246		constructor(array, itemSize, normalized) {
7247			super(new Int16Array(array), itemSize, normalized);
7248		}
7249
7250	}
7251
7252	class Uint16BufferAttribute extends BufferAttribute {
7253		constructor(array, itemSize, normalized) {
7254			super(new Uint16Array(array), itemSize, normalized);
7255		}
7256
7257	}
7258
7259	class Int32BufferAttribute extends BufferAttribute {
7260		constructor(array, itemSize, normalized) {
7261			super(new Int32Array(array), itemSize, normalized);
7262		}
7263
7264	}
7265
7266	class Uint32BufferAttribute extends BufferAttribute {
7267		constructor(array, itemSize, normalized) {
7268			super(new Uint32Array(array), itemSize, normalized);
7269		}
7270
7271	}
7272
7273	class Float16BufferAttribute extends BufferAttribute {
7274		constructor(array, itemSize, normalized) {
7275			super(new Uint16Array(array), itemSize, normalized);
7276		}
7277
7278	}
7279
7280	Float16BufferAttribute.prototype.isFloat16BufferAttribute = true;
7281
7282	class Float32BufferAttribute extends BufferAttribute {
7283		constructor(array, itemSize, normalized) {
7284			super(new Float32Array(array), itemSize, normalized);
7285		}
7286
7287	}
7288
7289	class Float64BufferAttribute extends BufferAttribute {
7290		constructor(array, itemSize, normalized) {
7291			super(new Float64Array(array), itemSize, normalized);
7292		}
7293
7294	} //
7295
7296	let _id$1 = 0;
7297
7298	const _m1 = /*@__PURE__*/new Matrix4();
7299
7300	const _obj = /*@__PURE__*/new Object3D();
7301
7302	const _offset = /*@__PURE__*/new Vector3();
7303
7304	const _box$1 = /*@__PURE__*/new Box3();
7305
7306	const _boxMorphTargets = /*@__PURE__*/new Box3();
7307
7308	const _vector$8 = /*@__PURE__*/new Vector3();
7309
vendor: 3,875 bytes, lines 7310-7500
7310	class BufferGeometry extends EventDispatcher {
7311		constructor() {
7312			super();
7313			Object.defineProperty(this, 'id', {
7314				value: _id$1++
7315			});
7316			this.uuid = generateUUID();
7317			this.name = '';
7318			this.type = 'BufferGeometry';
7319			this.index = null;
7320			this.attributes = {};
7321			this.morphAttributes = {};
7322			this.morphTargetsRelative = false;
7323			this.groups = [];
7324			this.boundingBox = null;
7325			this.boundingSphere = null;
7326			this.drawRange = {
7327				start: 0,
7328				count: Infinity
7329			};
7330			this.userData = {};
7331		}
7332
7333		getIndex() {
7334			return this.index;
7335		}
7336
7337		setIndex(index) {
7338			if (Array.isArray(index)) {
7339				this.index = new (arrayMax(index) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1);
7340			} else {
7341				this.index = index;
7342			}
7343
7344			return this;
7345		}
7346
7347		getAttribute(name) {
7348			return this.attributes[name];
7349		}
7350
7351		setAttribute(name, attribute) {
7352			this.attributes[name] = attribute;
7353			return this;
7354		}
7355
7356		deleteAttribute(name) {
7357			delete this.attributes[name];
7358			return this;
7359		}
7360
7361		hasAttribute(name) {
7362			return this.attributes[name] !== undefined;
7363		}
7364
7365		addGroup(start, count, materialIndex = 0) {
7366			this.groups.push({
7367				start: start,
7368				count: count,
7369				materialIndex: materialIndex
7370			});
7371		}
7372
7373		clearGroups() {
7374			this.groups = [];
7375		}
7376
7377		setDrawRange(start, count) {
7378			this.drawRange.start = start;
7379			this.drawRange.count = count;
7380		}
7381
7382		applyMatrix4(matrix) {
7383			const position = this.attributes.position;
7384
7385			if (position !== undefined) {
7386				position.applyMatrix4(matrix);
7387				position.needsUpdate = true;
7388			}
7389
7390			const normal = this.attributes.normal;
7391
7392			if (normal !== undefined) {
7393				const normalMatrix = new Matrix3().getNormalMatrix(matrix);
7394				normal.applyNormalMatrix(normalMatrix);
7395				normal.needsUpdate = true;
7396			}
7397
7398			const tangent = this.attributes.tangent;
7399
7400			if (tangent !== undefined) {
7401				tangent.transformDirection(matrix);
7402				tangent.needsUpdate = true;
7403			}
7404
7405			if (this.boundingBox !== null) {
7406				this.computeBoundingBox();
7407			}
7408
7409			if (this.boundingSphere !== null) {
7410				this.computeBoundingSphere();
7411			}
7412
7413			return this;
7414		}
7415
7416		applyQuaternion(q) {
7417			_m1.makeRotationFromQuaternion(q);
7418
7419			this.applyMatrix4(_m1);
7420			return this;
7421		}
7422
7423		rotateX(angle) {
7424			// rotate geometry around world x-axis
7425			_m1.makeRotationX(angle);
7426
7427			this.applyMatrix4(_m1);
7428			return this;
7429		}
7430
7431		rotateY(angle) {
7432			// rotate geometry around world y-axis
7433			_m1.makeRotationY(angle);
7434
7435			this.applyMatrix4(_m1);
7436			return this;
7437		}
7438
7439		rotateZ(angle) {
7440			// rotate geometry around world z-axis
7441			_m1.makeRotationZ(angle);
7442
7443			this.applyMatrix4(_m1);
7444			return this;
7445		}
7446
7447		translate(x, y, z) {
7448			// translate geometry
7449			_m1.makeTranslation(x, y, z);
7450
7451			this.applyMatrix4(_m1);
7452			return this;
7453		}
7454
7455		scale(x, y, z) {
7456			// scale geometry
7457			_m1.makeScale(x, y, z);
7458
7459			this.applyMatrix4(_m1);
7460			return this;
7461		}
7462
7463		lookAt(vector) {
7464			_obj.lookAt(vector);
7465
7466			_obj.updateMatrix();
7467
7468			this.applyMatrix4(_obj.matrix);
7469			return this;
7470		}
7471
7472		center() {
7473			this.computeBoundingBox();
7474			this.boundingBox.getCenter(_offset).negate();
7475			this.translate(_offset.x, _offset.y, _offset.z);
7476			return this;
7477		}
7478
7479		setFromPoints(points) {
7480			const position = [];
7481
7482			for (let i = 0, l = points.length; i < l; i++) {
7483				const point = points[i];
7484				position.push(point.x, point.y, point.z || 0);
7485			}
7486
7487			this.setAttribute('position', new Float32BufferAttribute(position, 3));
7488			return this;
7489		}
7490
7491		computeBoundingBox() {
7492			if (this.boundingBox === null) {
7493				this.boundingBox = new Box3();
7494			}
7495
7496			const position = this.attributes.position;
7497			const morphAttributesPosition = this.morphAttributes.position;
7498
7499			if (position && position.isGLBufferAttribute) {
7500				console.error('THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "fal
vendor: 1,673 bytes, lines 7500-7546
7500se".', this);
7501				this.boundingBox.set(new Vector3(-Infinity, -Infinity, -Infinity), new Vector3(+Infinity, +Infinity, +Infinity));
7502				return;
7503			}
7504
7505			if (position !== undefined) {
7506				this.boundingBox.setFromBufferAttribute(position); // process morph attributes if present
7507
7508				if (morphAttributesPosition) {
7509					for (let i = 0, il = morphAttributesPosition.length; i < il; i++) {
7510						const morphAttribute = morphAttributesPosition[i];
7511
7512						_box$1.setFromBufferAttribute(morphAttribute);
7513
7514						if (this.morphTargetsRelative) {
7515							_vector$8.addVectors(this.boundingBox.min, _box$1.min);
7516
7517							this.boundingBox.expandByPoint(_vector$8);
7518
7519							_vector$8.addVectors(this.boundingBox.max, _box$1.max);
7520
7521							this.boundingBox.expandByPoint(_vector$8);
7522						} else {
7523							this.boundingBox.expandByPoint(_box$1.min);
7524							this.boundingBox.expandByPoint(_box$1.max);
7525						}
7526					}
7527				}
7528			} else {
7529				this.boundingBox.makeEmpty();
7530			}
7531
7532			if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) {
7533				console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this);
7534			}
7535		}
7536
7537		computeBoundingSphere() {
7538			if (this.boundingSphere === null) {
7539				this.boundingSphere = new Sphere();
7540			}
7541
7542			const position = this.attributes.position;
7543			const morphAttributesPosition = this.morphAttributes.position;
7544
7545			if (position && position.isGLBufferAttribute) {
7546				console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "fal
vendor: 4,316 bytes, lines 7546-7688
7546se".', this);
7547				this.boundingSphere.set(new Vector3(), Infinity);
7548				return;
7549			}
7550
7551			if (position) {
7552				// first, find the center of the bounding sphere
7553				const center = this.boundingSphere.center;
7554
7555				_box$1.setFromBufferAttribute(position); // process morph attributes if present
7556
7557
7558				if (morphAttributesPosition) {
7559					for (let i = 0, il = morphAttributesPosition.length; i < il; i++) {
7560						const morphAttribute = morphAttributesPosition[i];
7561
7562						_boxMorphTargets.setFromBufferAttribute(morphAttribute);
7563
7564						if (this.morphTargetsRelative) {
7565							_vector$8.addVectors(_box$1.min, _boxMorphTargets.min);
7566
7567							_box$1.expandByPoint(_vector$8);
7568
7569							_vector$8.addVectors(_box$1.max, _boxMorphTargets.max);
7570
7571							_box$1.expandByPoint(_vector$8);
7572						} else {
7573							_box$1.expandByPoint(_boxMorphTargets.min);
7574
7575							_box$1.expandByPoint(_boxMorphTargets.max);
7576						}
7577					}
7578				}
7579
7580				_box$1.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the
7581				// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
7582
7583
7584				let maxRadiusSq = 0;
7585
7586				for (let i = 0, il = position.count; i < il; i++) {
7587					_vector$8.fromBufferAttribute(position, i);
7588
7589					maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8));
7590				} // process morph attributes if present
7591
7592
7593				if (morphAttributesPosition) {
7594					for (let i = 0, il = morphAttributesPosition.length; i < il; i++) {
7595						const morphAttribute = morphAttributesPosition[i];
7596						const morphTargetsRelative = this.morphTargetsRelative;
7597
7598						for (let j = 0, jl = morphAttribute.count; j < jl; j++) {
7599							_vector$8.fromBufferAttribute(morphAttribute, j);
7600
7601							if (morphTargetsRelative) {
7602								_offset.fromBufferAttribute(position, j);
7603
7604								_vector$8.add(_offset);
7605							}
7606
7607							maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8));
7608						}
7609					}
7610				}
7611
7612				this.boundingSphere.radius = Math.sqrt(maxRadiusSq);
7613
7614				if (isNaN(this.boundingSphere.radius)) {
7615					console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this);
7616				}
7617			}
7618		}
7619
7620		computeTangents() {
7621			const index = this.index;
7622			const attributes = this.attributes; // based on http://www.terathon.com/code/tangent.html
7623			// (per vertex tangents)
7624
7625			if (index === null || attributes.position === undefined || attributes.normal === undefined || attributes.uv === undefined) {
7626				console.error('THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)');
7627				return;
7628			}
7629
7630			const indices = index.array;
7631			const positions = attributes.position.array;
7632			const normals = attributes.normal.array;
7633			const uvs = attributes.uv.array;
7634			const nVertices = positions.length / 3;
7635
7636			if (attributes.tangent === undefined) {
7637				this.setAttribute('tangent', new BufferAttribute(new Float32Array(4 * nVertices), 4));
7638			}
7639
7640			const tangents = attributes.tangent.array;
7641			const tan1 = [],
7642						tan2 = [];
7643
7644			for (let i = 0; i < nVertices; i++) {
7645				tan1[i] = new Vector3();
7646				tan2[i] = new Vector3();
7647			}
7648
7649			const vA = new Vector3(),
7650						vB = new Vector3(),
7651						vC = new Vector3(),
7652						uvA = new Vector2(),
7653						uvB = new Vector2(),
7654						uvC = new Vector2(),
7655						sdir = new Vector3(),
7656						tdir = new Vector3();
7657
7658			function handleTriangle(a, b, c) {
7659				vA.fromArray(positions, a * 3);
7660				vB.fromArray(positions, b * 3);
7661				vC.fromArray(positions, c * 3);
7662				uvA.fromArray(uvs, a * 2);
7663				uvB.fromArray(uvs, b * 2);
7664				uvC.fromArray(uvs, c * 2);
7665				vB.sub(vA);
7666				vC.sub(vA);
7667				uvB.sub(uvA);
7668				uvC.sub(uvA);
7669				const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y); // silently ignore degenerate uv triangles having coincident or colinear vertices
7670
7671				if (!isFinite(r)) return;
7672				sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r);
7673				tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r);
7674				tan1[a].add(sdir);
7675				tan1[b].add(sdir);
7676				tan1[c].add(sdir);
7677				tan2[a].add(tdir);
7678				tan2[b].add(tdir);
7679				tan2[c].add(tdir);
7680			}
7681
7682			let groups = this.groups;
7683
7684			if (groups.length === 0) {
7685				groups = [{
7686					start: 0,
7687					count: indices.length
7688				}
vendor: 7,918 bytes, lines 7688-7958
7688];
7689			}
7690
7691			for (let i = 0, il = groups.length; i < il; ++i) {
7692				const group = groups[i];
7693				const start = group.start;
7694				const count = group.count;
7695
7696				for (let j = start, jl = start + count; j < jl; j += 3) {
7697					handleTriangle(indices[j + 0], indices[j + 1], indices[j + 2]);
7698				}
7699			}
7700
7701			const tmp = new Vector3(),
7702						tmp2 = new Vector3();
7703			const n = new Vector3(),
7704						n2 = new Vector3();
7705
7706			function handleVertex(v) {
7707				n.fromArray(normals, v * 3);
7708				n2.copy(n);
7709				const t = tan1[v]; // Gram-Schmidt orthogonalize
7710
7711				tmp.copy(t);
7712				tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); // Calculate handedness
7713
7714				tmp2.crossVectors(n2, t);
7715				const test = tmp2.dot(tan2[v]);
7716				const w = test < 0.0 ? -1.0 : 1.0;
7717				tangents[v * 4] = tmp.x;
7718				tangents[v * 4 + 1] = tmp.y;
7719				tangents[v * 4 + 2] = tmp.z;
7720				tangents[v * 4 + 3] = w;
7721			}
7722
7723			for (let i = 0, il = groups.length; i < il; ++i) {
7724				const group = groups[i];
7725				const start = group.start;
7726				const count = group.count;
7727
7728				for (let j = start, jl = start + count; j < jl; j += 3) {
7729					handleVertex(indices[j + 0]);
7730					handleVertex(indices[j + 1]);
7731					handleVertex(indices[j + 2]);
7732				}
7733			}
7734		}
7735
7736		computeVertexNormals() {
7737			const index = this.index;
7738			const positionAttribute = this.getAttribute('position');
7739
7740			if (positionAttribute !== undefined) {
7741				let normalAttribute = this.getAttribute('normal');
7742
7743				if (normalAttribute === undefined) {
7744					normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3);
7745					this.setAttribute('normal', normalAttribute);
7746				} else {
7747					// reset existing normals to zero
7748					for (let i = 0, il = normalAttribute.count; i < il; i++) {
7749						normalAttribute.setXYZ(i, 0, 0, 0);
7750					}
7751				}
7752
7753				const pA = new Vector3(),
7754							pB = new Vector3(),
7755							pC = new Vector3();
7756				const nA = new Vector3(),
7757							nB = new Vector3(),
7758							nC = new Vector3();
7759				const cb = new Vector3(),
7760							ab = new Vector3(); // indexed elements
7761
7762				if (index) {
7763					for (let i = 0, il = index.count; i < il; i += 3) {
7764						const vA = index.getX(i + 0);
7765						const vB = index.getX(i + 1);
7766						const vC = index.getX(i + 2);
7767						pA.fromBufferAttribute(positionAttribute, vA);
7768						pB.fromBufferAttribute(positionAttribute, vB);
7769						pC.fromBufferAttribute(positionAttribute, vC);
7770						cb.subVectors(pC, pB);
7771						ab.subVectors(pA, pB);
7772						cb.cross(ab);
7773						nA.fromBufferAttribute(normalAttribute, vA);
7774						nB.fromBufferAttribute(normalAttribute, vB);
7775						nC.fromBufferAttribute(normalAttribute, vC);
7776						nA.add(cb);
7777						nB.add(cb);
7778						nC.add(cb);
7779						normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z);
7780						normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z);
7781						normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z);
7782					}
7783				} else {
7784					// non-indexed elements (unconnected triangle soup)
7785					for (let i = 0, il = positionAttribute.count; i < il; i += 3) {
7786						pA.fromBufferAttribute(positionAttribute, i + 0);
7787						pB.fromBufferAttribute(positionAttribute, i + 1);
7788						pC.fromBufferAttribute(positionAttribute, i + 2);
7789						cb.subVectors(pC, pB);
7790						ab.subVectors(pA, pB);
7791						cb.cross(ab);
7792						normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z);
7793						normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z);
7794						normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z);
7795					}
7796				}
7797
7798				this.normalizeNormals();
7799				normalAttribute.needsUpdate = true;
7800			}
7801		}
7802
7803		merge(geometry, offset) {
7804			if (!(geometry && geometry.isBufferGeometry)) {
7805				console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry);
7806				return;
7807			}
7808
7809			if (offset === undefined) {
7810				offset = 0;
7811				console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.');
7812			}
7813
7814			const attributes = this.attributes;
7815
7816			for (const key in attributes) {
7817				if (geometry.attributes[key] === undefined) continue;
7818				const attribute1 = attributes[key];
7819				const attributeArray1 = attribute1.array;
7820				const attribute2 = geometry.attributes[key];
7821				const attributeArray2 = attribute2.array;
7822				const attributeOffset = attribute2.itemSize * offset;
7823				const length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset);
7824
7825				for (let i = 0, j = attributeOffset; i < length; i++, j++) {
7826					attributeArray1[j] = attributeArray2[i];
7827				}
7828			}
7829
7830			return this;
7831		}
7832
7833		normalizeNormals() {
7834			const normals = this.attributes.normal;
7835
7836			for (let i = 0, il = normals.count; i < il; i++) {
7837				_vector$8.fromBufferAttribute(normals, i);
7838
7839				_vector$8.normalize();
7840
7841				normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z);
7842			}
7843		}
7844
7845		toNonIndexed() {
7846			function convertBufferAttribute(attribute, indices) {
7847				const array = attribute.array;
7848				const itemSize = attribute.itemSize;
7849				const normalized = attribute.normalized;
7850				const array2 = new array.constructor(indices.length * itemSize);
7851				let index = 0,
7852						index2 = 0;
7853
7854				for (let i = 0, l = indices.length; i < l; i++) {
7855					if (attribute.isInterleavedBufferAttribute) {
7856						index = indices[i] * attribute.data.stride + attribute.offset;
7857					} else {
7858						index = indices[i] * itemSize;
7859					}
7860
7861					for (let j = 0; j < itemSize; j++) {
7862						array2[index2++] = array[index++];
7863					}
7864				}
7865
7866				return new BufferAttribute(array2, itemSize, normalized);
7867			} //
7868
7869
7870			if (this.index === null) {
7871				console.warn('THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.');
7872				return this;
7873			}
7874
7875			const geometry2 = new BufferGeometry();
7876			const indices = this.index.array;
7877			const attributes = this.attributes; // attributes
7878
7879			for (const name in attributes) {
7880				const attribute = attributes[name];
7881				const newAttribute = convertBufferAttribute(attribute, indices);
7882				geometry2.setAttribute(name, newAttribute);
7883			} // morph attributes
7884
7885
7886			const morphAttributes = this.morphAttributes;
7887
7888			for (const name in morphAttributes) {
7889				const morphArray = [];
7890				const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes
7891
7892				for (let i = 0, il = morphAttribute.length; i < il; i++) {
7893					const attribute = morphAttribute[i];
7894					const newAttribute = convertBufferAttribute(attribute, indices);
7895					morphArray.push(newAttribute);
7896				}
7897
7898				geometry2.morphAttributes[name] = morphArray;
7899			}
7900
7901			geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups
7902
7903			const groups = this.groups;
7904
7905			for (let i = 0, l = groups.length; i < l; i++) {
7906				const group = groups[i];
7907				geometry2.addGroup(group.start, group.count, group.materialIndex);
7908			}
7909
7910			return geometry2;
7911		}
7912
7913		toJSON() {
7914			const data = {
7915				metadata: {
7916					version: 4.5,
7917					type: 'BufferGeometry',
7918					generator: 'BufferGeometry.toJSON'
7919				}
7920			}; // standard BufferGeometry serialization
7921
7922			data.uuid = this.uuid;
7923			data.type = this.type;
7924			if (this.name !== '') data.name = this.name;
7925			if (Object.keys(this.userData).length > 0) data.userData = this.userData;
7926
7927			if (this.parameters !== undefined) {
7928				const parameters = this.parameters;
7929
7930				for (const key in parameters) {
7931					if (parameters[key] !== undefined) data[key] = parameters[key];
7932				}
7933
7934				return data;
7935			} // for simplicity the code assumes attributes are not shared across geometries, see #15811
7936
7937
7938			data.data = {
7939				attributes: {}
7940			};
7941			const index = this.index;
7942
7943			if (index !== null) {
7944				data.data.index = {
7945					type: index.array.constructor.name,
7946					array: Array.prototype.slice.call(index.array)
7947				};
7948			}
7949
7950			const attributes = this.attributes;
7951
7952			for (const key in attributes) {
7953				const attribute = attributes[key];
7954				data.data.attributes[key] = attribute.toJSON(data.data);
7955			}
7956
7957			const morphAttributes = {};
7958			let hasMorphAttributes = false;
vendor: 4,544 bytes, lines 7959-8149
7959
7960			for (const key in this.morphAttributes) {
7961				const attributeArray = this.morphAttributes[key];
7962				const array = [];
7963
7964				for (let i = 0, il = attributeArray.length; i < il; i++) {
7965					const attribute = attributeArray[i];
7966					array.push(attribute.toJSON(data.data));
7967				}
7968
7969				if (array.length > 0) {
7970					morphAttributes[key] = array;
7971					hasMorphAttributes = true;
7972				}
7973			}
7974
7975			if (hasMorphAttributes) {
7976				data.data.morphAttributes = morphAttributes;
7977				data.data.morphTargetsRelative = this.morphTargetsRelative;
7978			}
7979
7980			const groups = this.groups;
7981
7982			if (groups.length > 0) {
7983				data.data.groups = JSON.parse(JSON.stringify(groups));
7984			}
7985
7986			const boundingSphere = this.boundingSphere;
7987
7988			if (boundingSphere !== null) {
7989				data.data.boundingSphere = {
7990					center: boundingSphere.center.toArray(),
7991					radius: boundingSphere.radius
7992				};
7993			}
7994
7995			return data;
7996		}
7997
7998		clone() {
7999			return new this.constructor().copy(this);
8000		}
8001
8002		copy(source) {
8003			// reset
8004			this.index = null;
8005			this.attributes = {};
8006			this.morphAttributes = {};
8007			this.groups = [];
8008			this.boundingBox = null;
8009			this.boundingSphere = null; // used for storing cloned, shared data
8010
8011			const data = {}; // name
8012
8013			this.name = source.name; // index
8014
8015			const index = source.index;
8016
8017			if (index !== null) {
8018				this.setIndex(index.clone(data));
8019			} // attributes
8020
8021
8022			const attributes = source.attributes;
8023
8024			for (const name in attributes) {
8025				const attribute = attributes[name];
8026				this.setAttribute(name, attribute.clone(data));
8027			} // morph attributes
8028
8029
8030			const morphAttributes = source.morphAttributes;
8031
8032			for (const name in morphAttributes) {
8033				const array = [];
8034				const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes
8035
8036				for (let i = 0, l = morphAttribute.length; i < l; i++) {
8037					array.push(morphAttribute[i].clone(data));
8038				}
8039
8040				this.morphAttributes[name] = array;
8041			}
8042
8043			this.morphTargetsRelative = source.morphTargetsRelative; // groups
8044
8045			const groups = source.groups;
8046
8047			for (let i = 0, l = groups.length; i < l; i++) {
8048				const group = groups[i];
8049				this.addGroup(group.start, group.count, group.materialIndex);
8050			} // bounding box
8051
8052
8053			const boundingBox = source.boundingBox;
8054
8055			if (boundingBox !== null) {
8056				this.boundingBox = boundingBox.clone();
8057			} // bounding sphere
8058
8059
8060			const boundingSphere = source.boundingSphere;
8061
8062			if (boundingSphere !== null) {
8063				this.boundingSphere = boundingSphere.clone();
8064			} // draw range
8065
8066
8067			this.drawRange.start = source.drawRange.start;
8068			this.drawRange.count = source.drawRange.count; // user data
8069
8070			this.userData = source.userData; // geometry generator parameters
8071
8072			if (source.parameters !== undefined) this.parameters = Object.assign({}, source.parameters);
8073			return this;
8074		}
8075
8076		dispose() {
8077			this.dispatchEvent({
8078				type: 'dispose'
8079			});
8080		}
8081
8082	}
8083
8084	BufferGeometry.prototype.isBufferGeometry = true;
8085
8086	const _inverseMatrix$2 = /*@__PURE__*/new Matrix4();
8087
8088	const _ray$2 = /*@__PURE__*/new Ray();
8089
8090	const _sphere$3 = /*@__PURE__*/new Sphere();
8091
8092	const _vA$1 = /*@__PURE__*/new Vector3();
8093
8094	const _vB$1 = /*@__PURE__*/new Vector3();
8095
8096	const _vC$1 = /*@__PURE__*/new Vector3();
8097
8098	const _tempA = /*@__PURE__*/new Vector3();
8099
8100	const _tempB = /*@__PURE__*/new Vector3();
8101
8102	const _tempC = /*@__PURE__*/new Vector3();
8103
8104	const _morphA = /*@__PURE__*/new Vector3();
8105
8106	const _morphB = /*@__PURE__*/new Vector3();
8107
8108	const _morphC = /*@__PURE__*/new Vector3();
8109
8110	const _uvA$1 = /*@__PURE__*/new Vector2();
8111
8112	const _uvB$1 = /*@__PURE__*/new Vector2();
8113
8114	const _uvC$1 = /*@__PURE__*/new Vector2();
8115
8116	const _intersectionPoint = /*@__PURE__*/new Vector3();
8117
8118	const _intersectionPointWorld = /*@__PURE__*/new Vector3();
8119
8120	class Mesh extends Object3D {
8121		constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) {
8122			super();
8123			this.type = 'Mesh';
8124			this.geometry = geometry;
8125			this.material = material;
8126			this.updateMorphTargets();
8127		}
8128
8129		copy(source) {
8130			super.copy(source);
8131
8132			if (source.morphTargetInfluences !== undefined) {
8133				this.morphTargetInfluences = source.morphTargetInfluences.slice();
8134			}
8135
8136			if (source.morphTargetDictionary !== undefined) {
8137				this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary);
8138			}
8139
8140			this.material = source.material;
8141			this.geometry = source.geometry;
8142			return this;
8143		}
8144
8145		updateMorphTargets() {
8146			const geometry = this.geometry;
8147
8148			if (geometry.isBufferGeometry) {
8149				const morphAttributes = geometry.morphAttributes;
vendor: 12,234 bytes, lines 8150-8529
8150				const keys = Object.keys(morphAttributes);
8151
8152				if (keys.length > 0) {
8153					const morphAttribute = morphAttributes[keys[0]];
8154
8155					if (morphAttribute !== undefined) {
8156						this.morphTargetInfluences = [];
8157						this.morphTargetDictionary = {};
8158
8159						for (let m = 0, ml = morphAttribute.length; m < ml; m++) {
8160							const name = morphAttribute[m].name || String(m);
8161							this.morphTargetInfluences.push(0);
8162							this.morphTargetDictionary[name] = m;
8163						}
8164					}
8165				}
8166			} else {
8167				const morphTargets = geometry.morphTargets;
8168
8169				if (morphTargets !== undefined && morphTargets.length > 0) {
8170					console.error('THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.');
8171				}
8172			}
8173		}
8174
8175		raycast(raycaster, intersects) {
8176			const geometry = this.geometry;
8177			const material = this.material;
8178			const matrixWorld = this.matrixWorld;
8179			if (material === undefined) return; // Checking boundingSphere distance to ray
8180
8181			if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
8182
8183			_sphere$3.copy(geometry.boundingSphere);
8184
8185			_sphere$3.applyMatrix4(matrixWorld);
8186
8187			if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; //
8188
8189			_inverseMatrix$2.copy(matrixWorld).invert();
8190
8191			_ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); // Check boundingBox before continuing
8192
8193
8194			if (geometry.boundingBox !== null) {
8195				if (_ray$2.intersectsBox(geometry.boundingBox) === false) return;
8196			}
8197
8198			let intersection;
8199
8200			if (geometry.isBufferGeometry) {
8201				const index = geometry.index;
8202				const position = geometry.attributes.position;
8203				const morphPosition = geometry.morphAttributes.position;
8204				const morphTargetsRelative = geometry.morphTargetsRelative;
8205				const uv = geometry.attributes.uv;
8206				const uv2 = geometry.attributes.uv2;
8207				const groups = geometry.groups;
8208				const drawRange = geometry.drawRange;
8209
8210				if (index !== null) {
8211					// indexed buffer geometry
8212					if (Array.isArray(material)) {
8213						for (let i = 0, il = groups.length; i < il; i++) {
8214							const group = groups[i];
8215							const groupMaterial = material[group.materialIndex];
8216							const start = Math.max(group.start, drawRange.start);
8217							const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count));
8218
8219							for (let j = start, jl = end; j < jl; j += 3) {
8220								const a = index.getX(j);
8221								const b = index.getX(j + 1);
8222								const c = index.getX(j + 2);
8223								intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
8224
8225								if (intersection) {
8226									intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics
8227
8228									intersection.face.materialIndex = group.materialIndex;
8229									intersects.push(intersection);
8230								}
8231							}
8232						}
8233					} else {
8234						const start = Math.max(0, drawRange.start);
8235						const end = Math.min(index.count, drawRange.start + drawRange.count);
8236
8237						for (let i = start, il = end; i < il; i += 3) {
8238							const a = index.getX(i);
8239							const b = index.getX(i + 1);
8240							const c = index.getX(i + 2);
8241							intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
8242
8243							if (intersection) {
8244								intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics
8245
8246								intersects.push(intersection);
8247							}
8248						}
8249					}
8250				} else if (position !== undefined) {
8251					// non-indexed buffer geometry
8252					if (Array.isArray(material)) {
8253						for (let i = 0, il = groups.length; i < il; i++) {
8254							const group = groups[i];
8255							const groupMaterial = material[group.materialIndex];
8256							const start = Math.max(group.start, drawRange.start);
8257							const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count));
8258
8259							for (let j = start, jl = end; j < jl; j += 3) {
8260								const a = j;
8261								const b = j + 1;
8262								const c = j + 2;
8263								intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
8264
8265								if (intersection) {
8266									intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics
8267
8268									intersection.face.materialIndex = group.materialIndex;
8269									intersects.push(intersection);
8270								}
8271							}
8272						}
8273					} else {
8274						const start = Math.max(0, drawRange.start);
8275						const end = Math.min(position.count, drawRange.start + drawRange.count);
8276
8277						for (let i = start, il = end; i < il; i += 3) {
8278							const a = i;
8279							const b = i + 1;
8280							const c = i + 2;
8281							intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
8282
8283							if (intersection) {
8284								intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics
8285
8286								intersects.push(intersection);
8287							}
8288						}
8289					}
8290				}
8291			} else if (geometry.isGeometry) {
8292				console.error('THREE.Mesh.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.');
8293			}
8294		}
8295
8296	}
8297
8298	Mesh.prototype.isMesh = true;
8299
8300	function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) {
8301		let intersect;
8302
8303		if (material.side === BackSide) {
8304			intersect = ray.intersectTriangle(pC, pB, pA, true, point);
8305		} else {
8306			intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point);
8307		}
8308
8309		if (intersect === null) return null;
8310
8311		_intersectionPointWorld.copy(point);
8312
8313		_intersectionPointWorld.applyMatrix4(object.matrixWorld);
8314
8315		const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld);
8316		if (distance < raycaster.near || distance > raycaster.far) return null;
8317		return {
8318			distance: distance,
8319			point: _intersectionPointWorld.clone(),
8320			object: object
8321		};
8322	}
8323
8324	function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) {
8325		_vA$1.fromBufferAttribute(position, a);
8326
8327		_vB$1.fromBufferAttribute(position, b);
8328
8329		_vC$1.fromBufferAttribute(position, c);
8330
8331		const morphInfluences = object.morphTargetInfluences;
8332
8333		if (morphPosition && morphInfluences) {
8334			_morphA.set(0, 0, 0);
8335
8336			_morphB.set(0, 0, 0);
8337
8338			_morphC.set(0, 0, 0);
8339
8340			for (let i = 0, il = morphPosition.length; i < il; i++) {
8341				const influence = morphInfluences[i];
8342				const morphAttribute = morphPosition[i];
8343				if (influence === 0) continue;
8344
8345				_tempA.fromBufferAttribute(morphAttribute, a);
8346
8347				_tempB.fromBufferAttribute(morphAttribute, b);
8348
8349				_tempC.fromBufferAttribute(morphAttribute, c);
8350
8351				if (morphTargetsRelative) {
8352					_morphA.addScaledVector(_tempA, influence);
8353
8354					_morphB.addScaledVector(_tempB, influence);
8355
8356					_morphC.addScaledVector(_tempC, influence);
8357				} else {
8358					_morphA.addScaledVector(_tempA.sub(_vA$1), influence);
8359
8360					_morphB.addScaledVector(_tempB.sub(_vB$1), influence);
8361
8362					_morphC.addScaledVector(_tempC.sub(_vC$1), influence);
8363				}
8364			}
8365
8366			_vA$1.add(_morphA);
8367
8368			_vB$1.add(_morphB);
8369
8370			_vC$1.add(_morphC);
8371		}
8372
8373		if (object.isSkinnedMesh) {
8374			object.boneTransform(a, _vA$1);
8375			object.boneTransform(b, _vB$1);
8376			object.boneTransform(c, _vC$1);
8377		}
8378
8379		const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint);
8380
8381		if (intersection) {
8382			if (uv) {
8383				_uvA$1.fromBufferAttribute(uv, a);
8384
8385				_uvB$1.fromBufferAttribute(uv, b);
8386
8387				_uvC$1.fromBufferAttribute(uv, c);
8388
8389				intersection.uv = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
8390			}
8391
8392			if (uv2) {
8393				_uvA$1.fromBufferAttribute(uv2, a);
8394
8395				_uvB$1.fromBufferAttribute(uv2, b);
8396
8397				_uvC$1.fromBufferAttribute(uv2, c);
8398
8399				intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
8400			}
8401
8402			const face = {
8403				a: a,
8404				b: b,
8405				c: c,
8406				normal: new Vector3(),
8407				materialIndex: 0
8408			};
8409			Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal);
8410			intersection.face = face;
8411		}
8412
8413		return intersection;
8414	}
8415
8416	class BoxGeometry extends BufferGeometry {
8417		constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) {
8418			super();
8419			this.type = 'BoxGeometry';
8420			this.parameters = {
8421				width: width,
8422				height: height,
8423				depth: depth,
8424				widthSegments: widthSegments,
8425				heightSegments: heightSegments,
8426				depthSegments: depthSegments
8427			};
8428			const scope = this; // segments
8429
8430			widthSegments = Math.floor(widthSegments);
8431			heightSegments = Math.floor(heightSegments);
8432			depthSegments = Math.floor(depthSegments); // buffers
8433
8434			const indices = [];
8435			const vertices = [];
8436			const normals = [];
8437			const uvs = []; // helper variables
8438
8439			let numberOfVertices = 0;
8440			let groupStart = 0; // build each side of the box geometry
8441
8442			buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px
8443
8444			buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx
8445
8446			buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py
8447
8448			buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny
8449
8450			buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz
8451
8452			buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz
8453			// build geometry
8454
8455			this.setIndex(indices);
8456			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
8457			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
8458			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
8459
8460			function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) {
8461				const segmentWidth = width / gridX;
8462				const segmentHeight = height / gridY;
8463				const widthHalf = width / 2;
8464				const heightHalf = height / 2;
8465				const depthHalf = depth / 2;
8466				const gridX1 = gridX + 1;
8467				const gridY1 = gridY + 1;
8468				let vertexCounter = 0;
8469				let groupCount = 0;
8470				const vector = new Vector3(); // generate vertices, normals and uvs
8471
8472				for (let iy = 0; iy < gridY1; iy++) {
8473					const y = iy * segmentHeight - heightHalf;
8474
8475					for (let ix = 0; ix < gridX1; ix++) {
8476						const x = ix * segmentWidth - widthHalf; // set values to correct vector component
8477
8478						vector[u] = x * udir;
8479						vector[v] = y * vdir;
8480						vector[w] = depthHalf; // now apply vector to vertex buffer
8481
8482						vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component
8483
8484						vector[u] = 0;
8485						vector[v] = 0;
8486						vector[w] = depth > 0 ? 1 : -1; // now apply vector to normal buffer
8487
8488						normals.push(vector.x, vector.y, vector.z); // uvs
8489
8490						uvs.push(ix / gridX);
8491						uvs.push(1 - iy / gridY); // counters
8492
8493						vertexCounter += 1;
8494					}
8495				} // indices
8496				// 1. you need three indices to draw a single face
8497				// 2. a single segment consists of two faces
8498				// 3. so we need to generate six (2*3) indices per segment
8499
8500
8501				for (let iy = 0; iy < gridY; iy++) {
8502					for (let ix = 0; ix < gridX; ix++) {
8503						const a = numberOfVertices + ix + gridX1 * iy;
8504						const b = numberOfVertices + ix + gridX1 * (iy + 1);
8505						const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1);
8506						const d = numberOfVertices + (ix + 1) + gridX1 * iy; // faces
8507
8508						indices.push(a, b, d);
8509						indices.push(b, c, d); // increase counter
8510
8511						groupCount += 6;
8512					}
8513				} // add a group to the geometry. this will ensure multi material support
8514
8515
8516				scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups
8517
8518				groupStart += groupCount; // update total number of vertices
8519
8520				numberOfVertices += vertexCounter;
8521			}
8522		}
8523
8524		static fromJSON(data) {
8525			return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments);
8526		}
8527
8528	}
8529
vendor: 11,407 bytes, lines 8530-8951
8530	/**
8531	 * Uniform Utilities
8532	 */
8533	function cloneUniforms(src) {
8534		const dst = {};
8535
8536		for (const u in src) {
8537			dst[u] = {};
8538
8539			for (const p in src[u]) {
8540				const property = src[u][p];
8541
8542				if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion)) {
8543					dst[u][p] = property.clone();
8544				} else if (Array.isArray(property)) {
8545					dst[u][p] = property.slice();
8546				} else {
8547					dst[u][p] = property;
8548				}
8549			}
8550		}
8551
8552		return dst;
8553	}
8554	function mergeUniforms(uniforms) {
8555		const merged = {};
8556
8557		for (let u = 0; u < uniforms.length; u++) {
8558			const tmp = cloneUniforms(uniforms[u]);
8559
8560			for (const p in tmp) {
8561				merged[p] = tmp[p];
8562			}
8563		}
8564
8565		return merged;
8566	} // Legacy
8567
8568	const UniformsUtils = {
8569		clone: cloneUniforms,
8570		merge: mergeUniforms
8571	};
8572
8573	var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
8574
8575	var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";
8576
8577	/**
8578	 * parameters = {
8579	 *	defines: { "label" : "value" },
8580	 *	uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
8581	 *
8582	 *	fragmentShader: <string>,
8583	 *	vertexShader: <string>,
8584	 *
8585	 *	wireframe: <boolean>,
8586	 *	wireframeLinewidth: <float>,
8587	 *
8588	 *	lights: <bool>
8589	 * }
8590	 */
8591
8592	class ShaderMaterial extends Material {
8593		constructor(parameters) {
8594			super();
8595			this.type = 'ShaderMaterial';
8596			this.defines = {};
8597			this.uniforms = {};
8598			this.vertexShader = default_vertex;
8599			this.fragmentShader = default_fragment;
8600			this.linewidth = 1;
8601			this.wireframe = false;
8602			this.wireframeLinewidth = 1;
8603			this.fog = false; // set to use scene fog
8604
8605			this.lights = false; // set to use scene lights
8606
8607			this.clipping = false; // set to use user-defined clipping planes
8608
8609			this.extensions = {
8610				derivatives: false,
8611				// set to use derivatives
8612				fragDepth: false,
8613				// set to use fragment depth values
8614				drawBuffers: false,
8615				// set to use draw buffers
8616				shaderTextureLOD: false // set to use shader texture LOD
8617
8618			}; // When rendered geometry doesn't include these attributes but the material does,
8619			// use these default values in WebGL. This avoids errors when buffer data is missing.
8620
8621			this.defaultAttributeValues = {
8622				'color': [1, 1, 1],
8623				'uv': [0, 0],
8624				'uv2': [0, 0]
8625			};
8626			this.index0AttributeName = undefined;
8627			this.uniformsNeedUpdate = false;
8628			this.glslVersion = null;
8629
8630			if (parameters !== undefined) {
8631				if (parameters.attributes !== undefined) {
8632					console.error('THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.');
8633				}
8634
8635				this.setValues(parameters);
8636			}
8637		}
8638
8639		copy(source) {
8640			super.copy(source);
8641			this.fragmentShader = source.fragmentShader;
8642			this.vertexShader = source.vertexShader;
8643			this.uniforms = cloneUniforms(source.uniforms);
8644			this.defines = Object.assign({}, source.defines);
8645			this.wireframe = source.wireframe;
8646			this.wireframeLinewidth = source.wireframeLinewidth;
8647			this.lights = source.lights;
8648			this.clipping = source.clipping;
8649			this.extensions = Object.assign({}, source.extensions);
8650			this.glslVersion = source.glslVersion;
8651			return this;
8652		}
8653
8654		toJSON(meta) {
8655			const data = super.toJSON(meta);
8656			data.glslVersion = this.glslVersion;
8657			data.uniforms = {};
8658
8659			for (const name in this.uniforms) {
8660				const uniform = this.uniforms[name];
8661				const value = uniform.value;
8662
8663				if (value && value.isTexture) {
8664					data.uniforms[name] = {
8665						type: 't',
8666						value: value.toJSON(meta).uuid
8667					};
8668				} else if (value && value.isColor) {
8669					data.uniforms[name] = {
8670						type: 'c',
8671						value: value.getHex()
8672					};
8673				} else if (value && value.isVector2) {
8674					data.uniforms[name] = {
8675						type: 'v2',
8676						value: value.toArray()
8677					};
8678				} else if (value && value.isVector3) {
8679					data.uniforms[name] = {
8680						type: 'v3',
8681						value: value.toArray()
8682					};
8683				} else if (value && value.isVector4) {
8684					data.uniforms[name] = {
8685						type: 'v4',
8686						value: value.toArray()
8687					};
8688				} else if (value && value.isMatrix3) {
8689					data.uniforms[name] = {
8690						type: 'm3',
8691						value: value.toArray()
8692					};
8693				} else if (value && value.isMatrix4) {
8694					data.uniforms[name] = {
8695						type: 'm4',
8696						value: value.toArray()
8697					};
8698				} else {
8699					data.uniforms[name] = {
8700						value: value
8701					}; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far
8702				}
8703			}
8704
8705			if (Object.keys(this.defines).length > 0) data.defines = this.defines;
8706			data.vertexShader = this.vertexShader;
8707			data.fragmentShader = this.fragmentShader;
8708			const extensions = {};
8709
8710			for (const key in this.extensions) {
8711				if (this.extensions[key] === true) extensions[key] = true;
8712			}
8713
8714			if (Object.keys(extensions).length > 0) data.extensions = extensions;
8715			return data;
8716		}
8717
8718	}
8719
8720	ShaderMaterial.prototype.isShaderMaterial = true;
8721
8722	class Camera extends Object3D {
8723		constructor() {
8724			super();
8725			this.type = 'Camera';
8726			this.matrixWorldInverse = new Matrix4();
8727			this.projectionMatrix = new Matrix4();
8728			this.projectionMatrixInverse = new Matrix4();
8729		}
8730
8731		copy(source, recursive) {
8732			super.copy(source, recursive);
8733			this.matrixWorldInverse.copy(source.matrixWorldInverse);
8734			this.projectionMatrix.copy(source.projectionMatrix);
8735			this.projectionMatrixInverse.copy(source.projectionMatrixInverse);
8736			return this;
8737		}
8738
8739		getWorldDirection(target) {
8740			this.updateWorldMatrix(true, false);
8741			const e = this.matrixWorld.elements;
8742			return target.set(-e[8], -e[9], -e[10]).normalize();
8743		}
8744
8745		updateMatrixWorld(force) {
8746			super.updateMatrixWorld(force);
8747			this.matrixWorldInverse.copy(this.matrixWorld).invert();
8748		}
8749
8750		updateWorldMatrix(updateParents, updateChildren) {
8751			super.updateWorldMatrix(updateParents, updateChildren);
8752			this.matrixWorldInverse.copy(this.matrixWorld).invert();
8753		}
8754
8755		clone() {
8756			return new this.constructor().copy(this);
8757		}
8758
8759	}
8760
8761	Camera.prototype.isCamera = true;
8762
8763	class PerspectiveCamera extends Camera {
8764		constructor(fov = 50, aspect = 1, near = 0.1, far = 2000) {
8765			super();
8766			this.type = 'PerspectiveCamera';
8767			this.fov = fov;
8768			this.zoom = 1;
8769			this.near = near;
8770			this.far = far;
8771			this.focus = 10;
8772			this.aspect = aspect;
8773			this.view = null;
8774			this.filmGauge = 35; // width of the film (default in millimeters)
8775
8776			this.filmOffset = 0; // horizontal film offset (same unit as gauge)
8777
8778			this.updateProjectionMatrix();
8779		}
8780
8781		copy(source, recursive) {
8782			super.copy(source, recursive);
8783			this.fov = source.fov;
8784			this.zoom = source.zoom;
8785			this.near = source.near;
8786			this.far = source.far;
8787			this.focus = source.focus;
8788			this.aspect = source.aspect;
8789			this.view = source.view === null ? null : Object.assign({}, source.view);
8790			this.filmGauge = source.filmGauge;
8791			this.filmOffset = source.filmOffset;
8792			return this;
8793		}
8794		/**
8795		 * Sets the FOV by focal length in respect to the current .filmGauge.
8796		 *
8797		 * The default film gauge is 35, so that the focal length can be specified for
8798		 * a 35mm (full frame) camera.
8799		 *
8800		 * Values for focal length and film gauge must have the same unit.
8801		 */
8802
8803
8804		setFocalLength(focalLength) {
8805			/** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */
8806			const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
8807			this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope);
8808			this.updateProjectionMatrix();
8809		}
8810		/**
8811		 * Calculates the focal length from the current .fov and .filmGauge.
8812		 */
8813
8814
8815		getFocalLength() {
8816			const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov);
8817			return 0.5 * this.getFilmHeight() / vExtentSlope;
8818		}
8819
8820		getEffectiveFOV() {
8821			return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom);
8822		}
8823
8824		getFilmWidth() {
8825			// film not completely covered in portrait format (aspect < 1)
8826			return this.filmGauge * Math.min(this.aspect, 1);
8827		}
8828
8829		getFilmHeight() {
8830			// film not completely covered in landscape format (aspect > 1)
8831			return this.filmGauge / Math.max(this.aspect, 1);
8832		}
8833		/**
8834		 * Sets an offset in a larger frustum. This is useful for multi-window or
8835		 * multi-monitor/multi-machine setups.
8836		 *
8837		 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
8838		 * the monitors are in grid like this
8839		 *
8840		 *	 +---+---+---+
8841		 *	 | A | B | C |
8842		 *	 +---+---+---+
8843		 *	 | D | E | F |
8844		 *	 +---+---+---+
8845		 *
8846		 * then for each monitor you would call it like this
8847		 *
8848		 *	 const w = 1920;
8849		 *	 const h = 1080;
8850		 *	 const fullWidth = w * 3;
8851		 *	 const fullHeight = h * 2;
8852		 *
8853		 *	 --A--
8854		 *	 camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
8855		 *	 --B--
8856		 *	 camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
8857		 *	 --C--
8858		 *	 camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
8859		 *	 --D--
8860		 *	 camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
8861		 *	 --E--
8862		 *	 camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
8863		 *	 --F--
8864		 *	 camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
8865		 *
8866		 *	 Note there is no reason monitors have to be the same size or in a grid.
8867		 */
8868
8869
8870		setViewOffset(fullWidth, fullHeight, x, y, width, height) {
8871			this.aspect = fullWidth / fullHeight;
8872
8873			if (this.view === null) {
8874				this.view = {
8875					enabled: true,
8876					fullWidth: 1,
8877					fullHeight: 1,
8878					offsetX: 0,
8879					offsetY: 0,
8880					width: 1,
8881					height: 1
8882				};
8883			}
8884
8885			this.view.enabled = true;
8886			this.view.fullWidth = fullWidth;
8887			this.view.fullHeight = fullHeight;
8888			this.view.offsetX = x;
8889			this.view.offsetY = y;
8890			this.view.width = width;
8891			this.view.height = height;
8892			this.updateProjectionMatrix();
8893		}
8894
8895		clearViewOffset() {
8896			if (this.view !== null) {
8897				this.view.enabled = false;
8898			}
8899
8900			this.updateProjectionMatrix();
8901		}
8902
8903		updateProjectionMatrix() {
8904			const near = this.near;
8905			let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom;
8906			let height = 2 * top;
8907			let width = this.aspect * height;
8908			let left = -0.5 * width;
8909			const view = this.view;
8910
8911			if (this.view !== null && this.view.enabled) {
8912				const fullWidth = view.fullWidth,
8913							fullHeight = view.fullHeight;
8914				left += view.offsetX * width / fullWidth;
8915				top -= view.offsetY * height / fullHeight;
8916				width *= view.width / fullWidth;
8917				height *= view.height / fullHeight;
8918			}
8919
8920			const skew = this.filmOffset;
8921			if (skew !== 0) left += near * skew / this.getFilmWidth();
8922			this.projectionMatrix.makePerspective(left, left + width, top, top - height, near, this.far);
8923			this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
8924		}
8925
8926		toJSON(meta) {
8927			const data = super.toJSON(meta);
8928			data.object.fov = this.fov;
8929			data.object.zoom = this.zoom;
8930			data.object.near = this.near;
8931			data.object.far = this.far;
8932			data.object.focus = this.focus;
8933			data.object.aspect = this.aspect;
8934			if (this.view !== null) data.object.view = Object.assign({}, this.view);
8935			data.object.filmGauge = this.filmGauge;
8936			data.object.filmOffset = this.filmOffset;
8937			return data;
8938		}
8939
8940	}
8941
8942	PerspectiveCamera.prototype.isPerspectiveCamera = true;
8943
8944	const fov = 90,
8945				aspect = 1;
8946
8947	class CubeCamera extends Object3D {
8948		constructor(near, far, renderTarget) {
8949			super();
8950			this.type = 'CubeCamera';
8951
8952			if (renderTarget.isWebGLCubeRenderTarget !== true) {
8953				console.error('THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.');
8954				return;
8955			}
8956
8957			this.renderTarget = renderTarget;
8958			const cameraPX = new PerspectiveCamera(fov, aspect, near, far);
8959			cameraPX.layers = this.layers;
8960			cameraPX.up.set(0, -1, 0);
8961			cameraPX.lookAt(new Vector3(1, 0, 0));
8962			this.add(cameraPX);
8963			const cameraNX = new PerspectiveCamera(fov, aspect, near, far);
8964			cameraNX.layers = this.layers;
8965			cameraNX.up.set(0, -1, 0);
8966			cameraNX.lookAt(new Vector3(-1, 0, 0));
8967			this.add(cameraNX);
8968			const cameraPY = new PerspectiveCamera(fov, aspect, near, far);
8969			cameraPY.layers = this.layers;
8970			cameraPY.up.set(0, 0, 1);
8971			cameraPY.lookAt(new Vector3(0, 1, 0));
8972			this.add(cameraPY);
8973			const cameraNY = new PerspectiveCamera(fov, aspect, near, far);
8974			cameraNY.layers = this.layers;
8975			cameraNY.up.set(0, 0, -1);
8976			cameraNY.lookAt(new Vector3(0, -1, 0));
8977			this.add(cameraNY);
8978			const cameraPZ = new PerspectiveCamera(fov, aspect, near, far);
8979			cameraPZ.layers = this.layers;
8980			cameraPZ.up.set(0, -1, 0);
8981			cameraPZ.lookAt(new Vector3(0, 0, 1));
8982			this.add(cameraPZ);
8983			const cameraNZ = new PerspectiveCamera(fov, aspect, near, far);
8984			cameraNZ.layers = this.layers;
8985			cameraNZ.up.set(0, -1, 0);
8986			cameraNZ.lookAt(new Vector3(0, 0, -1));
8987			this.add(cameraNZ);
8988		}
8989
8990		update(renderer, scene) {
8991			if (this.parent === null) this.updateMatrixWorld();
8992			const renderTarget = this.renderTarget;
8993			const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children;
8994			const currentXrEnabled = renderer.xr.enabled;
8995			const currentRenderTarget = renderer.getRenderTarget();
8996			renderer.xr.enabled = false;
8997			const generateMipmaps = renderTarget.texture.generateMipmaps;
8998			renderTarget.texture.generateMipmaps = false;
8999			renderer.setRenderTarget(renderTarget, 0);
9000			renderer.render(scene, cameraPX);
9001			renderer.setRenderTarget(renderTarget, 1);
9002			renderer.render(scene, cameraNX);
9003			renderer.setRenderTarget(renderTarget, 2);
9004			renderer.render(scene, cameraPY);
9005			renderer.setRenderTarget(renderTarget, 3);
9006			renderer.render(scene, cameraNY);
9007			renderer.setRenderTarget(renderTarget, 4);
9008			renderer.render(scene, cameraPZ);
9009			renderTarget.texture.generateMipmaps = generateMipmaps;
9010			renderer.setRenderTarget(renderTarget, 5);
9011			renderer.render(scene, cameraNZ);
9012			renderer.setRenderTarget(currentRenderTarget);
9013			renderer.xr.enabled = currentXrEnabled;
9014		}
9015
9016	}
9017
9018	class CubeTexture extends Texture {
9019		constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) {
9020			images = images !== undefined ? images : [];
9021			mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
9022			super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
9023			this.flipY = false;
9024		}
9025
9026		get images() {
9027			return this.image;
9028		}
9029
9030		set images(value) {
9031			this.image = value;
9032		}
9033
9034	}
9035
9036	CubeTexture.prototype.isCubeTexture = true;
9037
9038	class WebGLCubeRenderTarget extends WebGLRenderTarget {
9039		constructor(size, options, dummy) {
9040			if (Number.isInteger(options)) {
9041				console.warn('THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )');
9042				options = dummy;
9043			}
9044
9045			super(size, size, options);
9046			options = options || {}; // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js)
9047			// in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words,
9048			// in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly.
9049			// three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped
9050			// and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture
9051			// as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures).
9052
9053			this.texture = new CubeTexture(undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding);
9054			this.texture.isRenderTargetTexture = true;
9055			this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
vendor: 4,431 bytes, lines 9056-9237
9056			this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
9057			this.texture._needsFlipEnvMap = false;
9058		}
9059
9060		fromEquirectangularTexture(renderer, texture) {
9061			this.texture.type = texture.type;
9062			this.texture.format = RGBAFormat; // see #18859
9063
9064			this.texture.encoding = texture.encoding;
9065			this.texture.generateMipmaps = texture.generateMipmaps;
9066			this.texture.minFilter = texture.minFilter;
9067			this.texture.magFilter = texture.magFilter;
9068			const shader = {
9069				uniforms: {
9070					tEquirect: {
9071						value: null
9072					}
9073				},
9074				vertexShader:
9075				/* glsl */
9076				`
9077
9078				varying vec3 vWorldDirection;
9079
9080				vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
9081
9082					return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
9083
9084				}
9085
9086				void main() {
9087
9088					vWorldDirection = transformDirection( position, modelMatrix );
9089
9090					#include <begin_vertex>
9091					#include <project_vertex>
9092
9093				}
9094			`,
9095				fragmentShader:
9096				/* glsl */
9097				`
9098
9099				uniform sampler2D tEquirect;
9100
9101				varying vec3 vWorldDirection;
9102
9103				#include <common>
9104
9105				void main() {
9106
9107					vec3 direction = normalize( vWorldDirection );
9108
9109					vec2 sampleUV = equirectUv( direction );
9110
9111					gl_FragColor = texture2D( tEquirect, sampleUV );
9112
9113				}
9114			`
9115			};
9116			const geometry = new BoxGeometry(5, 5, 5);
9117			const material = new ShaderMaterial({
9118				name: 'CubemapFromEquirect',
9119				uniforms: cloneUniforms(shader.uniforms),
9120				vertexShader: shader.vertexShader,
9121				fragmentShader: shader.fragmentShader,
9122				side: BackSide,
9123				blending: NoBlending
9124			});
9125			material.uniforms.tEquirect.value = texture;
9126			const mesh = new Mesh(geometry, material);
9127			const currentMinFilter = texture.minFilter; // Avoid blurred poles
9128
9129			if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter;
9130			const camera = new CubeCamera(1, 10, this);
9131			camera.update(renderer, mesh);
9132			texture.minFilter = currentMinFilter;
9133			mesh.geometry.dispose();
9134			mesh.material.dispose();
9135			return this;
9136		}
9137
9138		clear(renderer, color, depth, stencil) {
9139			const currentRenderTarget = renderer.getRenderTarget();
9140
9141			for (let i = 0; i < 6; i++) {
9142				renderer.setRenderTarget(this, i);
9143				renderer.clear(color, depth, stencil);
9144			}
9145
9146			renderer.setRenderTarget(currentRenderTarget);
9147		}
9148
9149	}
9150
9151	WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;
9152
9153	const _vector1 = /*@__PURE__*/new Vector3();
9154
9155	const _vector2 = /*@__PURE__*/new Vector3();
9156
9157	const _normalMatrix = /*@__PURE__*/new Matrix3();
9158
9159	class Plane {
9160		constructor(normal = new Vector3(1, 0, 0), constant = 0) {
9161			// normal is assumed to be normalized
9162			this.normal = normal;
9163			this.constant = constant;
9164		}
9165
9166		set(normal, constant) {
9167			this.normal.copy(normal);
9168			this.constant = constant;
9169			return this;
9170		}
9171
9172		setComponents(x, y, z, w) {
9173			this.normal.set(x, y, z);
9174			this.constant = w;
9175			return this;
9176		}
9177
9178		setFromNormalAndCoplanarPoint(normal, point) {
9179			this.normal.copy(normal);
9180			this.constant = -point.dot(this.normal);
9181			return this;
9182		}
9183
9184		setFromCoplanarPoints(a, b, c) {
9185			const normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize(); // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
9186
9187
9188			this.setFromNormalAndCoplanarPoint(normal, a);
9189			return this;
9190		}
9191
9192		copy(plane) {
9193			this.normal.copy(plane.normal);
9194			this.constant = plane.constant;
9195			return this;
9196		}
9197
9198		normalize() {
9199			// Note: will lead to a divide by zero if the plane is invalid.
9200			const inverseNormalLength = 1.0 / this.normal.length();
9201			this.normal.multiplyScalar(inverseNormalLength);
9202			this.constant *= inverseNormalLength;
9203			return this;
9204		}
9205
9206		negate() {
9207			this.constant *= -1;
9208			this.normal.negate();
9209			return this;
9210		}
9211
9212		distanceToPoint(point) {
9213			return this.normal.dot(point) + this.constant;
9214		}
9215
9216		distanceToSphere(sphere) {
9217			return this.distanceToPoint(sphere.center) - sphere.radius;
9218		}
9219
9220		projectPoint(point, target) {
9221			return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point);
9222		}
9223
9224		intersectLine(line, target) {
9225			const direction = line.delta(_vector1);
9226			const denominator = this.normal.dot(direction);
9227
9228			if (denominator === 0) {
9229				// line is coplanar, return origin
9230				if (this.distanceToPoint(line.start) === 0) {
9231					return target.copy(line.start);
9232				} // Unsure if this is the correct method to handle this case.
9233
9234
9235				return null;
9236			}
9237
vendor: 4,188 bytes, lines 9238-9396
9238			const t = -(line.start.dot(this.normal) + this.constant) / denominator;
9239
9240			if (t < 0 || t > 1) {
9241				return null;
9242			}
9243
9244			return target.copy(direction).multiplyScalar(t).add(line.start);
9245		}
9246
9247		intersectsLine(line) {
9248			// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
9249			const startSign = this.distanceToPoint(line.start);
9250			const endSign = this.distanceToPoint(line.end);
9251			return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0;
9252		}
9253
9254		intersectsBox(box) {
9255			return box.intersectsPlane(this);
9256		}
9257
9258		intersectsSphere(sphere) {
9259			return sphere.intersectsPlane(this);
9260		}
9261
9262		coplanarPoint(target) {
9263			return target.copy(this.normal).multiplyScalar(-this.constant);
9264		}
9265
9266		applyMatrix4(matrix, optionalNormalMatrix) {
9267			const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix);
9268
9269			const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix);
9270			const normal = this.normal.applyMatrix3(normalMatrix).normalize();
9271			this.constant = -referencePoint.dot(normal);
9272			return this;
9273		}
9274
9275		translate(offset) {
9276			this.constant -= offset.dot(this.normal);
9277			return this;
9278		}
9279
9280		equals(plane) {
9281			return plane.normal.equals(this.normal) && plane.constant === this.constant;
9282		}
9283
9284		clone() {
9285			return new this.constructor().copy(this);
9286		}
9287
9288	}
9289
9290	Plane.prototype.isPlane = true;
9291
9292	const _sphere$2 = /*@__PURE__*/new Sphere();
9293
9294	const _vector$7 = /*@__PURE__*/new Vector3();
9295
9296	class Frustum {
9297		constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()) {
9298			this.planes = [p0, p1, p2, p3, p4, p5];
9299		}
9300
9301		set(p0, p1, p2, p3, p4, p5) {
9302			const planes = this.planes;
9303			planes[0].copy(p0);
9304			planes[1].copy(p1);
9305			planes[2].copy(p2);
9306			planes[3].copy(p3);
9307			planes[4].copy(p4);
9308			planes[5].copy(p5);
9309			return this;
9310		}
9311
9312		copy(frustum) {
9313			const planes = this.planes;
9314
9315			for (let i = 0; i < 6; i++) {
9316				planes[i].copy(frustum.planes[i]);
9317			}
9318
9319			return this;
9320		}
9321
9322		setFromProjectionMatrix(m) {
9323			const planes = this.planes;
9324			const me = m.elements;
9325			const me0 = me[0],
9326						me1 = me[1],
9327						me2 = me[2],
9328						me3 = me[3];
9329			const me4 = me[4],
9330						me5 = me[5],
9331						me6 = me[6],
9332						me7 = me[7];
9333			const me8 = me[8],
9334						me9 = me[9],
9335						me10 = me[10],
9336						me11 = me[11];
9337			const me12 = me[12],
9338						me13 = me[13],
9339						me14 = me[14],
9340						me15 = me[15];
9341			planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize();
9342			planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize();
9343			planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize();
9344			planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize();
9345			planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize();
9346			planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize();
9347			return this;
9348		}
9349
9350		intersectsObject(object) {
9351			const geometry = object.geometry;
9352			if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
9353
9354			_sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld);
9355
9356			return this.intersectsSphere(_sphere$2);
9357		}
9358
9359		intersectsSprite(sprite) {
9360			_sphere$2.center.set(0, 0, 0);
9361
9362			_sphere$2.radius = 0.7071067811865476;
9363
9364			_sphere$2.applyMatrix4(sprite.matrixWorld);
9365
9366			return this.intersectsSphere(_sphere$2);
9367		}
9368
9369		intersectsSphere(sphere) {
9370			const planes = this.planes;
9371			const center = sphere.center;
9372			const negRadius = -sphere.radius;
9373
9374			for (let i = 0; i < 6; i++) {
9375				const distance = planes[i].distanceToPoint(center);
9376
9377				if (distance < negRadius) {
9378					return false;
9379				}
9380			}
9381
9382			return true;
9383		}
9384
9385		intersectsBox(box) {
9386			const planes = this.planes;
9387
9388			for (let i = 0; i < 6; i++) {
9389				const plane = planes[i]; // corner at max distance
9390
9391				_vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x;
9392				_vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y;
9393				_vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z;
9394
9395				if (plane.distanceToPoint(_vector$7) < 0) {
9396					return false;
vendor: 8,848 bytes, lines 9397-9645
9397				}
9398			}
9399
9400			return true;
9401		}
9402
9403		containsPoint(point) {
9404			const planes = this.planes;
9405
9406			for (let i = 0; i < 6; i++) {
9407				if (planes[i].distanceToPoint(point) < 0) {
9408					return false;
9409				}
9410			}
9411
9412			return true;
9413		}
9414
9415		clone() {
9416			return new this.constructor().copy(this);
9417		}
9418
9419	}
9420
9421	function WebGLAnimation() {
9422		let context = null;
9423		let isAnimating = false;
9424		let animationLoop = null;
9425		let requestId = null;
9426
9427		function onAnimationFrame(time, frame) {
9428			animationLoop(time, frame);
9429			requestId = context.requestAnimationFrame(onAnimationFrame);
9430		}
9431
9432		return {
9433			start: function () {
9434				if (isAnimating === true) return;
9435				if (animationLoop === null) return;
9436				requestId = context.requestAnimationFrame(onAnimationFrame);
9437				isAnimating = true;
9438			},
9439			stop: function () {
9440				context.cancelAnimationFrame(requestId);
9441				isAnimating = false;
9442			},
9443			setAnimationLoop: function (callback) {
9444				animationLoop = callback;
9445			},
9446			setContext: function (value) {
9447				context = value;
9448			}
9449		};
9450	}
9451
9452	function WebGLAttributes(gl, capabilities) {
9453		const isWebGL2 = capabilities.isWebGL2;
9454		const buffers = new WeakMap();
9455
9456		function createBuffer(attribute, bufferType) {
9457			const array = attribute.array;
9458			const usage = attribute.usage;
9459			const buffer = gl.createBuffer();
9460			gl.bindBuffer(bufferType, buffer);
9461			gl.bufferData(bufferType, array, usage);
9462			attribute.onUploadCallback();
9463			let type = gl.FLOAT;
9464
9465			if (array instanceof Float32Array) {
9466				type = gl.FLOAT;
9467			} else if (array instanceof Float64Array) {
9468				console.warn('THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.');
9469			} else if (array instanceof Uint16Array) {
9470				if (attribute.isFloat16BufferAttribute) {
9471					if (isWebGL2) {
9472						type = gl.HALF_FLOAT;
9473					} else {
9474						console.warn('THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.');
9475					}
9476				} else {
9477					type = gl.UNSIGNED_SHORT;
9478				}
9479			} else if (array instanceof Int16Array) {
9480				type = gl.SHORT;
9481			} else if (array instanceof Uint32Array) {
9482				type = gl.UNSIGNED_INT;
9483			} else if (array instanceof Int32Array) {
9484				type = gl.INT;
9485			} else if (array instanceof Int8Array) {
9486				type = gl.BYTE;
9487			} else if (array instanceof Uint8Array) {
9488				type = gl.UNSIGNED_BYTE;
9489			} else if (array instanceof Uint8ClampedArray) {
9490				type = gl.UNSIGNED_BYTE;
9491			}
9492
9493			return {
9494				buffer: buffer,
9495				type: type,
9496				bytesPerElement: array.BYTES_PER_ELEMENT,
9497				version: attribute.version
9498			};
9499		}
9500
9501		function updateBuffer(buffer, attribute, bufferType) {
9502			const array = attribute.array;
9503			const updateRange = attribute.updateRange;
9504			gl.bindBuffer(bufferType, buffer);
9505
9506			if (updateRange.count === -1) {
9507				// Not using update ranges
9508				gl.bufferSubData(bufferType, 0, array);
9509			} else {
9510				if (isWebGL2) {
9511					gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count);
9512				} else {
9513					gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count));
9514				}
9515
9516				updateRange.count = -1; // reset range
9517			}
9518		} //
9519
9520
9521		function get(attribute) {
9522			if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
9523			return buffers.get(attribute);
9524		}
9525
9526		function remove(attribute) {
9527			if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
9528			const data = buffers.get(attribute);
9529
9530			if (data) {
9531				gl.deleteBuffer(data.buffer);
9532				buffers.delete(attribute);
9533			}
9534		}
9535
9536		function update(attribute, bufferType) {
9537			if (attribute.isGLBufferAttribute) {
9538				const cached = buffers.get(attribute);
9539
9540				if (!cached || cached.version < attribute.version) {
9541					buffers.set(attribute, {
9542						buffer: attribute.buffer,
9543						type: attribute.type,
9544						bytesPerElement: attribute.elementSize,
9545						version: attribute.version
9546					});
9547				}
9548
9549				return;
9550			}
9551
9552			if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
9553			const data = buffers.get(attribute);
9554
9555			if (data === undefined) {
9556				buffers.set(attribute, createBuffer(attribute, bufferType));
9557			} else if (data.version < attribute.version) {
9558				updateBuffer(data.buffer, attribute, bufferType);
9559				data.version = attribute.version;
9560			}
9561		}
9562
9563		return {
9564			get: get,
9565			remove: remove,
9566			update: update
9567		};
9568	}
9569
9570	class PlaneGeometry extends BufferGeometry {
9571		constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {
9572			super();
9573			this.type = 'PlaneGeometry';
9574			this.parameters = {
9575				width: width,
9576				height: height,
9577				widthSegments: widthSegments,
9578				heightSegments: heightSegments
9579			};
9580			const width_half = width / 2;
9581			const height_half = height / 2;
9582			const gridX = Math.floor(widthSegments);
9583			const gridY = Math.floor(heightSegments);
9584			const gridX1 = gridX + 1;
9585			const gridY1 = gridY + 1;
9586			const segment_width = width / gridX;
9587			const segment_height = height / gridY; //
9588
9589			const indices = [];
9590			const vertices = [];
9591			const normals = [];
9592			const uvs = [];
9593
9594			for (let iy = 0; iy < gridY1; iy++) {
9595				const y = iy * segment_height - height_half;
9596
9597				for (let ix = 0; ix < gridX1; ix++) {
9598					const x = ix * segment_width - width_half;
9599					vertices.push(x, -y, 0);
9600					normals.push(0, 0, 1);
9601					uvs.push(ix / gridX);
9602					uvs.push(1 - iy / gridY);
9603				}
9604			}
9605
9606			for (let iy = 0; iy < gridY; iy++) {
9607				for (let ix = 0; ix < gridX; ix++) {
9608					const a = ix + gridX1 * iy;
9609					const b = ix + gridX1 * (iy + 1);
9610					const c = ix + 1 + gridX1 * (iy + 1);
9611					const d = ix + 1 + gridX1 * iy;
9612					indices.push(a, b, d);
9613					indices.push(b, c, d);
9614				}
9615			}
9616
9617			this.setIndex(indices);
9618			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
9619			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
9620			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
9621		}
9622
9623		static fromJSON(data) {
9624			return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);
9625		}
9626
9627	}
9628
9629	var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif";
9630
9631	var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
9632
9633	var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTest ) discard;\n#endif";
9634
9635	var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif";
9636
9637	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.roughness );\n\t#endif\n#endif";
9638
9639	var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
9640
9641	var begin_vertex = "vec3 transformed = vec3( position );";
9642
9643	var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
9644
9645	var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat V_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_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * 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;
9645\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\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_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif";
9646
9647	var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\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 ) * faceDirection;\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";
9648
9649	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";
9650
9651	var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
9652
9653	var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";
9654
9655	var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";
9656
9657	var color_fragment = "#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif";
9658
9659	var color_pars_fragment = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif";
9660
9661	var color_pars_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif";
9662
9663	var color_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif";
9664
9665	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 max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\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 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 USE_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}\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\treturn 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}";
9666
9667	var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_maxMipLevel 8.0\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_maxTileSize 256.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\tfloat texelSize = 1.0 / ( 3.0 * cubeUV_maxTileSize );\n\t\tvec2 uv = getUV( direction, face ) * ( faceSize - 1.0 ) + 0.5;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tif ( mipInt < cubeUV_maxMipLevel ) {\n\t\t\tuv.y += 2.0 * cubeUV_maxTileSize;\n\t\t}\n\t\tuv.y += filterInt * 2.0 * cubeUV_minTileSize;\n\t\tuv.x += 3.0 * max( 0.0, cubeUV_maxTileSize - 2.0 * faceSize );\n\t\tuv *= texelSize;\n\t\treturn texture2D( envMap, uv ).rgb;\n\t}\n\t#define r0 1.0\n\t#define v0 0.339\n\t#define m0 - 2.0\n\t#define r1 0.8\n\t#define v1 0.276\n\t#define m1 - 1.0\n\t#define r4 0.4\n\t#define v4 0.046\n\t#define m4 2.0\n\t#define r5 0.305\n\t#define v5 0.016\n\t#define m5 3.0\n\t#define r6 0.21\n\t#define v6 0.0038\n\t#define m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= r1 ) {\n\t\t\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\n\t\t} else if ( roughness >= r4 ) {\n\t\t\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\n\t\t} else if ( roughness >= r5 ) {\n\t\t\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\n\t\t} else if ( roughness >= r6 ) {\n\t\t\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), m0, cubeUV_maxMipLevel );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
9668
9669	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";
9670
9671	var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
9672
9673	var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + dis
9673placementBias );\n#endif";
9674
9675	var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";
9676
9677	var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";
9678
9679	var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
9680
9681	var encodings_pars_fragment = "vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\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}";
9682
9683	var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\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\tenvColor = envMapTexelToLinear( envColor );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\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";
9684
9685	var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\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";
9686
9687	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";
9688
9689	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";
9690
9691	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}
9691 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";
9692
9693	var fog_vertex = "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif";
9694
9695	var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif";
9696
9697	var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif";
9698
9699	var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\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";
9700
9701	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 vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}";
9702
9703	var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tlightMapIrradiance *= PI;\n\t#endif\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif";
9704
9705	var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
9706
9707	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.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\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\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = 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.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif";
9708
9709	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 vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\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 getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.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 getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}
9709\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 getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.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 vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif";
9710
9711	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 getIBLIrradiance( const in vec3 normal ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 reflectVec;\n\t\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\t\treflectVec = reflect( - viewDir, normal );\n\t\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\t#else\n\t\t\t\treflectVec = refract( - viewDir, normal, refractionRatio );\n\t\t\t#endif\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n#endif";
9712
9713	var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
9714
9715	var lights_toon_pars_fragment = "varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\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\treflectedLight.directDiffuse += irradiance * BRDF_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_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)";
9716
9717	var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
9718
9719	var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\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
9719( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, 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_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)";
9720
9721	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.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= specularColorMapTexelToLinear( texture2D( specularColorMap, vUv ) ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;
9721\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\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 = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= sheenColorMapTexelToLinear( texture2D( sheenColorMap, vUv ) ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif";
9722
9723	var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\
9723n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\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\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\tvec3 FssEss = specularColor * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.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}\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.roughness;\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#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\treflectedLight.directDiffuse += irradiance * BRDF_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_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 USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );
9723\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += 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}";
9724
9725	var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_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\tgetPointLightInfo( 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\tgetSpotLightInfo( 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\tgetDirectionalLightInfo( 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.normal );\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.normal );\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";
9726
9727	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 += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif";
9728
9729	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";
9730
9731	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";
9732
9733	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";
9734
9735	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";
9736
9737	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";
9738
9739	var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif";
9740
9741	var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif";
9742
9743	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";
9744
9745	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";
9746
9747	var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif";
9748
9749	var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
9750
9751	var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] > 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1, 2 ) * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\t\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\t\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\t\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n\t#endif\n#endif";
9752
9753	var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t\tuniform sampler2DArray morphTargetsTexture;\n\t\tuniform vec2 morphTargetsTextureSize;\n\t\tvec3 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset, const in int stride ) {\n\t\t\tfloat texelIndex = float( vertexIndex * stride + offset );\n\t\t\tfloat y = floor( texelIndex / morphTargetsTextureSize.x );\n\t\t\tfloat x = texelIndex - y * morphTargetsTextureSize.x;\n\t\t\tvec3 morphUV = vec3( ( x + 0.5 ) / morphTargetsTextureSize.x, y / morphTargetsTextureSize.y, morphTargetIndex );\n\t\t\treturn texture( morphTargetsTexture, morphUV ).xyz;\n\t\t}\n\t#else\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\tuniform float morphTargetInfluences[ 8 ];\n\t\t#else\n\t\t\tuniform float morphTargetInfluences[ 4 ];\n\t\t#endif\n\t#endif\n#endif";
9754
9755	var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\t#ifndef USE_MORPHNORMALS\n\t\t\t\tif ( morphTargetInfluences[ i ] > 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 1 ) * morphTargetInfluences[ i ];\n\t\t\t#else\n\t\t\t\tif ( morphTargetInfluences[ i ] > 0.0 ) transformed += getMorph( gl_VertexID, i, 0, 2 ) * morphTargetInfluences[ i ];\n\t\t\t#endif\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif";
9756
9757	var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#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 * faceDirection;\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 * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\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;";
9758
9759	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 * faceDirection;\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 );
9759\n\t#else\n\t\tnormal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif";
9760
9761	var normal_pars_fragment = "#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";
9762
9763	var normal_pars_vertex = "#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";
9764
9765	var normal_vertex = "#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";
9766
9767	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, float faceDirection ) {\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\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\n\t\treturn normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\n\t}\n#endif";
9768
9769	var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif";
9770
9771	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, faceDirection );\n\t#endif\n#endif";
9772
9773	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";
9774
9775	var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );";
9776
9777	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}";
9778
9779	var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
9780
9781	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;";
9782
9783	var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
9784
9785	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";
9786
9787	var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif";
9788
9789	var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
9790
9791	var shadowmap_pars_fragment = 
vendor: 6,176 bytes, line 9791
9791"#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
9791	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";
9792
9793	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";
9794
9795	var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS >
9795 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";
9796
9797	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}";
9798
9799	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";
9800
9801	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";
9802
9803	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";
9804
9805	var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif";
9806
9807	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";
9808
9809	var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
9810
9811	var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
9812
9813	var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;
9813\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; }";
9814
9815	var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tfloat transmissionAlpha = 1.0;\n\tfloat transmissionFactor = transmission;\n\tfloat thicknessFactor = thickness;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n\t\tattenuationColor, attenuationDistance );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\n#endif";
9816
9817	var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( vec3 n, vec3 v, float thickness, float ior, mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( float roughness, float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( vec2 fragCoord, float roughness, float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( vec3 radiance, float transmissionDistance, vec3 attenuationColor, float attenuationDistance ) {\n\t\tif ( attenuationDistance == 0.0 ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( vec3 n, vec3 v, float roughness, vec3 diffuseColor, vec3 specularColor, float specularF90,\n\t\tvec3 position, mat4 modelMatrix, mat4 viewMatrix, mat4 projMatrix, float ior, float thickness,\n\t\tvec3 attenuationColor, float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif";
9818
9819	var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif";
9820
9821	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";
9822
9823	var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif";
9824
9825	var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
9826
9827	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";
9828
9829	var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif";
9830
9831	var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\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";
9832
9833	const vertex$g = "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}";
9834	const fragment$g = "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}";
9835
9836	const vertex$f = "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}";
9837	const fragment$f = "#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}";
9838
9839	const vertex$e = "#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}";
9840	const fragment$e = "#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 <alphatest_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}";
9841
9842	const vertex$d = "#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}";
9843	const fragment$d = "#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 <alphatest_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}";
9844
9845	const vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
9846	const fragment$c = "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}";
9847
9848	const vertex$b = "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}";
9849	const fragment$b = "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\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
9850
9851	const vertex$a = "#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#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinbase_vertex>\n\t\t#include <skinnormal_vertex>\n\t\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 <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
9852	const fragment$a = "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 <alphatest_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\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\t#include <output_fragment>\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}";
9853
9854	const vertex$9 = "#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}";
9855	const fragment$9 = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLi
9855ghtBack;\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 <alphatest_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_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_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <output_fragment>\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}";
9856
9857	const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\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 <normal_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#include <normal_vertex>\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}";
9858	const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\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 <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <normal_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 );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;
9858\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\t#include <output_fragment>\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}";
9859
9860	const vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_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\t#include <normal_vertex>\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}";
9861	const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_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}";
9862
9863	const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\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 <normal_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 <normal_vertex>\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}";
9864	const fragment$6 = "#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 <alphatest_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 <normal_pars_fragment>\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\t#include <output_fragment>\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}";
9865
9866	const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\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 <normal_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 <normal_vertex>\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#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}";
9867	const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;
9867\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\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 <alphatest_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 <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_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 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include <transmission_fragment>\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;
vendor: 16,384 bytes, lines 9867-10240
9867\n\t#endif\n\t#include <output_fragment>\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}";
9868
9869	const vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\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 <normal_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 <normal_vertex>\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}";
9870	const fragment$4 = "#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 <alphatest_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 <normal_pars_fragment>\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\t#include <output_fragment>\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}";
9871
9872	const vertex$3 = "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}";
9873	const fragment$3 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_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\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
9874
9875	const vertex$2 = "#include <common>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\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 <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
9876	const fragment$2 = "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}";
9877
9878	const vertex$1 = "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}";
9879	const fragment$1 = "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 <alphatest_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\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
9880
9881	const ShaderChunk = {
9882		alphamap_fragment: alphamap_fragment,
9883		alphamap_pars_fragment: alphamap_pars_fragment,
9884		alphatest_fragment: alphatest_fragment,
9885		alphatest_pars_fragment: alphatest_pars_fragment,
9886		aomap_fragment: aomap_fragment,
9887		aomap_pars_fragment: aomap_pars_fragment,
9888		begin_vertex: begin_vertex,
9889		beginnormal_vertex: beginnormal_vertex,
9890		bsdfs: bsdfs,
9891		bumpmap_pars_fragment: bumpmap_pars_fragment,
9892		clipping_planes_fragment: clipping_planes_fragment,
9893		clipping_planes_pars_fragment: clipping_planes_pars_fragment,
9894		clipping_planes_pars_vertex: clipping_planes_pars_vertex,
9895		clipping_planes_vertex: clipping_planes_vertex,
9896		color_fragment: color_fragment,
9897		color_pars_fragment: color_pars_fragment,
9898		color_pars_vertex: color_pars_vertex,
9899		color_vertex: color_vertex,
9900		common: common,
9901		cube_uv_reflection_fragment: cube_uv_reflection_fragment,
9902		defaultnormal_vertex: defaultnormal_vertex,
9903		displacementmap_pars_vertex: displacementmap_pars_vertex,
9904		displacementmap_vertex: displacementmap_vertex,
9905		emissivemap_fragment: emissivemap_fragment,
9906		emissivemap_pars_fragment: emissivemap_pars_fragment,
9907		encodings_fragment: encodings_fragment,
9908		encodings_pars_fragment: encodings_pars_fragment,
9909		envmap_fragment: envmap_fragment,
9910		envmap_common_pars_fragment: envmap_common_pars_fragment,
9911		envmap_pars_fragment: envmap_pars_fragment,
9912		envmap_pars_vertex: envmap_pars_vertex,
9913		envmap_physical_pars_fragment: envmap_physical_pars_fragment,
9914		envmap_vertex: envmap_vertex,
9915		fog_vertex: fog_vertex,
9916		fog_pars_vertex: fog_pars_vertex,
9917		fog_fragment: fog_fragment,
9918		fog_pars_fragment: fog_pars_fragment,
9919		gradientmap_pars_fragment: gradientmap_pars_fragment,
9920		lightmap_fragment: lightmap_fragment,
9921		lightmap_pars_fragment: lightmap_pars_fragment,
9922		lights_lambert_vertex: lights_lambert_vertex,
9923		lights_pars_begin: lights_pars_begin,
9924		lights_toon_fragment: lights_toon_fragment,
9925		lights_toon_pars_fragment: lights_toon_pars_fragment,
9926		lights_phong_fragment: lights_phong_fragment,
9927		lights_phong_pars_fragment: lights_phong_pars_fragment,
9928		lights_physical_fragment: lights_physical_fragment,
9929		lights_physical_pars_fragment: lights_physical_pars_fragment,
9930		lights_fragment_begin: lights_fragment_begin,
9931		lights_fragment_maps: lights_fragment_maps,
9932		lights_fragment_end: lights_fragment_end,
9933		logdepthbuf_fragment: logdepthbuf_fragment,
9934		logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
9935		logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
9936		logdepthbuf_vertex: logdepthbuf_vertex,
9937		map_fragment: map_fragment,
9938		map_pars_fragment: map_pars_fragment,
9939		map_particle_fragment: map_particle_fragment,
9940		map_particle_pars_fragment: map_particle_pars_fragment,
9941		metalnessmap_fragment: metalnessmap_fragment,
9942		metalnessmap_pars_fragment: metalnessmap_pars_fragment,
9943		morphnormal_vertex: morphnormal_vertex,
9944		morphtarget_pars_vertex: morphtarget_pars_vertex,
9945		morphtarget_vertex: morphtarget_vertex,
9946		normal_fragment_begin: normal_fragment_begin,
9947		normal_fragment_maps: normal_fragment_maps,
9948		normal_pars_fragment: normal_pars_fragment,
9949		normal_pars_vertex: normal_pars_vertex,
9950		normal_vertex: normal_vertex,
9951		normalmap_pars_fragment: normalmap_pars_fragment,
9952		clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin,
9953		clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps,
9954		clearcoat_pars_fragment: clearcoat_pars_fragment,
9955		output_fragment: output_fragment,
9956		packing: packing,
9957		premultiplied_alpha_fragment: premultiplied_alpha_fragment,
9958		project_vertex: project_vertex,
9959		dithering_fragment: dithering_fragment,
9960		dithering_pars_fragment: dithering_pars_fragment,
9961		roughnessmap_fragment: roughnessmap_fragment,
9962		roughnessmap_pars_fragment: roughnessmap_pars_fragment,
9963		shadowmap_pars_fragment: shadowmap_pars_fragment,
9964		shadowmap_pars_vertex: shadowmap_pars_vertex,
9965		shadowmap_vertex: shadowmap_vertex,
9966		shadowmask_pars_fragment: shadowmask_pars_fragment,
9967		skinbase_vertex: skinbase_vertex,
9968		skinning_pars_vertex: skinning_pars_vertex,
9969		skinning_vertex: skinning_vertex,
9970		skinnormal_vertex: skinnormal_vertex,
9971		specularmap_fragment: specularmap_fragment,
9972		specularmap_pars_fragment: specularmap_pars_fragment,
9973		tonemapping_fragment: tonemapping_fragment,
9974		tonemapping_pars_fragment: tonemapping_pars_fragment,
9975		transmission_fragment: transmission_fragment,
9976		transmission_pars_fragment: transmission_pars_fragment,
9977		uv_pars_fragment: uv_pars_fragment,
9978		uv_pars_vertex: uv_pars_vertex,
9979		uv_vertex: uv_vertex,
9980		uv2_pars_fragment: uv2_pars_fragment,
9981		uv2_pars_vertex: uv2_pars_vertex,
9982		uv2_vertex: uv2_vertex,
9983		worldpos_vertex: worldpos_vertex,
9984		background_vert: vertex$g,
9985		background_frag: fragment$g,
9986		cube_vert: vertex$f,
9987		cube_frag: fragment$f,
9988		depth_vert: vertex$e,
9989		depth_frag: fragment$e,
9990		distanceRGBA_vert: vertex$d,
9991		distanceRGBA_frag: fragment$d,
9992		equirect_vert: vertex$c,
9993		equirect_frag: fragment$c,
9994		linedashed_vert: vertex$b,
9995		linedashed_frag: fragment$b,
9996		meshbasic_vert: vertex$a,
9997		meshbasic_frag: fragment$a,
9998		meshlambert_vert: vertex$9,
9999		meshlambert_frag: fragment$9,
10000		meshmatcap_vert: vertex$8,
10001		meshmatcap_frag: fragment$8,
10002		meshnormal_vert: vertex$7,
10003		meshnormal_frag: fragment$7,
10004		meshphong_vert: vertex$6,
10005		meshphong_frag: fragment$6,
10006		meshphysical_vert: vertex$5,
10007		meshphysical_frag: fragment$5,
10008		meshtoon_vert: vertex$4,
10009		meshtoon_frag: fragment$4,
10010		points_vert: vertex$3,
10011		points_frag: fragment$3,
10012		shadow_vert: vertex$2,
10013		shadow_frag: fragment$2,
10014		sprite_vert: vertex$1,
10015		sprite_frag: fragment$1
10016	};
10017
10018	/**
10019	 * Uniforms library for shared webgl shaders
10020	 */
10021
10022	const UniformsLib = {
10023		common: {
10024			diffuse: {
10025				value: new Color(0xffffff)
10026			},
10027			opacity: {
10028				value: 1.0
10029			},
10030			map: {
10031				value: null
10032			},
10033			uvTransform: {
10034				value: new Matrix3()
10035			},
10036			uv2Transform: {
10037				value: new Matrix3()
10038			},
10039			alphaMap: {
10040				value: null
10041			},
10042			alphaTest: {
10043				value: 0
10044			}
10045		},
10046		specularmap: {
10047			specularMap: {
10048				value: null
10049			}
10050		},
10051		envmap: {
10052			envMap: {
10053				value: null
10054			},
10055			flipEnvMap: {
10056				value: -1
10057			},
10058			reflectivity: {
10059				value: 1.0
10060			},
10061			// basic, lambert, phong
10062			ior: {
10063				value: 1.5
10064			},
10065			// standard, physical
10066			refractionRatio: {
10067				value: 0.98
10068			}
10069		},
10070		aomap: {
10071			aoMap: {
10072				value: null
10073			},
10074			aoMapIntensity: {
10075				value: 1
10076			}
10077		},
10078		lightmap: {
10079			lightMap: {
10080				value: null
10081			},
10082			lightMapIntensity: {
10083				value: 1
10084			}
10085		},
10086		emissivemap: {
10087			emissiveMap: {
10088				value: null
10089			}
10090		},
10091		bumpmap: {
10092			bumpMap: {
10093				value: null
10094			},
10095			bumpScale: {
10096				value: 1
10097			}
10098		},
10099		normalmap: {
10100			normalMap: {
10101				value: null
10102			},
10103			normalScale: {
10104				value: new Vector2(1, 1)
10105			}
10106		},
10107		displacementmap: {
10108			displacementMap: {
10109				value: null
10110			},
10111			displacementScale: {
10112				value: 1
10113			},
10114			displacementBias: {
10115				value: 0
10116			}
10117		},
10118		roughnessmap: {
10119			roughnessMap: {
10120				value: null
10121			}
10122		},
10123		metalnessmap: {
10124			metalnessMap: {
10125				value: null
10126			}
10127		},
10128		gradientmap: {
10129			gradientMap: {
10130				value: null
10131			}
10132		},
10133		fog: {
10134			fogDensity: {
10135				value: 0.00025
10136			},
10137			fogNear: {
10138				value: 1
10139			},
10140			fogFar: {
10141				value: 2000
10142			},
10143			fogColor: {
10144				value: new Color(0xffffff)
10145			}
10146		},
10147		lights: {
10148			ambientLightColor: {
10149				value: []
10150			},
10151			lightProbe: {
10152				value: []
10153			},
10154			directionalLights: {
10155				value: [],
10156				properties: {
10157					direction: {},
10158					color: {}
10159				}
10160			},
10161			directionalLightShadows: {
10162				value: [],
10163				properties: {
10164					shadowBias: {},
10165					shadowNormalBias: {},
10166					shadowRadius: {},
10167					shadowMapSize: {}
10168				}
10169			},
10170			directionalShadowMap: {
10171				value: []
10172			},
10173			directionalShadowMatrix: {
10174				value: []
10175			},
10176			spotLights: {
10177				value: [],
10178				properties: {
10179					color: {},
10180					position: {},
10181					direction: {},
10182					distance: {},
10183					coneCos: {},
10184					penumbraCos: {},
10185					decay: {}
10186				}
10187			},
10188			spotLightShadows: {
10189				value: [],
10190				properties: {
10191					shadowBias: {},
10192					shadowNormalBias: {},
10193					shadowRadius: {},
10194					shadowMapSize: {}
10195				}
10196			},
10197			spotShadowMap: {
10198				value: []
10199			},
10200			spotShadowMatrix: {
10201				value: []
10202			},
10203			pointLights: {
10204				value: [],
10205				properties: {
10206					color: {},
10207					position: {},
10208					decay: {},
10209					distance: {}
10210				}
10211			},
10212			pointLightShadows: {
10213				value: [],
10214				properties: {
10215					shadowBias: {},
10216					shadowNormalBias: {},
10217					shadowRadius: {},
10218					shadowMapSize: {},
10219					shadowCameraNear: {},
10220					shadowCameraFar: {}
10221				}
10222			},
10223			pointShadowMap: {
10224				value: []
10225			},
10226			pointShadowMatrix: {
10227				value: []
10228			},
10229			hemisphereLights: {
10230				value: [],
10231				properties: {
10232					direction: {},
10233					skyColor: {},
10234					groundColor: {}
10235				}
10236			},
10237			// TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
10238			rectAreaLights: {
10239				value: [],
10240			
vendor: 16,735 bytes, lines 10240-10874
10240	properties: {
10241					color: {},
10242					position: {},
10243					width: {},
10244					height: {}
10245				}
10246			},
10247			ltc_1: {
10248				value: null
10249			},
10250			ltc_2: {
10251				value: null
10252			}
10253		},
10254		points: {
10255			diffuse: {
10256				value: new Color(0xffffff)
10257			},
10258			opacity: {
10259				value: 1.0
10260			},
10261			size: {
10262				value: 1.0
10263			},
10264			scale: {
10265				value: 1.0
10266			},
10267			map: {
10268				value: null
10269			},
10270			alphaMap: {
10271				value: null
10272			},
10273			alphaTest: {
10274				value: 0
10275			},
10276			uvTransform: {
10277				value: new Matrix3()
10278			}
10279		},
10280		sprite: {
10281			diffuse: {
10282				value: new Color(0xffffff)
10283			},
10284			opacity: {
10285				value: 1.0
10286			},
10287			center: {
10288				value: new Vector2(0.5, 0.5)
10289			},
10290			rotation: {
10291				value: 0.0
10292			},
10293			map: {
10294				value: null
10295			},
10296			alphaMap: {
10297				value: null
10298			},
10299			alphaTest: {
10300				value: 0
10301			},
10302			uvTransform: {
10303				value: new Matrix3()
10304			}
10305		}
10306	};
10307
10308	const ShaderLib = {
10309		basic: {
10310			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.fog]),
10311			vertexShader: ShaderChunk.meshbasic_vert,
10312			fragmentShader: ShaderChunk.meshbasic_frag
10313		},
10314		lambert: {
10315			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, {
10316				emissive: {
10317					value: new Color(0x000000)
10318				}
10319			}]),
10320			vertexShader: ShaderChunk.meshlambert_vert,
10321			fragmentShader: ShaderChunk.meshlambert_frag
10322		},
10323		phong: {
10324			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, {
10325				emissive: {
10326					value: new Color(0x000000)
10327				},
10328				specular: {
10329					value: new Color(0x111111)
10330				},
10331				shininess: {
10332					value: 30
10333				}
10334			}]),
10335			vertexShader: ShaderChunk.meshphong_vert,
10336			fragmentShader: ShaderChunk.meshphong_frag
10337		},
10338		standard: {
10339			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.roughnessmap, UniformsLib.metalnessmap, UniformsLib.fog, UniformsLib.lights, {
10340				emissive: {
10341					value: new Color(0x000000)
10342				},
10343				roughness: {
10344					value: 1.0
10345				},
10346				metalness: {
10347					value: 0.0
10348				},
10349				envMapIntensity: {
10350					value: 1
10351				} // temporary
10352
10353			}]),
10354			vertexShader: ShaderChunk.meshphysical_vert,
10355			fragmentShader: ShaderChunk.meshphysical_frag
10356		},
10357		toon: {
10358			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, {
10359				emissive: {
10360					value: new Color(0x000000)
10361				}
10362			}]),
10363			vertexShader: ShaderChunk.meshtoon_vert,
10364			fragmentShader: ShaderChunk.meshtoon_frag
10365		},
10366		matcap: {
10367			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, {
10368				matcap: {
10369					value: null
10370				}
10371			}]),
10372			vertexShader: ShaderChunk.meshmatcap_vert,
10373			fragmentShader: ShaderChunk.meshmatcap_frag
10374		},
10375		points: {
10376			uniforms: mergeUniforms([UniformsLib.points, UniformsLib.fog]),
10377			vertexShader: ShaderChunk.points_vert,
10378			fragmentShader: ShaderChunk.points_frag
10379		},
10380		dashed: {
10381			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.fog, {
10382				scale: {
10383					value: 1
10384				},
10385				dashSize: {
10386					value: 1
10387				},
10388				totalSize: {
10389					value: 2
10390				}
10391			}]),
10392			vertexShader: ShaderChunk.linedashed_vert,
10393			fragmentShader: ShaderChunk.linedashed_frag
10394		},
10395		depth: {
10396			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap]),
10397			vertexShader: ShaderChunk.depth_vert,
10398			fragmentShader: ShaderChunk.depth_frag
10399		},
10400		normal: {
10401			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, {
10402				opacity: {
10403					value: 1.0
10404				}
10405			}]),
10406			vertexShader: ShaderChunk.meshnormal_vert,
10407			fragmentShader: ShaderChunk.meshnormal_frag
10408		},
10409		sprite: {
10410			uniforms: mergeUniforms([UniformsLib.sprite, UniformsLib.fog]),
10411			vertexShader: ShaderChunk.sprite_vert,
10412			fragmentShader: ShaderChunk.sprite_frag
10413		},
10414		background: {
10415			uniforms: {
10416				uvTransform: {
10417					value: new Matrix3()
10418				},
10419				t2D: {
10420					value: null
10421				}
10422			},
10423			vertexShader: ShaderChunk.background_vert,
10424			fragmentShader: ShaderChunk.background_frag
10425		},
10426
10427		/* -------------------------------------------------------------------------
10428		//	Cube map shader
10429		 ------------------------------------------------------------------------- */
10430		cube: {
10431			uniforms: mergeUniforms([UniformsLib.envmap, {
10432				opacity: {
10433					value: 1.0
10434				}
10435			}]),
10436			vertexShader: ShaderChunk.cube_vert,
10437			fragmentShader: ShaderChunk.cube_frag
10438		},
10439		equirect: {
10440			uniforms: {
10441				tEquirect: {
10442					value: null
10443				}
10444			},
10445			vertexShader: ShaderChunk.equirect_vert,
10446			fragmentShader: ShaderChunk.equirect_frag
10447		},
10448		distanceRGBA: {
10449			uniforms: mergeUniforms([UniformsLib.common, UniformsLib.displacementmap, {
10450				referencePosition: {
10451					value: new Vector3()
10452				},
10453				nearDistance: {
10454					value: 1
10455				},
10456				farDistance: {
10457					value: 1000
10458				}
10459			}]),
10460			vertexShader: ShaderChunk.distanceRGBA_vert,
10461			fragmentShader: ShaderChunk.distanceRGBA_frag
10462		},
10463		shadow: {
10464			uniforms: mergeUniforms([UniformsLib.lights, UniformsLib.fog, {
10465				color: {
10466					value: new Color(0x00000)
10467				},
10468				opacity: {
10469					value: 1.0
10470				}
10471			}]),
10472			vertexShader: ShaderChunk.shadow_vert,
10473			fragmentShader: ShaderChunk.shadow_frag
10474		}
10475	};
10476	ShaderLib.physical = {
10477		uniforms: mergeUniforms([ShaderLib.standard.uniforms, {
10478			clearcoat: {
10479				value: 0
10480			},
10481			clearcoatMap: {
10482				value: null
10483			},
10484			clearcoatRoughness: {
10485				value: 0
10486			},
10487			clearcoatRoughnessMap: {
10488				value: null
10489			},
10490			clearcoatNormalScale: {
10491				value: new Vector2(1, 1)
10492			},
10493			clearcoatNormalMap: {
10494				value: null
10495			},
10496			sheen: {
10497				value: 0
10498			},
10499			sheenColor: {
10500				value: new Color(0x000000)
10501			},
10502			sheenColorMap: {
10503				value: null
10504			},
10505			sheenRoughness: {
10506				value: 0
10507			},
10508			sheenRoughnessMap: {
10509				value: null
10510			},
10511			transmission: {
10512				value: 0
10513			},
10514			transmissionMap: {
10515				value: null
10516			},
10517			transmissionSamplerSize: {
10518				value: new Vector2()
10519			},
10520			transmissionSamplerMap: {
10521				value: null
10522			},
10523			thickness: {
10524				value: 0
10525			},
10526			thicknessMap: {
10527				value: null
10528			},
10529			attenuationDistance: {
10530				value: 0
10531			},
10532			attenuationColor: {
10533				value: new Color(0x000000)
10534			},
10535			specularIntensity: {
10536				value: 0
10537			},
10538			specularIntensityMap: {
10539				value: null
10540			},
10541			specularColor: {
10542				value: new Color(1, 1, 1)
10543			},
10544			specularColorMap: {
10545				value: null
10546			}
10547		}]),
10548		vertexShader: ShaderChunk.meshphysical_vert,
10549		fragmentShader: ShaderChunk.meshphysical_frag
10550	};
10551
10552	function WebGLBackground(renderer, cubemaps, state, objects, premultipliedAlpha) {
10553		const clearColor = new Color(0x000000);
10554		let clearAlpha = 0;
10555		let planeMesh;
10556		let boxMesh;
10557		let currentBackground = null;
10558		let currentBackgroundVersion = 0;
10559		let currentTonemapping = null;
10560
10561		function render(renderList, scene) {
10562			let forceClear = false;
10563			let background = scene.isScene === true ? scene.background : null;
10564
10565			if (background && background.isTexture) {
10566				background = cubemaps.get(background);
10567			} // Ignore background in AR
10568			// TODO: Reconsider this.
10569
10570
10571			const xr = renderer.xr;
10572			const session = xr.getSession && xr.getSession();
10573
10574			if (session && session.environmentBlendMode === 'additive') {
10575				background = null;
10576			}
10577
10578			if (background === null) {
10579				setClear(clearColor, clearAlpha);
10580			} else if (background && background.isColor) {
10581				setClear(background, 1);
10582				forceClear = true;
10583			}
10584
10585			if (renderer.autoClear || forceClear) {
10586				renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil);
10587			}
10588
10589			if (background && (background.isCubeTexture || background.mapping === CubeUVReflectionMapping)) {
10590				if (boxMesh === undefined) {
10591					boxMesh = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({
10592						name: 'BackgroundCubeMaterial',
10593						uniforms: cloneUniforms(ShaderLib.cube.uniforms),
10594						vertexShader: ShaderLib.cube.vertexShader,
10595						fragmentShader: ShaderLib.cube.fragmentShader,
10596						side: BackSide,
10597						depthTest: false,
10598						depthWrite: false,
10599						fog: false
10600					}));
10601					boxMesh.geometry.deleteAttribute('normal');
10602					boxMesh.geometry.deleteAttribute('uv');
10603
10604					boxMesh.onBeforeRender = function (renderer, scene, camera) {
10605						this.matrixWorld.copyPosition(camera.matrixWorld);
10606					}; // enable code injection for non-built-in material
10607
10608
10609					Object.defineProperty(boxMesh.material, 'envMap', {
10610						get: function () {
10611							return this.uniforms.envMap.value;
10612						}
10613					});
10614					objects.update(boxMesh);
10615				}
10616
10617				boxMesh.material.uniforms.envMap.value = background;
10618				boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1;
10619
10620				if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) {
10621					boxMesh.material.needsUpdate = true;
10622					currentBackground = background;
10623					currentBackgroundVersion = background.version;
10624					currentTonemapping = renderer.toneMapping;
10625				} // push to the pre-sorted opaque render list
10626
10627
10628				renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null);
10629			} else if (background && background.isTexture) {
10630				if (planeMesh === undefined) {
10631					planeMesh = new Mesh(new PlaneGeometry(2, 2), new ShaderMaterial({
10632						name: 'BackgroundMaterial',
10633						uniforms: cloneUniforms(ShaderLib.background.uniforms),
10634						vertexShader: ShaderLib.background.vertexShader,
10635						fragmentShader: ShaderLib.background.fragmentShader,
10636						side: FrontSide,
10637						depthTest: false,
10638						depthWrite: false,
10639						fog: false
10640					}));
10641					planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material
10642
10643					Object.defineProperty(planeMesh.material, 'map', {
10644						get: function () {
10645							return this.uniforms.t2D.value;
10646						}
10647					});
10648					objects.update(planeMesh);
10649				}
10650
10651				planeMesh.material.uniforms.t2D.value = background;
10652
10653				if (background.matrixAutoUpdate === true) {
10654					background.updateMatrix();
10655				}
10656
10657				planeMesh.material.uniforms.uvTransform.value.copy(background.matrix);
10658
10659				if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) {
10660					planeMesh.material.needsUpdate = true;
10661					currentBackground = background;
10662					currentBackgroundVersion = background.version;
10663					currentTonemapping = renderer.toneMapping;
10664				} // push to the pre-sorted opaque render list
10665
10666
10667				renderList.unshift(planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null);
10668			}
10669		}
10670
10671		function setClear(color, alpha) {
10672			state.buffers.color.setClear(color.r, color.g, color.b, alpha, premultipliedAlpha);
10673		}
10674
10675		return {
10676			getClearColor: function () {
10677				return clearColor;
10678			},
10679			setClearColor: function (color, alpha = 1) {
10680				clearColor.set(color);
10681				clearAlpha = alpha;
10682				setClear(clearColor, clearAlpha);
10683			},
10684			getClearAlpha: function () {
10685				return clearAlpha;
10686			},
10687			setClearAlpha: function (alpha) {
10688				clearAlpha = alpha;
10689				setClear(clearColor, clearAlpha);
10690			},
10691			render: render
10692		};
10693	}
10694
10695	function WebGLBindingStates(gl, extensions, attributes, capabilities) {
10696		const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
10697		const extension = capabilities.isWebGL2 ? null : extensions.get('OES_vertex_array_object');
10698		const vaoAvailable = capabilities.isWebGL2 || extension !== null;
10699		const bindingStates = {};
10700		const defaultState = createBindingState(null);
10701		let currentState = defaultState;
10702
10703		function setup(object, material, program, geometry, index) {
10704			let updateBuffers = false;
10705
10706			if (vaoAvailable) {
10707				const state = getBindingState(geometry, program, material);
10708
10709				if (currentState !== state) {
10710					currentState = state;
10711					bindVertexArrayObject(currentState.object);
10712				}
10713
10714				updateBuffers = needsUpdate(geometry, index);
10715				if (updateBuffers) saveCache(geometry, index);
10716			} else {
10717				const wireframe = material.wireframe === true;
10718
10719				if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) {
10720					currentState.geometry = geometry.id;
10721					currentState.program = program.id;
10722					currentState.wireframe = wireframe;
10723					updateBuffers = true;
10724				}
10725			}
10726
10727			if (object.isInstancedMesh === true) {
10728				updateBuffers = true;
10729			}
10730
10731			if (index !== null) {
10732				attributes.update(index, gl.ELEMENT_ARRAY_BUFFER);
10733			}
10734
10735			if (updateBuffers) {
10736				setupVertexAttributes(object, material, program, geometry);
10737
10738				if (index !== null) {
10739					gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer);
10740				}
10741			}
10742		}
10743
10744		function createVertexArrayObject() {
10745			if (capabilities.isWebGL2) return gl.createVertexArray();
10746			return extension.createVertexArrayOES();
10747		}
10748
10749		function bindVertexArrayObject(vao) {
10750			if (capabilities.isWebGL2) return gl.bindVertexArray(vao);
10751			return extension.bindVertexArrayOES(vao);
10752		}
10753
10754		function deleteVertexArrayObject(vao) {
10755			if (capabilities.isWebGL2) return gl.deleteVertexArray(vao);
10756			return extension.deleteVertexArrayOES(vao);
10757		}
10758
10759		function getBindingState(geometry, program, material) {
10760			const wireframe = material.wireframe === true;
10761			let programMap = bindingStates[geometry.id];
10762
10763			if (programMap === undefined) {
10764				programMap = {};
10765				bindingStates[geometry.id] = programMap;
10766			}
10767
10768			let stateMap = programMap[program.id];
10769
10770			if (stateMap === undefined) {
10771				stateMap = {};
10772				programMap[program.id] = stateMap;
10773			}
10774
10775			let state = stateMap[wireframe];
10776
10777			if (state === undefined) {
10778				state = createBindingState(createVertexArrayObject());
10779				stateMap[wireframe] = state;
10780			}
10781
10782			return state;
10783		}
10784
10785		function createBindingState(vao) {
10786			const newAttributes = [];
10787			const enabledAttributes = [];
10788			const attributeDivisors = [];
10789
10790			for (let i = 0; i < maxVertexAttributes; i++) {
10791				newAttributes[i] = 0;
10792				enabledAttributes[i] = 0;
10793				attributeDivisors[i] = 0;
10794			}
10795
10796			return {
10797				// for backward compatibility on non-VAO support browser
10798				geometry: null,
10799				program: null,
10800				wireframe: false,
10801				newAttributes: newAttributes,
10802				enabledAttributes: enabledAttributes,
10803				attributeDivisors: attributeDivisors,
10804				object: vao,
10805				attributes: {},
10806				index: null
10807			};
10808		}
10809
10810		function needsUpdate(geometry, index) {
10811			const cachedAttributes = currentState.attributes;
10812			const geometryAttributes = geometry.attributes;
10813			let attributesNum = 0;
10814
10815			for (const key in geometryAttributes) {
10816				const cachedAttribute = cachedAttributes[key];
10817				const geometryAttribute = geometryAttributes[key];
10818				if (cachedAttribute === undefined) return true;
10819				if (cachedAttribute.attribute !== geometryAttribute) return true;
10820				if (cachedAttribute.data !== geometryAttribute.data) return true;
10821				attributesNum++;
10822			}
10823
10824			if (currentState.attributesNum !== attributesNum) return true;
10825			if (currentState.index !== index) return true;
10826			return false;
10827		}
10828
10829		function saveCache(geometry, index) {
10830			const cache = {};
10831			const attributes = geometry.attributes;
10832			let attributesNum = 0;
10833
10834			for (const key in attributes) {
10835				const attribute = attributes[key];
10836				const data = {};
10837				data.attribute = attribute;
10838
10839				if (attribute.data) {
10840					data.data = attribute.data;
10841				}
10842
10843				cache[key] = data;
10844				attributesNum++;
10845			}
10846
10847			currentState.attributes = cache;
10848			currentState.attributesNum = attributesNum;
10849			currentState.index = index;
10850		}
10851
10852		function initAttributes() {
10853			const newAttributes = currentState.newAttributes;
10854
10855			for (let i = 0, il = newAttributes.length; i < il; i++) {
10856				newAttributes[i] = 0;
10857			}
10858		}
10859
10860		function enableAttribute(attribute) {
10861			enableAttributeAndDivisor(attribute, 0);
10862		}
10863
10864		function enableAttributeAndDivisor(attribute, meshPerAttribute) {
10865			const newAttributes = currentState.newAttributes;
10866			const enabledAttributes = currentState.enabledAttributes;
10867			const attributeDivisors = currentState.attributeDivisors;
10868			newAttributes[attribute] = 1;
10869
10870			if (enabledAttributes[attribute] === 0) {
10871				gl.enableVertexAttribArray(attribute);
10872				enabledAttributes[attribute] = 1;
10873			}
10874
vendor: 10,716 bytes, lines 10875-11188
10875			if (attributeDivisors[attribute] !== meshPerAttribute) {
10876				const extension = capabilities.isWebGL2 ? gl : extensions.get('ANGLE_instanced_arrays');
10877				extension[capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE'](attribute, meshPerAttribute);
10878				attributeDivisors[attribute] = meshPerAttribute;
10879			}
10880		}
10881
10882		function disableUnusedAttributes() {
10883			const newAttributes = currentState.newAttributes;
10884			const enabledAttributes = currentState.enabledAttributes;
10885
10886			for (let i = 0, il = enabledAttributes.length; i < il; i++) {
10887				if (enabledAttributes[i] !== newAttributes[i]) {
10888					gl.disableVertexAttribArray(i);
10889					enabledAttributes[i] = 0;
10890				}
10891			}
10892		}
10893
10894		function vertexAttribPointer(index, size, type, normalized, stride, offset) {
10895			if (capabilities.isWebGL2 === true && (type === gl.INT || type === gl.UNSIGNED_INT)) {
10896				gl.vertexAttribIPointer(index, size, type, stride, offset);
10897			} else {
10898				gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
10899			}
10900		}
10901
10902		function setupVertexAttributes(object, material, program, geometry) {
10903			if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) {
10904				if (extensions.get('ANGLE_instanced_arrays') === null) return;
10905			}
10906
10907			initAttributes();
10908			const geometryAttributes = geometry.attributes;
10909			const programAttributes = program.getAttributes();
10910			const materialDefaultAttributeValues = material.defaultAttributeValues;
10911
10912			for (const name in programAttributes) {
10913				const programAttribute = programAttributes[name];
10914
10915				if (programAttribute.location >= 0) {
10916					let geometryAttribute = geometryAttributes[name];
10917
10918					if (geometryAttribute === undefined) {
10919						if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix;
10920						if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor;
10921					}
10922
10923					if (geometryAttribute !== undefined) {
10924						const normalized = geometryAttribute.normalized;
10925						const size = geometryAttribute.itemSize;
10926						const attribute = attributes.get(geometryAttribute); // TODO Attribute may not be available on context restore
10927
10928						if (attribute === undefined) continue;
10929						const buffer = attribute.buffer;
10930						const type = attribute.type;
10931						const bytesPerElement = attribute.bytesPerElement;
10932
10933						if (geometryAttribute.isInterleavedBufferAttribute) {
10934							const data = geometryAttribute.data;
10935							const stride = data.stride;
10936							const offset = geometryAttribute.offset;
10937
10938							if (data && data.isInstancedInterleavedBuffer) {
10939								for (let i = 0; i < programAttribute.locationSize; i++) {
10940									enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute);
10941								}
10942
10943								if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) {
10944									geometry._maxInstanceCount = data.meshPerAttribute * data.count;
10945								}
10946							} else {
10947								for (let i = 0; i < programAttribute.locationSize; i++) {
10948									enableAttribute(programAttribute.location + i);
10949								}
10950							}
10951
10952							gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
10953
10954							for (let i = 0; i < programAttribute.locationSize; i++) {
10955								vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, stride * bytesPerElement, (offset + size / programAttribute.locationSize * i) * bytesPerElement);
10956							}
10957						} else {
10958							if (geometryAttribute.isInstancedBufferAttribute) {
10959								for (let i = 0; i < programAttribute.locationSize; i++) {
10960									enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute);
10961								}
10962
10963								if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) {
10964									geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
10965								}
10966							} else {
10967								for (let i = 0; i < programAttribute.locationSize; i++) {
10968									enableAttribute(programAttribute.location + i);
10969								}
10970							}
10971
10972							gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
10973
10974							for (let i = 0; i < programAttribute.locationSize; i++) {
10975								vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement);
10976							}
10977						}
10978					} else if (materialDefaultAttributeValues !== undefined) {
10979						const value = materialDefaultAttributeValues[name];
10980
10981						if (value !== undefined) {
10982							switch (value.length) {
10983								case 2:
10984									gl.vertexAttrib2fv(programAttribute.location, value);
10985									break;
10986
10987								case 3:
10988									gl.vertexAttrib3fv(programAttribute.location, value);
10989									break;
10990
10991								case 4:
10992									gl.vertexAttrib4fv(programAttribute.location, value);
10993									break;
10994
10995								default:
10996									gl.vertexAttrib1fv(programAttribute.location, value);
10997							}
10998						}
10999					}
11000				}
11001			}
11002
11003			disableUnusedAttributes();
11004		}
11005
11006		function dispose() {
11007			reset();
11008
11009			for (const geometryId in bindingStates) {
11010				const programMap = bindingStates[geometryId];
11011
11012				for (const programId in programMap) {
11013					const stateMap = programMap[programId];
11014
11015					for (const wireframe in stateMap) {
11016						deleteVertexArrayObject(stateMap[wireframe].object);
11017						delete stateMap[wireframe];
11018					}
11019
11020					delete programMap[programId];
11021				}
11022
11023				delete bindingStates[geometryId];
11024			}
11025		}
11026
11027		function releaseStatesOfGeometry(geometry) {
11028			if (bindingStates[geometry.id] === undefined) return;
11029			const programMap = bindingStates[geometry.id];
11030
11031			for (const programId in programMap) {
11032				const stateMap = programMap[programId];
11033
11034				for (const wireframe in stateMap) {
11035					deleteVertexArrayObject(stateMap[wireframe].object);
11036					delete stateMap[wireframe];
11037				}
11038
11039				delete programMap[programId];
11040			}
11041
11042			delete bindingStates[geometry.id];
11043		}
11044
11045		function releaseStatesOfProgram(program) {
11046			for (const geometryId in bindingStates) {
11047				const programMap = bindingStates[geometryId];
11048				if (programMap[program.id] === undefined) continue;
11049				const stateMap = programMap[program.id];
11050
11051				for (const wireframe in stateMap) {
11052					deleteVertexArrayObject(stateMap[wireframe].object);
11053					delete stateMap[wireframe];
11054				}
11055
11056				delete programMap[program.id];
11057			}
11058		}
11059
11060		function reset() {
11061			resetDefaultState();
11062			if (currentState === defaultState) return;
11063			currentState = defaultState;
11064			bindVertexArrayObject(currentState.object);
11065		} // for backward-compatilibity
11066
11067
11068		function resetDefaultState() {
11069			defaultState.geometry = null;
11070			defaultState.program = null;
11071			defaultState.wireframe = false;
11072		}
11073
11074		return {
11075			setup: setup,
11076			reset: reset,
11077			resetDefaultState: resetDefaultState,
11078			dispose: dispose,
11079			releaseStatesOfGeometry: releaseStatesOfGeometry,
11080			releaseStatesOfProgram: releaseStatesOfProgram,
11081			initAttributes: initAttributes,
11082			enableAttribute: enableAttribute,
11083			disableUnusedAttributes: disableUnusedAttributes
11084		};
11085	}
11086
11087	function WebGLBufferRenderer(gl, extensions, info, capabilities) {
11088		const isWebGL2 = capabilities.isWebGL2;
11089		let mode;
11090
11091		function setMode(value) {
11092			mode = value;
11093		}
11094
11095		function render(start, count) {
11096			gl.drawArrays(mode, start, count);
11097			info.update(count, mode, 1);
11098		}
11099
11100		function renderInstances(start, count, primcount) {
11101			if (primcount === 0) return;
11102			let extension, methodName;
11103
11104			if (isWebGL2) {
11105				extension = gl;
11106				methodName = 'drawArraysInstanced';
11107			} else {
11108				extension = extensions.get('ANGLE_instanced_arrays');
11109				methodName = 'drawArraysInstancedANGLE';
11110
11111				if (extension === null) {
11112					console.error('THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.');
11113					return;
11114				}
11115			}
11116
11117			extension[methodName](mode, start, count, primcount);
11118			info.update(count, mode, primcount);
11119		} //
11120
11121
11122		this.setMode = setMode;
11123		this.render = render;
11124		this.renderInstances = renderInstances;
11125	}
11126
11127	function WebGLCapabilities(gl, extensions, parameters) {
11128		let maxAnisotropy;
11129
11130		function getMaxAnisotropy() {
11131			if (maxAnisotropy !== undefined) return maxAnisotropy;
11132
11133			if (extensions.has('EXT_texture_filter_anisotropic') === true) {
11134				const extension = extensions.get('EXT_texture_filter_anisotropic');
11135				maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
11136			} else {
11137				maxAnisotropy = 0;
11138			}
11139
11140			return maxAnisotropy;
11141		}
11142
11143		function getMaxPrecision(precision) {
11144			if (precision === 'highp') {
11145				if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) {
11146					return 'highp';
11147				}
11148
11149				precision = 'mediump';
11150			}
11151
11152			if (precision === 'mediump') {
11153				if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) {
11154					return 'mediump';
11155				}
11156			}
11157
11158			return 'lowp';
11159		}
11160
11161		const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext || typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext;
11162		let precision = parameters.precision !== undefined ? parameters.precision : 'highp';
11163		const maxPrecision = getMaxPrecision(precision);
11164
11165		if (maxPrecision !== precision) {
11166			console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.');
11167			precision = maxPrecision;
11168		}
11169
11170		const drawBuffers = isWebGL2 || extensions.has('WEBGL_draw_buffers');
11171		const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
11172		const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
11173		const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
11174		const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
11175		const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
11176		const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
11177		const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);
11178		const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS);
11179		const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
11180		const vertexTextures = maxVertexTextures > 0;
11181		const floatFragmentTextures = isWebGL2 || extensions.has('OES_texture_float');
11182		const floatVertexTextures = vertexTextures && floatFragmentTextures;
11183		const maxSamples = isWebGL2 ? gl.getParameter(gl.MAX_SAMPLES) : 0;
11184		return {
11185			isWebGL2: isWebGL2,
11186			drawBuffers: drawBuffers,
11187			getMaxAnisotropy: getMaxAnisotropy,
11188			getMaxPrecision: getMaxPrecision,
vendor: 1,698 bytes, lines 11189-11244
11189			precision: precision,
11190			logarithmicDepthBuffer: logarithmicDepthBuffer,
11191			maxTextures: maxTextures,
11192			maxVertexTextures: maxVertexTextures,
11193			maxTextureSize: maxTextureSize,
11194			maxCubemapSize: maxCubemapSize,
11195			maxAttributes: maxAttributes,
11196			maxVertexUniforms: maxVertexUniforms,
11197			maxVaryings: maxVaryings,
11198			maxFragmentUniforms: maxFragmentUniforms,
11199			vertexTextures: vertexTextures,
11200			floatFragmentTextures: floatFragmentTextures,
11201			floatVertexTextures: floatVertexTextures,
11202			maxSamples: maxSamples
11203		};
11204	}
11205
11206	function WebGLClipping(properties) {
11207		const scope = this;
11208		let globalState = null,
11209				numGlobalPlanes = 0,
11210				localClippingEnabled = false,
11211				renderingShadows = false;
11212		const plane = new Plane(),
11213					viewNormalMatrix = new Matrix3(),
11214					uniform = {
11215			value: null,
11216			needsUpdate: false
11217		};
11218		this.uniform = uniform;
11219		this.numPlanes = 0;
11220		this.numIntersection = 0;
11221
11222		this.init = function (planes, enableLocalClipping, camera) {
11223			const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to
11224			// run another frame in order to reset the state:
11225			numGlobalPlanes !== 0 || localClippingEnabled;
11226			localClippingEnabled = enableLocalClipping;
11227			globalState = projectPlanes(planes, camera, 0);
11228			numGlobalPlanes = planes.length;
11229			return enabled;
11230		};
11231
11232		this.beginShadows = function () {
11233			renderingShadows = true;
11234			projectPlanes(null);
11235		};
11236
11237		this.endShadows = function () {
11238			renderingShadows = false;
11239			resetGlobalState();
11240		};
11241
11242		this.setState = function (material, camera, useCache) {
11243			const planes = material.clippingPlanes,
11244						clipIntersection = material.clipIntersection,
vendor: 5,162 bytes, lines 11245-11434
11245						clipShadows = material.clipShadows;
11246			const materialProperties = properties.get(material);
11247
11248			if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) {
11249				// there's no local clipping
11250				if (renderingShadows) {
11251					// there's no global clipping
11252					projectPlanes(null);
11253				} else {
11254					resetGlobalState();
11255				}
11256			} else {
11257				const nGlobal = renderingShadows ? 0 : numGlobalPlanes,
11258							lGlobal = nGlobal * 4;
11259				let dstArray = materialProperties.clippingState || null;
11260				uniform.value = dstArray; // ensure unique state
11261
11262				dstArray = projectPlanes(planes, camera, lGlobal, useCache);
11263
11264				for (let i = 0; i !== lGlobal; ++i) {
11265					dstArray[i] = globalState[i];
11266				}
11267
11268				materialProperties.clippingState = dstArray;
11269				this.numIntersection = clipIntersection ? this.numPlanes : 0;
11270				this.numPlanes += nGlobal;
11271			}
11272		};
11273
11274		function resetGlobalState() {
11275			if (uniform.value !== globalState) {
11276				uniform.value = globalState;
11277				uniform.needsUpdate = numGlobalPlanes > 0;
11278			}
11279
11280			scope.numPlanes = numGlobalPlanes;
11281			scope.numIntersection = 0;
11282		}
11283
11284		function projectPlanes(planes, camera, dstOffset, skipTransform) {
11285			const nPlanes = planes !== null ? planes.length : 0;
11286			let dstArray = null;
11287
11288			if (nPlanes !== 0) {
11289				dstArray = uniform.value;
11290
11291				if (skipTransform !== true || dstArray === null) {
11292					const flatSize = dstOffset + nPlanes * 4,
11293								viewMatrix = camera.matrixWorldInverse;
11294					viewNormalMatrix.getNormalMatrix(viewMatrix);
11295
11296					if (dstArray === null || dstArray.length < flatSize) {
11297						dstArray = new Float32Array(flatSize);
11298					}
11299
11300					for (let i = 0, i4 = dstOffset; i !== nPlanes; ++i, i4 += 4) {
11301						plane.copy(planes[i]).applyMatrix4(viewMatrix, viewNormalMatrix);
11302						plane.normal.toArray(dstArray, i4);
11303						dstArray[i4 + 3] = plane.constant;
11304					}
11305				}
11306
11307				uniform.value = dstArray;
11308				uniform.needsUpdate = true;
11309			}
11310
11311			scope.numPlanes = nPlanes;
11312			scope.numIntersection = 0;
11313			return dstArray;
11314		}
11315	}
11316
11317	function WebGLCubeMaps(renderer) {
11318		let cubemaps = new WeakMap();
11319
11320		function mapTextureMapping(texture, mapping) {
11321			if (mapping === EquirectangularReflectionMapping) {
11322				texture.mapping = CubeReflectionMapping;
11323			} else if (mapping === EquirectangularRefractionMapping) {
11324				texture.mapping = CubeRefractionMapping;
11325			}
11326
11327			return texture;
11328		}
11329
11330		function get(texture) {
11331			if (texture && texture.isTexture && texture.isRenderTargetTexture === false) {
11332				const mapping = texture.mapping;
11333
11334				if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) {
11335					if (cubemaps.has(texture)) {
11336						const cubemap = cubemaps.get(texture).texture;
11337						return mapTextureMapping(cubemap, texture.mapping);
11338					} else {
11339						const image = texture.image;
11340
11341						if (image && image.height > 0) {
11342							const currentRenderTarget = renderer.getRenderTarget();
11343							const renderTarget = new WebGLCubeRenderTarget(image.height / 2);
11344							renderTarget.fromEquirectangularTexture(renderer, texture);
11345							cubemaps.set(texture, renderTarget);
11346							renderer.setRenderTarget(currentRenderTarget);
11347							texture.addEventListener('dispose', onTextureDispose);
11348							return mapTextureMapping(renderTarget.texture, texture.mapping);
11349						} else {
11350							// image not yet ready. try the conversion next frame
11351							return null;
11352						}
11353					}
11354				}
11355			}
11356
11357			return texture;
11358		}
11359
11360		function onTextureDispose(event) {
11361			const texture = event.target;
11362			texture.removeEventListener('dispose', onTextureDispose);
11363			const cubemap = cubemaps.get(texture);
11364
11365			if (cubemap !== undefined) {
11366				cubemaps.delete(texture);
11367				cubemap.dispose();
11368			}
11369		}
11370
11371		function dispose() {
11372			cubemaps = new WeakMap();
11373		}
11374
11375		return {
11376			get: get,
11377			dispose: dispose
11378		};
11379	}
11380
11381	class OrthographicCamera extends Camera {
11382		constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2000) {
11383			super();
11384			this.type = 'OrthographicCamera';
11385			this.zoom = 1;
11386			this.view = null;
11387			this.left = left;
11388			this.right = right;
11389			this.top = top;
11390			this.bottom = bottom;
11391			this.near = near;
11392			this.far = far;
11393			this.updateProjectionMatrix();
11394		}
11395
11396		copy(source, recursive) {
11397			super.copy(source, recursive);
11398			this.left = source.left;
11399			this.right = source.right;
11400			this.top = source.top;
11401			this.bottom = source.bottom;
11402			this.near = source.near;
11403			this.far = source.far;
11404			this.zoom = source.zoom;
11405			this.view = source.view === null ? null : Object.assign({}, source.view);
11406			return this;
11407		}
11408
11409		setViewOffset(fullWidth, fullHeight, x, y, width, height) {
11410			if (this.view === null) {
11411				this.view = {
11412					enabled: true,
11413					fullWidth: 1,
11414					fullHeight: 1,
11415					offsetX: 0,
11416					offsetY: 0,
11417					width: 1,
11418					height: 1
11419				};
11420			}
11421
11422			this.view.enabled = true;
11423			this.view.fullWidth = fullWidth;
11424			this.view.fullHeight = fullHeight;
11425			this.view.offsetX = x;
11426			this.view.offsetY = y;
11427			this.view.width = width;
11428			this.view.height = height;
11429			this.updateProjectionMatrix();
11430		}
11431
11432		clearViewOffset() {
11433			if (this.view !== null) {
11434				this.view.enabled = false;
vendor: 7,091 bytes, lines 11435-11645
11435			}
11436
11437			this.updateProjectionMatrix();
11438		}
11439
11440		updateProjectionMatrix() {
11441			const dx = (this.right - this.left) / (2 * this.zoom);
11442			const dy = (this.top - this.bottom) / (2 * this.zoom);
11443			const cx = (this.right + this.left) / 2;
11444			const cy = (this.top + this.bottom) / 2;
11445			let left = cx - dx;
11446			let right = cx + dx;
11447			let top = cy + dy;
11448			let bottom = cy - dy;
11449
11450			if (this.view !== null && this.view.enabled) {
11451				const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom;
11452				const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom;
11453				left += scaleW * this.view.offsetX;
11454				right = left + scaleW * this.view.width;
11455				top -= scaleH * this.view.offsetY;
11456				bottom = top - scaleH * this.view.height;
11457			}
11458
11459			this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far);
11460			this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
11461		}
11462
11463		toJSON(meta) {
11464			const data = super.toJSON(meta);
11465			data.object.zoom = this.zoom;
11466			data.object.left = this.left;
11467			data.object.right = this.right;
11468			data.object.top = this.top;
11469			data.object.bottom = this.bottom;
11470			data.object.near = this.near;
11471			data.object.far = this.far;
11472			if (this.view !== null) data.object.view = Object.assign({}, this.view);
11473			return data;
11474		}
11475
11476	}
11477
11478	OrthographicCamera.prototype.isOrthographicCamera = true;
11479
11480	class RawShaderMaterial extends ShaderMaterial {
11481		constructor(parameters) {
11482			super(parameters);
11483			this.type = 'RawShaderMaterial';
11484		}
11485
11486	}
11487
11488	RawShaderMaterial.prototype.isRawShaderMaterial = true;
11489
11490	const LOD_MIN = 4;
11491	const LOD_MAX = 8;
11492	const SIZE_MAX = Math.pow(2, LOD_MAX); // The standard deviations (radians) associated with the extra mips. These are
11493	// chosen to approximate a Trowbridge-Reitz distribution function times the
11494	// geometric shadowing function. These sigma values squared must match the
11495	// variance #defines in cube_uv_reflection_fragment.glsl.js.
11496
11497	const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582];
11498	const TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; // The maximum length of the blur for loop. Smaller sigmas will use fewer
11499	// samples and exit early, but not recompile the shader.
11500
11501	const MAX_SAMPLES = 20;
11502	const ENCODINGS = {
11503		[LinearEncoding]: 0,
11504		[sRGBEncoding]: 1
11505	};
11506
11507	const _flatCamera = /*@__PURE__*/new OrthographicCamera();
11508
11509	const {
11510		_lodPlanes,
11511		_sizeLods,
11512		_sigmas
11513	} = /*@__PURE__*/_createPlanes();
11514
11515	const _clearColor = /*@__PURE__*/new Color();
11516
11517	let _oldTarget = null; // Golden Ratio
11518
11519	const PHI = (1 + Math.sqrt(5)) / 2;
11520	const INV_PHI = 1 / PHI; // Vertices of a dodecahedron (except the opposites, which represent the
11521	// same axis), used as axis directions evenly spread on a sphere.
11522
11523	const _axisDirections = [/*@__PURE__*/new Vector3(1, 1, 1), /*@__PURE__*/new Vector3(-1, 1, 1), /*@__PURE__*/new Vector3(1, 1, -1), /*@__PURE__*/new Vector3(-1, 1, -1), /*@__PURE__*/new Vector3(0, PHI, INV_PHI), /*@__PURE__*/new Vector3(0, PHI, -INV_PHI), /*@__PURE__*/new Vector3(INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(-INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(PHI, INV_PHI, 0), /*@__PURE__*/new Vector3(-PHI, INV_PHI, 0)];
11524	/**
11525	 * This class generates a Prefiltered, Mipmapped Radiance Environment Map
11526	 * (PMREM) from a cubeMap environment texture. This allows different levels of
11527	 * blur to be quickly accessed based on material roughness. It is packed into a
11528	 * special CubeUV format that allows us to perform custom interpolation so that
11529	 * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap
11530	 * chain, it only goes down to the LOD_MIN level (above), and then creates extra
11531	 * even more filtered 'mips' at the same LOD_MIN resolution, associated with
11532	 * higher roughness levels. In this way we maintain resolution to smoothly
11533	 * interpolate diffuse lighting while limiting sampling computation.
11534	 *
11535	 * Paper: Fast, Accurate Image-Based Lighting
11536	 * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view
11537	*/
11538
11539	class PMREMGenerator {
11540		constructor(renderer) {
11541			this._renderer = renderer;
11542			this._pingPongRenderTarget = null;
11543			this._blurMaterial = _getBlurShader(MAX_SAMPLES);
11544			this._equirectShader = null;
11545			this._cubemapShader = null;
11546
11547			this._compileMaterial(this._blurMaterial);
11548		}
11549		/**
11550		 * Generates a PMREM from a supplied Scene, which can be faster than using an
11551		 * image if networking bandwidth is low. Optional sigma specifies a blur radius
11552		 * in radians to be applied to the scene before PMREM generation. Optional near
11553		 * and far planes ensure the scene is rendered in its entirety (the cubeCamera
11554		 * is placed at the origin).
11555		 */
11556
11557
11558		fromScene(scene, sigma = 0, near = 0.1, far = 100) {
11559			_oldTarget = this._renderer.getRenderTarget();
11560
11561			const cubeUVRenderTarget = this._allocateTargets();
11562
11563			this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget);
11564
11565			if (sigma > 0) {
11566				this._blur(cubeUVRenderTarget, 0, 0, sigma);
11567			}
11568
11569			this._applyPMREM(cubeUVRenderTarget);
11570
11571			this._cleanup(cubeUVRenderTarget);
11572
11573			return cubeUVRenderTarget;
11574		}
11575		/**
11576		 * Generates a PMREM from an equirectangular texture, which can be either LDR
11577		 * or HDR. The ideal input image size is 1k (1024 x 512),
11578		 * as this matches best with the 256 x 256 cubemap output.
11579		 */
11580
11581
11582		fromEquirectangular(equirectangular) {
11583			return this._fromTexture(equirectangular);
11584		}
11585		/**
11586		 * Generates a PMREM from an cubemap texture, which can be either LDR
11587		 * or HDR. The ideal input cube size is 256 x 256,
11588		 * as this matches best with the 256 x 256 cubemap output.
11589		 */
11590
11591
11592		fromCubemap(cubemap) {
11593			return this._fromTexture(cubemap);
11594		}
11595		/**
11596		 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
11597		 * your texture's network fetch for increased concurrency.
11598		 */
11599
11600
11601		compileCubemapShader() {
11602			if (this._cubemapShader === null) {
11603				this._cubemapShader = _getCubemapShader();
11604
11605				this._compileMaterial(this._cubemapShader);
11606			}
11607		}
11608		/**
11609		 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
11610		 * your texture's network fetch for increased concurrency.
11611		 */
11612
11613
11614		compileEquirectangularShader() {
11615			if (this._equirectShader === null) {
11616				this._equirectShader = _getEquirectShader();
11617
11618				this._compileMaterial(this._equirectShader);
11619			}
11620		}
11621		/**
11622		 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
11623		 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
11624		 * one of them will cause any others to also become unusable.
11625		 */
11626
11627
11628		dispose() {
11629			this._blurMaterial.dispose();
11630
11631			if (this._cubemapShader !== null) this._cubemapShader.dispose();
11632			if (this._equirectShader !== null) this._equirectShader.dispose();
11633
11634			for (let i = 0; i < _lodPlanes.length; i++) {
11635				_lodPlanes[i].dispose();
11636			}
11637		} // private interface
11638
11639
11640		_cleanup(outputTarget) {
11641			this._pingPongRenderTarget.dispose();
11642
11643			this._renderer.setRenderTarget(_oldTarget);
11644
11645			outputTarget.scissorTest = false;
11646
11647			_setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height);
11648		}
11649
11650		_fromTexture(texture) {
11651			_oldTarget = this._renderer.getRenderTarget();
11652
11653			const cubeUVRenderTarget = this._allocateTargets(texture);
11654
11655			this._textureToCubeUV(texture, cubeUVRenderTarget);
11656
11657			this._applyPMREM(cubeUVRenderTarget);
11658
11659			this._cleanup(cubeUVRenderTarget);
11660
11661			return cubeUVRenderTarget;
11662		}
11663
11664		_allocateTargets(texture) {
11665			// warning: null texture is valid
11666			const params = {
11667				magFilter: LinearFilter,
11668				minFilter: LinearFilter,
11669				generateMipmaps: false,
11670				type: HalfFloatType,
11671				format: RGBAFormat,
11672				encoding: LinearEncoding,
11673				depthBuffer: false
11674			};
11675
11676			const cubeUVRenderTarget = _createRenderTarget(params);
11677
11678			cubeUVRenderTarget.depthBuffer = texture ? false : true;
11679			this._pingPongRenderTarget = _createRenderTarget(params);
11680			return cubeUVRenderTarget;
11681		}
11682
11683		_compileMaterial(material) {
11684			const tmpMesh = new Mesh(_lodPlanes[0], material);
11685
11686			this._renderer.compile(tmpMesh, _flatCamera);
11687		}
11688
11689		_sceneToCubeUV(scene, near, far, cubeUVRenderTarget) {
11690			const fov = 90;
11691			const aspect = 1;
11692			const cubeCamera = new PerspectiveCamera(fov, aspect, near, far);
11693			const upSign = [1, -1, 1, 1, 1, 1];
11694			const forwardSign = [1, 1, 1, -1, -1, -1];
11695			const renderer = this._renderer;
11696			const originalAutoClear = renderer.autoClear;
11697			const toneMapping = renderer.toneMapping;
11698			renderer.getClearColor(_clearColor);
11699			renderer.toneMapping = NoToneMapping;
11700			renderer.autoClear = false;
11701			const backgroundMaterial = new MeshBasicMaterial({
11702				name: 'PMREM.Background',
11703				side: BackSide,
11704				depthWrite: false,
11705				depthTest: false
11706			});
11707			const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial);
11708			let useSolidColor = false;
11709			const background = scene.background;
11710
11711			if (background) {
11712				if (background.isColor) {
11713					backgroundMaterial.color.copy(background);
11714					scene.background = null;
11715					useSolidColor = true;
11716				}
11717			} else {
11718				backgroundMaterial.color.copy(_clearColor);
11719				useSolidColor = true;
11720			}
11721
11722			for (let i = 0; i < 6; i++) {
11723				const col = i % 3;
11724
11725				if (col == 0) {
11726					cubeCamera.up.set(0, upSign[i], 0);
11727					cubeCamera.lookAt(forwardSign[i], 0, 0);
11728				} else if (col == 1) {
11729					cubeCamera.up.set(0, 0, upSign[i]);
11730					cubeCamera.lookAt(0, forwardSign[i], 0);
11731				} else {
11732					cubeCamera.up.set(0, upSign[i], 0);
11733					cubeCamera.lookAt(0, 0, forwardSign[i]);
11734				}
11735
11736				_setViewport(cubeUVRenderTarget, col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX);
11737
11738				renderer.setRenderTarget(cubeUVRenderTarget);
11739
11740				if (useSolidColor) {
11741					renderer.render(backgroundBox, cubeCamera);
11742				}
11743
11744				renderer.render(scene, cubeCamera);
11745			}
11746
11747			backgroundBox.geometry.dispose();
11748			backgroundBox.material.dispose();
11749			renderer.toneMapping = toneMapping;
11750			renderer.autoClear = originalAutoClear;
11751			scene.background = background;
11752		}
11753
11754		_setEncoding(uniform, texture) {
11755			if (this._renderer.capabilities.isWebGL2 === true && texture.format === RGBAFormat && texture.type === UnsignedByteType && texture.encoding === sRGBEncoding) {
11756				uniform.value = ENCODINGS[LinearEncoding];
11757			} else {
11758				uniform.value = ENCODINGS[texture.encoding];
11759			}
11760		}
11761
11762		_textureToCubeUV(texture, cubeUVRenderTarget) {
11763			const renderer = this._renderer;
11764			const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping;
11765
11766			if (isCubeTexture) {
11767				if (this._cubemapShader == null) {
11768					this._cubemapShader = _getCubemapShader();
11769				}
11770			} else {
11771				if (this._equirectShader == null) {
11772					this._equirectShader = _getEquirectShader();
11773				}
11774			}
11775
11776			const material = isCubeTexture ? this._cubemapShader : this._equirectShader;
11777			const mesh = new Mesh(_lodPlanes[0], material);
11778			const uniforms = material.uniforms;
11779			uniforms['envMap'].value = texture;
11780
11781			if (!isCubeTexture) {
11782				uniforms['texelSize'].value.set(1.0 / texture.image.width, 1.0 / texture.image.height);
11783			}
11784
11785			this._setEncoding(uniforms['inputEncoding'], texture);
11786
11787			_setViewport(cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX);
11788
11789			renderer.setRenderTarget(cubeUVRenderTarget);
11790			renderer.render(mesh, _flatCamera);
11791		}
11792
11793		_applyPMREM(cubeUVRenderTarget) {
11794			const renderer = this._renderer;
11795			const autoClear = renderer.autoClear;
11796			renderer.autoClear = false;
11797
11798			for (let i = 1; i < TOTAL_LODS; i++) {
11799				const sigma = Math.sqrt(_sigmas[i] * _sigmas[i] - _sigmas[i - 1] * _sigmas[i - 1]);
11800				const poleAxis = _axisDirections[(i - 1) % _axisDirections.length];
11801
11802				this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis);
11803			}
11804
11805			renderer.autoClear = autoClear;
11806		}
11807		/**
11808		 * This is a two-pass Gaussian blur for a cubemap. Normally this is done
11809		 * vertically and horizontally, but this breaks down on a cube. Here we apply
11810		 * the blur latitudinally (around the poles), and then longitudinally (towards
11811		 * the poles) to approximate the orthogonally-separable blur. It is least
11812		 * accurate at the poles, but still does a decent job.
11813		 */
11814
11815
11816		_blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) {
11817			const pingPongRenderTarget = this._pingPongRenderTarget;
11818
11819			this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis);
11820
11821			this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis);
11822		}
11823
11824		_halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) {
11825			const renderer = this._renderer;
11826			const blurMaterial = this._blurMaterial;
11827
11828			if (direction !== 'latitudinal' && direction !== 'longitudinal') {
11829				console.error('blur direction must be either latitudinal or longitudinal!');
11830			} // Number of standard deviations at which to cut off the discrete approximation.
11831
11832
11833			const STANDARD_DEVIATIONS = 3;
11834			const blurMesh = new Mesh(_lodPlanes[lodOut], blurMaterial);
11835			const blurUniforms = blurMaterial.uniforms;
11836			const pixels = _sizeLods[lodIn] - 1;
vendor: 4,190 bytes, lines 11837-11974
11837			const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1);
11838			const sigmaPixels = sigmaRadians / radiansPerPixel;
11839			const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES;
11840
11841			if (samples > MAX_SAMPLES) {
11842				console.warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES}`);
11843			}
11844
11845			const weights = [];
11846			let sum = 0;
11847
11848			for (let i = 0; i < MAX_SAMPLES; ++i) {
11849				const x = i / sigmaPixels;
11850				const weight = Math.exp(-x * x / 2);
11851				weights.push(weight);
11852
11853				if (i == 0) {
11854					sum += weight;
11855				} else if (i < samples) {
11856					sum += 2 * weight;
11857				}
11858			}
11859
11860			for (let i = 0; i < weights.length; i++) {
11861				weights[i] = weights[i] / sum;
11862			}
11863
11864			blurUniforms['envMap'].value = targetIn.texture;
11865			blurUniforms['samples'].value = samples;
11866			blurUniforms['weights'].value = weights;
11867			blurUniforms['latitudinal'].value = direction === 'latitudinal';
11868
11869			if (poleAxis) {
11870				blurUniforms['poleAxis'].value = poleAxis;
11871			}
11872
11873			blurUniforms['dTheta'].value = radiansPerPixel;
11874			blurUniforms['mipInt'].value = LOD_MAX - lodIn;
11875			const outputSize = _sizeLods[lodOut];
11876			const x = 3 * Math.max(0, SIZE_MAX - 2 * outputSize);
11877			const y = (lodOut === 0 ? 0 : 2 * SIZE_MAX) + 2 * outputSize * (lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0);
11878
11879			_setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize);
11880
11881			renderer.setRenderTarget(targetOut);
11882			renderer.render(blurMesh, _flatCamera);
11883		}
11884
11885	}
11886
11887	function _createPlanes() {
11888		const _lodPlanes = [];
11889		const _sizeLods = [];
11890		const _sigmas = [];
11891		let lod = LOD_MAX;
11892
11893		for (let i = 0; i < TOTAL_LODS; i++) {
11894			const sizeLod = Math.pow(2, lod);
11895
11896			_sizeLods.push(sizeLod);
11897
11898			let sigma = 1.0 / sizeLod;
11899
11900			if (i > LOD_MAX - LOD_MIN) {
11901				sigma = EXTRA_LOD_SIGMA[i - LOD_MAX + LOD_MIN - 1];
11902			} else if (i == 0) {
11903				sigma = 0;
11904			}
11905
11906			_sigmas.push(sigma);
11907
11908			const texelSize = 1.0 / (sizeLod - 1);
11909			const min = -texelSize / 2;
11910			const max = 1 + texelSize / 2;
11911			const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max];
11912			const cubeFaces = 6;
11913			const vertices = 6;
11914			const positionSize = 3;
11915			const uvSize = 2;
11916			const faceIndexSize = 1;
11917			const position = new Float32Array(positionSize * vertices * cubeFaces);
11918			const uv = new Float32Array(uvSize * vertices * cubeFaces);
11919			const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces);
11920
11921			for (let face = 0; face < cubeFaces; face++) {
11922				const x = face % 3 * 2 / 3 - 1;
11923				const y = face > 2 ? 0 : -1;
11924				const coordinates = [x, y, 0, x + 2 / 3, y, 0, x + 2 / 3, y + 1, 0, x, y, 0, x + 2 / 3, y + 1, 0, x, y + 1, 0];
11925				position.set(coordinates, positionSize * vertices * face);
11926				uv.set(uv1, uvSize * vertices * face);
11927				const fill = [face, face, face, face, face, face];
11928				faceIndex.set(fill, faceIndexSize * vertices * face);
11929			}
11930
11931			const planes = new BufferGeometry();
11932			planes.setAttribute('position', new BufferAttribute(position, positionSize));
11933			planes.setAttribute('uv', new BufferAttribute(uv, uvSize));
11934			planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize));
11935
11936			_lodPlanes.push(planes);
11937
11938			if (lod > LOD_MIN) {
11939				lod--;
11940			}
11941		}
11942
11943		return {
11944			_lodPlanes,
11945			_sizeLods,
11946			_sigmas
11947		};
11948	}
11949
11950	function _createRenderTarget(params) {
11951		const cubeUVRenderTarget = new WebGLRenderTarget(3 * SIZE_MAX, 3 * SIZE_MAX, params);
11952		cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
11953		cubeUVRenderTarget.texture.name = 'PMREM.cubeUv';
11954		cubeUVRenderTarget.scissorTest = true;
11955		return cubeUVRenderTarget;
11956	}
11957
11958	function _setViewport(target, x, y, width, height) {
11959		target.viewport.set(x, y, width, height);
11960		target.scissor.set(x, y, width, height);
11961	}
11962
11963	function _getBlurShader(maxSamples) {
11964		const weights = new Float32Array(maxSamples);
11965		const poleAxis = new Vector3(0, 1, 0);
11966		const shaderMaterial = new RawShaderMaterial({
11967			name: 'SphericalGaussianBlur',
11968			defines: {
11969				'n': maxSamples
11970			},
11971			uniforms: {
11972				'envMap': {
11973					value: null
11974				},
11975				'samples': {
11976					value: 1
11977				},
11978				'weights': {
11979					value: weights
11980				},
11981				'latitudinal': {
11982					value: false
11983				},
11984				'dTheta': {
11985					value: 0
11986				},
11987				'mipInt': {
11988					value: 0
11989				},
11990				'poleAxis': {
11991					value: poleAxis
11992				}
11993			},
11994			vertexShader: _getCommonVertexShader(),
11995			fragmentShader:
11996			/* glsl */
11997			`
11998
11999			precision mediump float;
12000			precision mediump int;
12001
12002			varying vec3 vOutputDirection;
12003
12004			uniform sampler2D envMap;
12005			uniform int samples;
12006			uniform float weights[ n ];
12007			uniform bool latitudinal;
12008			uniform float dTheta;
12009			uniform float mipInt;
12010			uniform vec3 poleAxis;
12011
12012			${_getEncodings()}
12013
12014			#define ENVMAP_TYPE_CUBE_UV
12015			#include <cube_uv_reflection_fragment>
12016
12017			vec3 getSample( float theta, vec3 axis ) {
12018
12019				float cosTheta = cos( theta );
12020				// Rodrigues' axis-angle rotation
12021				vec3 sampleDirection = vOutputDirection * cosTheta
12022					+ cross( axis, vOutputDirection ) * sin( theta )
12023					+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );
12024
12025				return bilinearCubeUV( envMap, sampleDirection, mipInt );
12026
12027			}
12028
12029			void main() {
12030
12031				vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );
12032
12033				if ( all( equal( axis, vec3( 0.0 ) ) ) ) {
12034
12035					axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );
12036
12037				}
12038
12039				axis = normalize( axis );
12040
12041				gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
12042				gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );
12043
12044				for ( int i = 1; i < n; i++ ) {
12045
12046					if ( i >= samples ) {
12047
12048						break;
12049
12050					}
12051
12052					float theta = dTheta * float( i );
12053					gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
12054					gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );
12055
12056				}
12057
12058			}
12059		`,
12060			blending: NoBlending,
12061			depthTest: false,
12062			depthWrite: false
12063		});
12064		return shaderMaterial;
12065	}
12066
12067	function _getEquirectShader() {
12068		const texelSize = new Vector2(1, 1);
12069		const shaderMaterial = new RawShaderMaterial({
12070			name: 'EquirectangularToCubeUV',
12071			uniforms: {
12072				'envMap': {
12073					value: null
12074				},
12075				'texelSize': {
12076					value: texelSize
12077				},
12078				'inputEncoding': {
12079					value: ENCODINGS[LinearEncoding]
12080				}
12081			},
12082			vertexShader: _getCommonVertexShader(),
12083			fragmentShader:
12084			/* glsl */
12085			`
12086
12087			precision mediump float;
12088			precision mediump int;
12089
12090			varying vec3 vOutputDirection;
12091
12092			uniform sampler2D envMap;
12093			uniform vec2 texelSize;
12094
12095			${_getEncodings()}
12096
12097			#include <common>
12098
12099			void main() {
12100
12101				gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
12102
12103				vec3 outputDirection = normalize( vOutputDirection );
12104				vec2 uv = equirectUv( outputDirection );
12105
12106				vec2 f = fract( uv / texelSize - 0.5 );
12107				uv -= f * texelSize;
12108				vec3 tl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
12109				uv.x += texelSize.x;
12110				vec3 tr = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
12111				uv.y += texelSize.y;
12112				vec3 br = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
12113				uv.x -= texelSize.x;
12114				vec3 bl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;
12115
12116				vec3 tm = mix( tl, tr, f.x );
12117				vec3 bm = mix( bl, br, f.x );
12118				gl_FragColor.rgb = mix( tm, bm, f.y );
12119
12120			}
12121		`,
12122			blending: NoBlending,
12123			depthTest: false,
12124			depthWrite: false
12125		});
12126		return shaderMaterial;
12127	}
12128
12129	function _getCubemapShader() {
12130		const shaderMaterial = new RawShaderMaterial({
12131			name: 'CubemapToCubeUV',
12132			uniforms: {
12133				'envMap': {
12134					value: null
12135				},
12136				'inputEncoding': {
12137					value: ENCODINGS[LinearEncoding]
12138				}
12139			},
12140			vertexShader: _getCommonVertexShader(),
12141			fragmentShader:
12142			/* glsl */
12143			`
12144
12145			precision mediump float;
12146			precision mediump int;
12147
12148			varying vec3 vOutputDirection;
12149
12150			uniform samplerCube envMap;
12151
12152			${_getEncodings()}
12153
12154			void main() {
12155
12156				gl_FragColor = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) );
12157
12158			}
12159		`,
12160			blending: NoBlending,
12161			depthTest: false,
12162			depthWrite: false
12163		});
12164		return shaderMaterial;
12165	}
12166
12167	function _getCommonVertexShader() {
12168		return (
12169			/* glsl */
12170			`
12171
12172		precision mediump float;
12173		precision mediump int;
12174
12175		attribute vec3 position;
12176		attribute vec2 uv;
12177		attribute float faceIndex;
12178
12179		varying vec3 vOutputDirection;
12180
12181		// RH coordinate system; PMREM face-indexing convention
12182		vec3 getDirection( vec2 uv, float face ) {
12183
12184			uv = 2.0 * uv - 1.0;
12185
12186			vec3 direction = vec3( uv, 1.0 );
12187
12188			if ( face == 0.0 ) {
12189
12190				direction = direction.zyx; // ( 1, v, u ) pos x
12191
12192			} else if ( face == 1.0 ) {
12193
12194				direction = direction.xzy;
12195				direction.xz *= -1.0; // ( -u, 1, -v ) pos y
12196
12197			} else if ( face == 2.0 ) {
12198
12199				direction.x *= -1.0; // ( -u, v, 1 ) pos z
12200
12201			} else if ( face == 3.0 ) {
12202
12203				direction = direction.zyx;
12204				direction.xz *= -1.0; // ( -1, v, -u ) neg x
12205
12206			} else if ( face == 4.0 ) {
12207
12208				direction = direction.xzy;
12209				direction.xy *= -1.0; // ( -u, -1, v ) neg y
12210
12211			} else if ( face == 5.0 ) {
12212
12213				direction.z *= -1.0; // ( u, v, -1 ) neg z
12214
12215			}
12216
12217			return direction;
12218
12219		}
12220
12221		void main() {
12222
12223			vOutputDirection = getDirection( uv, faceIndex );
12224			gl_Position = vec4( position, 1.0 );
12225
12226		}
12227	`
12228		);
12229	}
12230
12231	function _getEncodings() {
12232		return (
12233			/* glsl */
12234			`
12235
12236		uniform int inputEncoding;
12237
12238		#include <encodings_pars_fragment>
12239
12240		vec4 inputTexelToLinear( vec4 value ) {
12241
12242			if ( inputEncoding == 0 ) {
12243
12244				return value;
12245
12246			} else {
12247
12248				return sRGBToLinear( value );
12249
12250			}
12251
12252		}
12253
12254		vec4 envMapTexelToLinear( vec4 color ) {
12255
12256			return inputTexelToLinear( color );
12257
12258		}
12259	`
12260		);
12261	}
12262
12263	function WebGLCubeUVMaps(renderer) {
12264		let cubeUVmaps = new WeakMap();
12265		let pmremGenerator = null;
12266
12267		function get(texture) {
12268			if (texture && texture.isTexture && texture.isRenderTargetTexture === false) {
12269				const mapping = texture.mapping;
12270				const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping;
12271				const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping;
12272
12273				if (isEquirectMap || isCubeMap) {
12274					// equirect/cube map to cubeUV conversion
12275					if (cubeUVmaps.has(texture)) {
12276						return cubeUVmaps.get(texture).texture;
12277					} else {
12278						const image = texture.image;
12279
12280						if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) {
12281							const currentRenderTarget = renderer.getRenderTarget();
12282							if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer);
12283							const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture);
12284							cubeUVmaps.set(texture, renderTarget);
12285							renderer.setRenderTarget(currentRenderTarget);
12286							texture.addEventListener('dispose', onTextureDispose);
12287							return renderTarget.texture;
12288						} else {
12289							// image not yet ready. try the conversion next frame
12290							return null;
12291						}
12292					}
12293				}
12294			}
12295
12296			return texture;
12297		}
12298
12299		function isCubeTextureComplete(image) {
12300			let count = 0;
12301			const length = 6;
12302
12303			for (let i = 0; i < length; i++) {
12304				if (image[i] !== undefined) count++;
12305			}
12306
12307			return count === length;
12308		}
12309
12310		function onTextureDispose(event) {
12311			const texture = event.target;
12312			texture.removeEventListener('dispose', onTextureDispose);
12313			const cubemapUV = cubeUVmaps.get(texture);
12314
12315			if (cubemapUV !== undefined) {
12316				cubeUVmaps.delete(texture);
12317				cubemapUV.dispose();
12318			}
12319		}
12320
12321		function dispose() {
12322			cubeUVmaps = new WeakMap();
12323
12324			if (pmremGenerator !== null) {
12325				pmremGenerator.dispose();
12326				pmremGenerator = null;
12327			}
12328		}
12329
12330		return {
12331			get: get,
12332			dispose: dispose
12333		};
12334	}
12335
12336	function WebGLExtensions(gl) {
12337		const extensions = {};
12338
12339		function getExtension(name) {
12340			if (extensions[name] !== undefined) {
12341				return extensions[name];
12342			}
12343
12344			let extension;
12345
12346			switch (name) {
12347				case 'WEBGL_depth_texture':
12348					extension = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture');
12349					break;
12350
12351				case 'EXT_texture_filter_anisotropic':
12352					extension = gl.getExtension('EXT_texture_filter_anisotropic') || gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic');
12353					break;
12354
12355				case 'WEBGL_compressed_texture_s3tc':
12356					extension = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');
12357					break;
12358
12359				case 'WEBGL_compressed_texture_pvrtc':
12360					extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
12361					break;
12362
12363				default:
12364					extension = gl.getExtension(name);
12365			}
12366
12367			extensions[name] = extension;
12368			return extension;
12369		}
12370
12371		return {
12372			has: function (name) {
12373				return getExtension(name) !== null;
12374			},
12375			init: function (capabilities) {
12376				if (capabilities.isWebGL2) {
12377					getExtension('EXT_color_buffer_float');
12378				} else {
12379					getExtension('WEBGL_depth_texture');
12380					getExtension('OES_texture_float');
12381					getExtension('OES_texture_half_float');
12382					getExtension('OES_texture_half_float_linear');
12383					getExtension('OES_standard_derivatives');
12384					getExtension('OES_element_index_uint');
12385					getExtension('OES_vertex_array_object');
12386					getExtension('ANGLE_instanced_arrays');
12387				}
12388
12389				getExtension('OES_texture_float_linear');
12390				getExtension('EXT_color_buffer_half_float');
12391				getExtension('WEBGL_multisampled_render_to_texture');
12392			},
12393			get: function (name) {
12394				const extension = getExtension(name);
12395
12396				if (extension === null) {
12397					console.warn('THREE.WebGLRenderer: ' + name + ' extension not supported.');
12398				}
12399
12400				return extension;
12401			}
12402		};
12403	}
12404
12405	function WebGLGeometries(gl, attributes, info, bindingStates) {
12406		const geometries = {};
vendor: 4,198 bytes, lines 12407-12562
12407		const wireframeAttributes = new WeakMap();
12408
12409		function onGeometryDispose(event) {
12410			const geometry = event.target;
12411
12412			if (geometry.index !== null) {
12413				attributes.remove(geometry.index);
12414			}
12415
12416			for (const name in geometry.attributes) {
12417				attributes.remove(geometry.attributes[name]);
12418			}
12419
12420			geometry.removeEventListener('dispose', onGeometryDispose);
12421			delete geometries[geometry.id];
12422			const attribute = wireframeAttributes.get(geometry);
12423
12424			if (attribute) {
12425				attributes.remove(attribute);
12426				wireframeAttributes.delete(geometry);
12427			}
12428
12429			bindingStates.releaseStatesOfGeometry(geometry);
12430
12431			if (geometry.isInstancedBufferGeometry === true) {
12432				delete geometry._maxInstanceCount;
12433			} //
12434
12435
12436			info.memory.geometries--;
12437		}
12438
12439		function get(object, geometry) {
12440			if (geometries[geometry.id] === true) return geometry;
12441			geometry.addEventListener('dispose', onGeometryDispose);
12442			geometries[geometry.id] = true;
12443			info.memory.geometries++;
12444			return geometry;
12445		}
12446
12447		function update(geometry) {
12448			const geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates.
12449
12450			for (const name in geometryAttributes) {
12451				attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER);
12452			} // morph targets
12453
12454
12455			const morphAttributes = geometry.morphAttributes;
12456
12457			for (const name in morphAttributes) {
12458				const array = morphAttributes[name];
12459
12460				for (let i = 0, l = array.length; i < l; i++) {
12461					attributes.update(array[i], gl.ARRAY_BUFFER);
12462				}
12463			}
12464		}
12465
12466		function updateWireframeAttribute(geometry) {
12467			const indices = [];
12468			const geometryIndex = geometry.index;
12469			const geometryPosition = geometry.attributes.position;
12470			let version = 0;
12471
12472			if (geometryIndex !== null) {
12473				const array = geometryIndex.array;
12474				version = geometryIndex.version;
12475
12476				for (let i = 0, l = array.length; i < l; i += 3) {
12477					const a = array[i + 0];
12478					const b = array[i + 1];
12479					const c = array[i + 2];
12480					indices.push(a, b, b, c, c, a);
12481				}
12482			} else {
12483				const array = geometryPosition.array;
12484				version = geometryPosition.version;
12485
12486				for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) {
12487					const a = i + 0;
12488					const b = i + 1;
12489					const c = i + 2;
12490					indices.push(a, b, b, c, c, a);
12491				}
12492			}
12493
12494			const attribute = new (arrayMax(indices) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1);
12495			attribute.version = version; // Updating index buffer in VAO now. See WebGLBindingStates
12496			//
12497
12498			const previousAttribute = wireframeAttributes.get(geometry);
12499			if (previousAttribute) attributes.remove(previousAttribute); //
12500
12501			wireframeAttributes.set(geometry, attribute);
12502		}
12503
12504		function getWireframeAttribute(geometry) {
12505			const currentAttribute = wireframeAttributes.get(geometry);
12506
12507			if (currentAttribute) {
12508				const geometryIndex = geometry.index;
12509
12510				if (geometryIndex !== null) {
12511					// if the attribute is obsolete, create a new one
12512					if (currentAttribute.version < geometryIndex.version) {
12513						updateWireframeAttribute(geometry);
12514					}
12515				}
12516			} else {
12517				updateWireframeAttribute(geometry);
12518			}
12519
12520			return wireframeAttributes.get(geometry);
12521		}
12522
12523		return {
12524			get: get,
12525			update: update,
12526			getWireframeAttribute: getWireframeAttribute
12527		};
12528	}
12529
12530	function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) {
12531		const isWebGL2 = capabilities.isWebGL2;
12532		let mode;
12533
12534		function setMode(value) {
12535			mode = value;
12536		}
12537
12538		let type, bytesPerElement;
12539
12540		function setIndex(value) {
12541			type = value.type;
12542			bytesPerElement = value.bytesPerElement;
12543		}
12544
12545		function render(start, count) {
12546			gl.drawElements(mode, count, type, start * bytesPerElement);
12547			info.update(count, mode, 1);
12548		}
12549
12550		function renderInstances(start, count, primcount) {
12551			if (primcount === 0) return;
12552			let extension, methodName;
12553
12554			if (isWebGL2) {
12555				extension = gl;
12556				methodName = 'drawElementsInstanced';
12557			} else {
12558				extension = extensions.get('ANGLE_instanced_arrays');
12559				methodName = 'drawElementsInstancedANGLE';
12560
12561				if (extension === null) {
12562					console.error('THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_
12562instanced_arrays.');
12563					return;
12564				}
12565			}
12566
12567			extension[methodName](mode, count, type, start * bytesPerElement, primcount);
12568			info.update(count, mode, primcount);
12569		} //
12570
12571
12572		this.setMode = setMode;
12573		this.setIndex = setIndex;
12574		this.render = render;
12575		this.renderInstances = renderInstances;
12576	}
12577
12578	function WebGLInfo(gl) {
12579		const memory = {
12580			geometries: 0,
12581			textures: 0
12582		};
12583		const render = {
12584			frame: 0,
12585			calls: 0,
12586			triangles: 0,
12587			points: 0,
12588			lines: 0
12589		};
12590
12591		function update(count, mode, instanceCount) {
12592			render.calls++;
12593
12594			switch (mode) {
12595				case gl.TRIANGLES:
12596					render.triangles += instanceCount * (count / 3);
12597					break;
12598
12599				case gl.LINES:
12600					render.lines += instanceCount * (count / 2);
12601					break;
12602
12603				case gl.LINE_STRIP:
12604					render.lines += instanceCount * (count - 1);
12605					break;
12606
12607				case gl.LINE_LOOP:
12608					render.lines += instanceCount * count;
12609					break;
12610
12611				case gl.POINTS:
12612					render.points += instanceCount * count;
12613					break;
12614
12615				default:
12616					console.error('THREE.WebGLInfo: Unknown draw mode:', mode);
12617					break;
12618			}
12619		}
12620
12621		function reset() {
12622			render.frame++;
12623			render.calls = 0;
12624			render.triangles = 0;
12625			render.points = 0;
12626			render.lines = 0;
12627		}
12628
12629		return {
12630			memory: memory,
12631			render: render,
12632			programs: null,
12633			autoReset: true,
12634			reset: reset,
12635			update: update
12636		};
12637	}
12638
12639	class DataTexture2DArray extends Texture {
12640		constructor(data = null, width = 1, height = 1, depth = 1) {
12641			super(null);
12642			this.image = {
12643				data,
12644				width,
12645				height,
12646				depth
12647			};
12648			this.magFilter = NearestFilter;
12649			this.minFilter = NearestFilter;
12650			this.wrapR = ClampToEdgeWrapping;
12651			this.generateMipmaps = false;
12652			this.flipY = false;
12653			this.unpackAlignment = 1;
12654		}
12655
12656	}
12657
12658	DataTexture2DArray.prototype.isDataTexture2DArray = true;
12659
12660	function numericalSort(a, b) {
12661		return a[0] - b[0];
12662	}
12663
12664	function absNumericalSort(a, b) {
12665		return Math.abs(b[1]) - Math.abs(a[1]);
12666	}
12667
12668	function denormalize(morph, attribute) {
12669		let denominator = 1;
12670		const array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array;
12671		if (array instanceof Int8Array) denominator = 127;else if (array instanceof Int16Array) denominator = 32767;else if (array instanceof Int32Array) denominator = 2147483647;else console.error('THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array);
12672		morph.divideScalar(denominator);
12673	}
12674
12675	function WebGLMorphtargets(gl, capabilities, textures) {
12676		const influencesList = {};
12677		const morphInfluences = new Float32Array(8);
12678		const morphTextures = new WeakMap();
12679		const morph = new Vector3();
12680		const workInfluences = [];
12681
12682		for (let i = 0; i < 8; i++) {
12683			workInfluences[i] = [i, 0];
12684		}
12685
12686		function update(object, geometry, material, program) {
12687			const objectInfluences = object.morphTargetInfluences;
12688
12689			if (capabilities.isWebGL2 === true) {
12690				// instead of using attributes, the WebGL 2 code path encodes morph targets
12691				// into an array of data textures. Each layer represents a single morph target.
12692				const numberOfMorphTargets = geometry.morphAttributes.position.length;
12693				let entry = morphTextures.get(geometry);
12694
12695				if (entry === undefined || entry.count !== numberOfMorphTargets) {
12696					if (entry !== undefined) entry.texture.dispose();
12697					const hasMorphNormals = geometry.morphAttributes.normal !== undefined;
12698					const morphTargets = geometry.morphAttributes.position;
12699					const morphNormals = geometry.morphAttributes.normal || [];
12700					const numberOfVertices = geometry.attributes.position.count;
12701					const numberOfVertexData = hasMorphNormals === true ? 2 : 1; // (v,n) vs. (v)
12702
12703					let width = numberOfVertices * numberOfVertexData;
12704					let height = 1;
12705
12706					if (width > capabilities.maxTextureSize) {
12707						height = Math.ceil(width / capabilities.maxTextureSize);
12708						width = capabilities.maxTextureSize;
12709					}
12710
12711					const buffer = new Float32Array(width * height * 4 * numberOfMorphTargets);
12712					const texture = new DataTexture2DArray(buffer, width, height, numberOfMorphTargets);
12713					texture.format = RGBAFormat; // using RGBA since RGB might be emulated (and is thus slower)
12714
12715					texture.type = FloatType;
12716					texture.needsUpdate = true; // fill buffer
12717
12718					const vertexDataStride = numberOfVertexData * 4;
12719
12720					for (let i = 0;
vendor: 5,716 bytes, lines 12720-12889
12720 i < numberOfMorphTargets; i++) {
12721						const morphTarget = morphTargets[i];
12722						const morphNormal = morphNormals[i];
12723						const offset = width * height * 4 * i;
12724
12725						for (let j = 0; j < morphTarget.count; j++) {
12726							morph.fromBufferAttribute(morphTarget, j);
12727							if (morphTarget.normalized === true) denormalize(morph, morphTarget);
12728							const stride = j * vertexDataStride;
12729							buffer[offset + stride + 0] = morph.x;
12730							buffer[offset + stride + 1] = morph.y;
12731							buffer[offset + stride + 2] = morph.z;
12732							buffer[offset + stride + 3] = 0;
12733
12734							if (hasMorphNormals === true) {
12735								morph.fromBufferAttribute(morphNormal, j);
12736								if (morphNormal.normalized === true) denormalize(morph, morphNormal);
12737								buffer[offset + stride + 4] = morph.x;
12738								buffer[offset + stride + 5] = morph.y;
12739								buffer[offset + stride + 6] = morph.z;
12740								buffer[offset + stride + 7] = 0;
12741							}
12742						}
12743					}
12744
12745					entry = {
12746						count: numberOfMorphTargets,
12747						texture: texture,
12748						size: new Vector2(width, height)
12749					};
12750					morphTextures.set(geometry, entry);
12751				} //
12752
12753
12754				let morphInfluencesSum = 0;
12755
12756				for (let i = 0; i < objectInfluences.length; i++) {
12757					morphInfluencesSum += objectInfluences[i];
12758				}
12759
12760				const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
12761				program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence);
12762				program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences);
12763				program.getUniforms().setValue(gl, 'morphTargetsTexture', entry.texture, textures);
12764				program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry.size);
12765			} else {
12766				// When object doesn't have morph target influences defined, we treat it as a 0-length array
12767				// This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences
12768				const length = objectInfluences === undefined ? 0 : objectInfluences.length;
12769				let influences = influencesList[geometry.id];
12770
12771				if (influences === undefined || influences.length !== length) {
12772					// initialise list
12773					influences = [];
12774
12775					for (let i = 0; i < length; i++) {
12776						influences[i] = [i, 0];
12777					}
12778
12779					influencesList[geometry.id] = influences;
12780				} // Collect influences
12781
12782
12783				for (let i = 0; i < length; i++) {
12784					const influence = influences[i];
12785					influence[0] = i;
12786					influence[1] = objectInfluences[i];
12787				}
12788
12789				influences.sort(absNumericalSort);
12790
12791				for (let i = 0; i < 8; i++) {
12792					if (i < length && influences[i][1]) {
12793						workInfluences[i][0] = influences[i][0];
12794						workInfluences[i][1] = influences[i][1];
12795					} else {
12796						workInfluences[i][0] = Number.MAX_SAFE_INTEGER;
12797						workInfluences[i][1] = 0;
12798					}
12799				}
12800
12801				workInfluences.sort(numericalSort);
12802				const morphTargets = geometry.morphAttributes.position;
12803				const morphNormals = geometry.morphAttributes.normal;
12804				let morphInfluencesSum = 0;
12805
12806				for (let i = 0; i < 8; i++) {
12807					const influence = workInfluences[i];
12808					const index = influence[0];
12809					const value = influence[1];
12810
12811					if (index !== Number.MAX_SAFE_INTEGER && value) {
12812						if (morphTargets && geometry.getAttribute('morphTarget' + i) !== morphTargets[index]) {
12813							geometry.setAttribute('morphTarget' + i, morphTargets[index]);
12814						}
12815
12816						if (morphNormals && geometry.getAttribute('morphNormal' + i) !== morphNormals[index]) {
12817							geometry.setAttribute('morphNormal' + i, morphNormals[index]);
12818						}
12819
12820						morphInfluences[i] = value;
12821						morphInfluencesSum += value;
12822					} else {
12823						if (morphTargets && geometry.hasAttribute('morphTarget' + i) === true) {
12824							geometry.deleteAttribute('morphTarget' + i);
12825						}
12826
12827						if (morphNormals && geometry.hasAttribute('morphNormal' + i) === true) {
12828							geometry.deleteAttribute('morphNormal' + i);
12829						}
12830
12831						morphInfluences[i] = 0;
12832					}
12833				} // GLSL shader uses formula baseinfluence * base + sum(target * influence)
12834				// This allows us to switch between absolute morphs and relative morphs without changing shader code
12835				// When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence)
12836
12837
12838				const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
12839				program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence);
12840				program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences);
12841			}
12842		}
12843
12844		return {
12845			update: update
12846		};
12847	}
12848
12849	function WebGLObjects(gl, geometries, attributes, info) {
12850		let updateMap = new WeakMap();
12851
12852		function update(object) {
12853			const frame = info.render.frame;
12854			const geometry = object.geometry;
12855			const buffergeometry = geometries.get(object, geometry); // Update once per frame
12856
12857			if (updateMap.get(buffergeometry) !== frame) {
12858				geometries.update(buffergeometry);
12859				updateMap.set(buffergeometry, frame);
12860			}
12861
12862			if (object.isInstancedMesh) {
12863				if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) {
12864					object.addEventListener('dispose', onInstancedMeshDispose);
12865				}
12866
12867				attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER);
12868
12869				if (object.instanceColor !== null) {
12870					attributes.update(object.instanceColor, gl.ARRAY_BUFFER);
12871				}
12872			}
12873
12874			return buffergeometry;
12875		}
12876
12877		function dispose() {
12878			updateMap = new WeakMap();
12879		}
12880
12881		function onInstancedMeshDispose(event) {
12882			const instancedMesh = event.target;
12883			instancedMesh.removeEventListener('dispose', onInstancedMeshDispose);
12884			attributes.remove(instancedMesh.instanceMatrix);
12885			if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor);
12886		}
12887
12888		return {
12889			update: update,
vendor: 6,609 bytes, lines 12890-13159
12890			dispose: dispose
12891		};
12892	}
12893
12894	class DataTexture3D extends Texture {
12895		constructor(data = null, width = 1, height = 1, depth = 1) {
12896			// We're going to add .setXXX() methods for setting properties later.
12897			// Users can still set in DataTexture3D directly.
12898			//
12899			//	const texture = new THREE.DataTexture3D( data, width, height, depth );
12900			// 	texture.anisotropy = 16;
12901			//
12902			// See #14839
12903			super(null);
12904			this.image = {
12905				data,
12906				width,
12907				height,
12908				depth
12909			};
12910			this.magFilter = NearestFilter;
12911			this.minFilter = NearestFilter;
12912			this.wrapR = ClampToEdgeWrapping;
12913			this.generateMipmaps = false;
12914			this.flipY = false;
12915			this.unpackAlignment = 1;
12916		}
12917
12918	}
12919
12920	DataTexture3D.prototype.isDataTexture3D = true;
12921
12922	/**
12923	 * Uniforms of a program.
12924	 * Those form a tree structure with a special top-level container for the root,
12925	 * which you get by calling 'new WebGLUniforms( gl, program )'.
12926	 *
12927	 *
12928	 * Properties of inner nodes including the top-level container:
12929	 *
12930	 * .seq - array of nested uniforms
12931	 * .map - nested uniforms by name
12932	 *
12933	 *
12934	 * Methods of all nodes except the top-level container:
12935	 *
12936	 * .setValue( gl, value, [textures] )
12937	 *
12938	 * 		uploads a uniform value(s)
12939	 *		the 'textures' parameter is needed for sampler uniforms
12940	 *
12941	 *
12942	 * Static methods of the top-level container (textures factorizations):
12943	 *
12944	 * .upload( gl, seq, values, textures )
12945	 *
12946	 * 		sets uniforms in 'seq' to 'values[id].value'
12947	 *
12948	 * .seqWithValue( seq, values ) : filteredSeq
12949	 *
12950	 * 		filters 'seq' entries with corresponding entry in values
12951	 *
12952	 *
12953	 * Methods of the top-level container (textures factorizations):
12954	 *
12955	 * .setValue( gl, name, value, textures )
12956	 *
12957	 * 		sets uniform with	name 'name' to 'value'
12958	 *
12959	 * .setOptional( gl, obj, prop )
12960	 *
12961	 * 		like .set for an optional property of the object
12962	 *
12963	 */
12964	const emptyTexture = new Texture();
12965	const emptyTexture2dArray = new DataTexture2DArray();
12966	const emptyTexture3d = new DataTexture3D();
12967	const emptyCubeTexture = new CubeTexture(); // --- Utilities ---
12968	// Array Caches (provide typed arrays for temporary by size)
12969
12970	const arrayCacheF32 = [];
12971	const arrayCacheI32 = []; // Float32Array caches used for uploading Matrix uniforms
12972
12973	const mat4array = new Float32Array(16);
12974	const mat3array = new Float32Array(9);
12975	const mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices
12976
12977	function flatten(array, nBlocks, blockSize) {
12978		const firstElem = array[0];
12979		if (firstElem <= 0 || firstElem > 0) return array; // unoptimized: ! isNaN( firstElem )
12980		// see http://jacksondunstan.com/articles/983
12981
12982		const n = nBlocks * blockSize;
12983		let r = arrayCacheF32[n];
12984
12985		if (r === undefined) {
12986			r = new Float32Array(n);
12987			arrayCacheF32[n] = r;
12988		}
12989
12990		if (nBlocks !== 0) {
12991			firstElem.toArray(r, 0);
12992
12993			for (let i = 1, offset = 0; i !== nBlocks; ++i) {
12994				offset += blockSize;
12995				array[i].toArray(r, offset);
12996			}
12997		}
12998
12999		return r;
13000	}
13001
13002	function arraysEqual(a, b) {
13003		if (a.length !== b.length) return false;
13004
13005		for (let i = 0, l = a.length; i < l; i++) {
13006			if (a[i] !== b[i]) return false;
13007		}
13008
13009		return true;
13010	}
13011
13012	function copyArray(a, b) {
13013		for (let i = 0, l = b.length; i < l; i++) {
13014			a[i] = b[i];
13015		}
13016	} // Texture unit allocation
13017
13018
13019	function allocTexUnits(textures, n) {
13020		let r = arrayCacheI32[n];
13021
13022		if (r === undefined) {
13023			r = new Int32Array(n);
13024			arrayCacheI32[n] = r;
13025		}
13026
13027		for (let i = 0; i !== n; ++i) {
13028			r[i] = textures.allocateTextureUnit();
13029		}
13030
13031		return r;
13032	} // --- Setters ---
13033	// Note: Defining these methods externally, because they come in a bunch
13034	// and this way their names minify.
13035	// Single scalar
13036
13037
13038	function setValueV1f(gl, v) {
13039		const cache = this.cache;
13040		if (cache[0] === v) return;
13041		gl.uniform1f(this.addr, v);
13042		cache[0] = v;
13043	} // Single float vector (from flat array or THREE.VectorN)
13044
13045
13046	function setValueV2f(gl, v) {
13047		const cache = this.cache;
13048
13049		if (v.x !== undefined) {
13050			if (cache[0] !== v.x || cache[1] !== v.y) {
13051				gl.uniform2f(this.addr, v.x, v.y);
13052				cache[0] = v.x;
13053				cache[1] = v.y;
13054			}
13055		} else {
13056			if (arraysEqual(cache, v)) return;
13057			gl.uniform2fv(this.addr, v);
13058			copyArray(cache, v);
13059		}
13060	}
13061
13062	function setValueV3f(gl, v) {
13063		const cache = this.cache;
13064
13065		if (v.x !== undefined) {
13066			if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) {
13067				gl.uniform3f(this.addr, v.x, v.y, v.z);
13068				cache[0] = v.x;
13069				cache[1] = v.y;
13070				cache[2] = v.z;
13071			}
13072		} else if (v.r !== undefined) {
13073			if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) {
13074				gl.uniform3f(this.addr, v.r, v.g, v.b);
13075				cache[0] = v.r;
13076				cache[1] = v.g;
13077				cache[2] = v.b;
13078			}
13079		} else {
13080			if (arraysEqual(cache, v)) return;
13081			gl.uniform3fv(this.addr, v);
13082			copyArray(cache, v);
13083		}
13084	}
13085
13086	function setValueV4f(gl, v) {
13087		const cache = this.cache;
13088
13089		if (v.x !== undefined) {
13090			if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) {
13091				gl.uniform4f(this.addr, v.x, v.y, v.z, v.w);
13092				cache[0] = v.x;
13093				cache[1] = v.y;
13094				cache[2] = v.z;
13095				cache[3] = v.w;
13096			}
13097		} else {
13098			if (arraysEqual(cache, v)) return;
13099			gl.uniform4fv(this.addr, v);
13100			copyArray(cache, v);
13101		}
13102	} // Single matrix (from flat array or THREE.MatrixN)
13103
13104
13105	function setValueM2(gl, v) {
13106		const cache = this.cache;
13107		const elements = v.elements;
13108
13109		if (elements === undefined) {
13110			if (arraysEqual(cache, v)) return;
13111			gl.uniformMatrix2fv(this.addr, false, v);
13112			copyArray(cache, v);
13113		} else {
13114			if (arraysEqual(cache, elements)) return;
13115			mat2array.set(elements);
13116			gl.uniformMatrix2fv(this.addr, false, mat2array);
13117			copyArray(cache, elements);
13118		}
13119	}
13120
13121	function setValueM3(gl, v) {
13122		const cache = this.cache;
13123		const elements = v.elements;
13124
13125		if (elements === undefined) {
13126			if (arraysEqual(cache, v)) return;
13127			gl.uniformMatrix3fv(this.addr, false, v);
13128			copyArray(cache, v);
13129		} else {
13130			if (arraysEqual(cache, elements)) return;
13131			mat3array.set(elements);
13132			gl.uniformMatrix3fv(this.addr, false, mat3array);
13133			copyArray(cache, elements);
13134		}
13135	}
13136
13137	function setValueM4(gl, v) {
13138		const cache = this.cache;
13139		const elements = v.elements;
13140
13141		if (elements === undefined) {
13142			if (arraysEqual(cache, v)) return;
13143			gl.uniformMatrix4fv(this.addr, false, v);
13144			copyArray(cache, v);
13145		} else {
13146			if (arraysEqual(cache, elements)) return;
13147			mat4array.set(elements);
13148			gl.uniformMatrix4fv(this.addr, false, mat4array);
13149			copyArray(cache, elements);
13150		}
13151	} // Single integer / boolean
13152
13153
13154	function setValueV1i(gl, v) {
13155		const cache = this.cache;
13156		if (cache[0] === v) return;
13157		gl.uniform1i(this.addr, v);
13158		cache[0] = v;
13159	}
vendor: 20,137 bytes, lines 13159-13945
13159 // Single integer / boolean vector (from flat array)
13160
13161
13162	function setValueV2i(gl, v) {
13163		const cache = this.cache;
13164		if (arraysEqual(cache, v)) return;
13165		gl.uniform2iv(this.addr, v);
13166		copyArray(cache, v);
13167	}
13168
13169	function setValueV3i(gl, v) {
13170		const cache = this.cache;
13171		if (arraysEqual(cache, v)) return;
13172		gl.uniform3iv(this.addr, v);
13173		copyArray(cache, v);
13174	}
13175
13176	function setValueV4i(gl, v) {
13177		const cache = this.cache;
13178		if (arraysEqual(cache, v)) return;
13179		gl.uniform4iv(this.addr, v);
13180		copyArray(cache, v);
13181	} // Single unsigned integer
13182
13183
13184	function setValueV1ui(gl, v) {
13185		const cache = this.cache;
13186		if (cache[0] === v) return;
13187		gl.uniform1ui(this.addr, v);
13188		cache[0] = v;
13189	} // Single unsigned integer vector (from flat array)
13190
13191
13192	function setValueV2ui(gl, v) {
13193		const cache = this.cache;
13194		if (arraysEqual(cache, v)) return;
13195		gl.uniform2uiv(this.addr, v);
13196		copyArray(cache, v);
13197	}
13198
13199	function setValueV3ui(gl, v) {
13200		const cache = this.cache;
13201		if (arraysEqual(cache, v)) return;
13202		gl.uniform3uiv(this.addr, v);
13203		copyArray(cache, v);
13204	}
13205
13206	function setValueV4ui(gl, v) {
13207		const cache = this.cache;
13208		if (arraysEqual(cache, v)) return;
13209		gl.uniform4uiv(this.addr, v);
13210		copyArray(cache, v);
13211	} // Single texture (2D / Cube)
13212
13213
13214	function setValueT1(gl, v, textures) {
13215		const cache = this.cache;
13216		const unit = textures.allocateTextureUnit();
13217
13218		if (cache[0] !== unit) {
13219			gl.uniform1i(this.addr, unit);
13220			cache[0] = unit;
13221		}
13222
13223		textures.safeSetTexture2D(v || emptyTexture, unit);
13224	}
13225
13226	function setValueT3D1(gl, v, textures) {
13227		const cache = this.cache;
13228		const unit = textures.allocateTextureUnit();
13229
13230		if (cache[0] !== unit) {
13231			gl.uniform1i(this.addr, unit);
13232			cache[0] = unit;
13233		}
13234
13235		textures.setTexture3D(v || emptyTexture3d, unit);
13236	}
13237
13238	function setValueT6(gl, v, textures) {
13239		const cache = this.cache;
13240		const unit = textures.allocateTextureUnit();
13241
13242		if (cache[0] !== unit) {
13243			gl.uniform1i(this.addr, unit);
13244			cache[0] = unit;
13245		}
13246
13247		textures.safeSetTextureCube(v || emptyCubeTexture, unit);
13248	}
13249
13250	function setValueT2DArray1(gl, v, textures) {
13251		const cache = this.cache;
13252		const unit = textures.allocateTextureUnit();
13253
13254		if (cache[0] !== unit) {
13255			gl.uniform1i(this.addr, unit);
13256			cache[0] = unit;
13257		}
13258
13259		textures.setTexture2DArray(v || emptyTexture2dArray, unit);
13260	} // Helper to pick the right setter for the singular case
13261
13262
13263	function getSingularSetter(type) {
13264		switch (type) {
13265			case 0x1406:
13266				return setValueV1f;
13267			// FLOAT
13268
13269			case 0x8b50:
13270				return setValueV2f;
13271			// _VEC2
13272
13273			case 0x8b51:
13274				return setValueV3f;
13275			// _VEC3
13276
13277			case 0x8b52:
13278				return setValueV4f;
13279			// _VEC4
13280
13281			case 0x8b5a:
13282				return setValueM2;
13283			// _MAT2
13284
13285			case 0x8b5b:
13286				return setValueM3;
13287			// _MAT3
13288
13289			case 0x8b5c:
13290				return setValueM4;
13291			// _MAT4
13292
13293			case 0x1404:
13294			case 0x8b56:
13295				return setValueV1i;
13296			// INT, BOOL
13297
13298			case 0x8b53:
13299			case 0x8b57:
13300				return setValueV2i;
13301			// _VEC2
13302
13303			case 0x8b54:
13304			case 0x8b58:
13305				return setValueV3i;
13306			// _VEC3
13307
13308			case 0x8b55:
13309			case 0x8b59:
13310				return setValueV4i;
13311			// _VEC4
13312
13313			case 0x1405:
13314				return setValueV1ui;
13315			// UINT
13316
13317			case 0x8dc6:
13318				return setValueV2ui;
13319			// _VEC2
13320
13321			case 0x8dc7:
13322				return setValueV3ui;
13323			// _VEC3
13324
13325			case 0x8dc8:
13326				return setValueV4ui;
13327			// _VEC4
13328
13329			case 0x8b5e: // SAMPLER_2D
13330
13331			case 0x8d66: // SAMPLER_EXTERNAL_OES
13332
13333			case 0x8dca: // INT_SAMPLER_2D
13334
13335			case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
13336
13337			case 0x8b62:
13338				// SAMPLER_2D_SHADOW
13339				return setValueT1;
13340
13341			case 0x8b5f: // SAMPLER_3D
13342
13343			case 0x8dcb: // INT_SAMPLER_3D
13344
13345			case 0x8dd3:
13346				// UNSIGNED_INT_SAMPLER_3D
13347				return setValueT3D1;
13348
13349			case 0x8b60: // SAMPLER_CUBE
13350
13351			case 0x8dcc: // INT_SAMPLER_CUBE
13352
13353			case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
13354
13355			case 0x8dc5:
13356				// SAMPLER_CUBE_SHADOW
13357				return setValueT6;
13358
13359			case 0x8dc1: // SAMPLER_2D_ARRAY
13360
13361			case 0x8dcf: // INT_SAMPLER_2D_ARRAY
13362
13363			case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY
13364
13365			case 0x8dc4:
13366				// SAMPLER_2D_ARRAY_SHADOW
13367				return setValueT2DArray1;
13368		}
13369	} // Array of scalars
13370
13371
13372	function setValueV1fArray(gl, v) {
13373		gl.uniform1fv(this.addr, v);
13374	} // Array of vectors (from flat array or array of THREE.VectorN)
13375
13376
13377	function setValueV2fArray(gl, v) {
13378		const data = flatten(v, this.size, 2);
13379		gl.uniform2fv(this.addr, data);
13380	}
13381
13382	function setValueV3fArray(gl, v) {
13383		const data = flatten(v, this.size, 3);
13384		gl.uniform3fv(this.addr, data);
13385	}
13386
13387	function setValueV4fArray(gl, v) {
13388		const data = flatten(v, this.size, 4);
13389		gl.uniform4fv(this.addr, data);
13390	} // Array of matrices (from flat array or array of THREE.MatrixN)
13391
13392
13393	function setValueM2Array(gl, v) {
13394		const data = flatten(v, this.size, 4);
13395		gl.uniformMatrix2fv(this.addr, false, data);
13396	}
13397
13398	function setValueM3Array(gl, v) {
13399		const data = flatten(v, this.size, 9);
13400		gl.uniformMatrix3fv(this.addr, false, data);
13401	}
13402
13403	function setValueM4Array(gl, v) {
13404		const data = flatten(v, this.size, 16);
13405		gl.uniformMatrix4fv(this.addr, false, data);
13406	} // Array of integer / boolean
13407
13408
13409	function setValueV1iArray(gl, v) {
13410		gl.uniform1iv(this.addr, v);
13411	} // Array of integer / boolean vectors (from flat array)
13412
13413
13414	function setValueV2iArray(gl, v) {
13415		gl.uniform2iv(this.addr, v);
13416	}
13417
13418	function setValueV3iArray(gl, v) {
13419		gl.uniform3iv(this.addr, v);
13420	}
13421
13422	function setValueV4iArray(gl, v) {
13423		gl.uniform4iv(this.addr, v);
13424	} // Array of unsigned integer
13425
13426
13427	function setValueV1uiArray(gl, v) {
13428		gl.uniform1uiv(this.addr, v);
13429	} // Array of unsigned integer vectors (from flat array)
13430
13431
13432	function setValueV2uiArray(gl, v) {
13433		gl.uniform2uiv(this.addr, v);
13434	}
13435
13436	function setValueV3uiArray(gl, v) {
13437		gl.uniform3uiv(this.addr, v);
13438	}
13439
13440	function setValueV4uiArray(gl, v) {
13441		gl.uniform4uiv(this.addr, v);
13442	} // Array of textures (2D / 3D / Cube / 2DArray)
13443
13444
13445	function setValueT1Array(gl, v, textures) {
13446		const n = v.length;
13447		const units = allocTexUnits(textures, n);
13448		gl.uniform1iv(this.addr, units);
13449
13450		for (let i = 0; i !== n; ++i) {
13451			textures.safeSetTexture2D(v[i] || emptyTexture, units[i]);
13452		}
13453	}
13454
13455	function setValueT3DArray(gl, v, textures) {
13456		const n = v.length;
13457		const units = allocTexUnits(textures, n);
13458		gl.uniform1iv(this.addr, units);
13459
13460		for (let i = 0; i !== n; ++i) {
13461			textures.setTexture3D(v[i] || emptyTexture3d, units[i]);
13462		}
13463	}
13464
13465	function setValueT6Array(gl, v, textures) {
13466		const n = v.length;
13467		const units = allocTexUnits(textures, n);
13468		gl.uniform1iv(this.addr, units);
13469
13470		for (let i = 0; i !== n; ++i) {
13471			textures.safeSetTextureCube(v[i] || emptyCubeTexture, units[i]);
13472		}
13473	}
13474
13475	function setValueT2DArrayArray(gl, v, textures) {
13476		const n = v.length;
13477		const units = allocTexUnits(textures, n);
13478		gl.uniform1iv(this.addr, units);
13479
13480		for (let i = 0; i !== n; ++i) {
13481			textures.setTexture2DArray(v[i] || emptyTexture2dArray, units[i]);
13482		}
13483	} // Helper to pick the right setter for a pure (bottom-level) array
13484
13485
13486	function getPureArraySetter(type) {
13487		switch (type) {
13488			case 0x1406:
13489				return setValueV1fArray;
13490			// FLOAT
13491
13492			case 0x8b50:
13493				return setValueV2fArray;
13494			// _VEC2
13495
13496			case 0x8b51:
13497				return setValueV3fArray;
13498			// _VEC3
13499
13500			case 0x8b52:
13501				return setValueV4fArray;
13502			// _VEC4
13503
13504			case 0x8b5a:
13505				return setValueM2Array;
13506			// _MAT2
13507
13508			case 0x8b5b:
13509				return setValueM3Array;
13510			// _MAT3
13511
13512			case 0x8b5c:
13513				return setValueM4Array;
13514			// _MAT4
13515
13516			case 0x1404:
13517			case 0x8b56:
13518				return setValueV1iArray;
13519			// INT, BOOL
13520
13521			case 0x8b53:
13522			case 0x8b57:
13523				return setValueV2iArray;
13524			// _VEC2
13525
13526			case 0x8b54:
13527			case 0x8b58:
13528				return setValueV3iArray;
13529			// _VEC3
13530
13531			case 0x8b55:
13532			case 0x8b59:
13533				return setValueV4iArray;
13534			// _VEC4
13535
13536			case 0x1405:
13537				return setValueV1uiArray;
13538			// UINT
13539
13540			case 0x8dc6:
13541				return setValueV2uiArray;
13542			// _VEC2
13543
13544			case 0x8dc7:
13545				return setValueV3uiArray;
13546			// _VEC3
13547
13548			case 0x8dc8:
13549				return setValueV4uiArray;
13550			// _VEC4
13551
13552			case 0x8b5e: // SAMPLER_2D
13553
13554			case 0x8d66: // SAMPLER_EXTERNAL_OES
13555
13556			case 0x8dca: // INT_SAMPLER_2D
13557
13558			case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
13559
13560			case 0x8b62:
13561				// SAMPLER_2D_SHADOW
13562				return setValueT1Array;
13563
13564			case 0x8b5f: // SAMPLER_3D
13565
13566			case 0x8dcb: // INT_SAMPLER_3D
13567
13568			case 0x8dd3:
13569				// UNSIGNED_INT_SAMPLER_3D
13570				return setValueT3DArray;
13571
13572			case 0x8b60: // SAMPLER_CUBE
13573
13574			case 0x8dcc: // INT_SAMPLER_CUBE
13575
13576			case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
13577
13578			case 0x8dc5:
13579				// SAMPLER_CUBE_SHADOW
13580				return setValueT6Array;
13581
13582			case 0x8dc1: // SAMPLER_2D_ARRAY
13583
13584			case 0x8dcf: // INT_SAMPLER_2D_ARRAY
13585
13586			case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY
13587
13588			case 0x8dc4:
13589				// SAMPLER_2D_ARRAY_SHADOW
13590				return setValueT2DArrayArray;
13591		}
13592	} // --- Uniform Classes ---
13593
13594
13595	function SingleUniform(id, activeInfo, addr) {
13596		this.id = id;
13597		this.addr = addr;
13598		this.cache = [];
13599		this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG
13600	}
13601
13602	function PureArrayUniform(id, activeInfo, addr) {
13603		this.id = id;
13604		this.addr = addr;
13605		this.cache = [];
13606		this.size = activeInfo.size;
13607		this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG
13608	}
13609
13610	PureArrayUniform.prototype.updateCache = function (data) {
13611		const cache = this.cache;
13612
13613		if (data instanceof Float32Array && cache.length !== data.length) {
13614			this.cache = new Float32Array(data.length);
13615		}
13616
13617		copyArray(cache, data);
13618	};
13619
13620	function StructuredUniform(id) {
13621		this.id = id;
13622		this.seq = [];
13623		this.map = {};
13624	}
13625
13626	StructuredUniform.prototype.setValue = function (gl, value, textures) {
13627		const seq = this.seq;
13628
13629		for (let i = 0, n = seq.length; i !== n; ++i) {
13630			const u = seq[i];
13631			u.setValue(gl, value[u.id], textures);
13632		}
13633	}; // --- Top-level ---
13634	// Parser - builds up the property tree from the path strings
13635
13636
13637	const RePathPart = /(\w+)(\])?(\[|\.)?/g; // extracts
13638	// 	- the identifier (member name or array index)
13639	//	- followed by an optional right bracket (found when array index)
13640	//	- followed by an optional left bracket or dot (type of subscript)
13641	//
13642	// Note: These portions can be read in a non-overlapping fashion and
13643	// allow straightforward parsing of the hierarchy that WebGL encodes
13644	// in the uniform names.
13645
13646	function addUniform(container, uniformObject) {
13647		container.seq.push(uniformObject);
13648		container.map[uniformObject.id] = uniformObject;
13649	}
13650
13651	function parseUniform(activeInfo, addr, container) {
13652		const path = activeInfo.name,
13653					pathLength = path.length; // reset RegExp object, because of the early exit of a previous run
13654
13655		RePathPart.lastIndex = 0;
13656
13657		while (true) {
13658			const match = RePathPart.exec(path),
13659						matchEnd = RePathPart.lastIndex;
13660			let id = match[1];
13661			const idIsIndex = match[2] === ']',
13662						subscript = match[3];
13663			if (idIsIndex) id = id | 0; // convert to integer
13664
13665			if (subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength) {
13666				// bare name or "pure" bottom-level array "[0]" suffix
13667				addUniform(container, subscript === undefined ? new SingleUniform(id, activeInfo, addr) : new PureArrayUniform(id, activeInfo, addr));
13668				break;
13669			} else {
13670				// step into inner node / create it in case it doesn't exist
13671				const map = container.map;
13672				let next = map[id];
13673
13674				if (next === undefined) {
13675					next = new StructuredUniform(id);
13676					addUniform(container, next);
13677				}
13678
13679				container = next;
13680			}
13681		}
13682	} // Root Container
13683
13684
13685	function WebGLUniforms(gl, program) {
13686		this.seq = [];
13687		this.map = {};
13688		const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
13689
13690		for (let i = 0; i < n; ++i) {
13691			const info = gl.getActiveUniform(program, i),
13692						addr = gl.getUniformLocation(program, info.name);
13693			parseUniform(info, addr, this);
13694		}
13695	}
13696
13697	WebGLUniforms.prototype.setValue = function (gl, name, value, textures) {
13698		const u = this.map[name];
13699		if (u !== undefined) u.setValue(gl, value, textures);
13700	};
13701
13702	WebGLUniforms.prototype.setOptional = function (gl, object, name) {
13703		const v = object[name];
13704		if (v !== undefined) this.setValue(gl, name, v);
13705	}; // Static interface
13706
13707
13708	WebGLUniforms.upload = function (gl, seq, values, textures) {
13709		for (let i = 0, n = seq.length; i !== n; ++i) {
13710			const u = seq[i],
13711						v = values[u.id];
13712
13713			if (v.needsUpdate !== false) {
13714				// note: always updating when .needsUpdate is undefined
13715				u.setValue(gl, v.value, textures);
13716			}
13717		}
13718	};
13719
13720	WebGLUniforms.seqWithValue = function (seq, values) {
13721		const r = [];
13722
13723		for (let i = 0, n = seq.length; i !== n; ++i) {
13724			const u = seq[i];
13725			if (u.id in values) r.push(u);
13726		}
13727
13728		return r;
13729	};
13730
13731	function WebGLShader(gl, type, string) {
13732		const shader = gl.createShader(type);
13733		gl.shaderSource(shader, string);
13734		gl.compileShader(shader);
13735		return shader;
13736	}
13737
13738	let programIdCount = 0;
13739
13740	function addLineNumbers(string) {
13741		const lines = string.split('\n');
13742
13743		for (let i = 0; i < lines.length; i++) {
13744			lines[i] = i + 1 + ': ' + lines[i];
13745		}
13746
13747		return lines.join('\n');
13748	}
13749
13750	function getEncodingComponents(encoding) {
13751		switch (encoding) {
13752			case LinearEncoding:
13753				return ['Linear', '( value )'];
13754
13755			case sRGBEncoding:
13756				return ['sRGB', '( value )'];
13757
13758			default:
13759				console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding);
13760				return ['Linear', '( value )'];
13761		}
13762	}
13763
13764	function getShaderErrors(gl, shader, type) {
13765		const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
13766		const errors = gl.getShaderInfoLog(shader).trim();
13767		if (status && errors === '') return ''; // --enable-privileged-webgl-extension
13768		// console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
13769
13770		return type.toUpperCase() + '\n\n' + errors + '\n\n' + addLineNumbers(gl.getShaderSource(shader));
13771	}
13772
13773	function getTexelDecodingFunction(functionName, encoding) {
13774		const components = getEncodingComponents(encoding);
13775		return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[0] + 'ToLinear' + components[1] + '; }';
13776	}
13777
13778	function getTexelEncodingFunction(functionName, encoding) {
13779		const components = getEncodingComponents(encoding);
13780		return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }';
13781	}
13782
13783	function getToneMappingFunction(functionName, toneMapping) {
13784		let toneMappingName;
13785
13786		switch (toneMapping) {
13787			case LinearToneMapping:
13788				toneMappingName = 'Linear';
13789				break;
13790
13791			case ReinhardToneMapping:
13792				toneMappingName = 'Reinhard';
13793				break;
13794
13795			case CineonToneMapping:
13796				toneMappingName = 'OptimizedCineon';
13797				break;
13798
13799			case ACESFilmicToneMapping:
13800				toneMappingName = 'ACESFilmic';
13801				break;
13802
13803			case CustomToneMapping:
13804				toneMappingName = 'Custom';
13805				break;
13806
13807			default:
13808				console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping);
13809				toneMappingName = 'Linear';
13810		}
13811
13812		return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';
13813	}
13814
13815	function generateExtensions(parameters) {
13816		const chunks = [parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ? '#extension GL_OES_standard_derivatives : enable' : '', (parameters.extensionFragDepth || parameters.logarithmicDepthBuffer) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ? '#extension GL_EXT_draw_buffers : require' : '', (parameters.extensionShaderTextureLOD || parameters.envMap || parameters.transmission) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : ''];
13817		return chunks.filter(filterEmptyLine).join('\n');
13818	}
13819
13820	function generateDefines(defines) {
13821		const chunks = [];
13822
13823		for (const name in defines) {
13824			const value = defines[name];
13825			if (value === false) continue;
13826			chunks.push('#define ' + name + ' ' + value);
13827		}
13828
13829		return chunks.join('\n');
13830	}
13831
13832	function fetchAttributeLocations(gl, program) {
13833		const attributes = {};
13834		const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
13835
13836		for (let i = 0; i < n; i++) {
13837			const info = gl.getActiveAttrib(program, i);
13838			const name = info.name;
13839			let locationSize = 1;
13840			if (info.type === gl.FLOAT_MAT2) locationSize = 2;
13841			if (info.type === gl.FLOAT_MAT3) locationSize = 3;
13842			if (info.type === gl.FLOAT_MAT4) locationSize = 4; // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i );
13843
13844			attributes[name] = {
13845				type: info.type,
13846				location: gl.getAttribLocation(program, name),
13847				locationSize: locationSize
13848			};
13849		}
13850
13851		return attributes;
13852	}
13853
13854	function filterEmptyLine(string) {
13855		return string !== '';
13856	}
13857
13858	function replaceLightNums(string, parameters) {
13859		return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, parameters.numPointLights).replace(/NUM_HEMI_LIGHTS/g, parameters.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows);
13860	}
13861
13862	function replaceClippingPlaneNums(string, parameters) {
13863		return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection);
13864	} // Resolve Includes
13865
13866
13867	const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
13868
13869	function resolveIncludes(string) {
13870		return string.replace(includePattern, includeReplacer);
13871	}
13872
13873	function includeReplacer(match, include) {
13874		const string = ShaderChunk[include];
13875
13876		if (string === undefined) {
13877			throw new Error('Can not resolve #include <' + include + '>');
13878		}
13879
13880		return resolveIncludes(string);
13881	} // Unroll Loops
13882
13883
13884	const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
13885	const unrollLoopPattern = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;
13886
13887	function unrollLoops(string) {
13888		return string.replace(unrollLoopPattern, loopReplacer).replace(deprecatedUnrollLoopPattern, deprecatedLoopReplacer);
13889	}
13890
13891	function deprecatedLoopReplacer(match, start, end, snippet) {
13892		console.warn('WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.');
13893		return loopReplacer(match, start, end, snippet);
13894	}
13895
13896	function loopReplacer(match, start, end, snippet) {
13897		let string = '';
13898
13899		for (let i = parseInt(start); i < parseInt(end); i++) {
13900			string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i);
13901		}
13902
13903		return string;
13904	} //
13905
13906
13907	function generatePrecision(parameters) {
13908		let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;';
13909
13910		if (parameters.precision === 'highp') {
13911			precisionstring += '\n#define HIGH_PRECISION';
13912		} else if (parameters.precision === 'mediump') {
13913			precisionstring += '\n#define MEDIUM_PRECISION';
13914		} else if (parameters.precision === 'lowp') {
13915			precisionstring += '\n#define LOW_PRECISION';
13916		}
13917
13918		return precisionstring;
13919	}
13920
13921	function generateShadowMapTypeDefine(parameters) {
13922		let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
13923
13924		if (parameters.shadowMapType === PCFShadowMap) {
13925			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
13926		} else if (parameters.shadowMapType === PCFSoftShadowMap) {
13927			shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
13928		} else if (parameters.shadowMapType === VSMShadowMap) {
13929			shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';
13930		}
13931
13932		return shadowMapTypeDefine;
13933	}
13934
13935	function generateEnvMapTypeDefine(parameters) {
13936		let envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
13937
13938		if (parameters.envMap) {
13939			switch (parameters.envMapMode) {
13940				case CubeReflectionMapping:
13941				case CubeRefractionMapping:
13942					envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
13943					break;
13944
13945				case CubeUVReflectionMapping:
13946				case CubeUVRefractionMapping:
13947					envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
13948					break;
13949			}
13950		}
13951
13952		return envMapTypeDefine;
13953	}
13954
13955	function generateEnvMapModeDefine(parameters) {
13956		let envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
13957
13958		if (parameters.envMap) {
13959			switch (parameters.envMapMode) {
13960				case CubeRefractionMapping:
13961				case CubeUVRefractionMapping:
13962					envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
13963					break;
13964			}
13965		}
13966
13967		return envMapModeDefine;
13968	}
13969
13970	function generateEnvMapBlendingDefine(parameters) {
13971		let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
13972
13973		if (parameters.envMap) {
13974			switch (parameters.combine) {
13975				case MultiplyOperation:
13976					envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
13977					break;
13978
13979				case MixOperation:
13980					envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
13981					break;
13982
13983				case AddOperation:
13984					envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
13985					break;
13986			}
13987		}
13988
13989		return envMapBlendingDefine;
13990	}
13991
13992	function WebGLProgram(renderer, cacheKey, parameters, bindingStates) {
13993		// TODO Send this event to Three.js DevTools
vendor: 12,392 bytes, lines 13994-14048
13994		// console.log( 'WebGLProgram', cacheKey );
13995		const gl = renderer.getContext();
13996		const defines = parameters.defines;
13997		let vertexShader = parameters.vertexShader;
13998		let fragmentShader = parameters.fragmentShader;
13999		const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters);
14000		const envMapTypeDefine = generateEnvMapTypeDefine(parameters);
14001		const envMapModeDefine = generateEnvMapModeDefine(parameters);
14002		const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters);
14003		const customExtensions = parameters.isWebGL2 ? '' : generateExtensions(parameters);
14004		const customDefines = generateDefines(defines);
14005		const program = gl.createProgram();
14006		let prefixVertex, prefixFragment;
14007		let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : '';
14008
14009		if (parameters.isRawShaderMaterial) {
14010			prefixVertex = [customDefines].filter(filterEmptyLine).join('\n');
14011
14012			if (prefixVertex.length > 0) {
14013				prefixVertex += '\n';
14014			}
14015
14016			prefixFragment = [customExtensions, customDefines].filter(filterEmptyLine).join('\n');
14017
14018			if (prefixFragment.length > 0) {
14019				prefixFragment += '\n';
14020			}
14021		} else {
14022			prefixVertex = [generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.instancing ? '#define USE_INSTANCING' : '', parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '', parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', '#define MAX_BONES ' + parameters.maxBones, parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', parameters.useVertexTexture ? '#define BONE_TEXTURE' : '', parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', parameters.morphTargets && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE' : '', parameters.morphTargets && parameters.isWebGL2 ? '#define MORPHTARGETS_COUNT ' + parameters.morphTargetsCount : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat3 normalMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', '#ifdef USE_INSTANCING', '	attribute mat4 instanceMatrix;', '#endif', '#ifdef USE_INSTANCING_COLOR', '	attribute vec3 instanceColor;', '#endif', 'attribute vec3 position;', 'attribute vec3 normal;', 'attribute vec2 uv;', '#ifdef USE_TANGENT', '	attribute vec4 tangent;', '#endif', '#if defined( USE_COLOR_ALPHA )', '	attribute vec4 color;', '#elif defined( USE_COLOR )', '	attribute vec3 color;', '#endif', '#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )', '	attribute vec3 morphTarget0;', '	attribute vec3 morphTarget1;', '	attribute vec3 morphTarget2;', '	attribute vec3 morphTarget3;', '	#ifdef USE_MORPHNORMALS', '		attribute vec3 morphNormal0;', '		attribute vec3 morphNormal1;', '		attribute vec3 morphNormal2;', '		attribute vec3 morphNormal3;', '	#else', '		attribute vec3 morphTarget4;', '		attribute vec3 morphTarget5;', '		attribute vec3 morphTarget6;', '		attribute vec3 morphTarget7;', '	#endif', '#endif', '#ifdef USE_SKINNING', '	attribute vec4 skinIndex;', '	attribute vec4 skinWeight;', '#endif', '\n'].filter(filterEmptyLine).join('\n');
14023			prefixFragment = [customExtensions, generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.matcap ? '#define USE_MATCAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapTypeDefine : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.envMap ? '#define ' + envMapBlendingDefine : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoat ? '#define USE_CLEARCOAT' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.alphaTest ? '#define USE_ALPHATEST' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', (parameters.extensionShaderTextureLOD || parameters.envMap) && parameters.rendererExtensionShaderTextureLod ? '#define TEXTURE_LOD_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', parameters.toneMapping !== NoToneMapping ? '#define TONE_MAPPING' : '', parameters.toneMapping !== NoToneMapping ? ShaderChunk['tonemapping_pars_fragment'] : '', // this code is required here because it is used by the toneMapping() function defined below
14024			parameters.toneMapping !== NoToneMapping ? getToneMappingFunction('toneMapping', parameters.toneMapping) : '', parameters.dithering ? '#define DITHERING' : '', parameters.format === RGBFormat ? '#define OPAQUE' : '', ShaderChunk['encodings_pars_fragment'], // this code is required here because it is used by the various encoding/decoding function defined below
14025			parameters.map ? getTexelDecodingFunction('mapTexelToLinear', parameters.mapEncoding) : '', parameters.matcap ? getTexelDecodingFunction('matcapTexelToLinear', parameters.matcapEncoding) : '', parameters.envMap ? getTexelDecodingFunction('envMapTexelToLinear', parameters.envMapEncoding) : '', parameters.emissiveMap ? getTexelDecodingFunction('emissiveMapTexelToLinear', parameters.emissiveMapEncoding) : '', parameters.specularColorMap ? getTexelDecodingFunction('specularColorMapTexelToLinear', parameters.specularColorMapEncoding) : '', parameters.sheenColorMap ? getTexelDecodingFunction('sheenColorMapTexelToLinear', parameters.sheenColorMapEncoding) : '', parameters.lightMap ? getTexelDecodingFunction('lightMapTexelToLinear', parameters.lightMapEncoding) : '', getTexelEncodingFunction('linearToOutputTexel', parameters.outputEncoding), parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n'].filter(filterEmptyLine).join('\n');
14026		}
14027
14028		vertexShader = resolveIncludes(vertexShader);
14029		vertexShader = replaceLightNums(vertexShader, parameters);
14030		vertexShader = replaceClippingPlaneNums(vertexShader, parameters);
14031		fragmentShader = resolveIncludes(fragmentShader);
14032		fragmentShader = replaceLightNums(fragmentShader, parameters);
14033		fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters);
14034		vertexShader = unrollLoops(vertexShader);
14035		fragmentShader = unrollLoops(fragmentShader);
14036
14037		if (parameters.isWebGL2 && parameters.isRawShaderMaterial !== true) {
14038			// GLSL 3.0 conversion for built-in materials and ShaderMaterial
14039			versionString = '#version 300 es\n';
14040			prefixVertex = ['precision mediump sampler2DArray;', '#define attribute in', '#define varying out', '#define texture2D texture'].join('\n') + '\n' + prefixVertex;
14041			prefixFragment = ['#define varying in', parameters.glslVersion === GLSL3 ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;', parameters.glslVersion === GLSL3 ? '' : '#define gl_FragColor pc_fragColor', '#define gl_FragDepthEXT gl_FragDepth', '#define texture2D texture', '#define textureCube texture', '#define texture2DProj textureProj', '#define texture2DLodEXT textureLod', '#define texture2DProjLodEXT textureProjLod', '#define textureCubeLodEXT textureLod', '#define texture2DGradEXT textureGrad', '#define texture2DProjGradEXT textureProjGrad', '#define textureCubeGradEXT textureGrad'].join('\n') + '\n' + prefixFragment;
14042		}
14043
14044		const vertexGlsl = versionString + prefixVertex + vertexShader;
14045		const fragmentGlsl = versionString + prefixFragment + fragmentShader; // console.log( '*VERTEX*', vertexGlsl );
14046		// console.log( '*FRAGMENT*', fragmentGlsl );
14047
14048		const glVertexShader = WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl);
vendor: 4,356 bytes, lines 14049-14199
14049		const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl);
14050		gl.attachShader(program, glVertexShader);
14051		gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0.
14052
14053		if (parameters.index0AttributeName !== undefined) {
14054			gl.bindAttribLocation(program, 0, parameters.index0AttributeName);
14055		} else if (parameters.morphTargets === true) {
14056			// programs with morphTargets displace position out of attribute 0
14057			gl.bindAttribLocation(program, 0, 'position');
14058		}
14059
14060		gl.linkProgram(program); // check for link errors
14061
14062		if (renderer.debug.checkShaderErrors) {
14063			const programLog = gl.getProgramInfoLog(program).trim();
14064			const vertexLog = gl.getShaderInfoLog(glVertexShader).trim();
14065			const fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim();
14066			let runnable = true;
14067			let haveDiagnostics = true;
14068
14069			if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) {
14070				runnable = false;
14071				const vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex');
14072				const fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment');
14073				console.error('THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + 'VALIDATE_STATUS ' + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + '\n\n' + 'Program Info Log: ' + programLog + '\n' + vertexErrors + '\n' + fragmentErrors);
14074			} else if (programLog !== '') {
14075				console.warn('THREE.WebGLProgram: Program Info Log:', programLog);
14076			} else if (vertexLog === '' || fragmentLog === '') {
14077				haveDiagnostics = false;
14078			}
14079
14080			if (haveDiagnostics) {
14081				this.diagnostics = {
14082					runnable: runnable,
14083					programLog: programLog,
14084					vertexShader: {
14085						log: vertexLog,
14086						prefix: prefixVertex
14087					},
14088					fragmentShader: {
14089						log: fragmentLog,
14090						prefix: prefixFragment
14091					}
14092				};
14093			}
14094		} // Clean up
14095		// Crashes in iOS9 and iOS10. #18402
14096		// gl.detachShader( program, glVertexShader );
14097		// gl.detachShader( program, glFragmentShader );
14098
14099
14100		gl.deleteShader(glVertexShader);
14101		gl.deleteShader(glFragmentShader); // set up caching for uniform locations
14102
14103		let cachedUniforms;
14104
14105		this.getUniforms = function () {
14106			if (cachedUniforms === undefined) {
14107				cachedUniforms = new WebGLUniforms(gl, program);
14108			}
14109
14110			return cachedUniforms;
14111		}; // set up caching for attribute locations
14112
14113
14114		let cachedAttributes;
14115
14116		this.getAttributes = function () {
14117			if (cachedAttributes === undefined) {
14118				cachedAttributes = fetchAttributeLocations(gl, program);
14119			}
14120
14121			return cachedAttributes;
14122		}; // free resource
14123
14124
14125		this.destroy = function () {
14126			bindingStates.releaseStatesOfProgram(this);
14127			gl.deleteProgram(program);
14128			this.program = undefined;
14129		}; //
14130
14131
14132		this.name = parameters.shaderName;
14133		this.id = programIdCount++;
14134		this.cacheKey = cacheKey;
14135		this.usedTimes = 1;
14136		this.program = program;
14137		this.vertexShader = glVertexShader;
14138		this.fragmentShader = glFragmentShader;
14139		return this;
14140	}
14141
14142	let _id = 0;
14143
14144	class WebGLShaderCache {
14145		constructor() {
14146			this.shaderCache = new Map();
14147			this.materialCache = new Map();
14148		}
14149
14150		update(material) {
14151			const vertexShader = material.vertexShader;
14152			const fragmentShader = material.fragmentShader;
14153
14154			const vertexShaderStage = this._getShaderStage(vertexShader);
14155
14156			const fragmentShaderStage = this._getShaderStage(fragmentShader);
14157
14158			const materialShaders = this._getShaderCacheForMaterial(material);
14159
14160			if (materialShaders.has(vertexShaderStage) === false) {
14161				materialShaders.add(vertexShaderStage);
14162				vertexShaderStage.usedTimes++;
14163			}
14164
14165			if (materialShaders.has(fragmentShaderStage) === false) {
14166				materialShaders.add(fragmentShaderStage);
14167				fragmentShaderStage.usedTimes++;
14168			}
14169
14170			return this;
14171		}
14172
14173		remove(material) {
14174			const materialShaders = this.materialCache.get(material);
14175
14176			for (const shaderStage of materialShaders) {
14177				shaderStage.usedTimes--;
14178				if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage);
14179			}
14180
14181			this.materialCache.delete(material);
14182			return this;
14183		}
14184
14185		getVertexShaderID(material) {
14186			return this._getShaderStage(material.vertexShader).id;
14187		}
14188
14189		getFragmentShaderID(material) {
14190			return this._getShaderStage(material.fragmentShader).id;
14191		}
14192
14193		dispose() {
14194			this.shaderCache.clear();
14195			this.materialCache.clear();
14196		}
14197
14198		_getShaderCacheForMaterial(material) {
14199			const cache = this.materialCache;
14200
14201			if (cache.has(material) === false) {
14202				cache.set(material, new Set());
14203			}
14204
14205			return cache.get(material);
14206		}
14207
14208		_getShaderStage(code) {
14209			const cache = this.shaderCache;
14210
14211			if (cache.has(code) === false) {
14212				const stage = new WebGLShaderStage();
14213				cache.set(code, stage);
14214			}
14215
14216			return cache.get(code);
14217		}
14218
14219	}
14220
14221	class WebGLShaderStage {
14222		constructor() {
14223			this.id = _id++;
14224			this.usedTimes = 0;
14225		}
14226
14227	}
14228
14229	function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) {
14230		const _programLayers = new Layers();
14231
14232		const _customShaders = new WebGLShaderCache();
14233
14234		const programs = [];
14235		const isWebGL2 = capabilities.isWebGL2;
14236		const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
14237		const floatVertexTextures = capabilities.floatVertexTextures;
14238		const maxVertexUniforms = capabilities.maxVertexUniforms;
14239		const vertexTextures = capabilities.vertexTextures;
14240		let precision = capabilities.precision;
14241		const shaderIDs = {
14242			MeshDepthMaterial: 'depth',
14243			MeshDistanceMaterial: 'distanceRGBA',
14244			MeshNormalMaterial: 'normal',
14245			MeshBasicMaterial: 'basic',
14246			MeshLambertMaterial: 'lambert',
14247			MeshPhongMaterial: 'phong',
14248			MeshToonMaterial: 'toon',
14249			MeshStandardMaterial: 'physical',
14250			MeshPhysicalMaterial: 'physical',
14251			MeshMatcapMaterial: 'matcap',
14252			LineBasicMaterial: 'basic',
14253			LineDashedMaterial: 'dashed',
14254			PointsMaterial: 'points',
14255			ShadowMaterial: 'shadow',
14256			SpriteMaterial: 'sprite'
14257		};
14258
14259		function getMaxBones(object) {
14260			const skeleton = object.skeleton;
14261			const bones = skeleton.bones;
14262
14263			if (floatVertexTextures) {
14264				return 1024;
14265			} else {
14266				// default for when object is not specified
14267				// ( for example when prebuilding shader to be used with multiple objects )
14268				//
14269				//	- leave some extra space for other uniforms
14270				//	- limit here is ANGLE's 254 max uniform vectors
14271				//		(up to 54 should be safe)
14272				const nVertexUniforms = maxVertexUniforms;
14273				const nVertexMatrices = Math.floor((nVertexUniforms - 20) / 4);
14274				const maxBones = Math.min(nVertexMatrices, bones.length);
14275
14276				if (maxBones < bones.length) {
14277					console.warn('THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.');
14278					return 0;
14279				}
14280
14281				return maxBones;
14282			}
14283		}
14284
14285		function getTextureEncodingFromMap(map) {
14286			let encoding;
14287
14288			if (map && map.isTexture) {
14289				encoding = map.encoding;
14290			} else if (map && map.isWebGLRenderTarget) {
14291				console.warn('THREE.WebGLPrograms.getTextureEncodingFromMap: don\'t use render targets as textures. Use their .texture property instead.');
14292				encoding = map.texture.encoding;
14293			} else {
14294				encoding = LinearEncoding;
14295			}
14296
14297			if (isWebGL2 && map && map.isTexture && map.format === RGBAFormat && map.type === UnsignedByteType && map.encoding === sRGBEncoding) {
14298				encoding = LinearEncoding; // disable inline decode for sRGB textures in WebGL 2
14299			}
14300
14301			return encoding;
14302		}
14303
14304		function getParameters(material, lights, shadows, scene, object) {
14305			const fog = scene.fog;
14306			const environment = material.isMeshStandardMaterial ? scene.environment : null;
14307			const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
14308			const shaderID = shaderIDs[material.type]; // heuristics to create shader parameters according to lights in the scene
14309			// (not to blow over maxLights budget)
14310
14311			const maxBones = object.isSkinnedMesh ? getMaxBones(object) : 0;
14312
14313			if (material.precision !== null) {
14314				precision = capabilities.getMaxPrecision(material.precision);
14315
14316				if (precision !== material.precision) {
14317					console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.');
14318				}
14319			}
14320
14321			let vertexShader, fragmentShader;
14322			let customVertexShaderID, customFragmentShaderID;
14323
14324			if (shaderID) {
14325				const shader = ShaderLib[shaderID];
14326				vertexShader = shader.vertexShader;
14327				fragmentShader = shader.fragmentShader;
14328			} else {
14329				vertexShader = material.vertexShader;
14330				fragmentShader = material.fragmentShader;
14331
14332				_customShaders.update(material);
14333
14334				customVertexShaderID = _customShaders.getVertexShaderID(material);
14335				customFragmentShaderID = _customShaders.getFragmentShaderID(material);
14336			}
14337
14338			const currentRenderTarget = renderer.getRenderTarget();
14339			const useAlphaTest = material.alphaTest > 0;
14340			const useClearcoat = material.clearcoat > 0;
14341			const parameters = {
14342				isWebGL2: isWebGL2,
14343				shaderID: shaderID,
14344				shaderName: material.type,
14345				vertexShader: vertexShader,
14346				fragmentShader: fragmentShader,
14347				defines: material.defines,
14348				customVertexShaderID: customVertexShaderID,
14349				customFragmentShaderID: customFragmentShaderID,
14350				isRawShaderMaterial: material.isRawShaderMaterial === true,
14351				glslVersion: material.glslVersion,
14352				precision: precision,
14353				instancing: object.isInstancedMesh === true,
14354				instancingColor: object.isInstancedMesh === true && object.instanceColor !== null,
14355				supportsVertexTextures: vertexTextures,
14356				outputEncoding: currentRenderTarget !== null ? getTextureEncodingFromMap(currentRenderTarget.texture) : renderer.outputEncoding,
14357				map: !!material.map,
14358				mapEncoding: getTextureEncodingFromMap(material.map),
14359				matcap: !!material.matcap,
14360				matcapEncoding: getTextureEncodingFromMap(material.matcap),
14361				envMap: !!envMap,
14362				envMapMode: envMap && envMap.mapping,
14363				envMapEncoding: getTextureEncodingFromMap(envMap),
14364				envMapCubeUV: !!envMap && (envMap.mapping === CubeUVReflectionMapping || envMap.mapping === CubeUVRefractionMapping),
14365				lightMap: !!material.lightMap,
14366				lightMapEncoding: getTextureEncodingFromMap(material.lightMap),
14367				aoMap: !!material.aoMap,
14368				emissiveMap: !!material.emissiveMap,
14369				emissiveMapEncoding: getTextureEncodingFromMap(material.emissiveMap),
14370				bumpMap: !!material.bumpMap,
14371				normalMap: !!material.normalMap,
14372				objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap,
14373				tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap,
14374				clearcoat: useClearcoat,
14375				clearcoatMap: useClearcoat && !!material.clearcoatMap,
14376				clearcoatRoughnessMap: useClearcoat && !!material.clearcoatRoughnessMap,
14377				clearcoatNormalMap: useClearcoat && !!material.clearcoatNormalMap,
14378				displacementMap: !!material.displacementMap,
14379				roughnessMap: !!material.roughnessMap,
14380				metalnessMap: !!material.metalnessMap,
14381				specularMap: !!material.specularMap,
14382				specularIntensityMap: !!material.specularIntensityMap,
14383				specularColorMap: !!material.specularColorMap,
14384				specularColorMapEncoding: getTextureEncodingFromMap(material.specularColorMap),
14385				alphaMap: !!material.alphaMap,
14386				alphaTest: useAlphaTest,
14387				gradientMap: !!material.gradientMap,
14388				sheen: material.sheen > 0,
14389				sheenColorMap: !!material.sheenColorMap,
14390				sheenColorMapEncoding: getTextureEncodingFromMap(material.sheenColorMap),
14391				sheenRoughnessMap: !!material.sheenRoughnessMap,
14392				transmission: material.transmission > 0,
14393				transmissionMap: !!material.transmissionMap,
14394				thicknessMap: !!material.thicknessMap,
14395				combine: material.combine,
14396				vertexTangents: !!material.normalMap && !!object.geometry && !!object.geometry.attributes.tangent,
14397				vertexColors: material.vertexColors,
14398				vertexAlphas: material.vertexColors === true && !!object.geometry && !!object.geometry.attributes.color && object.geometry.attributes.color.itemSize === 4,
14399				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 || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularColorMap || !!material.sheenColorMap || !!material.sheenRoughnessMap,
14400				uvsVertexOnly: !(!!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatNormalMap || material.transmission > 0 || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularColorMap || material.sheen > 0 || !!material.sheenColorMap || !!material.sheenRoughnessMap) && !!material.displacementMap,
14401				fog: !!fog,
14402				useFog: material.fog,
14403				fogExp2: fog && fog.isFogExp2,
14404				flatShading: !!material.flatShading,
14405				sizeAttenuation: material.sizeAttenuation,
14406				logarithmicDepthBuffer: logarithmicDepthBuffer,
14407				skinning: object.isSkinnedMesh === true && maxBones > 0,
14408				maxBones: maxBones,
14409				useVertexTexture: floatVertexTextures,
14410				morphTargets: !!object.geometry && !!object.geometry.morphAttributes.position,
14411				morphNormals: !!object.geometry && !!object.geometry.morphAttributes.normal,
14412				morphTargetsCount: !!object.geometry && !!object.geometry.morphAttributes.position ? object.geometry.morphAttributes.position.length : 0,
14413				numDirLights: lights.directional.length,
14414				numPointLights: lights.point.length,
14415				numSpotLights: lights.spot.length,
14416				numRectAreaLights: lights.rectArea.length,
14417				numHemiLights: lights.hemi.length,
14418				numDirLightShadows: lights.directionalShadowMap.length,
14419				numPointLightShadows: lights.pointShadowMap.length,
14420				numSpotLightShadows: lights.spotShadowMap.length,
14421				numClippingPlanes: clipping.numPlanes,
14422				numClipIntersection: clipping.numIntersection,
14423				format: material.format,
14424				dithering: material.dithering,
14425				shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
14426				shadowMapType: renderer.shadowMap.type,
14427				toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
14428				physicallyCorrectLights: renderer.physicallyCorrectLights,
14429				premultipliedAlpha: material.premultipliedAlpha,
14430				doubleSided: material.side === DoubleSide,
14431				flipSided: material.side === BackSide,
14432				depthPacking: material.depthPacking !== undefined ? material.depthPacking : false,
14433				index0AttributeName: material.index0AttributeName,
14434				extensionDerivatives: material.extensions && material.extensions.derivatives,
14435				extensionFragDepth: material.extensions && material.extensions.fragDepth,
14436				extensionDrawBuffers: material.extensions && material.extensions.drawBuffers,
14437				extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD,
14438				rendererExtensionFragDepth: isWebGL2 || extensions.has('EXT_frag_depth'),
14439				rendererExtensionDrawBuffers: isWebGL2 || extensions.has('WEBGL_draw_buffers'),
14440				rendererExtensionShaderTextureLod: isWebGL2 || extensions.has('EXT_shader_texture_lod'),
14441				customProgramCacheKey: material.customProgramCacheKey()
14442			};
14443			return parameters;
14444		}
14445
14446		function getProgramCacheKey(parameters) {
14447			const array = [];
14448
14449			if (parameters.shaderID) {
14450				array.push(parameters.shaderID);
14451			} else {
14452				array.push(parameters.customVertexShaderID);
14453				array.push(parameters.customFragmentShaderID);
14454			}
14455
14456			if (parameters.defines !== undefined) {
14457				for (const name in parameters.defines) {
14458					array.push(name);
14459					array.push(parameters.defines[name]);
14460				}
14461			}
14462
14463			if (parameters.isRawShaderMaterial === false) {
14464				getProgramCacheKeyParameters(array, parameters);
14465				getProgramCacheKeyBooleans(array, parameters);
14466				array.push(renderer.outputEncoding);
14467			}
14468
14469			array.push(parameters.customProgramCacheKey);
14470			return array.join();
14471		}
14472
14473		function getProgramCacheKeyParameters(array, parameters) {
14474			array.push(parameters.precision);
14475			array.push(parameters.outputEncoding);
14476			array.push(parameters.mapEncoding);
14477			array.push(parameters.matcapEncoding);
14478			array.push(parameters.envMapMode);
14479			array.push(parameters.envMapEncoding);
14480			array.push(parameters.lightMapEncoding);
14481			array.push(parameters.emissiveMapEncoding);
14482			array.push(parameters.combine);
14483			array.push(parameters.vertexUvs);
14484			array.push(parameters.fogExp2);
14485			array.push(parameters.sizeAttenuation);
14486			array.push(parameters.maxBones);
14487			array.push(parameters.morphTargetsCount);
14488			array.push(parameters.numDirLights);
14489			array.push(parameters.numPointLights);
14490			array.push(parameters.numSpotLights);
14491			array.push(parameters.numHemiLights);
14492			array.push(parameters.numRectAreaLights);
14493			array.push(parameters.numDirLightShadows);
14494			array.push(parameters.numPointLightShadows);
14495			array.push(parameters.numSpotLightShadows);
14496			array.push(parameters.shadowMapType);
14497			array.push(parameters.toneMapping);
14498			array.push(parameters.numClippingPlanes);
14499			array.push(parameters.numClipIntersection);
14500			array.push(parameters.format);
14501			array.push(parameters.specularColorMapEncoding);
14502			array.push(parameters.sheenColorMapEncoding);
14503		}
14504
14505		function getProgramCacheKeyBooleans(array, parameters) {
14506			_programLayers.disableAll();
14507
14508			if (parameters.isWebGL2) _programLayers.enable(0);
14509			if (parameters.supportsVertexTextures) _programLayers.enable(1);
14510			if (parameters.instancing) _programLayers.enable(2);
14511			if (parameters.instancingColor) _programLayers.enable(3);
14512			if (parameters.map) _programLayers.enable(4);
14513			if (parameters.matcap) _programLayers.enable(5);
14514			if (parameters.envMap) _programLayers.enable(6);
14515			if (parameters.envMapCubeUV) _programLayers.enable(7);
14516			if (parameters.lightMap) _programLayers.enable(8);
14517			if (parameters.aoMap) _programLayers.enable(9);
14518			if (parameters.emissiveMap) _programLayers.enable(10);
14519			if (parameters.bumpMap) _programLayers.enable(11);
14520			if (parameters.normalMap) _programLayers.enable(12);
14521			if (parameters.objectSpaceNormalMap) _programLayers.enable(13);
14522			if (parameters.tangentSpaceNormalMap) _programLayers.enable(14);
14523			if (parameters.clearcoat) _programLayers.enable(15);
14524			if (parameters.clearcoatMap) _programLayers.enable(16);
14525			if (parameters.clearcoatRoughnessMap) _programLayers.enable(17);
14526			if (parameters.clearcoatNormalMap) _programLayers.enable(18);
14527			if (parameters.displacementMap) _programLayers.enable(19);
14528			if (parameters.specularMap) _programLayers.enable(20);
14529			if (parameters.roughnessMap) _programLayers.enable(21);
14530			if (parameters.metalnessMap) _programLayers.enable(22);
14531			if (parameters.gradientMap) _programLayers.enable(23);
14532			if (parameters.alphaMap) _programLayers.enable(24);
14533			if (parameters.alphaTest) _programLayers.enable(25);
14534			if (parameters.vertexColors) _programLayers.enable(26);
14535			if (parameters.vertexAlphas) _programLayers.enable(27);
14536			if (parameters.vertexUvs) _programLayers.enable(28);
14537			if (parameters.vertexTangents) _programLayers.enable(29);
14538			if (parameters.uvsVertexOnly) _programLayers.enable(30);
14539			if (parameters.fog) _programLayers.enable(31);
14540			array.push(_programLayers.mask);
14541
14542			_programLayers.disableAll();
14543
14544			if (parameters.useFog) _programLayers.enable(0);
14545			if (parameters.flatShading) _programLayers.enable(1);
14546			if (parameters.logarithmicDepthBuffer) _programLayers.enable(2);
14547			if (parameters.skinning) _programLayers.enable(3);
14548			if (parameters.useVertexTexture) _programLayers.enable(4);
14549			if (parameters.morphTargets) _programLayers.enable(5);
14550			if (parameters.morphNormals) _programLayers.enable(6);
14551			if (parameters.premultipliedAlpha) _programLayers.enable(7);
14552			if (parameters.shadowMapEnabled) _programLayers.enable(8);
14553			if (parameters.physicallyCorrectLights) _programLayers.enable(9);
14554			if (parameters.doubleSided) _programLayers.enable(10);
14555			if (parameters.flipSided) _programLayers.enable(11);
14556			if (parameters.depthPacking) _programLayers.enable(12);
14557			if (parameters.dithering) _programLayers.enable(13);
14558			if (parameters.specularIntensityMap) _programLayers.enable(14);
14559			if (parameters.specularColorMap) _programLayers.enable(15);
14560			if (parameters.transmission) _programLayers.enable(16);
14561			if (parameters.transmissionMap) _programLayers.enable(17);
14562			if (parameters.thicknessMap) _programLayers.enable(18);
14563			if (parameters.sheen) _programLayers.enable(19);
14564			if (parameters.sheenColorMap) _programLayers.enable(20);
14565			if (parameters.sheenRoughnessMap) _programLayers.enable(21);
14566			array.push(_programLayers.mask);
14567		}
14568
14569		function getUniforms(material) {
14570			const shaderID = shaderIDs[material.type];
14571			let uniforms;
14572
14573			if (shaderID) {
14574				const shader = ShaderLib[shaderID];
14575				uniforms = UniformsUtils.clone(shader.uniforms);
14576			} else {
14577				uniforms = material.uniforms;
14578			}
14579
14580			return uniforms;
14581		}
14582
14583		function acquireProgram(parameters, cacheKey) {
14584			let program; // Check if code has been already compiled
14585
14586			for (let p = 0, pl = programs.length; p < pl; p++) {
vendor: 17,332 bytes, lines 14587-15190
14587				const preexistingProgram = programs[p];
14588
14589				if (preexistingProgram.cacheKey === cacheKey) {
14590					program = preexistingProgram;
14591					++program.usedTimes;
14592					break;
14593				}
14594			}
14595
14596			if (program === undefined) {
14597				program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates);
14598				programs.push(program);
14599			}
14600
14601			return program;
14602		}
14603
14604		function releaseProgram(program) {
14605			if (--program.usedTimes === 0) {
14606				// Remove from unordered set
14607				const i = programs.indexOf(program);
14608				programs[i] = programs[programs.length - 1];
14609				programs.pop(); // Free WebGL resources
14610
14611				program.destroy();
14612			}
14613		}
14614
14615		function releaseShaderCache(material) {
14616			_customShaders.remove(material);
14617		}
14618
14619		function dispose() {
14620			_customShaders.dispose();
14621		}
14622
14623		return {
14624			getParameters: getParameters,
14625			getProgramCacheKey: getProgramCacheKey,
14626			getUniforms: getUniforms,
14627			acquireProgram: acquireProgram,
14628			releaseProgram: releaseProgram,
14629			releaseShaderCache: releaseShaderCache,
14630			// Exposed for resource monitoring & error feedback via renderer.info:
14631			programs: programs,
14632			dispose: dispose
14633		};
14634	}
14635
14636	function WebGLProperties() {
14637		let properties = new WeakMap();
14638
14639		function get(object) {
14640			let map = properties.get(object);
14641
14642			if (map === undefined) {
14643				map = {};
14644				properties.set(object, map);
14645			}
14646
14647			return map;
14648		}
14649
14650		function remove(object) {
14651			properties.delete(object);
14652		}
14653
14654		function update(object, key, value) {
14655			properties.get(object)[key] = value;
14656		}
14657
14658		function dispose() {
14659			properties = new WeakMap();
14660		}
14661
14662		return {
14663			get: get,
14664			remove: remove,
14665			update: update,
14666			dispose: dispose
14667		};
14668	}
14669
14670	function painterSortStable(a, b) {
14671		if (a.groupOrder !== b.groupOrder) {
14672			return a.groupOrder - b.groupOrder;
14673		} else if (a.renderOrder !== b.renderOrder) {
14674			return a.renderOrder - b.renderOrder;
14675		} else if (a.material.id !== b.material.id) {
14676			return a.material.id - b.material.id;
14677		} else if (a.z !== b.z) {
14678			return a.z - b.z;
14679		} else {
14680			return a.id - b.id;
14681		}
14682	}
14683
14684	function reversePainterSortStable(a, b) {
14685		if (a.groupOrder !== b.groupOrder) {
14686			return a.groupOrder - b.groupOrder;
14687		} else if (a.renderOrder !== b.renderOrder) {
14688			return a.renderOrder - b.renderOrder;
14689		} else if (a.z !== b.z) {
14690			return b.z - a.z;
14691		} else {
14692			return a.id - b.id;
14693		}
14694	}
14695
14696	function WebGLRenderList() {
14697		const renderItems = [];
14698		let renderItemsIndex = 0;
14699		const opaque = [];
14700		const transmissive = [];
14701		const transparent = [];
14702
14703		function init() {
14704			renderItemsIndex = 0;
14705			opaque.length = 0;
14706			transmissive.length = 0;
14707			transparent.length = 0;
14708		}
14709
14710		function getNextRenderItem(object, geometry, material, groupOrder, z, group) {
14711			let renderItem = renderItems[renderItemsIndex];
14712
14713			if (renderItem === undefined) {
14714				renderItem = {
14715					id: object.id,
14716					object: object,
14717					geometry: geometry,
14718					material: material,
14719					groupOrder: groupOrder,
14720					renderOrder: object.renderOrder,
14721					z: z,
14722					group: group
14723				};
14724				renderItems[renderItemsIndex] = renderItem;
14725			} else {
14726				renderItem.id = object.id;
14727				renderItem.object = object;
14728				renderItem.geometry = geometry;
14729				renderItem.material = material;
14730				renderItem.groupOrder = groupOrder;
14731				renderItem.renderOrder = object.renderOrder;
14732				renderItem.z = z;
14733				renderItem.group = group;
14734			}
14735
14736			renderItemsIndex++;
14737			return renderItem;
14738		}
14739
14740		function push(object, geometry, material, groupOrder, z, group) {
14741			const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group);
14742
14743			if (material.transmission > 0.0) {
14744				transmissive.push(renderItem);
14745			} else if (material.transparent === true) {
14746				transparent.push(renderItem);
14747			} else {
14748				opaque.push(renderItem);
14749			}
14750		}
14751
14752		function unshift(object, geometry, material, groupOrder, z, group) {
14753			const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group);
14754
14755			if (material.transmission > 0.0) {
14756				transmissive.unshift(renderItem);
14757			} else if (material.transparent === true) {
14758				transparent.unshift(renderItem);
14759			} else {
14760				opaque.unshift(renderItem);
14761			}
14762		}
14763
14764		function sort(customOpaqueSort, customTransparentSort) {
14765			if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable);
14766			if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable);
14767			if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable);
14768		}
14769
14770		function finish() {
14771			// Clear references from inactive renderItems in the list
14772			for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) {
14773				const renderItem = renderItems[i];
14774				if (renderItem.id === null) break;
14775				renderItem.id = null;
14776				renderItem.object = null;
14777				renderItem.geometry = null;
14778				renderItem.material = null;
14779				renderItem.group = null;
14780			}
14781		}
14782
14783		return {
14784			opaque: opaque,
14785			transmissive: transmissive,
14786			transparent: transparent,
14787			init: init,
14788			push: push,
14789			unshift: unshift,
14790			finish: finish,
14791			sort: sort
14792		};
14793	}
14794
14795	function WebGLRenderLists() {
14796		let lists = new WeakMap();
14797
14798		function get(scene, renderCallDepth) {
14799			let list;
14800
14801			if (lists.has(scene) === false) {
14802				list = new WebGLRenderList();
14803				lists.set(scene, [list]);
14804			} else {
14805				if (renderCallDepth >= lists.get(scene).length) {
14806					list = new WebGLRenderList();
14807					lists.get(scene).push(list);
14808				} else {
14809					list = lists.get(scene)[renderCallDepth];
14810				}
14811			}
14812
14813			return list;
14814		}
14815
14816		function dispose() {
14817			lists = new WeakMap();
14818		}
14819
14820		return {
14821			get: get,
14822			dispose: dispose
14823		};
14824	}
14825
14826	function UniformsCache() {
14827		const lights = {};
14828		return {
14829			get: function (light) {
14830				if (lights[light.id] !== undefined) {
14831					return lights[light.id];
14832				}
14833
14834				let uniforms;
14835
14836				switch (light.type) {
14837					case 'DirectionalLight':
14838						uniforms = {
14839							direction: new Vector3(),
14840							color: new Color()
14841						};
14842						break;
14843
14844					case 'SpotLight':
14845						uniforms = {
14846							position: new Vector3(),
14847							direction: new Vector3(),
14848							color: new Color(),
14849							distance: 0,
14850							coneCos: 0,
14851							penumbraCos: 0,
14852							decay: 0
14853						};
14854						break;
14855
14856					case 'PointLight':
14857						uniforms = {
14858							position: new Vector3(),
14859							color: new Color(),
14860							distance: 0,
14861							decay: 0
14862						};
14863						break;
14864
14865					case 'HemisphereLight':
14866						uniforms = {
14867							direction: new Vector3(),
14868							skyColor: new Color(),
14869							groundColor: new Color()
14870						};
14871						break;
14872
14873					case 'RectAreaLight':
14874						uniforms = {
14875							color: new Color(),
14876							position: new Vector3(),
14877							halfWidth: new Vector3(),
14878							halfHeight: new Vector3()
14879						};
14880						break;
14881				}
14882
14883				lights[light.id] = uniforms;
14884				return uniforms;
14885			}
14886		};
14887	}
14888
14889	function ShadowUniformsCache() {
14890		const lights = {};
14891		return {
14892			get: function (light) {
14893				if (lights[light.id] !== undefined) {
14894					return lights[light.id];
14895				}
14896
14897				let uniforms;
14898
14899				switch (light.type) {
14900					case 'DirectionalLight':
14901						uniforms = {
14902							shadowBias: 0,
14903							shadowNormalBias: 0,
14904							shadowRadius: 1,
14905							shadowMapSize: new Vector2()
14906						};
14907						break;
14908
14909					case 'SpotLight':
14910						uniforms = {
14911							shadowBias: 0,
14912							shadowNormalBias: 0,
14913							shadowRadius: 1,
14914							shadowMapSize: new Vector2()
14915						};
14916						break;
14917
14918					case 'PointLight':
14919						uniforms = {
14920							shadowBias: 0,
14921							shadowNormalBias: 0,
14922							shadowRadius: 1,
14923							shadowMapSize: new Vector2(),
14924							shadowCameraNear: 1,
14925							shadowCameraFar: 1000
14926						};
14927						break;
14928					// TODO (abelnation): set RectAreaLight shadow uniforms
14929				}
14930
14931				lights[light.id] = uniforms;
14932				return uniforms;
14933			}
14934		};
14935	}
14936
14937	let nextVersion = 0;
14938
14939	function shadowCastingLightsFirst(lightA, lightB) {
14940		return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0);
14941	}
14942
14943	function WebGLLights(extensions, capabilities) {
14944		const cache = new UniformsCache();
14945		const shadowCache = ShadowUniformsCache();
14946		const state = {
14947			version: 0,
14948			hash: {
14949				directionalLength: -1,
14950				pointLength: -1,
14951				spotLength: -1,
14952				rectAreaLength: -1,
14953				hemiLength: -1,
14954				numDirectionalShadows: -1,
14955				numPointShadows: -1,
14956				numSpotShadows: -1
14957			},
14958			ambient: [0, 0, 0],
14959			probe: [],
14960			directional: [],
14961			directionalShadow: [],
14962			directionalShadowMap: [],
14963			directionalShadowMatrix: [],
14964			spot: [],
14965			spotShadow: [],
14966			spotShadowMap: [],
14967			spotShadowMatrix: [],
14968			rectArea: [],
14969			rectAreaLTC1: null,
14970			rectAreaLTC2: null,
14971			point: [],
14972			pointShadow: [],
14973			pointShadowMap: [],
14974			pointShadowMatrix: [],
14975			hemi: []
14976		};
14977
14978		for (let i = 0; i < 9; i++) state.probe.push(new Vector3());
14979
14980		const vector3 = new Vector3();
14981		const matrix4 = new Matrix4();
14982		const matrix42 = new Matrix4();
14983
14984		function setup(lights, physicallyCorrectLights) {
14985			let r = 0,
14986					g = 0,
14987					b = 0;
14988
14989			for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0);
14990
14991			let directionalLength = 0;
14992			let pointLength = 0;
14993			let spotLength = 0;
14994			let rectAreaLength = 0;
14995			let hemiLength = 0;
14996			let numDirectionalShadows = 0;
14997			let numPointShadows = 0;
14998			let numSpotShadows = 0;
14999			lights.sort(shadowCastingLightsFirst); // artist-friendly light intensity scaling factor
15000
15001			const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1;
15002
15003			for (let i = 0, l = lights.length; i < l; i++) {
15004				const light = lights[i];
15005				const color = light.color;
15006				const intensity = light.intensity;
15007				const distance = light.distance;
15008				const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null;
15009
15010				if (light.isAmbientLight) {
15011					r += color.r * intensity * scaleFactor;
15012					g += color.g * intensity * scaleFactor;
15013					b += color.b * intensity * scaleFactor;
15014				} else if (light.isLightProbe) {
15015					for (let j = 0; j < 9; j++) {
15016						state.probe[j].addScaledVector(light.sh.coefficients[j], intensity);
15017					}
15018				} else if (light.isDirectionalLight) {
15019					const uniforms = cache.get(light);
15020					uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor);
15021
15022					if (light.castShadow) {
15023						const shadow = light.shadow;
15024						const shadowUniforms = shadowCache.get(light);
15025						shadowUniforms.shadowBias = shadow.bias;
15026						shadowUniforms.shadowNormalBias = shadow.normalBias;
15027						shadowUniforms.shadowRadius = shadow.radius;
15028						shadowUniforms.shadowMapSize = shadow.mapSize;
15029						state.directionalShadow[directionalLength] = shadowUniforms;
15030						state.directionalShadowMap[directionalLength] = shadowMap;
15031						state.directionalShadowMatrix[directionalLength] = light.shadow.matrix;
15032						numDirectionalShadows++;
15033					}
15034
15035					state.directional[directionalLength] = uniforms;
15036					directionalLength++;
15037				} else if (light.isSpotLight) {
15038					const uniforms = cache.get(light);
15039					uniforms.position.setFromMatrixPosition(light.matrixWorld);
15040					uniforms.color.copy(color).multiplyScalar(intensity * scaleFactor);
15041					uniforms.distance = distance;
15042					uniforms.coneCos = Math.cos(light.angle);
15043					uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra));
15044					uniforms.decay = light.decay;
15045
15046					if (light.castShadow) {
15047						const shadow = light.shadow;
15048						const shadowUniforms = shadowCache.get(light);
15049						shadowUniforms.shadowBias = shadow.bias;
15050						shadowUniforms.shadowNormalBias = shadow.normalBias;
15051						shadowUniforms.shadowRadius = shadow.radius;
15052						shadowUniforms.shadowMapSize = shadow.mapSize;
15053						state.spotShadow[spotLength] = shadowUniforms;
15054						state.spotShadowMap[spotLength] = shadowMap;
15055						state.spotShadowMatrix[spotLength] = light.shadow.matrix;
15056						numSpotShadows++;
15057					}
15058
15059					state.spot[spotLength] = uniforms;
15060					spotLength++;
15061				} else if (light.isRectAreaLight) {
15062					const uniforms = cache.get(light); // (a) intensity is the total visible light emitted
15063					//uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) );
15064					// (b) intensity is the brightness of the light
15065
15066					uniforms.color.copy(color).multiplyScalar(intensity);
15067					uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0);
15068					uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0);
15069					state.rectArea[rectAreaLength] = uniforms;
15070					rectAreaLength++;
15071				} else if (light.isPointLight) {
15072					const uniforms = cache.get(light);
15073					uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor);
15074					uniforms.distance = light.distance;
15075					uniforms.decay = light.decay;
15076
15077					if (light.castShadow) {
15078						const shadow = light.shadow;
15079						const shadowUniforms = shadowCache.get(light);
15080						shadowUniforms.shadowBias = shadow.bias;
15081						shadowUniforms.shadowNormalBias = shadow.normalBias;
15082						shadowUniforms.shadowRadius = shadow.radius;
15083						shadowUniforms.shadowMapSize = shadow.mapSize;
15084						shadowUniforms.shadowCameraNear = shadow.camera.near;
15085						shadowUniforms.shadowCameraFar = shadow.camera.far;
15086						state.pointShadow[pointLength] = shadowUniforms;
15087						state.pointShadowMap[pointLength] = shadowMap;
15088						state.pointShadowMatrix[pointLength] = light.shadow.matrix;
15089						numPointShadows++;
15090					}
15091
15092					state.point[pointLength] = uniforms;
15093					pointLength++;
15094				} else if (light.isHemisphereLight) {
15095					const uniforms = cache.get(light);
15096					uniforms.skyColor.copy(light.color).multiplyScalar(intensity * scaleFactor);
15097					uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity * scaleFactor);
15098					state.hemi[hemiLength] = uniforms;
15099					hemiLength++;
15100				}
15101			}
15102
15103			if (rectAreaLength > 0) {
15104				if (capabilities.isWebGL2) {
15105					// WebGL 2
15106					state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
15107					state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
15108				} else {
15109					// WebGL 1
15110					if (extensions.has('OES_texture_float_linear') === true) {
15111						state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
15112						state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
15113					} else if (extensions.has('OES_texture_half_float_linear') === true) {
15114						state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
15115						state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
15116					} else {
15117						console.error('THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.');
15118					}
15119				}
15120			}
15121
15122			state.ambient[0] = r;
15123			state.ambient[1] = g;
15124			state.ambient[2] = b;
15125			const hash = state.hash;
15126
15127			if (hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows) {
15128				state.directional.length = directionalLength;
15129				state.spot.length = spotLength;
15130				state.rectArea.length = rectAreaLength;
15131				state.point.length = pointLength;
15132				state.hemi.length = hemiLength;
15133				state.directionalShadow.length = numDirectionalShadows;
15134				state.directionalShadowMap.length = numDirectionalShadows;
15135				state.pointShadow.length = numPointShadows;
15136				state.pointShadowMap.length = numPointShadows;
15137				state.spotShadow.length = numSpotShadows;
15138				state.spotShadowMap.length = numSpotShadows;
15139				state.directionalShadowMatrix.length = numDirectionalShadows;
15140				state.pointShadowMatrix.length = numPointShadows;
15141				state.spotShadowMatrix.length = numSpotShadows;
15142				hash.directionalLength = directionalLength;
15143				hash.pointLength = pointLength;
15144				hash.spotLength = spotLength;
15145				hash.rectAreaLength = rectAreaLength;
15146				hash.hemiLength = hemiLength;
15147				hash.numDirectionalShadows = numDirectionalShadows;
15148				hash.numPointShadows = numPointShadows;
15149				hash.numSpotShadows = numSpotShadows;
15150				state.version = nextVersion++;
15151			}
15152		}
15153
15154		function setupView(lights, camera) {
15155			let directionalLength = 0;
15156			let pointLength = 0;
15157			let spotLength = 0;
15158			let rectAreaLength = 0;
15159			let hemiLength = 0;
15160			const viewMatrix = camera.matrixWorldInverse;
15161
15162			for (let i = 0, l = lights.length; i < l; i++) {
15163				const light = lights[i];
15164
15165				if (light.isDirectionalLight) {
15166					const uniforms = state.directional[directionalLength];
15167					uniforms.direction.setFromMatrixPosition(light.matrixWorld);
15168					vector3.setFromMatrixPosition(light.target.matrixWorld);
15169					uniforms.direction.sub(vector3);
15170					uniforms.direction.transformDirection(viewMatrix);
15171					directionalLength++;
15172				} else if (light.isSpotLight) {
15173					const uniforms = state.spot[spotLength];
15174					uniforms.position.setFromMatrixPosition(light.matrixWorld);
15175					uniforms.position.applyMatrix4(viewMatrix);
15176					uniforms.direction.setFromMatrixPosition(light.matrixWorld);
15177					vector3.setFromMatrixPosition(light.target.matrixWorld);
15178					uniforms.direction.sub(vector3);
15179					uniforms.direction.transformDirection(viewMatrix);
15180					spotLength++;
15181				} else if (light.isRectAreaLight) {
15182					const uniforms = state.rectArea[rectAreaLength];
15183					uniforms.position.setFromMatrixPosition(light.matrixWorld);
15184					uniforms.position.applyMatrix4(viewMatrix); // extract local rotation of light to derive width/height half vectors
15185
15186					matrix42.identity();
15187					matrix4.copy(light.matrixWorld);
15188					matrix4.premultiply(viewMatrix);
15189					matrix42.extractRotation(matrix4);
15190					uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0);
vendor: 4,288 bytes, lines 15191-15370
15191					uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0);
15192					uniforms.halfWidth.applyMatrix4(matrix42);
15193					uniforms.halfHeight.applyMatrix4(matrix42);
15194					rectAreaLength++;
15195				} else if (light.isPointLight) {
15196					const uniforms = state.point[pointLength];
15197					uniforms.position.setFromMatrixPosition(light.matrixWorld);
15198					uniforms.position.applyMatrix4(viewMatrix);
15199					pointLength++;
15200				} else if (light.isHemisphereLight) {
15201					const uniforms = state.hemi[hemiLength];
15202					uniforms.direction.setFromMatrixPosition(light.matrixWorld);
15203					uniforms.direction.transformDirection(viewMatrix);
15204					uniforms.direction.normalize();
15205					hemiLength++;
15206				}
15207			}
15208		}
15209
15210		return {
15211			setup: setup,
15212			setupView: setupView,
15213			state: state
15214		};
15215	}
15216
15217	function WebGLRenderState(extensions, capabilities) {
15218		const lights = new WebGLLights(extensions, capabilities);
15219		const lightsArray = [];
15220		const shadowsArray = [];
15221
15222		function init() {
15223			lightsArray.length = 0;
15224			shadowsArray.length = 0;
15225		}
15226
15227		function pushLight(light) {
15228			lightsArray.push(light);
15229		}
15230
15231		function pushShadow(shadowLight) {
15232			shadowsArray.push(shadowLight);
15233		}
15234
15235		function setupLights(physicallyCorrectLights) {
15236			lights.setup(lightsArray, physicallyCorrectLights);
15237		}
15238
15239		function setupLightsView(camera) {
15240			lights.setupView(lightsArray, camera);
15241		}
15242
15243		const state = {
15244			lightsArray: lightsArray,
15245			shadowsArray: shadowsArray,
15246			lights: lights
15247		};
15248		return {
15249			init: init,
15250			state: state,
15251			setupLights: setupLights,
15252			setupLightsView: setupLightsView,
15253			pushLight: pushLight,
15254			pushShadow: pushShadow
15255		};
15256	}
15257
15258	function WebGLRenderStates(extensions, capabilities) {
15259		let renderStates = new WeakMap();
15260
15261		function get(scene, renderCallDepth = 0) {
15262			let renderState;
15263
15264			if (renderStates.has(scene) === false) {
15265				renderState = new WebGLRenderState(extensions, capabilities);
15266				renderStates.set(scene, [renderState]);
15267			} else {
15268				if (renderCallDepth >= renderStates.get(scene).length) {
15269					renderState = new WebGLRenderState(extensions, capabilities);
15270					renderStates.get(scene).push(renderState);
15271				} else {
15272					renderState = renderStates.get(scene)[renderCallDepth];
15273				}
15274			}
15275
15276			return renderState;
15277		}
15278
15279		function dispose() {
15280			renderStates = new WeakMap();
15281		}
15282
15283		return {
15284			get: get,
15285			dispose: dispose
15286		};
15287	}
15288
15289	/**
15290	 * parameters = {
15291	 *
15292	 *	opacity: <float>,
15293	 *
15294	 *	map: new THREE.Texture( <Image> ),
15295	 *
15296	 *	alphaMap: new THREE.Texture( <Image> ),
15297	 *
15298	 *	displacementMap: new THREE.Texture( <Image> ),
15299	 *	displacementScale: <float>,
15300	 *	displacementBias: <float>,
15301	 *
15302	 *	wireframe: <boolean>,
15303	 *	wireframeLinewidth: <float>
15304	 * }
15305	 */
15306
15307	class MeshDepthMaterial extends Material {
15308		constructor(parameters) {
15309			super();
15310			this.type = 'MeshDepthMaterial';
15311			this.depthPacking = BasicDepthPacking;
15312			this.map = null;
15313			this.alphaMap = null;
15314			this.displacementMap = null;
15315			this.displacementScale = 1;
15316			this.displacementBias = 0;
15317			this.wireframe = false;
15318			this.wireframeLinewidth = 1;
15319			this.fog = false;
15320			this.setValues(parameters);
15321		}
15322
15323		copy(source) {
15324			super.copy(source);
15325			this.depthPacking = source.depthPacking;
15326			this.map = source.map;
15327			this.alphaMap = source.alphaMap;
15328			this.displacementMap = source.displacementMap;
15329			this.displacementScale = source.displacementScale;
15330			this.displacementBias = source.displacementBias;
15331			this.wireframe = source.wireframe;
15332			this.wireframeLinewidth = source.wireframeLinewidth;
15333			return this;
15334		}
15335
15336	}
15337
15338	MeshDepthMaterial.prototype.isMeshDepthMaterial = true;
15339
15340	/**
15341	 * parameters = {
15342	 *
15343	 *	referencePosition: <float>,
15344	 *	nearDistance: <float>,
15345	 *	farDistance: <float>,
15346	 *
15347	 *	map: new THREE.Texture( <Image> ),
15348	 *
15349	 *	alphaMap: new THREE.Texture( <Image> ),
15350	 *
15351	 *	displacementMap: new THREE.Texture( <Image> ),
15352	 *	displacementScale: <float>,
15353	 *	displacementBias: <float>
15354	 *
15355	 * }
15356	 */
15357
15358	class MeshDistanceMaterial extends Material {
15359		constructor(parameters) {
15360			super();
15361			this.type = 'MeshDistanceMaterial';
15362			this.referencePosition = new Vector3();
15363			this.nearDistance = 1;
15364			this.farDistance = 1000;
15365			this.map = null;
15366			this.alphaMap = null;
15367			this.displacementMap = null;
15368			this.displacementScale = 1;
15369			this.displacementBias = 0;
15370			this.fog = false;
vendor: 4,751 bytes, lines 15371-15495
15371			this.setValues(parameters);
15372		}
15373
15374		copy(source) {
15375			super.copy(source);
15376			this.referencePosition.copy(source.referencePosition);
15377			this.nearDistance = source.nearDistance;
15378			this.farDistance = source.farDistance;
15379			this.map = source.map;
15380			this.alphaMap = source.alphaMap;
15381			this.displacementMap = source.displacementMap;
15382			this.displacementScale = source.displacementScale;
15383			this.displacementBias = source.displacementBias;
15384			return this;
15385		}
15386
15387	}
15388
15389	MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true;
15390
15391	const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}";
15392	const fragment = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
15393
15394	function WebGLShadowMap(_renderer, _objects, _capabilities) {
15395		let _frustum = new Frustum();
15396
15397		const _shadowMapSize = new Vector2(),
15398					_viewportSize = new Vector2(),
15399					_viewport = new Vector4(),
15400					_depthMaterial = new MeshDepthMaterial({
15401			depthPacking: RGBADepthPacking
15402		}),
15403					_distanceMaterial = new MeshDistanceMaterial(),
15404					_materialCache = {},
15405					_maxTextureSize = _capabilities.maxTextureSize;
15406
15407		const shadowSide = {
15408			0: BackSide,
15409			1: FrontSide,
15410			2: DoubleSide
15411		};
15412		const shadowMaterialVertical = new ShaderMaterial({
15413			defines: {
15414				VSM_SAMPLES: 8
15415			},
15416			uniforms: {
15417				shadow_pass: {
15418					value: null
15419				},
15420				resolution: {
15421					value: new Vector2()
15422				},
15423				radius: {
15424					value: 4.0
15425				}
15426			},
15427			vertexShader: vertex,
15428			fragmentShader: fragment
15429		});
15430		const shadowMaterialHorizontal = shadowMaterialVertical.clone();
15431		shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1;
15432		const fullScreenTri = new BufferGeometry();
15433		fullScreenTri.setAttribute('position', new BufferAttribute(new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 3));
15434		const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical);
15435		const scope = this;
15436		this.enabled = false;
15437		this.autoUpdate = true;
15438		this.needsUpdate = false;
15439		this.type = PCFShadowMap;
15440
15441		this.render = function (lights, scene, camera) {
15442			if (scope.enabled === false) return;
15443			if (scope.autoUpdate === false && scope.needsUpdate === false) return;
15444			if (lights.length === 0) return;
15445
15446			const currentRenderTarget = _renderer.getRenderTarget();
15447
15448			const activeCubeFace = _renderer.getActiveCubeFace();
15449
15450			const activeMipmapLevel = _renderer.getActiveMipmapLevel();
15451
15452			const _state = _renderer.state; // Set GL state for depth map.
15453
15454			_state.setBlending(NoBlending);
15455
15456			_state.buffers.color.setClear(1, 1, 1, 1);
15457
15458			_state.buffers.depth.setTest(true);
15459
15460			_state.setScissorTest(false); // render depth map
15461
15462
15463			for (let i = 0, il = lights.length; i < il; i++) {
15464				const light = lights[i];
15465				const shadow = light.shadow;
15466
15467				if (shadow === undefined) {
15468					console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.');
15469					continue;
15470				}
15471
15472				if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue;
15473
15474				_shadowMapSize.copy(shadow.mapSize);
15475
15476				const shadowFrameExtents = shadow.getFrameExtents();
15477
15478				_shadowMapSize.multiply(shadowFrameExtents);
15479
15480				_viewportSize.copy(shadow.mapSize);
15481
15482				if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) {
15483					if (_shadowMapSize.x > _maxTextureSize) {
15484						_viewportSize.x = Math.floor(_maxTextureSize / shadowFrameExtents.x);
15485						_shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
15486						shadow.mapSize.x = _viewportSize.x;
15487					}
15488
15489					if (_shadowMapSize.y > _maxTextureSize) {
15490						_viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y);
15491						_shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
15492						shadow.mapSize.y = _viewportSize.y;
15493					}
15494				}
15495
15496				if (shadow.map === null && !shadow.isPointLightShadow && this.type === VSMShadowMap) {
15497					const pars = {
15498						minFilter: LinearFilter,
15499						magFilter: LinearFilter,
15500						format: RGBAFormat
15501					};
15502					shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars);
15503					shadow.map.texture.name = light.name + '.shadowMap';
15504					shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars);
15505					shadow.camera.updateProjectionMatrix();
15506				}
15507
15508				if (shadow.map === null) {
15509					const pars = {
15510						minFilter: NearestFilter,
15511						magFilter: NearestFilter,
15512						format: RGBAFormat
15513					};
15514					shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars);
15515					shadow.map.texture.name = light.name + '.shadowMap';
15516					shadow.camera.updateProjectionMatrix();
15517				}
15518
15519				_renderer.setRenderTarget(shadow.map);
15520
15521				_renderer.clear();
15522
15523				const viewportCount = shadow.getViewportCount();
15524
15525				for (let vp = 0; vp < viewportCount; vp++) {
15526					const viewport = shadow.getViewport(vp);
15527
15528					_viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w);
15529
15530					_state.viewport(_viewport);
15531
15532					shadow.updateMatrices(light, vp);
15533					_frustum = shadow.getFrustum();
15534					renderObject(scene, camera, shadow.camera, light, this.type);
15535				} // do blur pass for VSM
15536
15537
15538				if (!shadow.isPointLightShadow && this.type === VSMShadowMap) {
15539					VSMPass(shadow, camera);
15540				}
15541
15542				shadow.needsUpdate = false;
15543			}
15544
15545			scope.needsUpdate = false;
15546
15547			_renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel);
15548		};
15549
15550		function VSMPass(shadow, camera) {
15551			const geometry = _objects.update(fullScreenMesh);
15552
15553			if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples) {
15554				shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples;
15555				shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples;
15556				shadowMaterialVertical.needsUpdate = true;
15557				shadowMaterialHorizontal.needsUpdate = true;
15558			} // vertical pass
15559
15560
15561			shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;
15562			shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
15563			shadowMaterialVertical.uniforms.radius.value = shadow.radius;
15564
15565			_renderer.setRenderTarget(shadow.mapPass);
15566
15567			_renderer.clear();
15568
15569			_renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizontal pass
15570
15571
15572			shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;
15573			shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;
15574			shadowMaterialHorizontal.uniforms.radius.value = shadow.radius;
15575
15576			_renderer.setRenderTarget(shadow.map);
15577
15578			_renderer.clear();
15579
15580			_renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null);
15581		}
15582
15583		function getDepthMaterial(object, geometry, material, light, shadowCameraNear, shadowCameraFar, type) {
15584			let result = null;
15585			const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial;
15586
15587			if (customMaterial !== undefined) {
15588				result = customMaterial;
15589			} else {
15590				result = light.isPointLight === true ? _distanceMaterial : _depthMaterial;
15591			}
15592
15593			if (_renderer.localClippingEnabled && material.clipShadows === true && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) {
15594				// in this case we need a unique material instance reflecting the
15595				// appropriate state
15596				const keyA = result.uuid,
15597							keyB = material.uuid;
15598				let materialsForVariant = _materialCache[keyA];
15599
15600				if (materialsForVariant === undefined) {
15601					materialsForVariant = {};
15602					_materialCache[keyA] = materialsForVariant;
15603				}
15604
15605				let cachedMaterial = materialsForVariant[keyB];
15606
15607				if (cachedMaterial === undefined) {
15608					cachedMaterial = result.clone();
15609					materialsForVariant[keyB] = cachedMaterial;
15610				}
15611
15612				result = cachedMaterial;
15613			}
15614
15615			result.visible = material.visible;
15616			result.wireframe = material.wireframe;
15617
15618			if (type === VSMShadowMap) {
15619				result.side = material.shadowSide !== null ? material.shadowSide : material.side;
15620			} else {
15621				result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side];
15622			}
15623
15624			result.alphaMap = material.alphaMap;
15625			result.alphaTest = material.alphaTest;
vendor: 9,779 bytes, lines 15626-15953
15626			result.clipShadows = material.clipShadows;
15627			result.clippingPlanes = material.clippingPlanes;
15628			result.clipIntersection = material.clipIntersection;
15629			result.displacementMap = material.displacementMap;
15630			result.displacementScale = material.displacementScale;
15631			result.displacementBias = material.displacementBias;
15632			result.wireframeLinewidth = material.wireframeLinewidth;
15633			result.linewidth = material.linewidth;
15634
15635			if (light.isPointLight === true && result.isMeshDistanceMaterial === true) {
15636				result.referencePosition.setFromMatrixPosition(light.matrixWorld);
15637				result.nearDistance = shadowCameraNear;
15638				result.farDistance = shadowCameraFar;
15639			}
15640
15641			return result;
15642		}
15643
15644		function renderObject(object, camera, shadowCamera, light, type) {
15645			if (object.visible === false) return;
15646			const visible = object.layers.test(camera.layers);
15647
15648			if (visible && (object.isMesh || object.isLine || object.isPoints)) {
15649				if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum.intersectsObject(object))) {
15650					object.modelViewMatrix.multiplyMatrices(shadowCamera.matrixWorldInverse, object.matrixWorld);
15651
15652					const geometry = _objects.update(object);
15653
15654					const material = object.material;
15655
15656					if (Array.isArray(material)) {
15657						const groups = geometry.groups;
15658
15659						for (let k = 0, kl = groups.length; k < kl; k++) {
15660							const group = groups[k];
15661							const groupMaterial = material[group.materialIndex];
15662
15663							if (groupMaterial && groupMaterial.visible) {
15664								const depthMaterial = getDepthMaterial(object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type);
15665
15666								_renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group);
15667							}
15668						}
15669					} else if (material.visible) {
15670						const depthMaterial = getDepthMaterial(object, geometry, material, light, shadowCamera.near, shadowCamera.far, type);
15671
15672						_renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null);
15673					}
15674				}
15675			}
15676
15677			const children = object.children;
15678
15679			for (let i = 0, l = children.length; i < l; i++) {
15680				renderObject(children[i], camera, shadowCamera, light, type);
15681			}
15682		}
15683	}
15684
15685	function WebGLState(gl, extensions, capabilities) {
15686		const isWebGL2 = capabilities.isWebGL2;
15687
15688		function ColorBuffer() {
15689			let locked = false;
15690			const color = new Vector4();
15691			let currentColorMask = null;
15692			const currentColorClear = new Vector4(0, 0, 0, 0);
15693			return {
15694				setMask: function (colorMask) {
15695					if (currentColorMask !== colorMask && !locked) {
15696						gl.colorMask(colorMask, colorMask, colorMask, colorMask);
15697						currentColorMask = colorMask;
15698					}
15699				},
15700				setLocked: function (lock) {
15701					locked = lock;
15702				},
15703				setClear: function (r, g, b, a, premultipliedAlpha) {
15704					if (premultipliedAlpha === true) {
15705						r *= a;
15706						g *= a;
15707						b *= a;
15708					}
15709
15710					color.set(r, g, b, a);
15711
15712					if (currentColorClear.equals(color) === false) {
15713						gl.clearColor(r, g, b, a);
15714						currentColorClear.copy(color);
15715					}
15716				},
15717				reset: function () {
15718					locked = false;
15719					currentColorMask = null;
15720					currentColorClear.set(-1, 0, 0, 0); // set to invalid state
15721				}
15722			};
15723		}
15724
15725		function DepthBuffer() {
15726			let locked = false;
15727			let currentDepthMask = null;
15728			let currentDepthFunc = null;
15729			let currentDepthClear = null;
15730			return {
15731				setTest: function (depthTest) {
15732					if (depthTest) {
15733						enable(gl.DEPTH_TEST);
15734					} else {
15735						disable(gl.DEPTH_TEST);
15736					}
15737				},
15738				setMask: function (depthMask) {
15739					if (currentDepthMask !== depthMask && !locked) {
15740						gl.depthMask(depthMask);
15741						currentDepthMask = depthMask;
15742					}
15743				},
15744				setFunc: function (depthFunc) {
15745					if (currentDepthFunc !== depthFunc) {
15746						if (depthFunc) {
15747							switch (depthFunc) {
15748								case NeverDepth:
15749									gl.depthFunc(gl.NEVER);
15750									break;
15751
15752								case AlwaysDepth:
15753									gl.depthFunc(gl.ALWAYS);
15754									break;
15755
15756								case LessDepth:
15757									gl.depthFunc(gl.LESS);
15758									break;
15759
15760								case LessEqualDepth:
15761									gl.depthFunc(gl.LEQUAL);
15762									break;
15763
15764								case EqualDepth:
15765									gl.depthFunc(gl.EQUAL);
15766									break;
15767
15768								case GreaterEqualDepth:
15769									gl.depthFunc(gl.GEQUAL);
15770									break;
15771
15772								case GreaterDepth:
15773									gl.depthFunc(gl.GREATER);
15774									break;
15775
15776								case NotEqualDepth:
15777									gl.depthFunc(gl.NOTEQUAL);
15778									break;
15779
15780								default:
15781									gl.depthFunc(gl.LEQUAL);
15782							}
15783						} else {
15784							gl.depthFunc(gl.LEQUAL);
15785						}
15786
15787						currentDepthFunc = depthFunc;
15788					}
15789				},
15790				setLocked: function (lock) {
15791					locked = lock;
15792				},
15793				setClear: function (depth) {
15794					if (currentDepthClear !== depth) {
15795						gl.clearDepth(depth);
15796						currentDepthClear = depth;
15797					}
15798				},
15799				reset: function () {
15800					locked = false;
15801					currentDepthMask = null;
15802					currentDepthFunc = null;
15803					currentDepthClear = null;
15804				}
15805			};
15806		}
15807
15808		function StencilBuffer() {
15809			let locked = false;
15810			let currentStencilMask = null;
15811			let currentStencilFunc = null;
15812			let currentStencilRef = null;
15813			let currentStencilFuncMask = null;
15814			let currentStencilFail = null;
15815			let currentStencilZFail = null;
15816			let currentStencilZPass = null;
15817			let currentStencilClear = null;
15818			return {
15819				setTest: function (stencilTest) {
15820					if (!locked) {
15821						if (stencilTest) {
15822							enable(gl.STENCIL_TEST);
15823						} else {
15824							disable(gl.STENCIL_TEST);
15825						}
15826					}
15827				},
15828				setMask: function (stencilMask) {
15829					if (currentStencilMask !== stencilMask && !locked) {
15830						gl.stencilMask(stencilMask);
15831						currentStencilMask = stencilMask;
15832					}
15833				},
15834				setFunc: function (stencilFunc, stencilRef, stencilMask) {
15835					if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) {
15836						gl.stencilFunc(stencilFunc, stencilRef, stencilMask);
15837						currentStencilFunc = stencilFunc;
15838						currentStencilRef = stencilRef;
15839						currentStencilFuncMask = stencilMask;
15840					}
15841				},
15842				setOp: function (stencilFail, stencilZFail, stencilZPass) {
15843					if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) {
15844						gl.stencilOp(stencilFail, stencilZFail, stencilZPass);
15845						currentStencilFail = stencilFail;
15846						currentStencilZFail = stencilZFail;
15847						currentStencilZPass = stencilZPass;
15848					}
15849				},
15850				setLocked: function (lock) {
15851					locked = lock;
15852				},
15853				setClear: function (stencil) {
15854					if (currentStencilClear !== stencil) {
15855						gl.clearStencil(stencil);
15856						currentStencilClear = stencil;
15857					}
15858				},
15859				reset: function () {
15860					locked = false;
15861					currentStencilMask = null;
15862					currentStencilFunc = null;
15863					currentStencilRef = null;
15864					currentStencilFuncMask = null;
15865					currentStencilFail = null;
15866					currentStencilZFail = null;
15867					currentStencilZPass = null;
15868					currentStencilClear = null;
15869				}
15870			};
15871		} //
15872
15873
15874		const colorBuffer = new ColorBuffer();
15875		const depthBuffer = new DepthBuffer();
15876		const stencilBuffer = new StencilBuffer();
15877		let enabledCapabilities = {};
15878		let currentBoundFramebuffers = {};
15879		let currentProgram = null;
15880		let currentBlendingEnabled = false;
15881		let currentBlending = null;
15882		let currentBlendEquation = null;
15883		let currentBlendSrc = null;
15884		let currentBlendDst = null;
15885		let currentBlendEquationAlpha = null;
15886		let currentBlendSrcAlpha = null;
15887		let currentBlendDstAlpha = null;
15888		let currentPremultipledAlpha = false;
15889		let currentFlipSided = null;
15890		let currentCullFace = null;
15891		let currentLineWidth = null;
15892		let currentPolygonOffsetFactor = null;
15893		let currentPolygonOffsetUnits = null;
15894		const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
15895		let lineWidthAvailable = false;
15896		let version = 0;
15897		const glVersion = gl.getParameter(gl.VERSION);
15898
15899		if (glVersion.indexOf('WebGL') !== -1) {
15900			version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]);
15901			lineWidthAvailable = version >= 1.0;
15902		} else if (glVersion.indexOf('OpenGL ES') !== -1) {
15903			version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]);
15904			lineWidthAvailable = version >= 2.0;
15905		}
15906
15907		let currentTextureSlot = null;
15908		let currentBoundTextures = {};
15909		const scissorParam = gl.getParameter(gl.SCISSOR_BOX);
15910		const viewportParam = gl.getParameter(gl.VIEWPORT);
15911		const currentScissor = new Vector4().fromArray(scissorParam);
15912		const currentViewport = new Vector4().fromArray(viewportParam);
15913
15914		function createTexture(type, target, count) {
15915			const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4.
15916
15917			const texture = gl.createTexture();
15918			gl.bindTexture(type, texture);
15919			gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
15920			gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
15921
15922			for (let i = 0; i < count; i++) {
15923				gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
15924			}
15925
15926			return texture;
15927		}
15928
15929		const emptyTextures = {};
15930		emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1);
15931		emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); // init
15932
15933		colorBuffer.setClear(0, 0, 0, 1);
15934		depthBuffer.setClear(1);
15935		stencilBuffer.setClear(0);
15936		enable(gl.DEPTH_TEST);
15937		depthBuffer.setFunc(LessEqualDepth);
15938		setFlipSided(false);
15939		setCullFace(CullFaceBack);
15940		enable(gl.CULL_FACE);
15941		setBlending(NoBlending); //
15942
15943		function enable(id) {
15944			if (enabledCapabilities[id] !== true) {
15945				gl.enable(id);
15946				enabledCapabilities[id] = true;
15947			}
15948		}
15949
15950		function disable(id) {
15951			if (enabledCapabilities[id] !== false) {
15952				gl.disable(id);
15953				enabledCapabilities[id] = false;
vendor: 11,726 bytes, lines 15954-16373
15954			}
15955		}
15956
15957		function bindFramebuffer(target, framebuffer) {
15958			if (currentBoundFramebuffers[target] !== framebuffer) {
15959				gl.bindFramebuffer(target, framebuffer);
15960				currentBoundFramebuffers[target] = framebuffer;
15961
15962				if (isWebGL2) {
15963					// gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER
15964					if (target === gl.DRAW_FRAMEBUFFER) {
15965						currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer;
15966					}
15967
15968					if (target === gl.FRAMEBUFFER) {
15969						currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer;
15970					}
15971				}
15972
15973				return true;
15974			}
15975
15976			return false;
15977		}
15978
15979		function useProgram(program) {
15980			if (currentProgram !== program) {
15981				gl.useProgram(program);
15982				currentProgram = program;
15983				return true;
15984			}
15985
15986			return false;
15987		}
15988
15989		const equationToGL = {
15990			[AddEquation]: gl.FUNC_ADD,
15991			[SubtractEquation]: gl.FUNC_SUBTRACT,
15992			[ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT
15993		};
15994
15995		if (isWebGL2) {
15996			equationToGL[MinEquation] = gl.MIN;
15997			equationToGL[MaxEquation] = gl.MAX;
15998		} else {
15999			const extension = extensions.get('EXT_blend_minmax');
16000
16001			if (extension !== null) {
16002				equationToGL[MinEquation] = extension.MIN_EXT;
16003				equationToGL[MaxEquation] = extension.MAX_EXT;
16004			}
16005		}
16006
16007		const factorToGL = {
16008			[ZeroFactor]: gl.ZERO,
16009			[OneFactor]: gl.ONE,
16010			[SrcColorFactor]: gl.SRC_COLOR,
16011			[SrcAlphaFactor]: gl.SRC_ALPHA,
16012			[SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE,
16013			[DstColorFactor]: gl.DST_COLOR,
16014			[DstAlphaFactor]: gl.DST_ALPHA,
16015			[OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR,
16016			[OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA,
16017			[OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR,
16018			[OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA
16019		};
16020
16021		function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) {
16022			if (blending === NoBlending) {
16023				if (currentBlendingEnabled === true) {
16024					disable(gl.BLEND);
16025					currentBlendingEnabled = false;
16026				}
16027
16028				return;
16029			}
16030
16031			if (currentBlendingEnabled === false) {
16032				enable(gl.BLEND);
16033				currentBlendingEnabled = true;
16034			}
16035
16036			if (blending !== CustomBlending) {
16037				if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) {
16038					if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) {
16039						gl.blendEquation(gl.FUNC_ADD);
16040						currentBlendEquation = AddEquation;
16041						currentBlendEquationAlpha = AddEquation;
16042					}
16043
16044					if (premultipliedAlpha) {
16045						switch (blending) {
16046							case NormalBlending:
16047								gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
16048								break;
16049
16050							case AdditiveBlending:
16051								gl.blendFunc(gl.ONE, gl.ONE);
16052								break;
16053
16054							case SubtractiveBlending:
16055								gl.blendFuncSeparate(gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA);
16056								break;
16057
16058							case MultiplyBlending:
16059								gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA);
16060								break;
16061
16062							default:
16063								console.error('THREE.WebGLState: Invalid blending: ', blending);
16064								break;
16065						}
16066					} else {
16067						switch (blending) {
16068							case NormalBlending:
16069								gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
16070								break;
16071
16072							case AdditiveBlending:
16073								gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
16074								break;
16075
16076							case SubtractiveBlending:
16077								gl.blendFunc(gl.ZERO, gl.ONE_MINUS_SRC_COLOR);
16078								break;
16079
16080							case MultiplyBlending:
16081								gl.blendFunc(gl.ZERO, gl.SRC_COLOR);
16082								break;
16083
16084							default:
16085								console.error('THREE.WebGLState: Invalid blending: ', blending);
16086								break;
16087						}
16088					}
16089
16090					currentBlendSrc = null;
16091					currentBlendDst = null;
16092					currentBlendSrcAlpha = null;
16093					currentBlendDstAlpha = null;
16094					currentBlending = blending;
16095					currentPremultipledAlpha = premultipliedAlpha;
16096				}
16097
16098				return;
16099			} // custom blending
16100
16101
16102			blendEquationAlpha = blendEquationAlpha || blendEquation;
16103			blendSrcAlpha = blendSrcAlpha || blendSrc;
16104			blendDstAlpha = blendDstAlpha || blendDst;
16105
16106			if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) {
16107				gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]);
16108				currentBlendEquation = blendEquation;
16109				currentBlendEquationAlpha = blendEquationAlpha;
16110			}
16111
16112			if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) {
16113				gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]);
16114				currentBlendSrc = blendSrc;
16115				currentBlendDst = blendDst;
16116				currentBlendSrcAlpha = blendSrcAlpha;
16117				currentBlendDstAlpha = blendDstAlpha;
16118			}
16119
16120			currentBlending = blending;
16121			currentPremultipledAlpha = null;
16122		}
16123
16124		function setMaterial(material, frontFaceCW) {
16125			material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE);
16126			let flipSided = material.side === BackSide;
16127			if (frontFaceCW) flipSided = !flipSided;
16128			setFlipSided(flipSided);
16129			material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha);
16130			depthBuffer.setFunc(material.depthFunc);
16131			depthBuffer.setTest(material.depthTest);
16132			depthBuffer.setMask(material.depthWrite);
16133			colorBuffer.setMask(material.colorWrite);
16134			const stencilWrite = material.stencilWrite;
16135			stencilBuffer.setTest(stencilWrite);
16136
16137			if (stencilWrite) {
16138				stencilBuffer.setMask(material.stencilWriteMask);
16139				stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask);
16140				stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass);
16141			}
16142
16143			setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits);
16144			material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
16145		} //
16146
16147
16148		function setFlipSided(flipSided) {
16149			if (currentFlipSided !== flipSided) {
16150				if (flipSided) {
16151					gl.frontFace(gl.CW);
16152				} else {
16153					gl.frontFace(gl.CCW);
16154				}
16155
16156				currentFlipSided = flipSided;
16157			}
16158		}
16159
16160		function setCullFace(cullFace) {
16161			if (cullFace !== CullFaceNone) {
16162				enable(gl.CULL_FACE);
16163
16164				if (cullFace !== currentCullFace) {
16165					if (cullFace === CullFaceBack) {
16166						gl.cullFace(gl.BACK);
16167					} else if (cullFace === CullFaceFront) {
16168						gl.cullFace(gl.FRONT);
16169					} else {
16170						gl.cullFace(gl.FRONT_AND_BACK);
16171					}
16172				}
16173			} else {
16174				disable(gl.CULL_FACE);
16175			}
16176
16177			currentCullFace = cullFace;
16178		}
16179
16180		function setLineWidth(width) {
16181			if (width !== currentLineWidth) {
16182				if (lineWidthAvailable) gl.lineWidth(width);
16183				currentLineWidth = width;
16184			}
16185		}
16186
16187		function setPolygonOffset(polygonOffset, factor, units) {
16188			if (polygonOffset) {
16189				enable(gl.POLYGON_OFFSET_FILL);
16190
16191				if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) {
16192					gl.polygonOffset(factor, units);
16193					currentPolygonOffsetFactor = factor;
16194					currentPolygonOffsetUnits = units;
16195				}
16196			} else {
16197				disable(gl.POLYGON_OFFSET_FILL);
16198			}
16199		}
16200
16201		function setScissorTest(scissorTest) {
16202			if (scissorTest) {
16203				enable(gl.SCISSOR_TEST);
16204			} else {
16205				disable(gl.SCISSOR_TEST);
16206			}
16207		} // texture
16208
16209
16210		function activeTexture(webglSlot) {
16211			if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1;
16212
16213			if (currentTextureSlot !== webglSlot) {
16214				gl.activeTexture(webglSlot);
16215				currentTextureSlot = webglSlot;
16216			}
16217		}
16218
16219		function bindTexture(webglType, webglTexture) {
16220			if (currentTextureSlot === null) {
16221				activeTexture();
16222			}
16223
16224			let boundTexture = currentBoundTextures[currentTextureSlot];
16225
16226			if (boundTexture === undefined) {
16227				boundTexture = {
16228					type: undefined,
16229					texture: undefined
16230				};
16231				currentBoundTextures[currentTextureSlot] = boundTexture;
16232			}
16233
16234			if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) {
16235				gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]);
16236				boundTexture.type = webglType;
16237				boundTexture.texture = webglTexture;
16238			}
16239		}
16240
16241		function unbindTexture() {
16242			const boundTexture = currentBoundTextures[currentTextureSlot];
16243
16244			if (boundTexture !== undefined && boundTexture.type !== undefined) {
16245				gl.bindTexture(boundTexture.type, null);
16246				boundTexture.type = undefined;
16247				boundTexture.texture = undefined;
16248			}
16249		}
16250
16251		function compressedTexImage2D() {
16252			try {
16253				gl.compressedTexImage2D.apply(gl, arguments);
16254			} catch (error) {
16255				console.error('THREE.WebGLState:', error);
16256			}
16257		}
16258
16259		function texSubImage2D() {
16260			try {
16261				gl.texSubImage2D.apply(gl, arguments);
16262			} catch (error) {
16263				console.error('THREE.WebGLState:', error);
16264			}
16265		}
16266
16267		function texSubImage3D() {
16268			try {
16269				gl.texSubImage3D.apply(gl, arguments);
16270			} catch (error) {
16271				console.error('THREE.WebGLState:', error);
16272			}
16273		}
16274
16275		function compressedTexSubImage2D() {
16276			try {
16277				gl.compressedTexSubImage2D.apply(gl, arguments);
16278			} catch (error) {
16279				console.error('THREE.WebGLState:', error);
16280			}
16281		}
16282
16283		function texStorage2D() {
16284			try {
16285				gl.texStorage2D.apply(gl, arguments);
16286			} catch (error) {
16287				console.error('THREE.WebGLState:', error);
16288			}
16289		}
16290
16291		function texStorage3D() {
16292			try {
16293				gl.texStorage3D.apply(gl, arguments);
16294			} catch (error) {
16295				console.error('THREE.WebGLState:', error);
16296			}
16297		}
16298
16299		function texImage2D() {
16300			try {
16301				gl.texImage2D.apply(gl, arguments);
16302			} catch (error) {
16303				console.error('THREE.WebGLState:', error);
16304			}
16305		}
16306
16307		function texImage3D() {
16308			try {
16309				gl.texImage3D.apply(gl, arguments);
16310			} catch (error) {
16311				console.error('THREE.WebGLState:', error);
16312			}
16313		} //
16314
16315
16316		function scissor(scissor) {
16317			if (currentScissor.equals(scissor) === false) {
16318				gl.scissor(scissor.x, scissor.y, scissor.z, scissor.w);
16319				currentScissor.copy(scissor);
16320			}
16321		}
16322
16323		function viewport(viewport) {
16324			if (currentViewport.equals(viewport) === false) {
16325				gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w);
16326				currentViewport.copy(viewport);
16327			}
16328		} //
16329
16330
16331		function reset() {
16332			// reset state
16333			gl.disable(gl.BLEND);
16334			gl.disable(gl.CULL_FACE);
16335			gl.disable(gl.DEPTH_TEST);
16336			gl.disable(gl.POLYGON_OFFSET_FILL);
16337			gl.disable(gl.SCISSOR_TEST);
16338			gl.disable(gl.STENCIL_TEST);
16339			gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
16340			gl.blendEquation(gl.FUNC_ADD);
16341			gl.blendFunc(gl.ONE, gl.ZERO);
16342			gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO);
16343			gl.colorMask(true, true, true, true);
16344			gl.clearColor(0, 0, 0, 0);
16345			gl.depthMask(true);
16346			gl.depthFunc(gl.LESS);
16347			gl.clearDepth(1);
16348			gl.stencilMask(0xffffffff);
16349			gl.stencilFunc(gl.ALWAYS, 0, 0xffffffff);
16350			gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
16351			gl.clearStencil(0);
16352			gl.cullFace(gl.BACK);
16353			gl.frontFace(gl.CCW);
16354			gl.polygonOffset(0, 0);
16355			gl.activeTexture(gl.TEXTURE0);
16356			gl.bindFramebuffer(gl.FRAMEBUFFER, null);
16357
16358			if (isWebGL2 === true) {
16359				gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
16360				gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
16361			}
16362
16363			gl.useProgram(null);
16364			gl.lineWidth(1);
16365			gl.scissor(0, 0, gl.canvas.width, gl.canvas.height);
16366			gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); // reset internals
16367
16368			enabledCapabilities = {};
16369			currentTextureSlot = null;
16370			currentBoundTextures = {};
16371			currentBoundFramebuffers = {};
16372			currentProgram = null;
16373			currentBlendingEnabled = false;
vendor: 4,534 bytes, lines 16374-16496
16374			currentBlending = null;
16375			currentBlendEquation = null;
16376			currentBlendSrc = null;
16377			currentBlendDst = null;
16378			currentBlendEquationAlpha = null;
16379			currentBlendSrcAlpha = null;
16380			currentBlendDstAlpha = null;
16381			currentPremultipledAlpha = false;
16382			currentFlipSided = null;
16383			currentCullFace = null;
16384			currentLineWidth = null;
16385			currentPolygonOffsetFactor = null;
16386			currentPolygonOffsetUnits = null;
16387			currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height);
16388			currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height);
16389			colorBuffer.reset();
16390			depthBuffer.reset();
16391			stencilBuffer.reset();
16392		}
16393
16394		return {
16395			buffers: {
16396				color: colorBuffer,
16397				depth: depthBuffer,
16398				stencil: stencilBuffer
16399			},
16400			enable: enable,
16401			disable: disable,
16402			bindFramebuffer: bindFramebuffer,
16403			useProgram: useProgram,
16404			setBlending: setBlending,
16405			setMaterial: setMaterial,
16406			setFlipSided: setFlipSided,
16407			setCullFace: setCullFace,
16408			setLineWidth: setLineWidth,
16409			setPolygonOffset: setPolygonOffset,
16410			setScissorTest: setScissorTest,
16411			activeTexture: activeTexture,
16412			bindTexture: bindTexture,
16413			unbindTexture: unbindTexture,
16414			compressedTexImage2D: compressedTexImage2D,
16415			texImage2D: texImage2D,
16416			texImage3D: texImage3D,
16417			texStorage2D: texStorage2D,
16418			texStorage3D: texStorage3D,
16419			texSubImage2D: texSubImage2D,
16420			texSubImage3D: texSubImage3D,
16421			compressedTexSubImage2D: compressedTexSubImage2D,
16422			scissor: scissor,
16423			viewport: viewport,
16424			reset: reset
16425		};
16426	}
16427
16428	function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) {
16429		const isWebGL2 = capabilities.isWebGL2;
16430		const maxTextures = capabilities.maxTextures;
16431		const maxCubemapSize = capabilities.maxCubemapSize;
16432		const maxTextureSize = capabilities.maxTextureSize;
16433		const maxSamples = capabilities.maxSamples;
16434		const hasMultisampledRenderToTexture = extensions.has('WEBGL_multisampled_render_to_texture');
16435		const MultisampledRenderToTextureExtension = hasMultisampledRenderToTexture ? extensions.get('WEBGL_multisampled_render_to_texture') : undefined;
16436
16437		const _videoTextures = new WeakMap();
16438
16439		let _canvas; // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
16440		// also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
16441		// Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
16442
16443
16444		let useOffscreenCanvas = false;
16445
16446		try {
16447			useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' && new OffscreenCanvas(1, 1).getContext('2d') !== null;
16448		} catch (err) {// Ignore any errors
16449		}
16450
16451		function createCanvas(width, height) {
16452			// Use OffscreenCanvas when available. Specially needed in web workers
16453			return useOffscreenCanvas ? new OffscreenCanvas(width, height) : createElementNS('canvas');
16454		}
16455
16456		function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) {
16457			let scale = 1; // handle case if texture exceeds max size
16458
16459			if (image.width > maxSize || image.height > maxSize) {
16460				scale = maxSize / Math.max(image.width, image.height);
16461			} // only perform resize if necessary
16462
16463
16464			if (scale < 1 || needsPowerOfTwo === true) {
16465				// only perform resize for certain image types
16466				if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
16467					const floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor;
16468					const width = floor(scale * image.width);
16469					const height = floor(scale * image.height);
16470					if (_canvas === undefined) _canvas = createCanvas(width, height); // cube textures can't reuse the same canvas
16471
16472					const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas;
16473					canvas.width = width;
16474					canvas.height = height;
16475					const context = canvas.getContext('2d');
16476					context.drawImage(image, 0, 0, width, height);
16477					console.warn('THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').');
16478					return canvas;
16479				} else {
16480					if ('data' in image) {
16481						console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').');
16482					}
16483
16484					return image;
16485				}
16486			}
16487
16488			return image;
16489		}
16490
16491		function isPowerOfTwo$1(image) {
16492			return isPowerOfTwo(image.width) && isPowerOfTwo(image.height);
16493		}
16494
16495		function textureNeedsPowerOfTwo(texture) {
16496			if (isWebGL2) return false;
16497			return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
16498		}
16499
16500		function textureNeedsGenerateMipmaps(texture, supportsMips) {
16501			return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
16502		}
16503
16504		function generateMipmap(target) {
16505			_gl.generateMipmap(target);
16506		}
16507
16508		function getInternalFormat(internalFormatName, glFormat, glType, encoding) {
16509			if (isWebGL2 === false) return glFormat;
16510
16511			if (internalFormatName !== null) {
16512				if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName];
16513				console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'');
16514			}
16515
16516			let internalFormat = glFormat;
16517
16518			if (glFormat === _gl.RED) {
16519				if (glType === _gl.FLOAT) internalFormat = _gl.R32F;
16520				if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F;
16521				if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8;
16522			}
16523
16524			if (glFormat === _gl.RGB) {
16525				if (glType === _gl.FLOAT) internalFormat = _gl.RGB32F;
16526				if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGB16F;
16527				if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGB8;
16528			}
16529
16530			if (glFormat === _gl.RGBA) {
16531				if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F;
16532				if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F;
16533				if (glType === _gl.UNSIGNED_BYTE) internalFormat = encoding === sRGBEncoding ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
16534			}
16535
16536			if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) {
16537				extensions.get('EXT_color_buffer_float');
16538			}
16539
16540			return internalFormat;
16541		}
16542
16543		function getMipLevels(texture, image, supportsMips) {
16544			if (textureNeedsGenerateMipmaps(texture, supportsMips) === true || texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) {
16545				return Math.log2(Math.max(image.width, image.height)) + 1;
16546			} else if (texture.mipmaps !== undefined && texture.mipmaps.length > 0) {
16547				// user-defined mipmaps
16548				return texture.mipmaps.length;
16549			} else if (texture.isCompressedTexture && Array.isArray(texture.image)) {
16550				return image.mipmaps.length;
16551			} else {
16552				// texture without mipmaps (only base level)
16553				return 1;
16554			}
16555		} // Fallback filters for non-power-of-2 textures
16556
16557
16558		function filterFallback(f) {
16559			if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) {
16560				return _gl.NEAREST;
16561			}
16562
16563			return _gl.LINEAR;
16564		} //
16565
16566
16567		function onTextureDispose(event) {
16568			const texture = event.target;
16569			texture.removeEventListener('dispose', onTextureDispose);
16570			deallocateTexture(texture);
16571
16572			if (texture.isVideoTexture) {
16573				_videoTextures.delete(texture);
16574			}
16575
16576			info.memory.textures--;
16577		}
16578
16579		function onRenderTargetDispose(event) {
16580			const renderTarget = event.target;
16581			renderTarget.removeEventListener('dispose', onRenderTargetDispose);
16582			deallocateRenderTarget(renderTarget);
16583		} //
16584
16585
16586		function deallocateTexture(texture) {
16587			const textureProperties = properties.get(texture);
16588			if (textureProperties.__webglInit === undefined) return;
16589
16590			_gl.deleteTexture(textureProperties.__webglTexture);
16591
16592			properties.remove(texture);
16593		}
16594
16595		function deallocateRenderTarget(renderTarget) {
16596			const texture = renderTarget.texture;
16597			const renderTargetProperties = properties.get(renderTarget);
16598			const textureProperties = properties.get(texture);
16599			if (!renderTarget) return;
16600
16601			if (textureProperties.__webglTexture !== undefined) {
16602				_gl.deleteTexture(textureProperties.__webglTexture);
16603
16604				info.memory.textures--;
16605			}
16606
16607			if (renderTarget.depthTexture) {
16608				renderTarget.depthTexture.dispose();
16609			}
16610
16611			if (renderTarget.isWebGLCubeRenderTarget) {
16612				for (let i = 0; i < 6; i++) {
16613					_gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]);
16614
16615					if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]);
16616				}
16617			} else {
16618				_gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer);
16619
16620				if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer);
16621				if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer);
vendor: 10,835 bytes, lines 16622-16892
16622				if (renderTargetProperties.__webglColorRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer);
16623				if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer);
16624			}
16625
16626			if (renderTarget.isWebGLMultipleRenderTargets) {
16627				for (let i = 0, il = texture.length; i < il; i++) {
16628					const attachmentProperties = properties.get(texture[i]);
16629
16630					if (attachmentProperties.__webglTexture) {
16631						_gl.deleteTexture(attachmentProperties.__webglTexture);
16632
16633						info.memory.textures--;
16634					}
16635
16636					properties.remove(texture[i]);
16637				}
16638			}
16639
16640			properties.remove(texture);
16641			properties.remove(renderTarget);
16642		} //
16643
16644
16645		let textureUnits = 0;
16646
16647		function resetTextureUnits() {
16648			textureUnits = 0;
16649		}
16650
16651		function allocateTextureUnit() {
16652			const textureUnit = textureUnits;
16653
16654			if (textureUnit >= maxTextures) {
16655				console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures);
16656			}
16657
16658			textureUnits += 1;
16659			return textureUnit;
16660		} //
16661
16662
16663		function setTexture2D(texture, slot) {
16664			const textureProperties = properties.get(texture);
16665			if (texture.isVideoTexture) updateVideoTexture(texture);
16666
16667			if (texture.version > 0 && textureProperties.__version !== texture.version) {
16668				const image = texture.image;
16669
16670				if (image === undefined) {
16671					console.warn('THREE.WebGLRenderer: Texture marked for update but image is undefined');
16672				} else if (image.complete === false) {
16673					console.warn('THREE.WebGLRenderer: Texture marked for update but image is incomplete');
16674				} else {
16675					uploadTexture(textureProperties, texture, slot);
16676					return;
16677				}
16678			}
16679
16680			state.activeTexture(_gl.TEXTURE0 + slot);
16681			state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture);
16682		}
16683
16684		function setTexture2DArray(texture, slot) {
16685			const textureProperties = properties.get(texture);
16686
16687			if (texture.version > 0 && textureProperties.__version !== texture.version) {
16688				uploadTexture(textureProperties, texture, slot);
16689				return;
16690			}
16691
16692			state.activeTexture(_gl.TEXTURE0 + slot);
16693			state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture);
16694		}
16695
16696		function setTexture3D(texture, slot) {
16697			const textureProperties = properties.get(texture);
16698
16699			if (texture.version > 0 && textureProperties.__version !== texture.version) {
16700				uploadTexture(textureProperties, texture, slot);
16701				return;
16702			}
16703
16704			state.activeTexture(_gl.TEXTURE0 + slot);
16705			state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture);
16706		}
16707
16708		function setTextureCube(texture, slot) {
16709			const textureProperties = properties.get(texture);
16710
16711			if (texture.version > 0 && textureProperties.__version !== texture.version) {
16712				uploadCubeTexture(textureProperties, texture, slot);
16713				return;
16714			}
16715
16716			state.activeTexture(_gl.TEXTURE0 + slot);
16717			state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture);
16718		}
16719
16720		const wrappingToGL = {
16721			[RepeatWrapping]: _gl.REPEAT,
16722			[ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE,
16723			[MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT
16724		};
16725		const filterToGL = {
16726			[NearestFilter]: _gl.NEAREST,
16727			[NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST,
16728			[NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR,
16729			[LinearFilter]: _gl.LINEAR,
16730			[LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST,
16731			[LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR
16732		};
16733
16734		function setTextureParameters(textureType, texture, supportsMips) {
16735			if (supportsMips) {
16736				_gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]);
16737
16738				_gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]);
16739
16740				if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) {
16741					_gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]);
16742				}
16743
16744				_gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]);
16745
16746				_gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[texture.minFilter]);
16747			} else {
16748				_gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE);
16749
16750				_gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE);
16751
16752				if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) {
16753					_gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE);
16754				}
16755
16756				if (texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping) {
16757					console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.');
16758				}
16759
16760				_gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterFallback(texture.magFilter));
16761
16762				_gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterFallback(texture.minFilter));
16763
16764				if (texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) {
16765					console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.');
16766				}
16767			}
16768
16769			if (extensions.has('EXT_texture_filter_anisotropic') === true) {
16770				const extension = extensions.get('EXT_texture_filter_anisotropic');
16771				if (texture.type === FloatType && extensions.has('OES_texture_float_linear') === false) return; // verify extension for WebGL 1 and WebGL 2
16772
16773				if (isWebGL2 === false && texture.type === HalfFloatType && extensions.has('OES_texture_half_float_linear') === false) return; // verify extension for WebGL 1 only
16774
16775				if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) {
16776					_gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy()));
16777
16778					properties.get(texture).__currentAnisotropy = texture.anisotropy;
16779				}
16780			}
16781		}
16782
16783		function initTexture(textureProperties, texture) {
16784			if (textureProperties.__webglInit === undefined) {
16785				textureProperties.__webglInit = true;
16786				texture.addEventListener('dispose', onTextureDispose);
16787				textureProperties.__webglTexture = _gl.createTexture();
16788				info.memory.textures++;
16789			}
16790		}
16791
16792		function uploadTexture(textureProperties, texture, slot) {
16793			let textureType = _gl.TEXTURE_2D;
16794			if (texture.isDataTexture2DArray) textureType = _gl.TEXTURE_2D_ARRAY;
16795			if (texture.isDataTexture3D) textureType = _gl.TEXTURE_3D;
16796			initTexture(textureProperties, texture);
16797			state.activeTexture(_gl.TEXTURE0 + slot);
16798			state.bindTexture(textureType, textureProperties.__webglTexture);
16799
16800			_gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
16801
16802			_gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
16803
16804			_gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
16805
16806			_gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE);
16807
16808			const needsPowerOfTwo = textureNeedsPowerOfTwo(texture) && isPowerOfTwo$1(texture.image) === false;
16809			const image = resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize);
16810			const supportsMips = isPowerOfTwo$1(image) || isWebGL2,
16811						glFormat = utils.convert(texture.format);
16812			let glType = utils.convert(texture.type),
16813					glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
16814			setTextureParameters(textureType, texture, supportsMips);
16815			let mipmap;
16816			const mipmaps = texture.mipmaps;
16817			const useTexStorage = isWebGL2 && texture.isVideoTexture !== true;
16818			const allocateMemory = textureProperties.__version === undefined;
16819			const levels = getMipLevels(texture, image, supportsMips);
16820
16821			if (texture.isDepthTexture) {
16822				// populate depth texture with dummy data
16823				glInternalFormat = _gl.DEPTH_COMPONENT;
16824
16825				if (isWebGL2) {
16826					if (texture.type === FloatType) {
16827						glInternalFormat = _gl.DEPTH_COMPONENT32F;
16828					} else if (texture.type === UnsignedIntType) {
16829						glInternalFormat = _gl.DEPTH_COMPONENT24;
16830					} else if (texture.type === UnsignedInt248Type) {
16831						glInternalFormat = _gl.DEPTH24_STENCIL8;
16832					} else {
16833						glInternalFormat = _gl.DEPTH_COMPONENT16; // WebGL2 requires sized internalformat for glTexImage2D
16834					}
16835				} else {
16836					if (texture.type === FloatType) {
16837						console.error('WebGLRenderer: Floating point depth texture requires WebGL2.');
16838					}
16839				} // validation checks for WebGL 1
16840
16841
16842				if (texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT) {
16843					// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
16844					// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
16845					// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
16846					if (texture.type !== UnsignedShortType && texture.type !== UnsignedIntType) {
16847						console.warn('THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.');
16848						texture.type = UnsignedShortType;
16849						glType = utils.convert(texture.type);
16850					}
16851				}
16852
16853				if (texture.format === DepthStencilFormat && glInternalFormat === _gl.DEPTH_COMPONENT) {
16854					// Depth stencil textures need the DEPTH_STENCIL internal format
16855					// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
16856					glInternalFormat = _gl.DEPTH_STENCIL; // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
16857					// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
16858					// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
16859
16860					if (texture.type !== UnsignedInt248Type) {
16861						console.warn('THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.');
16862						texture.type = UnsignedInt248Type;
16863						glType = utils.convert(texture.type);
16864					}
16865				} //
16866
16867
16868				if (useTexStorage && allocateMemory) {
16869					state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height);
16870				} else {
16871					state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null);
16872				}
16873			} else if (texture.isDataTexture) {
16874				// use manually created mipmaps if available
16875				// if there are no manual mipmaps
16876				// set 0 level mipmap and then use GL to generate other mipmap levels
16877				if (mipmaps.length > 0 && supportsMips) {
16878					if (useTexStorage && allocateMemory) {
16879						state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
16880					}
16881
16882					for (let i = 0, il = mipmaps.length; i < il; i++) {
16883						mipmap = mipmaps[i];
16884
16885						if (useTexStorage) {
16886							state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
16887						} else {
16888							state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
16889						}
16890					}
16891
16892					texture.generateMipmaps = false;
16893				} else {
16894					if (useTexStorage) {
16895						if (allocateMemory) {
16896							state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
16897						}
16898
16899						state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data);
16900					} else {
16901						state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data);
16902					}
16903				}
16904			} else if (texture.isCompressedTexture) {
16905				if (useTexStorage && allocateMemory) {
16906					state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
16907				}
16908
16909				for (let i = 0, il = mipmaps.length; i < il; i++) {
16910					mipmap = mipmaps[i];
16911
16912					if (texture.format !== RGBAFormat && texture.format !== RGBFormat) {
16913						if (glFormat !== null) {
16914							if (useTexStorage) {
16915								state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);
16916							} else {
16917								state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data);
16918							}
16919						} else {
16920							console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()');
16921						}
16922					} else {
16923						if (useTexStorage) {
16924							state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
16925						} else {
16926							state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
16927						}
16928					}
16929				}
16930			} else if (texture.isDataTexture2DArray) {
16931				if (useTexStorage) {
16932					if (allocateMemory) {
16933						state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth);
16934					}
16935
16936					state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data);
16937				} else {
16938					state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data);
16939				}
16940			} else if (texture.isDataTexture3D) {
16941				if (useTexStorage) {
16942					if (allocateMemory) {
16943						state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth);
16944					}
16945
16946					state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data);
16947				} else {
16948					state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data);
16949				}
16950			} else if (texture.isFramebufferTexture) {
16951				if (useTexStorage && allocateMemory) {
16952					state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
16953				} else {
16954					state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null);
16955				}
16956			} else {
16957				// regular Texture (image, video, canvas)
16958				// use manually created mipmaps if available
16959				// if there are no manual mipmaps
16960				// set 0 level mipmap and then use GL to generate other mipmap levels
16961				if (mipmaps.length > 0 && supportsMips) {
16962					if (useTexStorage && allocateMemory) {
16963						state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
16964					}
16965
16966					for (let i = 0, il = mipmaps.length; i < il; i++) {
16967						mipmap = mipmaps[i];
16968
16969						if (useTexStorage) {
16970							state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap);
16971						} else {
16972							state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap);
16973						}
16974					}
16975
16976					texture.generateMipmaps = false;
16977				} else {
16978					if (useTexStorage) {
16979						if (allocateMemory) {
16980							state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
16981						}
16982
16983						state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image);
16984					} else {
16985						state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image);
16986					}
16987				}
16988			}
16989
16990			if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
16991				generateMipmap(textureType);
16992			}
16993
16994			textureProperties.__version = texture.version;
16995			if (texture.onUpdate) texture.onUpdate(texture);
16996		}
16997
16998		function uploadCubeTexture(textureProperties, texture, slot) {
16999			if (texture.image.length !== 6) return;
17000			initTexture(textureProperties, texture);
17001			state.activeTexture(_gl.TEXTURE0 + slot);
17002			state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture);
17003
17004			_gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
17005
17006			_gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
17007
17008			_gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
17009
17010			_gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE);
17011
17012			const isCompressed = texture && (texture.isCompressedTexture || texture.image[0].isCompressedTexture);
17013			const isDataTexture = texture.image[0] && texture.image[0].isDataTexture;
17014			const cubeImage = [];
17015
17016			for (let i = 0; i < 6; i++) {
17017				if (!isCompressed && !isDataTexture) {
17018					cubeImage[i] = resizeImage(texture.image[i], false, true, maxCubemapSize);
17019				} else {
17020					cubeImage[i] = isDataTexture ? texture.image[i].image : texture.image[i];
17021				}
17022			}
17023
17024			const image = cubeImage[0],
17025						supportsMips = isPowerOfTwo$1(image) || isWebGL2,
17026						glFormat = utils.convert(texture.format),
17027						glType = utils.convert(texture.type),
17028						glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
17029			const useTexStorage = isWebGL2 && texture.isVideoTexture !== true;
17030			const allocateMemory = textureProperties.__version === undefined;
17031			let levels = getMipLevels(texture, image, supportsMips);
17032			setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips);
17033			let mipmaps;
17034
17035			if (isCompressed) {
17036				if (useTexStorage && allocateMemory) {
17037					state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height);
17038				}
17039
17040				for (let i = 0; i < 6; i++) {
17041					mipmaps = cubeImage[i].mipmaps;
17042
17043					for (let j = 0; j < mipmaps.length; j++) {
17044						const mipmap = mipmaps[j];
17045
17046						if (texture.format !== RGBAFormat && texture.format !== RGBFormat) {
17047							if (glFormat !== null) {
17048								if (useTexStorage) {
17049									state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);
17050								} else {
17051									state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data);
17052								}
17053							} else {
17054								console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()');
17055							}
17056						} else {
17057							if (useTexStorage) {
17058								state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
17059							} else {
17060								state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
17061							}
17062						}
17063					}
17064				}
17065			} else {
17066				mipmaps = texture.mipmaps;
17067
17068				if (useTexStorage && allocateMemory) {
17069					// TODO: Uniformly handle mipmap definitions
17070					// Normal textures and compressed cube textures define base level + mips with their mipmap array
17071					// Uncompressed cube textures use their mipmap array only for mips (no base level)
17072					if (mipmaps.length > 0) levels++;
17073					state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[0].width, cubeImage[0].height);
17074				}
17075
17076				for (let i = 0; i < 6; i++) {
17077					if (isDataTexture) {
17078						if (useTexStorage) {
17079							state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data);
17080						} else {
17081							state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data);
17082						}
17083
17084						for (let j = 0; j < mipmaps.length; j++) {
17085							const mipmap = mipmaps[j];
17086							const mipmapImage = mipmap.image[i].image;
17087
17088							if (useTexStorage) {
17089								state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data);
17090							} else {
17091								state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data);
17092							}
17093						}
17094					} else {
17095						if (useTexStorage) {
17096							state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]);
17097						} else {
17098							state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]);
17099						}
17100
17101						for (let j = 0; j < mipmaps.length; j++) {
17102							const mipmap = mipmaps[j];
17103
17104							if (useTexStorage) {
17105								state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]);
17106							} else {
17107								state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]);
17108							}
17109						}
17110					}
17111				}
17112			}
17113
17114			if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
17115				// We assume images for cube map have the same size.
17116				generateMipmap(_gl.TEXTURE_CUBE_MAP);
17117			}
17118
17119			textureProperties.__version = texture.version;
17120			if (texture.onUpdate) texture.onUpdate(texture);
17121		} // Render targets
17122		// Setup storage for target texture and bind it to correct framebuffer
17123
17124
17125		function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget) {
17126			const glFormat = utils.convert(texture.format);
17127			const glType = utils.convert(texture.type);
17128			const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
17129			const renderTargetProperties = properties.get(renderTarget);
17130
17131			if (!renderTargetProperties.__hasExternalTextures) {
17132				if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) {
17133					state.texImage3D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null);
17134				} else {
17135					state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null);
17136				}
17137			}
17138
17139			state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
17140
17141			if (renderTarget.useRenderToTexture) {
17142				MultisampledRenderToTextureExtension.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0, getRenderTargetSamples(renderTarget));
17143			} else {
17144				_gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0);
17145			}
17146
17147			state.bindFramebuffer(_gl.FRAMEBUFFER, null);
17148		} // Setup storage for internal depth/stencil buffers and bind to correct framebuffer
17149
17150
17151		function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) {
17152			_gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer);
17153
17154			if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) {
17155				let glInternalFormat = _gl.DEPTH_COMPONENT16;
17156
17157				if (isMultisample || renderTarget.useRenderToTexture) {
17158					const depthTexture = renderTarget.depthTexture;
17159
17160					if (depthTexture && depthTexture.isDepthTexture) {
17161						if (depthTexture.type === FloatType) {
17162							glInternalFormat = _gl.DEPTH_COMPONENT32F;
17163						} else if (depthTexture.type === UnsignedIntType) {
17164							glInternalFormat = _gl.DEPTH_COMPONENT24;
17165						}
17166					}
17167
17168					const samples = getRenderTargetSamples(renderTarget);
17169
17170					if (renderTarget.useRenderToTexture) {
17171						MultisampledRenderToTextureExtension.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
17172					} else {
17173						_gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
17174					}
17175				} else {
17176					_gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height);
17177				}
17178
17179				_gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer);
17180			} else if (renderTarget.depthBuffer && renderTarget.stencilBuffer) {
17181				const samples = getRenderTargetSamples(renderTarget);
17182
17183				if (isMultisample && renderTarget.useRenderbuffer) {
17184					_gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height);
17185				} else if (renderTarget.useRenderToTexture) {
17186					MultisampledRenderToTextureExtension.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height);
17187				} else {
17188					_gl.renderbufferStorage(_gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height);
17189				}
17190
17191				_gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer);
17192			} else {
17193				// Use the first texture for MRT so far
17194				const texture = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture[0] : renderTarget.texture;
17195				const glFormat = utils.convert(texture.format);
17196				const glType = utils.convert(texture.type);
17197				const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
17198				const samples = getRenderTargetSamples(renderTarget);
17199
17200				if (isMultisample && renderTarget.useRenderbuffer) {
17201					_gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
17202				} else if (renderTarget.useRenderToTexture) {
17203					MultisampledRenderToTextureExtension.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
17204				} else {
17205					_gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height);
17206				}
17207			}
17208
17209			_gl.bindRenderbuffer(_gl.RENDERBUFFER, null);
17210		} // Setup resources for a Depth Texture for a FBO (needs an extension)
17211
17212
17213		function setupDepthTexture(framebuffer, renderTarget) {
vendor: 4,205 bytes, lines 17214-17307
17214			const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget;
17215			if (isCube) throw new Error('Depth Texture with cube render targets is not supported');
17216			state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
17217
17218			if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) {
17219				throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
17220			} // upload an empty depth texture with framebuffer size
17221
17222
17223			if (!properties.get(renderTarget.depthTexture).__webglTexture || renderTarget.depthTexture.image.width !== renderTarget.width || renderTarget.depthTexture.image.height !== renderTarget.height) {
17224				renderTarget.depthTexture.image.width = renderTarget.width;
17225				renderTarget.depthTexture.image.height = renderTarget.height;
17226				renderTarget.depthTexture.needsUpdate = true;
17227			}
17228
17229			setTexture2D(renderTarget.depthTexture, 0);
17230
17231			const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture;
17232
17233			const samples = getRenderTargetSamples(renderTarget);
17234
17235			if (renderTarget.depthTexture.format === DepthFormat) {
17236				if (renderTarget.useRenderToTexture) {
17237					MultisampledRenderToTextureExtension.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples);
17238				} else {
17239					_gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0);
17240				}
17241			} else if (renderTarget.depthTexture.format === DepthStencilFormat) {
17242				if (renderTarget.useRenderToTexture) {
17243					MultisampledRenderToTextureExtension.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples);
17244				} else {
17245					_gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0);
17246				}
17247			} else {
17248				throw new Error('Unknown depthTexture format');
17249			}
17250		} // Setup GL resources for a non-texture depth buffer
17251
17252
17253		function setupDepthRenderbuffer(renderTarget) {
17254			const renderTargetProperties = properties.get(renderTarget);
17255			const isCube = renderTarget.isWebGLCubeRenderTarget === true;
17256
17257			if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) {
17258				if (isCube) throw new Error('target.depthTexture not supported in Cube render targets');
17259				setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget);
17260			} else {
17261				if (isCube) {
17262					renderTargetProperties.__webglDepthbuffer = [];
17263
17264					for (let i = 0; i < 6; i++) {
17265						state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]);
17266						renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer();
17267						setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false);
17268					}
17269				} else {
17270					state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
17271					renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
17272					setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false);
17273				}
17274			}
17275
17276			state.bindFramebuffer(_gl.FRAMEBUFFER, null);
17277		} // rebind framebuffer with external textures
17278
17279
17280		function rebindTextures(renderTarget, colorTexture, depthTexture) {
17281			const renderTargetProperties = properties.get(renderTarget);
17282
17283			if (colorTexture !== undefined) {
17284				setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D);
17285			}
17286
17287			if (depthTexture !== undefined) {
17288				setupDepthRenderbuffer(renderTarget);
17289			}
17290		} // Set up GL resources for the render target
17291
17292
17293		function setupRenderTarget(renderTarget) {
17294			const texture = renderTarget.texture;
17295			const renderTargetProperties = properties.get(renderTarget);
17296			const textureProperties = properties.get(texture);
17297			renderTarget.addEventListener('dispose', onRenderTargetDispose);
17298
17299			if (renderTarget.isWebGLMultipleRenderTargets !== true) {
17300				if (textureProperties.__webglTexture === undefined) {
17301					textureProperties.__webglTexture = _gl.createTexture();
17302				}
17303
17304				textureProperties.__version = texture.version;
17305				info.memory.textures++;
17306			}
17307
17308			const isCube = renderTarget.isWebGLCubeRenderTarget === true;
17309			const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true;
17310			const isRenderTarget3D = texture.isDataTexture3D || texture.isDataTexture2DArray;
17311			const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; // Handles WebGL2 RGBFormat fallback - #18858
17312
17313			if (isWebGL2 && texture.format === RGBFormat && (texture.type === FloatType || texture.type === HalfFloatType)) {
17314				texture.format = RGBAFormat;
17315				console.warn('THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead.');
17316			} // Setup framebuffer
17317
17318
17319			if (isCube) {
17320				renderTargetProperties.__webglFramebuffer = [];
17321
17322				for (let i = 0; i < 6; i++) {
17323					renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer();
17324				}
17325			} else {
17326				renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
17327
17328				if (isMultipleRenderTargets) {
17329					if (capabilities.drawBuffers) {
17330						const textures = renderTarget.texture;
17331
17332						for (let i = 0, il = textures.length; i < il; i++) {
17333							const attachmentProperties = properties.get(textures[i]);
17334
17335							if (attachmentProperties.__webglTexture === undefined) {
17336								attachmentProperties.__webglTexture = _gl.createTexture();
17337								info.memory.textures++;
17338							}
17339						}
17340					} else {
17341						console.warn('THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.');
17342					}
17343				} else if (renderTarget.useRenderbuffer) {
17344					if (isWebGL2) {
17345						renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();
17346						renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer();
17347
17348						_gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer);
17349
17350						const glFormat = utils.convert(texture.format);
17351						const glType = utils.convert(texture.type);
17352						const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
17353						const samples = getRenderTargetSamples(renderTarget);
17354
17355						_gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
17356
17357						state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
17358
17359						_gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer);
17360
17361						_gl.bindRenderbuffer(_gl.RENDERBUFFER, null);
17362
17363						if (renderTarget.depthBuffer) {
17364							renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();
17365							setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true);
17366						}
17367
17368						state.bindFramebuffer(_gl.FRAMEBUFFER, null);
17369					} else {
17370						console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.');
17371					}
17372				}
17373			} // Setup color buffer
17374
17375
17376			if (isCube) {
17377				state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture);
17378				setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips);
17379
17380				for (let i = 0; i < 6; i++) {
17381					setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i);
17382				}
17383
17384				if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
17385					generateMipmap(_gl.TEXTURE_CUBE_MAP);
17386				}
17387
17388				state.unbindTexture();
17389			} else if (isMultipleRenderTargets) {
17390				const textures = renderTarget.texture;
17391
17392				for (let i = 0, il = textures.length; i < il; i++) {
17393					const attachment = textures[i];
17394					const attachmentProperties = properties.get(attachment);
17395					state.bindTexture(_gl.TEXTURE_2D, attachmentProperties.__webglTexture);
17396					setTextureParameters(_gl.TEXTURE_2D, attachment, supportsMips);
17397					setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D);
17398
17399					if (textureNeedsGenerateMipmaps(attachment, supportsMips)) {
17400						generateMipmap(_gl.TEXTURE_2D);
17401					}
17402				}
17403
17404				state.unbindTexture();
17405			} else {
17406				let glTextureType = _gl.TEXTURE_2D;
17407
17408				if (isRenderTarget3D) {
17409					// Render targets containing layers, i.e: Texture 3D and 2d arrays
17410					if (isWebGL2) {
17411						const isTexture3D = texture.isDataTexture3D;
17412						glTextureType = isTexture3D ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY;
17413					} else {
17414						console.warn('THREE.DataTexture3D and THREE.DataTexture2DArray only supported with WebGL2.');
17415					}
17416				}
17417
17418				state.bindTexture(glTextureType, textureProperties.__webglTexture);
17419				setTextureParameters(glTextureType, texture, supportsMips);
17420				setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType);
17421
17422				if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
17423					generateMipmap(glTextureType);
17424				}
17425
17426				state.unbindTexture();
17427			} // Setup depth and stencil buffers
17428
17429
17430			if (renderTarget.depthBuffer) {
17431				setupDepthRenderbuffer(renderTarget);
17432			}
17433		}
17434
17435		function updateRenderTargetMipmap(renderTarget) {
17436			const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2;
17437			const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture];
17438
17439			for (let i = 0, il = textures.length; i < il; i++) {
17440				const texture = textures[i];
17441
17442				if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
17443					const target = renderTarget.isWebGLCubeRenderTarget ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
17444
17445					const webglTexture = properties.get(texture).__webglTexture;
17446
17447					state.bindTexture(target, webglTexture);
17448					generateMipmap(target);
17449					state.unbindTexture();
17450				}
17451			}
17452		}
17453
17454		function updateMultisampleRenderTarget(renderTarget) {
17455			if (renderTarget.useRenderbuffer) {
17456				if (isWebGL2) {
17457					const width = renderTarget.width;
17458					const height = renderTarget.height;
17459					let mask = _gl.COLOR_BUFFER_BIT;
17460					const invalidationArray = [_gl.COLOR_ATTACHMENT0];
17461					const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
17462
17463					if (renderTarget.depthBuffer) {
17464						invalidationArray.push(depthStyle);
17465					}
17466
17467					if (!renderTarget.ignoreDepthForMultisampleCopy) {
17468						if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT;
17469						if (renderTarget.stencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT;
17470					}
17471
17472					const renderTargetProperties = properties.get(renderTarget);
17473					state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
17474					state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
17475
17476					if (renderTarget.ignoreDepthForMultisampleCopy) {
17477						_gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, [depthStyle]);
17478
17479						_gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]);
17480					}
17481
17482					_gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST);
17483
17484					_gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArray);
17485
17486					state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null);
17487					state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
17488				} else {
17489					console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.');
17490				}
17491			}
17492		}
17493
17494		function getRenderTargetSamples(renderTarget) {
17495			return isWebGL2 && (renderTarget.useRenderbuffer || renderTarget.useRenderToTexture) ? Math.min(maxSamples, renderTarget.samples) : 0;
17496		}
17497
17498		function updateVideoTexture(texture) {
17499			const frame = info.render.frame; // Check the last frame we updated the VideoTexture
17500
17501			if (_videoTextures.get(texture) !== frame) {
17502				_videoTextures.set(texture, frame);
17503
17504				texture.update();
17505			}
17506		} // backwards compatibility
17507
17508
17509		let warnedTexture2D = false;
17510		let warnedTextureCube = false;
17511
17512		function safeSetTexture2D(texture, slot) {
17513			if (texture && texture.isWebGLRenderTarget) {
17514				if (warnedTexture2D === false) {
17515					console.warn('THREE.WebGLTextures.safeSetTexture2D: don\'t use render targets as textures. Use their .texture property instead.');
17516					warnedTexture2D = true;
17517				}
17518
17519				texture = texture.texture;
17520			}
17521
17522			setTexture2D(texture, slot);
17523		}
17524
17525		function safeSetTextureCube(texture, slot) {
17526			if (texture && texture.isWebGLCubeRenderTarget) {
17527				if (warnedTextureCube === false) {
17528					console.warn('THREE.WebGLTextures.safeSetTextureCube: don\'t use cube render targets as textures. Use their .texture property instead.');
17529					warnedTextureCube = true;
17530				}
17531
17532				texture = texture.texture;
17533			}
17534
17535			setTextureCube(texture, slot);
17536		} //
17537
17538
17539		this.allocateTextureUnit = allocateTextureUnit;
17540		this.resetTextureUnits = resetTextureUnits;
17541		this.setTexture2D = setTexture2D;
17542		this.setTexture2DArray = setTexture2DArray;
17543		this.setTexture3D = setTexture3D;
17544		this.setTextureCube = setTextureCube;
17545		this.rebindTextures = rebindTextures;
17546		this.setupRenderTarget = setupRenderTarget;
17547		this.updateRenderTargetMipmap = updateRenderTargetMipmap;
17548		this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
17549		this.setupDepthRenderbuffer = setupDepthRenderbuffer;
17550		this.setupFrameBufferTexture = setupFrameBufferTexture;
17551		this.safeSetTexture2D = safeSetTexture2D;
17552		this.safeSetTextureCube = safeSetTextureCube;
17553	}
17554
17555	function WebGLUtils(gl, extensions, capabilities) {
17556		const isWebGL2 = capabilities.isWebGL2;
17557
17558		function convert(p) {
17559			let extension;
17560			if (p === UnsignedByteType) return gl.UNSIGNED_BYTE;
17561			if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4;
17562			if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1;
17563			if (p === UnsignedShort565Type) return gl.UNSIGNED_SHORT_5_6_5;
17564			if (p === ByteType) return gl.BYTE;
17565			if (p === ShortType) return gl.SHORT;
17566			if (p === UnsignedShortType) return gl.UNSIGNED_SHORT;
17567			if (p === IntType) return gl.INT;
17568			if (p === UnsignedIntType) return gl.UNSIGNED_INT;
17569			if (p === FloatType) return gl.FLOAT;
17570
17571			if (p === HalfFloatType) {
17572				if (isWebGL2) return gl.HALF_FLOAT;
17573				extension = extensions.get('OES_texture_half_float');
17574
17575				if (extension !== null) {
17576					return extension.HALF_FLOAT_OES;
17577				} else {
17578					return null;
17579				}
17580			}
17581
17582			if (p === AlphaFormat) return gl.ALPHA;
17583			if (p === RGBFormat) return gl.RGB;
17584			if (p === RGBAFormat) return gl.RGBA;
17585			if (p === LuminanceFormat) return gl.LUMINANCE;
17586			if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA;
17587			if (p === DepthFormat) return gl.DEPTH_COMPONENT;
17588			if (p === DepthStencilFormat) return gl.DEPTH_STENCIL;
17589			if (p === RedFormat) return gl.RED; // WebGL2 formats.
17590
17591			if (p === RedIntegerFormat) return gl.RED_INTEGER;
17592			if (p === RGFormat) return gl.RG;
17593			if (p === RGIntegerFormat) return gl.RG_INTEGER;
17594			if (p === RGBIntegerFormat) return gl.RGB_INTEGER;
17595			if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER;
17596
17597			if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) {
17598				extension = extensions.get('WEBGL_compressed_texture_s3tc');
17599
17600				if (extension !== null) {
17601					if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
17602					if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
17603					if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
17604					if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
17605				} else {
17606					return null;
17607				}
17608			}
17609
17610			if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) {
17611				extension = extensions.get('WEBGL_compressed_texture_pvrtc');
17612
17613				if (extension !== null) {
17614					if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
17615					if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
17616					if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
17617					if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
17618				} else {
17619					return null;
17620				}
17621			}
17622
17623			if (p === RGB_ETC1_Format) {
17624				extension = extensions.get('WEBGL_compressed_texture_etc1');
17625
17626				if (extension !== null) {
17627					return extension.COMPRESSED_RGB_ETC1_WEBGL;
17628				} else {
17629					return null;
17630				}
17631			}
17632
17633			if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) {
17634				extension = extensions.get('WEBGL_compressed_texture_etc');
17635
17636				if (extension !== null) {
17637					if (p === RGB_ETC2_Format) return extension.COMPRESSED_RGB8_ETC2;
17638					if (p === RGBA_ETC2_EAC_Format) return extension.COMPRESSED_RGBA8_ETC2_EAC;
17639				}
17640			}
17641
17642			if (p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format || p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format || p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format || p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format || p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format || p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format) {
17643				extension = extensions.get('WEBGL_compressed_texture_astc');
17644
17645				if (extension !== null) {
17646					// TODO Complete?
17647					return p;
17648				} else {
17649					return null;
17650				}
17651			}
17652
17653			if (p === RGBA_BPTC_Format) {
17654				extension = extensions.get('EXT_texture_compression_bptc');
17655
17656				if (extension !== null) {
17657					// TODO Complete?
17658					return p;
17659				} else {
17660					return null;
17661				}
17662			}
17663
17664			if (p === UnsignedInt248Type) {
17665				if (isWebGL2) return gl.UNSIGNED_INT_24_8;
17666				extension = extensions.get('WEBGL_depth_texture');
17667
17668				if (extension !== null) {
17669					return extension.UNSIGNED_INT_24_8_WEBGL;
17670				} else {
17671					return null;
17672				}
17673			}
17674		}
17675
17676		return {
17677			convert: convert
17678		};
17679	}
17680
17681	class ArrayCamera extends PerspectiveCamera {
17682		constructor(array = []) {
17683			super();
17684			this.cameras = array;
17685		}
17686
17687	}
17688
17689	ArrayCamera.prototype.isArrayCamera = true;
17690
17691	class Group extends Object3D {
17692		constructor() {
17693			super();
17694			this.type = 'Group';
17695		}
17696
17697	}
17698
17699	Group.prototype.isGroup = true;
17700
17701	const _moveEvent = {
17702		type: 'move'
17703	};
17704
17705	class WebXRController {
17706		constructor() {
17707			this._targetRay = null;
17708			this._grip = null;
17709			this._hand = null;
17710		}
17711
17712		getHandSpace() {
17713			if (this._hand === null) {
17714				this._hand = new Group();
17715				this._hand.matrixAutoUpdate = false;
vendor: 4,806 bytes, lines 17716-17888
17716				this._hand.visible = false;
17717				this._hand.joints = {};
17718				this._hand.inputState = {
17719					pinching: false
17720				};
17721			}
17722
17723			return this._hand;
17724		}
17725
17726		getTargetRaySpace() {
17727			if (this._targetRay === null) {
17728				this._targetRay = new Group();
17729				this._targetRay.matrixAutoUpdate = false;
17730				this._targetRay.visible = false;
17731				this._targetRay.hasLinearVelocity = false;
17732				this._targetRay.linearVelocity = new Vector3();
17733				this._targetRay.hasAngularVelocity = false;
17734				this._targetRay.angularVelocity = new Vector3();
17735			}
17736
17737			return this._targetRay;
17738		}
17739
17740		getGripSpace() {
17741			if (this._grip === null) {
17742				this._grip = new Group();
17743				this._grip.matrixAutoUpdate = false;
17744				this._grip.visible = false;
17745				this._grip.hasLinearVelocity = false;
17746				this._grip.linearVelocity = new Vector3();
17747				this._grip.hasAngularVelocity = false;
17748				this._grip.angularVelocity = new Vector3();
17749			}
17750
17751			return this._grip;
17752		}
17753
17754		dispatchEvent(event) {
17755			if (this._targetRay !== null) {
17756				this._targetRay.dispatchEvent(event);
17757			}
17758
17759			if (this._grip !== null) {
17760				this._grip.dispatchEvent(event);
17761			}
17762
17763			if (this._hand !== null) {
17764				this._hand.dispatchEvent(event);
17765			}
17766
17767			return this;
17768		}
17769
17770		disconnect(inputSource) {
17771			this.dispatchEvent({
17772				type: 'disconnected',
17773				data: inputSource
17774			});
17775
17776			if (this._targetRay !== null) {
17777				this._targetRay.visible = false;
17778			}
17779
17780			if (this._grip !== null) {
17781				this._grip.visible = false;
17782			}
17783
17784			if (this._hand !== null) {
17785				this._hand.visible = false;
17786			}
17787
17788			return this;
17789		}
17790
17791		update(inputSource, frame, referenceSpace) {
17792			let inputPose = null;
17793			let gripPose = null;
17794			let handPose = null;
17795			const targetRay = this._targetRay;
17796			const grip = this._grip;
17797			const hand = this._hand;
17798
17799			if (inputSource && frame.session.visibilityState !== 'visible-blurred') {
17800				if (targetRay !== null) {
17801					inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace);
17802
17803					if (inputPose !== null) {
17804						targetRay.matrix.fromArray(inputPose.transform.matrix);
17805						targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale);
17806
17807						if (inputPose.linearVelocity) {
17808							targetRay.hasLinearVelocity = true;
17809							targetRay.linearVelocity.copy(inputPose.linearVelocity);
17810						} else {
17811							targetRay.hasLinearVelocity = false;
17812						}
17813
17814						if (inputPose.angularVelocity) {
17815							targetRay.hasAngularVelocity = true;
17816							targetRay.angularVelocity.copy(inputPose.angularVelocity);
17817						} else {
17818							targetRay.hasAngularVelocity = false;
17819						}
17820
17821						this.dispatchEvent(_moveEvent);
17822					}
17823				}
17824
17825				if (hand && inputSource.hand) {
17826					handPose = true;
17827
17828					for (const inputjoint of inputSource.hand.values()) {
17829						// Update the joints groups with the XRJoint poses
17830						const jointPose = frame.getJointPose(inputjoint, referenceSpace);
17831
17832						if (hand.joints[inputjoint.jointName] === undefined) {
17833							// The transform of this joint will be updated with the joint pose on each frame
17834							const joint = new Group();
17835							joint.matrixAutoUpdate = false;
17836							joint.visible = false;
17837							hand.joints[inputjoint.jointName] = joint; // ??
17838
17839							hand.add(joint);
17840						}
17841
17842						const joint = hand.joints[inputjoint.jointName];
17843
17844						if (jointPose !== null) {
17845							joint.matrix.fromArray(jointPose.transform.matrix);
17846							joint.matrix.decompose(joint.position, joint.rotation, joint.scale);
17847							joint.jointRadius = jointPose.radius;
17848						}
17849
17850						joint.visible = jointPose !== null;
17851					} // Custom events
17852					// Check pinchz
17853
17854
17855					const indexTip = hand.joints['index-finger-tip'];
17856					const thumbTip = hand.joints['thumb-tip'];
17857					const distance = indexTip.position.distanceTo(thumbTip.position);
17858					const distanceToPinch = 0.02;
17859					const threshold = 0.005;
17860
17861					if (hand.inputState.pinching && distance > distanceToPinch + threshold) {
17862						hand.inputState.pinching = false;
17863						this.dispatchEvent({
17864							type: 'pinchend',
17865							handedness: inputSource.handedness,
17866							target: this
17867						});
17868					} else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) {
17869						hand.inputState.pinching = true;
17870						this.dispatchEvent({
17871							type: 'pinchstart',
17872							handedness: inputSource.handedness,
17873							target: this
17874						});
17875					}
17876				} else {
17877					if (grip !== null && inputSource.gripSpace) {
17878						gripPose = frame.getPose(inputSource.gripSpace, referenceSpace);
17879
17880						if (gripPose !== null) {
17881							grip.matrix.fromArray(gripPose.transform.matrix);
17882							grip.matrix.decompose(grip.position, grip.rotation, grip.scale);
17883
17884							if (gripPose.linearVelocity) {
17885								grip.hasLinearVelocity = true;
17886								grip.linearVelocity.copy(gripPose.linearVelocity);
17887							} else {
17888								grip.hasLinearVelocity = false;
17889							}
17890
17891							if (gripPose.angularVelocity) {
17892								grip.hasAngularVelocity = true;
17893								grip.angularVelocity.copy(gripPose.angularVelocity);
17894							} else {
17895								grip.hasAngularVelocity = false;
17896							}
17897						}
17898					}
17899				}
17900			}
17901
17902			if (targetRay !== null) {
17903				targetRay.visible = inputPose !== null;
17904			}
17905
17906			if (grip !== null) {
17907				grip.visible = gripPose !== null;
17908			}
17909
17910			if (hand !== null) {
17911				hand.visible = handPose !== null;
17912			}
17913
17914			return this;
17915		}
17916
17917	}
17918
17919	class DepthTexture extends Texture {
17920		constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) {
17921			format = format !== undefined ? format : DepthFormat;
17922
17923			if (format !== DepthFormat && format !== DepthStencilFormat) {
17924				throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat');
17925			}
17926
17927			if (type === undefined && format === DepthFormat) type = UnsignedShortType;
17928			if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type;
17929			super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
17930			this.image = {
17931				width: width,
17932				height: height
17933			};
17934			this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
17935			this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
17936			this.flipY = false;
17937			this.generateMipmaps = false;
17938		}
17939
17940	}
17941
17942	DepthTexture.prototype.isDepthTexture = true;
17943
17944	class WebXRManager extends EventDispatcher {
17945		constructor(renderer, gl) {
17946			super();
17947			const scope = this;
17948			let session = null;
17949			let framebufferScaleFactor = 1.0;
17950			let referenceSpace = null;
17951			let referenceSpaceType = 'local-floor';
17952			const hasMultisampledRenderToTexture = renderer.extensions.has('WEBGL_multisampled_render_to_texture');
17953			let pose = null;
17954			let glBinding = null;
17955			let glProjLayer = null;
17956			let glBaseLayer = null;
17957			let isMultisample = false;
17958			let xrFrame = null;
17959			const attributes = gl.getContextAttributes();
17960			let initialRenderTarget = null;
17961			let newRenderTarget = null;
17962			const controllers = [];
17963			const inputSourcesMap = new Map(); //
17964
17965			const cameraL = new PerspectiveCamera();
17966			cameraL.layers.enable(1);
17967			cameraL.viewport = new Vector4();
17968			const cameraR = new PerspectiveCamera();
17969			cameraR.layers.enable(2);
17970			cameraR.viewport = new Vector4();
17971			const cameras = [cameraL, cameraR];
17972			const cameraVR = new ArrayCamera();
17973			cameraVR.layers.enable(1);
17974			cameraVR.layers.enable(2);
17975			let _currentDepthNear = null;
17976			let _currentDepthFar = null; //
17977
17978			this.cameraAutoUpdate = true;
17979			this.enabled = false;
17980			this.isPresenting = false;
17981
17982			this.getController = function (index) {
17983				let controller = controllers[index];
17984
17985				if (controller === undefined) {
17986					controller = new WebXRController();
17987					controllers[index] = controller;
17988				}
17989
17990				return controller.getTargetRaySpace();
17991			};
17992
17993			this.getControllerGrip = function (index) {
17994				let controller = controllers[index];
17995
17996				if (controller === undefined) {
17997					controller = new WebXRController();
17998					controllers[index] = controller;
17999				}
18000
18001				return controller.getGripSpace();
18002			};
18003
18004			this.getHand = function (index) {
18005				let controller = controllers[index];
18006
18007				if (controller === undefined) {
18008					controller = new WebXRController();
18009					controllers[index] = controller;
18010				}
18011
18012				return controller.getHandSpace();
18013			}; //
18014
18015
18016			function onSessionEvent(event) {
18017				const controller = inputSourcesMap.get(event.inputSource);
18018
18019				if (controller) {
18020					controller.dispatchEvent({
18021						type: event.type,
18022						data: event.inputSource
18023					});
18024				}
18025			}
18026
18027			function onSessionEnd() {
18028				inputSourcesMap.forEach(function (controller, inputSource) {
18029					controller.disconnect(inputSource);
18030				});
18031				inputSourcesMap.clear();
18032				_currentDepthNear = null;
18033				_currentDepthFar = null; // restore framebuffer/rendering state
18034
18035				renderer.setRenderTarget(initialRenderTarget);
18036				glBaseLayer = null;
18037				glProjLayer = null;
18038				glBinding = null;
18039				session = null;
18040				newRenderTarget = null; //
18041
18042				animation.stop();
18043				scope.isPresenting = false;
18044				scope.dispatchEvent({
18045					type: 'sessionend'
18046				});
18047			}
18048
18049			this.setFramebufferScaleFactor = function (value) {
18050				framebufferScaleFactor = value;
18051
18052				if (scope.isPresenting === true) {
18053					console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.');
18054				}
18055			};
18056
18057			this.setReferenceSpaceType = function (value) {
18058				referenceSpaceType = value;
18059
18060				if (scope.isPresenting === true) {
18061					console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.');
18062				}
18063			};
18064
18065			this.getReferenceSpace = function () {
18066				return referenceSpace;
18067			};
18068
18069			this.getBaseLayer = function () {
18070				return glProjLayer !== null ? glProjLayer : glBaseLayer;
18071			};
18072
18073			this.getBinding = function () {
18074				return glBinding;
18075			};
18076
18077			this.getFrame = function () {
18078				return xrFrame;
18079			};
18080
18081			this.getSession = function () {
18082				return session;
18083			};
18084
18085			this.setSession = async function (value) {
18086				session = value;
18087
18088				if (session !== null) {
18089					initialRenderTarget = renderer.getRenderTarget();
18090					session.addEventListener('select', onSessionEvent);
18091					session.addEventListener('selectstart', onSessionEvent);
18092					session.addEventListener('selectend', onSessionEvent);
18093					session.addEventListener('squeeze', onSessionEvent);
18094					session.addEventListener('squeezestart', onSessionEvent);
18095					session.addEventListener('squeezeend', onSessionEvent);
18096					session.addEventListener('end', onSessionEnd);
18097					session.addEventListener('inputsourceschange', onInputSourcesChange);
18098
18099					if (attributes.xrCompatible !== true) {
18100						await gl.makeXRCompatible();
18101					}
18102
18103					if (session.renderState.layers === undefined || renderer.capabilities.isWebGL2 === false) {
18104						const layerInit = {
18105							antialias: session.renderState.layers === undefined ? attributes.antialias : true,
18106							alpha: attributes.alpha,
18107							depth: attributes.depth,
18108							stencil: attributes.stencil,
18109							framebufferScaleFactor: framebufferScaleFactor
18110						};
18111						glBaseLayer = new XRWebGLLayer(session, gl, layerInit);
18112						session.updateRenderState({
18113							baseLayer: glBaseLayer
18114						});
18115						newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, {
18116							format: RGBAFormat,
18117							type: UnsignedByteType,
18118							encoding: renderer.outputEncoding
18119						});
18120					} else {
18121						isMultisample = attributes.antialias;
18122						let depthFormat = null;
18123						let depthType = null;
18124						let glDepthFormat = null;
18125
18126						if (attributes.depth) {
18127							glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24;
18128							depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat;
18129							depthType = attributes.stencil ? UnsignedInt248Type : UnsignedShortType;
18130						}
18131
18132						const projectionlayerInit = {
18133							colorFormat: attributes.alpha || isMultisample ? gl.RGBA8 : gl.RGB8,
18134							depthFormat: glDepthFormat,
18135							scaleFactor: framebufferScaleFactor
18136						};
18137						glBinding = new XRWebGLBinding(session, gl);
18138						glProjLayer = glBinding.createProjectionLayer(projectionlayerInit);
18139						session.updateRenderState({
18140							layers: [glProjLayer]
18141						});
18142
18143						if (isMultisample) {
18144							newRenderTarget = new WebGLMultisampleRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, {
18145								format: RGBAFormat,
18146								type: UnsignedByteType,
18147								depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat),
18148								stencilBuffer: attributes.stencil,
18149								ignoreDepth: glProjLayer.ignoreDepthValues,
18150								useRenderToTexture: hasMultisampledRenderToTexture,
18151								encoding: renderer.outputEncoding
18152							});
18153						} else {
18154							newRenderTarget = new WebGLRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, {
18155								format: attributes.alpha ? RGBAFormat : RGBFormat,
18156								type: UnsignedByteType,
18157								depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat),
18158								stencilBuffer: attributes.stencil,
18159								ignoreDepth: glProjLayer.ignoreDepthValues,
18160								encoding: renderer.outputEncoding
18161							});
18162						}
18163					} // Set foveation to maximum.
18164
18165
18166					this.setFoveation(1.0);
18167					referenceSpace = await session.requestReferenceSpace(referenceSpaceType);
18168					animation.setContext(session);
18169					animation.start();
18170					scope.isPresenting = true;
18171					scope.dispatchEvent({
18172						type: 'sessionstart'
18173					});
18174				}
18175			};
18176
18177			function onInputSourcesChange(event) {
18178				const inputSources = session.inputSources; // Assign inputSources to available controllers
18179
18180				for (let i = 0; i < controllers.length; i++) {
18181					inputSourcesMap.set(inputSources[i], controllers[i]);
18182				} // Notify disconnected
18183
18184
18185				for (let i = 0; i < event.removed.length; i++) {
18186					const inputSource = event.removed[i];
18187					const controller = inputSourcesMap.get(inputSource);
18188
18189					if (controller) {
18190						controller.dispatchEvent({
18191							type: 'disconnected',
18192							data: inputSource
18193						});
18194						inputSourcesMap.delete(inputSource);
18195					}
18196				} // Notify connected
18197
18198
18199				for (let i = 0; i < event.added.length; i++) {
18200					const inputSource = event.added[i];
18201					const controller = inputSourcesMap.get(inputSource);
18202
18203					if (controller) {
18204						controller.dispatchEvent({
18205							type: 'connected',
18206							data: inputSource
18207						});
18208					}
18209				}
18210			} //
18211
18212
18213			const cameraLPos = new Vector3();
18214			const cameraRPos = new Vector3();
18215			/**
18216			 * Assumes 2 cameras that are parallel and share an X-axis, and that
18217			 * the cameras' projection and world matrices have already been set.
18218			 * And that near and far planes are identical for both cameras.
18219			 * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
18220			 */
18221
18222			function setProjectionFromUnion(camera, cameraL, cameraR) {
18223				cameraLPos.setFromMatrixPosition(cameraL.matrixWorld);
18224				cameraRPos.setFromMatrixPosition(cameraR.matrixWorld);
18225				const ipd = cameraLPos.distanceTo(cameraRPos);
18226				const projL = cameraL.projectionMatrix.elements;
18227				const projR = cameraR.projectionMatrix.elements; // VR systems will have identical far and near planes, and
18228				// most likely identical top and bottom frustum extents.
18229				// Use the left camera for these values.
18230
18231				const near = projL[14] / (projL[10] - 1);
18232				const far = projL[14] / (projL[10] + 1);
18233				const topFov = (projL[9] + 1) / projL[5];
18234				const bottomFov = (projL[9] - 1) / projL[5];
18235				const leftFov = (projL[8] - 1) / projL[0];
18236				const rightFov = (projR[8] + 1) / projR[0];
18237				const left = near * leftFov;
18238				const right = near * rightFov; // Calculate the new camera's position offset from the
18239				// left camera. xOffset should be roughly half `ipd`.
18240
18241				const zOffset = ipd / (-leftFov + rightFov);
18242				const xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset?
18243
18244				cameraL.matrixWorld.decompose(camera.position, camera.quaternion, camera.scale);
18245				camera.translateX(xOffset);
18246				camera.translateZ(zOffset);
18247				camera.matrixWorld.compose(camera.position, camera.quaternion, camera.scale);
18248				camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); // Find the union of the frustum values of the cameras and scale
18249				// the values so that the near plane's position does not change in world space,
18250				// although must now be relative to the new union camera.
18251
18252				const near2 = near + zOffset;
18253				const far2 = far + zOffset;
18254				const left2 = left - xOffset;
18255				const right2 = right + (ipd - xOffset);
18256				const top2 = topFov * far / far2 * near2;
18257				const bottom2 = bottomFov * far / far2 * near2;
18258				camera.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2);
18259			}
18260
18261			function updateCamera(camera, parent) {
18262				if (parent === null) {
18263					camera.matrixWorld.copy(camera.matrix);
18264				} else {
18265					camera.matrixWorld.multiplyMatrices(parent.matrixWorld, camera.matrix);
18266				}
18267
18268				camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
18269			}
18270
18271			this.updateCamera = function (camera) {
18272				if (session === null) return;
18273				cameraVR.near = cameraR.near = cameraL.near = camera.near;
18274				cameraVR.far = cameraR.far = cameraL.far = camera.far;
18275
18276				if (_currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far) {
18277					// Note that the new renderState won't apply until the next frame. See #18320
18278					session.updateRenderState({
18279						depthNear: cameraVR.near,
18280						depthFar: cameraVR.far
18281					});
18282					_currentDepthNear = cameraVR.near;
18283					_currentDepthFar = cameraVR.far;
18284				}
18285
18286				const parent = camera.parent;
18287				const cameras = cameraVR.cameras;
18288				updateCamera(cameraVR, parent);
18289
18290				for (let i = 0; i < cameras.length; i++) {
18291					updateCamera(cameras[i], parent);
18292				}
18293
18294				cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); // update user camera and its children
18295
18296				camera.position.copy(cameraVR.position);
18297				camera.quaternion.copy(cameraVR.quaternion);
18298				camera.scale.copy(cameraVR.scale);
18299				camera.matrix.copy(cameraVR.matrix);
18300				camera.matrixWorld.copy(cameraVR.matrixWorld);
18301				const children = camera.children;
18302
18303				for (let i = 0, l = children.length; i < l; i++) {
18304					children[i].updateMatrixWorld(true);
18305				} // update projection matrix for proper view frustum culling
18306
18307
18308				if (cameras.length === 2) {
18309					setProjectionFromUnion(cameraVR, cameraL, cameraR);
18310				} else {
18311					// assume single camera setup (AR)
18312					cameraVR.projectionMatrix.copy(cameraL.projectionMatrix);
18313				}
18314			};
18315
18316			this.getCamera = function () {
18317				return cameraVR;
18318			};
18319
18320			this.getFoveation = function () {
18321				if (glProjLayer !== null) {
18322					return glProjLayer.fixedFoveation;
18323				}
18324
18325				if (glBaseLayer !== null) {
18326					return glBaseLayer.fixedFoveation;
18327				}
18328
18329				return undefined;
18330			};
18331
18332			this.setFoveation = function (foveation) {
18333				// 0 = no foveation = full resolution
18334				// 1 = maximum foveation = the edges render at lower resolution
18335				if (glProjLayer !== null) {
18336					glProjLayer.fixedFoveation = foveation;
18337				}
18338
18339				if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) {
18340					glBaseLayer.fixedFoveation = foveation;
18341				}
18342			}; // Animation Loop
18343
18344
18345			let onAnimationFrameCallback = null;
18346
18347			function onAnimationFrame(time, frame) {
18348				pose = frame.getViewerPose(referenceSpace);
18349				xrFrame = frame;
18350
18351				if (pose !== null) {
18352					const views = pose.views;
18353
18354					if (glBaseLayer !== null) {
18355						renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer);
18356						renderer.setRenderTarget(newRenderTarget);
18357					}
18358
vendor: 16,384 bytes, lines 18359-18892
18359					let cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list
18360
18361					if (views.length !== cameraVR.cameras.length) {
18362						cameraVR.cameras.length = 0;
18363						cameraVRNeedsUpdate = true;
18364					}
18365
18366					for (let i = 0; i < views.length; i++) {
18367						const view = views[i];
18368						let viewport = null;
18369
18370						if (glBaseLayer !== null) {
18371							viewport = glBaseLayer.getViewport(view);
18372						} else {
18373							const glSubImage = glBinding.getViewSubImage(glProjLayer, view);
18374							viewport = glSubImage.viewport; // For side-by-side projection, we only produce a single texture for both eyes.
18375
18376							if (i === 0) {
18377								renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture);
18378								renderer.setRenderTarget(newRenderTarget);
18379							}
18380						}
18381
18382						const camera = cameras[i];
18383						camera.matrix.fromArray(view.transform.matrix);
18384						camera.projectionMatrix.fromArray(view.projectionMatrix);
18385						camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height);
18386
18387						if (i === 0) {
18388							cameraVR.matrix.copy(camera.matrix);
18389						}
18390
18391						if (cameraVRNeedsUpdate === true) {
18392							cameraVR.cameras.push(camera);
18393						}
18394					}
18395				} //
18396
18397
18398				const inputSources = session.inputSources;
18399
18400				for (let i = 0; i < controllers.length; i++) {
18401					const controller = controllers[i];
18402					const inputSource = inputSources[i];
18403					controller.update(inputSource, frame, referenceSpace);
18404				}
18405
18406				if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame);
18407				xrFrame = null;
18408			}
18409
18410			const animation = new WebGLAnimation();
18411			animation.setAnimationLoop(onAnimationFrame);
18412
18413			this.setAnimationLoop = function (callback) {
18414				onAnimationFrameCallback = callback;
18415			};
18416
18417			this.dispose = function () {};
18418		}
18419
18420	}
18421
18422	function WebGLMaterials(properties) {
18423		function refreshFogUniforms(uniforms, fog) {
18424			uniforms.fogColor.value.copy(fog.color);
18425
18426			if (fog.isFog) {
18427				uniforms.fogNear.value = fog.near;
18428				uniforms.fogFar.value = fog.far;
18429			} else if (fog.isFogExp2) {
18430				uniforms.fogDensity.value = fog.density;
18431			}
18432		}
18433
18434		function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) {
18435			if (material.isMeshBasicMaterial) {
18436				refreshUniformsCommon(uniforms, material);
18437			} else if (material.isMeshLambertMaterial) {
18438				refreshUniformsCommon(uniforms, material);
18439				refreshUniformsLambert(uniforms, material);
18440			} else if (material.isMeshToonMaterial) {
18441				refreshUniformsCommon(uniforms, material);
18442				refreshUniformsToon(uniforms, material);
18443			} else if (material.isMeshPhongMaterial) {
18444				refreshUniformsCommon(uniforms, material);
18445				refreshUniformsPhong(uniforms, material);
18446			} else if (material.isMeshStandardMaterial) {
18447				refreshUniformsCommon(uniforms, material);
18448
18449				if (material.isMeshPhysicalMaterial) {
18450					refreshUniformsPhysical(uniforms, material, transmissionRenderTarget);
18451				} else {
18452					refreshUniformsStandard(uniforms, material);
18453				}
18454			} else if (material.isMeshMatcapMaterial) {
18455				refreshUniformsCommon(uniforms, material);
18456				refreshUniformsMatcap(uniforms, material);
18457			} else if (material.isMeshDepthMaterial) {
18458				refreshUniformsCommon(uniforms, material);
18459				refreshUniformsDepth(uniforms, material);
18460			} else if (material.isMeshDistanceMaterial) {
18461				refreshUniformsCommon(uniforms, material);
18462				refreshUniformsDistance(uniforms, material);
18463			} else if (material.isMeshNormalMaterial) {
18464				refreshUniformsCommon(uniforms, material);
18465				refreshUniformsNormal(uniforms, material);
18466			} else if (material.isLineBasicMaterial) {
18467				refreshUniformsLine(uniforms, material);
18468
18469				if (material.isLineDashedMaterial) {
18470					refreshUniformsDash(uniforms, material);
18471				}
18472			} else if (material.isPointsMaterial) {
18473				refreshUniformsPoints(uniforms, material, pixelRatio, height);
18474			} else if (material.isSpriteMaterial) {
18475				refreshUniformsSprites(uniforms, material);
18476			} else if (material.isShadowMaterial) {
18477				uniforms.color.value.copy(material.color);
18478				uniforms.opacity.value = material.opacity;
18479			} else if (material.isShaderMaterial) {
18480				material.uniformsNeedUpdate = false; // #15581
18481			}
18482		}
18483
18484		function refreshUniformsCommon(uniforms, material) {
18485			uniforms.opacity.value = material.opacity;
18486
18487			if (material.color) {
18488				uniforms.diffuse.value.copy(material.color);
18489			}
18490
18491			if (material.emissive) {
18492				uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity);
18493			}
18494
18495			if (material.map) {
18496				uniforms.map.value = material.map;
18497			}
18498
18499			if (material.alphaMap) {
18500				uniforms.alphaMap.value = material.alphaMap;
18501			}
18502
18503			if (material.specularMap) {
18504				uniforms.specularMap.value = material.specularMap;
18505			}
18506
18507			if (material.alphaTest > 0) {
18508				uniforms.alphaTest.value = material.alphaTest;
18509			}
18510
18511			const envMap = properties.get(material).envMap;
18512
18513			if (envMap) {
18514				uniforms.envMap.value = envMap;
18515				uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1;
18516				uniforms.reflectivity.value = material.reflectivity;
18517				uniforms.ior.value = material.ior;
18518				uniforms.refractionRatio.value = material.refractionRatio;
18519			}
18520
18521			if (material.lightMap) {
18522				uniforms.lightMap.value = material.lightMap;
18523				uniforms.lightMapIntensity.value = material.lightMapIntensity;
18524			}
18525
18526			if (material.aoMap) {
18527				uniforms.aoMap.value = material.aoMap;
18528				uniforms.aoMapIntensity.value = material.aoMapIntensity;
18529			} // uv repeat and offset setting priorities
18530			// 1. color map
18531			// 2. specular map
18532			// 3. displacementMap map
18533			// 4. normal map
18534			// 5. bump map
18535			// 6. roughnessMap map
18536			// 7. metalnessMap map
18537			// 8. alphaMap map
18538			// 9. emissiveMap map
18539			// 10. clearcoat map
18540			// 11. clearcoat normal map
18541			// 12. clearcoat roughnessMap map
18542			// 13. specular intensity map
18543			// 14. specular tint map
18544			// 15. transmission map
18545			// 16. thickness map
18546
18547
18548			let uvScaleMap;
18549
18550			if (material.map) {
18551				uvScaleMap = material.map;
18552			} else if (material.specularMap) {
18553				uvScaleMap = material.specularMap;
18554			} else if (material.displacementMap) {
18555				uvScaleMap = material.displacementMap;
18556			} else if (material.normalMap) {
18557				uvScaleMap = material.normalMap;
18558			} else if (material.bumpMap) {
18559				uvScaleMap = material.bumpMap;
18560			} else if (material.roughnessMap) {
18561				uvScaleMap = material.roughnessMap;
18562			} else if (material.metalnessMap) {
18563				uvScaleMap = material.metalnessMap;
18564			} else if (material.alphaMap) {
18565				uvScaleMap = material.alphaMap;
18566			} else if (material.emissiveMap) {
18567				uvScaleMap = material.emissiveMap;
18568			} else if (material.clearcoatMap) {
18569				uvScaleMap = material.clearcoatMap;
18570			} else if (material.clearcoatNormalMap) {
18571				uvScaleMap = material.clearcoatNormalMap;
18572			} else if (material.clearcoatRoughnessMap) {
18573				uvScaleMap = material.clearcoatRoughnessMap;
18574			} else if (material.specularIntensityMap) {
18575				uvScaleMap = material.specularIntensityMap;
18576			} else if (material.specularColorMap) {
18577				uvScaleMap = material.specularColorMap;
18578			} else if (material.transmissionMap) {
18579				uvScaleMap = material.transmissionMap;
18580			} else if (material.thicknessMap) {
18581				uvScaleMap = material.thicknessMap;
18582			} else if (material.sheenColorMap) {
18583				uvScaleMap = material.sheenColorMap;
18584			} else if (material.sheenRoughnessMap) {
18585				uvScaleMap = material.sheenRoughnessMap;
18586			}
18587
18588			if (uvScaleMap !== undefined) {
18589				// backwards compatibility
18590				if (uvScaleMap.isWebGLRenderTarget) {
18591					uvScaleMap = uvScaleMap.texture;
18592				}
18593
18594				if (uvScaleMap.matrixAutoUpdate === true) {
18595					uvScaleMap.updateMatrix();
18596				}
18597
18598				uniforms.uvTransform.value.copy(uvScaleMap.matrix);
18599			} // uv repeat and offset setting priorities for uv2
18600			// 1. ao map
18601			// 2. light map
18602
18603
18604			let uv2ScaleMap;
18605
18606			if (material.aoMap) {
18607				uv2ScaleMap = material.aoMap;
18608			} else if (material.lightMap) {
18609				uv2ScaleMap = material.lightMap;
18610			}
18611
18612			if (uv2ScaleMap !== undefined) {
18613				// backwards compatibility
18614				if (uv2ScaleMap.isWebGLRenderTarget) {
18615					uv2ScaleMap = uv2ScaleMap.texture;
18616				}
18617
18618				if (uv2ScaleMap.matrixAutoUpdate === true) {
18619					uv2ScaleMap.updateMatrix();
18620				}
18621
18622				uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix);
18623			}
18624		}
18625
18626		function refreshUniformsLine(uniforms, material) {
18627			uniforms.diffuse.value.copy(material.color);
18628			uniforms.opacity.value = material.opacity;
18629		}
18630
18631		function refreshUniformsDash(uniforms, material) {
18632			uniforms.dashSize.value = material.dashSize;
18633			uniforms.totalSize.value = material.dashSize + material.gapSize;
18634			uniforms.scale.value = material.scale;
18635		}
18636
18637		function refreshUniformsPoints(uniforms, material, pixelRatio, height) {
18638			uniforms.diffuse.value.copy(material.color);
18639			uniforms.opacity.value = material.opacity;
18640			uniforms.size.value = material.size * pixelRatio;
18641			uniforms.scale.value = height * 0.5;
18642
18643			if (material.map) {
18644				uniforms.map.value = material.map;
18645			}
18646
18647			if (material.alphaMap) {
18648				uniforms.alphaMap.value = material.alphaMap;
18649			}
18650
18651			if (material.alphaTest > 0) {
18652				uniforms.alphaTest.value = material.alphaTest;
18653			} // uv repeat and offset setting priorities
18654			// 1. color map
18655			// 2. alpha map
18656
18657
18658			let uvScaleMap;
18659
18660			if (material.map) {
18661				uvScaleMap = material.map;
18662			} else if (material.alphaMap) {
18663				uvScaleMap = material.alphaMap;
18664			}
18665
18666			if (uvScaleMap !== undefined) {
18667				if (uvScaleMap.matrixAutoUpdate === true) {
18668					uvScaleMap.updateMatrix();
18669				}
18670
18671				uniforms.uvTransform.value.copy(uvScaleMap.matrix);
18672			}
18673		}
18674
18675		function refreshUniformsSprites(uniforms, material) {
18676			uniforms.diffuse.value.copy(material.color);
18677			uniforms.opacity.value = material.opacity;
18678			uniforms.rotation.value = material.rotation;
18679
18680			if (material.map) {
18681				uniforms.map.value = material.map;
18682			}
18683
18684			if (material.alphaMap) {
18685				uniforms.alphaMap.value = material.alphaMap;
18686			}
18687
18688			if (material.alphaTest > 0) {
18689				uniforms.alphaTest.value = material.alphaTest;
18690			} // uv repeat and offset setting priorities
18691			// 1. color map
18692			// 2. alpha map
18693
18694
18695			let uvScaleMap;
18696
18697			if (material.map) {
18698				uvScaleMap = material.map;
18699			} else if (material.alphaMap) {
18700				uvScaleMap = material.alphaMap;
18701			}
18702
18703			if (uvScaleMap !== undefined) {
18704				if (uvScaleMap.matrixAutoUpdate === true) {
18705					uvScaleMap.updateMatrix();
18706				}
18707
18708				uniforms.uvTransform.value.copy(uvScaleMap.matrix);
18709			}
18710		}
18711
18712		function refreshUniformsLambert(uniforms, material) {
18713			if (material.emissiveMap) {
18714				uniforms.emissiveMap.value = material.emissiveMap;
18715			}
18716		}
18717
18718		function refreshUniformsPhong(uniforms, material) {
18719			uniforms.specular.value.copy(material.specular);
18720			uniforms.shininess.value = Math.max(material.shininess, 1e-4); // to prevent pow( 0.0, 0.0 )
18721
18722			if (material.emissiveMap) {
18723				uniforms.emissiveMap.value = material.emissiveMap;
18724			}
18725
18726			if (material.bumpMap) {
18727				uniforms.bumpMap.value = material.bumpMap;
18728				uniforms.bumpScale.value = material.bumpScale;
18729				if (material.side === BackSide) uniforms.bumpScale.value *= -1;
18730			}
18731
18732			if (material.normalMap) {
18733				uniforms.normalMap.value = material.normalMap;
18734				uniforms.normalScale.value.copy(material.normalScale);
18735				if (material.side === BackSide) uniforms.normalScale.value.negate();
18736			}
18737
18738			if (material.displacementMap) {
18739				uniforms.displacementMap.value = material.displacementMap;
18740				uniforms.displacementScale.value = material.displacementScale;
18741				uniforms.displacementBias.value = material.displacementBias;
18742			}
18743		}
18744
18745		function refreshUniformsToon(uniforms, material) {
18746			if (material.gradientMap) {
18747				uniforms.gradientMap.value = material.gradientMap;
18748			}
18749
18750			if (material.emissiveMap) {
18751				uniforms.emissiveMap.value = material.emissiveMap;
18752			}
18753
18754			if (material.bumpMap) {
18755				uniforms.bumpMap.value = material.bumpMap;
18756				uniforms.bumpScale.value = material.bumpScale;
18757				if (material.side === BackSide) uniforms.bumpScale.value *= -1;
18758			}
18759
18760			if (material.normalMap) {
18761				uniforms.normalMap.value = material.normalMap;
18762				uniforms.normalScale.value.copy(material.normalScale);
18763				if (material.side === BackSide) uniforms.normalScale.value.negate();
18764			}
18765
18766			if (material.displacementMap) {
18767				uniforms.displacementMap.value = material.displacementMap;
18768				uniforms.displacementScale.value = material.displacementScale;
18769				uniforms.displacementBias.value = material.displacementBias;
18770			}
18771		}
18772
18773		function refreshUniformsStandard(uniforms, material) {
18774			uniforms.roughness.value = material.roughness;
18775			uniforms.metalness.value = material.metalness;
18776
18777			if (material.roughnessMap) {
18778				uniforms.roughnessMap.value = material.roughnessMap;
18779			}
18780
18781			if (material.metalnessMap) {
18782				uniforms.metalnessMap.value = material.metalnessMap;
18783			}
18784
18785			if (material.emissiveMap) {
18786				uniforms.emissiveMap.value = material.emissiveMap;
18787			}
18788
18789			if (material.bumpMap) {
18790				uniforms.bumpMap.value = material.bumpMap;
18791				uniforms.bumpScale.value = material.bumpScale;
18792				if (material.side === BackSide) uniforms.bumpScale.value *= -1;
18793			}
18794
18795			if (material.normalMap) {
18796				uniforms.normalMap.value = material.normalMap;
18797				uniforms.normalScale.value.copy(material.normalScale);
18798				if (material.side === BackSide) uniforms.normalScale.value.negate();
18799			}
18800
18801			if (material.displacementMap) {
18802				uniforms.displacementMap.value = material.displacementMap;
18803				uniforms.displacementScale.value = material.displacementScale;
18804				uniforms.displacementBias.value = material.displacementBias;
18805			}
18806
18807			const envMap = properties.get(material).envMap;
18808
18809			if (envMap) {
18810				//uniforms.envMap.value = material.envMap; // part of uniforms common
18811				uniforms.envMapIntensity.value = material.envMapIntensity;
18812			}
18813		}
18814
18815		function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) {
18816			refreshUniformsStandard(uniforms, material);
18817			uniforms.ior.value = material.ior; // also part of uniforms common
18818
18819			if (material.sheen > 0) {
18820				uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen);
18821				uniforms.sheenRoughness.value = material.sheenRoughness;
18822
18823				if (material.sheenColorMap) {
18824					uniforms.sheenColorMap.value = material.sheenColorMap;
18825				}
18826
18827				if (material.sheenRoughnessMap) {
18828					uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap;
18829				}
18830			}
18831
18832			if (material.clearcoat > 0) {
18833				uniforms.clearcoat.value = material.clearcoat;
18834				uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
18835
18836				if (material.clearcoatMap) {
18837					uniforms.clearcoatMap.value = material.clearcoatMap;
18838				}
18839
18840				if (material.clearcoatRoughnessMap) {
18841					uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;
18842				}
18843
18844				if (material.clearcoatNormalMap) {
18845					uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale);
18846					uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
18847
18848					if (material.side === BackSide) {
18849						uniforms.clearcoatNormalScale.value.negate();
18850					}
18851				}
18852			}
18853
18854			if (material.transmission > 0) {
18855				uniforms.transmission.value = material.transmission;
18856				uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture;
18857				uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height);
18858
18859				if (material.transmissionMap) {
18860					uniforms.transmissionMap.value = material.transmissionMap;
18861				}
18862
18863				uniforms.thickness.value = material.thickness;
18864
18865				if (material.thicknessMap) {
18866					uniforms.thicknessMap.value = material.thicknessMap;
18867				}
18868
18869				uniforms.attenuationDistance.value = material.attenuationDistance;
18870				uniforms.attenuationColor.value.copy(material.attenuationColor);
18871			}
18872
18873			uniforms.specularIntensity.value = material.specularIntensity;
18874			uniforms.specularColor.value.copy(material.specularColor);
18875
18876			if (material.specularIntensityMap) {
18877				uniforms.specularIntensityMap.value = material.specularIntensityMap;
18878			}
18879
18880			if (material.specularColorMap) {
18881				uniforms.specularColorMap.value = material.specularColorMap;
18882			}
18883		}
18884
18885		function refreshUniformsMatcap(uniforms, material) {
18886			if (material.matcap) {
18887				uniforms.matcap.value = material.matcap;
18888			}
18889
18890			if (material.bumpMap) {
18891				uniforms.bumpMap.value = material.bumpMap;
18892				uniforms.bumpScale.value = m
vendor: 10,377 bytes, lines 18892-19203
18892aterial.bumpScale;
18893				if (material.side === BackSide) uniforms.bumpScale.value *= -1;
18894			}
18895
18896			if (material.normalMap) {
18897				uniforms.normalMap.value = material.normalMap;
18898				uniforms.normalScale.value.copy(material.normalScale);
18899				if (material.side === BackSide) uniforms.normalScale.value.negate();
18900			}
18901
18902			if (material.displacementMap) {
18903				uniforms.displacementMap.value = material.displacementMap;
18904				uniforms.displacementScale.value = material.displacementScale;
18905				uniforms.displacementBias.value = material.displacementBias;
18906			}
18907		}
18908
18909		function refreshUniformsDepth(uniforms, material) {
18910			if (material.displacementMap) {
18911				uniforms.displacementMap.value = material.displacementMap;
18912				uniforms.displacementScale.value = material.displacementScale;
18913				uniforms.displacementBias.value = material.displacementBias;
18914			}
18915		}
18916
18917		function refreshUniformsDistance(uniforms, material) {
18918			if (material.displacementMap) {
18919				uniforms.displacementMap.value = material.displacementMap;
18920				uniforms.displacementScale.value = material.displacementScale;
18921				uniforms.displacementBias.value = material.displacementBias;
18922			}
18923
18924			uniforms.referencePosition.value.copy(material.referencePosition);
18925			uniforms.nearDistance.value = material.nearDistance;
18926			uniforms.farDistance.value = material.farDistance;
18927		}
18928
18929		function refreshUniformsNormal(uniforms, material) {
18930			if (material.bumpMap) {
18931				uniforms.bumpMap.value = material.bumpMap;
18932				uniforms.bumpScale.value = material.bumpScale;
18933				if (material.side === BackSide) uniforms.bumpScale.value *= -1;
18934			}
18935
18936			if (material.normalMap) {
18937				uniforms.normalMap.value = material.normalMap;
18938				uniforms.normalScale.value.copy(material.normalScale);
18939				if (material.side === BackSide) uniforms.normalScale.value.negate();
18940			}
18941
18942			if (material.displacementMap) {
18943				uniforms.displacementMap.value = material.displacementMap;
18944				uniforms.displacementScale.value = material.displacementScale;
18945				uniforms.displacementBias.value = material.displacementBias;
18946			}
18947		}
18948
18949		return {
18950			refreshFogUniforms: refreshFogUniforms,
18951			refreshMaterialUniforms: refreshMaterialUniforms
18952		};
18953	}
18954
18955	function createCanvasElement() {
18956		const canvas = createElementNS('canvas');
18957		canvas.style.display = 'block';
18958		return canvas;
18959	}
18960
18961	function WebGLRenderer(parameters = {}) {
18962		const _canvas = parameters.canvas !== undefined ? parameters.canvas : createCanvasElement(),
18963					_context = parameters.context !== undefined ? parameters.context : null,
18964					_alpha = parameters.alpha !== undefined ? parameters.alpha : false,
18965					_depth = parameters.depth !== undefined ? parameters.depth : true,
18966					_stencil = parameters.stencil !== undefined ? parameters.stencil : true,
18967					_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
18968					_premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
18969					_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
18970					_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',
18971					_failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;
18972
18973		let currentRenderList = null;
18974		let currentRenderState = null; // render() can be called from within a callback triggered by another render.
18975		// We track this so that the nested render call gets its list and state isolated from the parent render call.
18976
18977		const renderListStack = [];
18978		const renderStateStack = []; // public properties
18979
18980		this.domElement = _canvas; // Debug configuration container
18981
18982		this.debug = {
18983			/**
18984			 * Enables error checking and reporting when shader programs are being compiled
18985			 * @type {boolean}
18986			 */
18987			checkShaderErrors: true
18988		}; // clearing
18989
18990		this.autoClear = true;
18991		this.autoClearColor = true;
18992		this.autoClearDepth = true;
18993		this.autoClearStencil = true; // scene graph
18994
18995		this.sortObjects = true; // user-defined clipping
18996
18997		this.clippingPlanes = [];
18998		this.localClippingEnabled = false; // physically based shading
18999
19000		this.outputEncoding = LinearEncoding; // physical lights
19001
19002		this.physicallyCorrectLights = false; // tone mapping
19003
19004		this.toneMapping = NoToneMapping;
19005		this.toneMappingExposure = 1.0; // internal properties
19006
19007		const _this = this;
19008
19009		let _isContextLost = false; // internal state cache
19010
19011		let _currentActiveCubeFace = 0;
19012		let _currentActiveMipmapLevel = 0;
19013		let _currentRenderTarget = null;
19014
19015		let _currentMaterialId = -1;
19016
19017		let _currentCamera = null;
19018
19019		const _currentViewport = new Vector4();
19020
19021		const _currentScissor = new Vector4();
19022
19023		let _currentScissorTest = null; //
19024
19025		let _width = _canvas.width;
19026		let _height = _canvas.height;
19027		let _pixelRatio = 1;
19028		let _opaqueSort = null;
19029		let _transparentSort = null;
19030
19031		const _viewport = new Vector4(0, 0, _width, _height);
19032
19033		const _scissor = new Vector4(0, 0, _width, _height);
19034
19035		let _scissorTest = false; //
19036
19037		const _currentDrawBuffers = []; // frustum
19038
19039		const _frustum = new Frustum(); // clipping
19040
19041
19042		let _clippingEnabled = false;
19043		let _localClippingEnabled = false; // transmission
19044
19045		let _transmissionRenderTarget = null; // camera matrices cache
19046
19047		const _projScreenMatrix = new Matrix4();
19048
19049		const _vector3 = new Vector3();
19050
19051		const _emptyScene = {
19052			background: null,
19053			fog: null,
19054			environment: null,
19055			overrideMaterial: null,
19056			isScene: true
19057		};
19058
19059		function getTargetPixelRatio() {
19060			return _currentRenderTarget === null ? _pixelRatio : 1;
19061		} // initialize
19062
19063
19064		let _gl = _context;
19065
19066		function getContext(contextNames, contextAttributes) {
19067			for (let i = 0; i < contextNames.length; i++) {
19068				const contextName = contextNames[i];
19069
19070				const context = _canvas.getContext(contextName, contextAttributes);
19071
19072				if (context !== null) return context;
19073			}
19074
19075			return null;
19076		}
19077
19078		try {
19079			const contextAttributes = {
19080				alpha: _alpha,
19081				depth: _depth,
19082				stencil: _stencil,
19083				antialias: _antialias,
19084				premultipliedAlpha: _premultipliedAlpha,
19085				preserveDrawingBuffer: _preserveDrawingBuffer,
19086				powerPreference: _powerPreference,
19087				failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat
19088			}; // OffscreenCanvas does not have setAttribute, see #22811
19089
19090			if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); // event listeners must be registered before WebGL context is created, see #12753
19091
19092			_canvas.addEventListener('webglcontextlost', onContextLost, false);
19093
19094			_canvas.addEventListener('webglcontextrestored', onContextRestore, false);
19095
19096			if (_gl === null) {
19097				const contextNames = ['webgl2', 'webgl', 'experimental-webgl'];
19098
19099				if (_this.isWebGL1Renderer === true) {
19100					contextNames.shift();
19101				}
19102
19103				_gl = getContext(contextNames, contextAttributes);
19104
19105				if (_gl === null) {
19106					if (getContext(contextNames)) {
19107						throw new Error('Error creating WebGL context with your selected attributes.');
19108					} else {
19109						throw new Error('Error creating WebGL context.');
19110					}
19111				}
19112			} // Some experimental-webgl implementations do not have getShaderPrecisionFormat
19113
19114
19115			if (_gl.getShaderPrecisionFormat === undefined) {
19116				_gl.getShaderPrecisionFormat = function () {
19117					return {
19118						'rangeMin': 1,
19119						'rangeMax': 1,
19120						'precision': 1
19121					};
19122				};
19123			}
19124		} catch (error) {
19125			console.error('THREE.WebGLRenderer: ' + error.message);
19126			throw error;
19127		}
19128
19129		let extensions, capabilities, state, info;
19130		let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects;
19131		let programCache, materials, renderLists, renderStates, clipping, shadowMap;
19132		let background, morphtargets, bufferRenderer, indexedBufferRenderer;
19133		let utils, bindingStates;
19134
19135		function initGLContext() {
19136			extensions = new WebGLExtensions(_gl);
19137			capabilities = new WebGLCapabilities(_gl, extensions, parameters);
19138			extensions.init(capabilities);
19139			utils = new WebGLUtils(_gl, extensions, capabilities);
19140			state = new WebGLState(_gl, extensions, capabilities);
19141			_currentDrawBuffers[0] = _gl.BACK;
19142			info = new WebGLInfo(_gl);
19143			properties = new WebGLProperties();
19144			textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info);
19145			cubemaps = new WebGLCubeMaps(_this);
19146			cubeuvmaps = new WebGLCubeUVMaps(_this);
19147			attributes = new WebGLAttributes(_gl, capabilities);
19148			bindingStates = new WebGLBindingStates(_gl, extensions, attributes, capabilities);
19149			geometries = new WebGLGeometries(_gl, attributes, info, bindingStates);
19150			objects = new WebGLObjects(_gl, geometries, attributes, info);
19151			morphtargets = new WebGLMorphtargets(_gl, capabilities, textures);
19152			clipping = new WebGLClipping(properties);
19153			programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping);
19154			materials = new WebGLMaterials(properties);
19155			renderLists = new WebGLRenderLists();
19156			renderStates = new WebGLRenderStates(extensions, capabilities);
19157			background = new WebGLBackground(_this, cubemaps, state, objects, _premultipliedAlpha);
19158			shadowMap = new WebGLShadowMap(_this, objects, capabilities);
19159			bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities);
19160			indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info, capabilities);
19161			info.programs = programCache.programs;
19162			_this.capabilities = capabilities;
19163			_this.extensions = extensions;
19164			_this.properties = properties;
19165			_this.renderLists = renderLists;
19166			_this.shadowMap = shadowMap;
19167			_this.state = state;
19168			_this.info = info;
19169		}
19170
19171		initGLContext(); // xr
19172
19173		const xr = new WebXRManager(_this, _gl);
19174		this.xr = xr; // API
19175
19176		this.getContext = function () {
19177			return _gl;
19178		};
19179
19180		this.getContextAttributes = function () {
19181			return _gl.getContextAttributes();
19182		};
19183
19184		this.forceContextLoss = function () {
19185			const extension = extensions.get('WEBGL_lose_context');
19186			if (extension) extension.loseContext();
19187		};
19188
19189		this.forceContextRestore = function () {
19190			const extension = extensions.get('WEBGL_lose_context');
19191			if (extension) extension.restoreContext();
19192		};
19193
19194		this.getPixelRatio = function () {
19195			return _pixelRatio;
19196		};
19197
19198		this.setPixelRatio = function (value) {
19199			if (value === undefined) return;
19200			_pixelRatio = value;
19201			this.setSize(_width, _height, false);
19202		};
19203
vendor: 4,937 bytes, lines 19204-19391
19204		this.getSize = function (target) {
19205			return target.set(_width, _height);
19206		};
19207
19208		this.setSize = function (width, height, updateStyle) {
19209			if (xr.isPresenting) {
19210				console.warn('THREE.WebGLRenderer: Can\'t change size while VR device is presenting.');
19211				return;
19212			}
19213
19214			_width = width;
19215			_height = height;
19216			_canvas.width = Math.floor(width * _pixelRatio);
19217			_canvas.height = Math.floor(height * _pixelRatio);
19218
19219			if (updateStyle !== false) {
19220				_canvas.style.width = width + 'px';
19221				_canvas.style.height = height + 'px';
19222			}
19223
19224			this.setViewport(0, 0, width, height);
19225		};
19226
19227		this.getDrawingBufferSize = function (target) {
19228			return target.set(_width * _pixelRatio, _height * _pixelRatio).floor();
19229		};
19230
19231		this.setDrawingBufferSize = function (width, height, pixelRatio) {
19232			_width = width;
19233			_height = height;
19234			_pixelRatio = pixelRatio;
19235			_canvas.width = Math.floor(width * pixelRatio);
19236			_canvas.height = Math.floor(height * pixelRatio);
19237			this.setViewport(0, 0, width, height);
19238		};
19239
19240		this.getCurrentViewport = function (target) {
19241			return target.copy(_currentViewport);
19242		};
19243
19244		this.getViewport = function (target) {
19245			return target.copy(_viewport);
19246		};
19247
19248		this.setViewport = function (x, y, width, height) {
19249			if (x.isVector4) {
19250				_viewport.set(x.x, x.y, x.z, x.w);
19251			} else {
19252				_viewport.set(x, y, width, height);
19253			}
19254
19255			state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor());
19256		};
19257
19258		this.getScissor = function (target) {
19259			return target.copy(_scissor);
19260		};
19261
19262		this.setScissor = function (x, y, width, height) {
19263			if (x.isVector4) {
19264				_scissor.set(x.x, x.y, x.z, x.w);
19265			} else {
19266				_scissor.set(x, y, width, height);
19267			}
19268
19269			state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor());
19270		};
19271
19272		this.getScissorTest = function () {
19273			return _scissorTest;
19274		};
19275
19276		this.setScissorTest = function (boolean) {
19277			state.setScissorTest(_scissorTest = boolean);
19278		};
19279
19280		this.setOpaqueSort = function (method) {
19281			_opaqueSort = method;
19282		};
19283
19284		this.setTransparentSort = function (method) {
19285			_transparentSort = method;
19286		}; // Clearing
19287
19288
19289		this.getClearColor = function (target) {
19290			return target.copy(background.getClearColor());
19291		};
19292
19293		this.setClearColor = function () {
19294			background.setClearColor.apply(background, arguments);
19295		};
19296
19297		this.getClearAlpha = function () {
19298			return background.getClearAlpha();
19299		};
19300
19301		this.setClearAlpha = function () {
19302			background.setClearAlpha.apply(background, arguments);
19303		};
19304
19305		this.clear = function (color, depth, stencil) {
19306			let bits = 0;
19307			if (color === undefined || color) bits |= _gl.COLOR_BUFFER_BIT;
19308			if (depth === undefined || depth) bits |= _gl.DEPTH_BUFFER_BIT;
19309			if (stencil === undefined || stencil) bits |= _gl.STENCIL_BUFFER_BIT;
19310
19311			_gl.clear(bits);
19312		};
19313
19314		this.clearColor = function () {
19315			this.clear(true, false, false);
19316		};
19317
19318		this.clearDepth = function () {
19319			this.clear(false, true, false);
19320		};
19321
19322		this.clearStencil = function () {
19323			this.clear(false, false, true);
19324		}; //
19325
19326
19327		this.dispose = function () {
19328			_canvas.removeEventListener('webglcontextlost', onContextLost, false);
19329
19330			_canvas.removeEventListener('webglcontextrestored', onContextRestore, false);
19331
19332			renderLists.dispose();
19333			renderStates.dispose();
19334			properties.dispose();
19335			cubemaps.dispose();
19336			cubeuvmaps.dispose();
19337			objects.dispose();
19338			bindingStates.dispose();
19339			programCache.dispose();
19340			xr.dispose();
19341			xr.removeEventListener('sessionstart', onXRSessionStart);
19342			xr.removeEventListener('sessionend', onXRSessionEnd);
19343
19344			if (_transmissionRenderTarget) {
19345				_transmissionRenderTarget.dispose();
19346
19347				_transmissionRenderTarget = null;
19348			}
19349
19350			animation.stop();
19351		}; // Events
19352
19353
19354		function onContextLost(event) {
19355			event.preventDefault();
19356			console.log('THREE.WebGLRenderer: Context Lost.');
19357			_isContextLost = true;
19358		}
19359
19360		function onContextRestore() {
19361			console.log('THREE.WebGLRenderer: Context Restored.');
19362			_isContextLost = false;
19363			const infoAutoReset = info.autoReset;
19364			const shadowMapEnabled = shadowMap.enabled;
19365			const shadowMapAutoUpdate = shadowMap.autoUpdate;
19366			const shadowMapNeedsUpdate = shadowMap.needsUpdate;
19367			const shadowMapType = shadowMap.type;
19368			initGLContext();
19369			info.autoReset = infoAutoReset;
19370			shadowMap.enabled = shadowMapEnabled;
19371			shadowMap.autoUpdate = shadowMapAutoUpdate;
19372			shadowMap.needsUpdate = shadowMapNeedsUpdate;
19373			shadowMap.type = shadowMapType;
19374		}
19375
19376		function onMaterialDispose(event) {
19377			const material = event.target;
19378			material.removeEventListener('dispose', onMaterialDispose);
19379			deallocateMaterial(material);
19380		} // Buffer deallocation
19381
19382
19383		function deallocateMaterial(material) {
19384			releaseMaterialProgramReferences(material);
19385			properties.remove(material);
19386		}
19387
19388		function releaseMaterialProgramReferences(material) {
19389			const programs = properties.get(material).programs;
19390
19391			if (programs !== undefined) {
19392				programs.forEach(function (program) {
19393					programCache.releaseProgram(program);
19394				});
19395
19396				if (material.isShaderMaterial) {
19397					programCache.releaseShaderCache(material);
19398				}
19399			}
19400		} // Buffer rendering
19401
19402
19403		this.renderBufferDirect = function (camera, scene, geometry, material, object, group) {
19404			if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null)
19405
19406			const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0;
19407			const program = setProgram(camera, scene, geometry, material, object);
19408			state.setMaterial(material, frontFaceCW); //
19409
19410			let index = geometry.index;
19411			const position = geometry.attributes.position; //
19412
19413			if (index === null) {
19414				if (position === undefined || position.count === 0) return;
19415			} else if (index.count === 0) {
19416				return;
19417			} //
19418
19419
19420			let rangeFactor = 1;
19421
19422			if (material.wireframe === true) {
19423				index = geometries.getWireframeAttribute(geometry);
19424				rangeFactor = 2;
19425			}
19426
19427			bindingStates.setup(object, material, program, geometry, index);
19428			let attribute;
19429			let renderer = bufferRenderer;
19430
19431			if (index !== null) {
19432				attribute = attributes.get(index);
19433				renderer = indexedBufferRenderer;
19434				renderer.setIndex(attribute);
19435			} //
19436
19437
19438			const dataCount = index !== null ? index.count : position.count;
19439			const rangeStart = geometry.drawRange.start * rangeFactor;
19440			const rangeCount = geometry.drawRange.count * rangeFactor;
19441			const groupStart = group !== null ? group.start * rangeFactor : 0;
19442			const groupCount = group !== null ? group.count * rangeFactor : Infinity;
19443			const drawStart = Math.max(rangeStart, groupStart);
19444			const drawEnd = Math.min(dataCount, rangeStart + rangeCount, groupStart + groupCount) - 1;
19445			const drawCount = Math.max(0, drawEnd - drawStart + 1);
19446			if (drawCount === 0) return; //
19447
19448			if (object.isMesh) {
19449				if (material.wireframe === true) {
19450					state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio());
19451					renderer.setMode(_gl.LINES);
19452				} else {
19453					renderer.setMode(_gl.TRIANGLES);
19454				}
19455			} else if (object.isLine) {
19456				let lineWidth = material.linewidth;
19457				if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material
19458
19459				state.setLineWidth(lineWidth * getTargetPixelRatio());
19460
19461				if (object.isLineSegments) {
19462					renderer.setMode(_gl.LINES);
19463				} else if (object.isLineLoop) {
19464					renderer.setMode(_gl.LINE_LOOP);
19465				} else {
19466					renderer.setMode(_gl.LINE_STRIP);
19467				}
19468			} else if (object.isPoints) {
19469				renderer.setMode(_gl.POINTS);
19470			} else if (object.isSprite) {
19471				renderer.setMode(_gl.TRIANGLES);
19472			}
19473
19474			if (object.isInstancedMesh) {
19475				renderer.renderInstances(drawStart, drawCount, object.count);
19476			} else if (geometry.isInstancedBufferGeometry) {
19477				const instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount);
19478				renderer.renderInstances(drawStart, drawCount, instanceCount);
19479			} else {
19480				renderer.render(drawStart, drawCount);
19481			}
19482		}; // Compile
19483
19484
19485		this.compile = function (scene, camera) {
19486			currentRenderState = renderStates.get(scene);
19487			currentRenderState.init();
19488			renderStateStack.push(currentRenderState);
19489			scene.traverseVisible(function (object) {
19490				if (object.isLight && object.layers.test(camera.layers)) {
19491					currentRenderState.pushLight(object);
19492
19493					if (object.castShadow) {
19494						currentRenderState.pushShadow(object);
19495					}
19496				}
19497			});
19498			currentRenderState.setupLights(_this.physicallyCorrectLights);
19499			scene.traverse(function (object) {
19500				const material = object.material;
19501
19502				if (material) {
19503					if (Array.isArray(material)) {
19504						for (let i = 0; i < material.length; i++) {
19505							const material2 = material[i];
19506							getProgram(material2, scene, object);
19507						}
19508					} else {
19509						getProgram(material, scene, object);
19510					}
19511				}
19512			});
19513			renderStateStack.pop();
19514			currentRenderState = null;
19515		}; // Animation Loop
19516
19517
19518		let onAnimationFrameCallback = null;
19519
19520		function onAnimationFrame(time) {
19521			if (onAnimationFrameCallback) onAnimationFrameCallback(time);
19522		}
19523
19524		function onXRSessionStart() {
19525			animation.stop();
19526		}
19527
19528		function onXRSessionEnd() {
19529			animation.start();
19530		}
19531
19532		const animation = new WebGLAnimation();
19533		animation.setAnimationLoop(onAnimationFrame);
19534		if (typeof window !== 'undefined') animation.setContext(window);
19535
19536		this.setAnimationLoop = function (callback) {
19537			onAnimationFrameCallback = callback;
19538			xr.setAnimationLoop(callback);
19539			callback === null ? animation.stop() : animation.start();
19540		};
19541
19542		xr.addEventListener('sessionstart', onXRSessionStart);
19543		xr.addEventListener('sessionend', onXRSessionEnd); // Rendering
19544
19545		this.render = function (scene, camera) {
19546			if (camera !== undefined && camera.isCamera !== true) {
19547				console.error('THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.');
19548				return;
19549			}
19550
19551			if (_isContextLost === true) return; // update scene graph
19552
19553			if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum
19554
19555			if (camera.parent === null) camera.updateMatrixWorld();
19556
19557			if (xr.enabled === true && xr.isPresenting === true) {
19558				if (xr.cameraAutoUpdate === true) xr.updateCamera(camera);
19559				camera = xr.getCamera(); // use XR camera for rendering
19560			} //
19561
19562
19563			if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget);
19564			currentRenderState = renderStates.get(scene, renderStateStack.length);
vendor: 4,795 bytes, lines 19565-19712
19565			currentRenderState.init();
19566			renderStateStack.push(currentRenderState);
19567
19568			_projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
19569
19570			_frustum.setFromProjectionMatrix(_projScreenMatrix);
19571
19572			_localClippingEnabled = this.localClippingEnabled;
19573			_clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera);
19574			currentRenderList = renderLists.get(scene, renderListStack.length);
19575			currentRenderList.init();
19576			renderListStack.push(currentRenderList);
19577			projectObject(scene, camera, 0, _this.sortObjects);
19578			currentRenderList.finish();
19579
19580			if (_this.sortObjects === true) {
19581				currentRenderList.sort(_opaqueSort, _transparentSort);
19582			} //
19583
19584
19585			if (_clippingEnabled === true) clipping.beginShadows();
19586			const shadowsArray = currentRenderState.state.shadowsArray;
19587			shadowMap.render(shadowsArray, scene, camera);
19588			if (_clippingEnabled === true) clipping.endShadows(); //
19589
19590			if (this.info.autoReset === true) this.info.reset(); //
19591
19592			background.render(currentRenderList, scene); // render scene
19593
19594			currentRenderState.setupLights(_this.physicallyCorrectLights);
19595
19596			if (camera.isArrayCamera) {
19597				const cameras = camera.cameras;
19598
19599				for (let i = 0, l = cameras.length; i < l; i++) {
19600					const camera2 = cameras[i];
19601					renderScene(currentRenderList, scene, camera2, camera2.viewport);
19602				}
19603			} else {
19604				renderScene(currentRenderList, scene, camera);
19605			} //
19606
19607
19608			if (_currentRenderTarget !== null) {
19609				// resolve multisample renderbuffers to a single-sample texture if necessary
19610				textures.updateMultisampleRenderTarget(_currentRenderTarget); // Generate mipmap if we're using any kind of mipmap filtering
19611
19612				textures.updateRenderTargetMipmap(_currentRenderTarget);
19613			} //
19614
19615
19616			if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // Ensure depth buffer writing is enabled so it can be cleared on next render
19617
19618			state.buffers.depth.setTest(true);
19619			state.buffers.depth.setMask(true);
19620			state.buffers.color.setMask(true);
19621			state.setPolygonOffset(false); // _gl.finish();
19622
19623			bindingStates.resetDefaultState();
19624			_currentMaterialId = -1;
19625			_currentCamera = null;
19626			renderStateStack.pop();
19627
19628			if (renderStateStack.length > 0) {
19629				currentRenderState = renderStateStack[renderStateStack.length - 1];
19630			} else {
19631				currentRenderState = null;
19632			}
19633
19634			renderListStack.pop();
19635
19636			if (renderListStack.length > 0) {
19637				currentRenderList = renderListStack[renderListStack.length - 1];
19638			} else {
19639				currentRenderList = null;
19640			}
19641		};
19642
19643		function projectObject(object, camera, groupOrder, sortObjects) {
19644			if (object.visible === false) return;
19645			const visible = object.layers.test(camera.layers);
19646
19647			if (visible) {
19648				if (object.isGroup) {
19649					groupOrder = object.renderOrder;
19650				} else if (object.isLOD) {
19651					if (object.autoUpdate === true) object.update(camera);
19652				} else if (object.isLight) {
19653					currentRenderState.pushLight(object);
19654
19655					if (object.castShadow) {
19656						currentRenderState.pushShadow(object);
19657					}
19658				} else if (object.isSprite) {
19659					if (!object.frustumCulled || _frustum.intersectsSprite(object)) {
19660						if (sortObjects) {
19661							_vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix);
19662						}
19663
19664						const geometry = objects.update(object);
19665						const material = object.material;
19666
19667						if (material.visible) {
19668							currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null);
19669						}
19670					}
19671				} else if (object.isMesh || object.isLine || object.isPoints) {
19672					if (object.isSkinnedMesh) {
19673						// update skeleton only once in a frame
19674						if (object.skeleton.frame !== info.render.frame) {
19675							object.skeleton.update();
19676							object.skeleton.frame = info.render.frame;
19677						}
19678					}
19679
19680					if (!object.frustumCulled || _frustum.intersectsObject(object)) {
19681						if (sortObjects) {
19682							_vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix);
19683						}
19684
19685						const geometry = objects.update(object);
19686						const material = object.material;
19687
19688						if (Array.isArray(material)) {
19689							const groups = geometry.groups;
19690
19691							for (let i = 0, l = groups.length; i < l; i++) {
19692								const group = groups[i];
19693								const groupMaterial = material[group.materialIndex];
19694
19695								if (groupMaterial && groupMaterial.visible) {
19696									currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group);
19697								}
19698							}
19699						} else if (material.visible) {
19700							currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null);
19701						}
19702					}
19703				}
19704			}
19705
19706			const children = object.children;
19707
19708			for (let i = 0, l = children.length; i < l; i++) {
19709				projectObject(children[i], camera, groupOrder, sortObjects);
19710			}
19711		}
19712
19713		function renderScene(currentRenderList, scene, camera, viewport) {
19714			const opaqueObjects = currentRenderList.opaque;
19715			const transmissiveObjects = currentRenderList.transmissive;
19716			const transparentObjects = currentRenderList.transparent;
19717			currentRenderState.setupLightsView(camera);
19718			if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, scene, camera);
19719			if (viewport) state.viewport(_currentViewport.copy(viewport));
19720			if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera);
19721			if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera);
19722			if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera);
19723		}
19724
19725		function renderTransmissionPass(opaqueObjects, scene, camera) {
19726			if (_transmissionRenderTarget === null) {
19727				const needsAntialias = _antialias === true && capabilities.isWebGL2 === true;
19728				const renderTargetType = needsAntialias ? WebGLMultisampleRenderTarget : WebGLRenderTarget;
19729				_transmissionRenderTarget = new renderTargetType(1024, 1024, {
19730					generateMipmaps: true,
19731					type: utils.convert(HalfFloatType) !== null ? HalfFloatType : UnsignedByteType,
19732					minFilter: LinearMipmapLinearFilter,
19733					magFilter: NearestFilter,
19734					wrapS: ClampToEdgeWrapping,
19735					wrapT: ClampToEdgeWrapping,
19736					useRenderToTexture: extensions.has('WEBGL_multisampled_render_to_texture')
19737				});
19738			}
19739
19740			const currentRenderTarget = _this.getRenderTarget();
19741
19742			_this.setRenderTarget(_transmissionRenderTarget);
19743
19744			_this.clear(); // Turn off the features which can affect the frag color for opaque objects pass.
19745			// Otherwise they are applied twice in opaque objects pass and transmission objects pass.
19746
19747
19748			const currentToneMapping = _this.toneMapping;
19749			_this.toneMapping = NoToneMapping;
19750			renderObjects(opaqueObjects, scene, camera);
19751			_this.toneMapping = currentToneMapping;
19752			textures.updateMultisampleRenderTarget(_transmissionRenderTarget);
19753			textures.updateRenderTargetMipmap(_transmissionRenderTarget);
19754
19755			_this.setRenderTarget(currentRenderTarget);
19756		}
19757
19758		function renderObjects(renderList, scene, camera) {
19759			const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
19760
19761			for (let i = 0, l = renderList.length; i < l; i++) {
19762				const renderItem = renderList[i];
19763				const object = renderItem.object;
19764				const geometry = renderItem.geometry;
19765				const material = overrideMaterial === null ? renderItem.material : overrideMaterial;
19766				const group = renderItem.group;
19767
19768				if (object.layers.test(camera.layers)) {
19769					renderObject(object, scene, camera, geometry, material, group);
19770				}
19771			}
19772		}
19773
19774		function renderObject(object, scene, camera, geometry, material, group) {
19775			object.onBeforeRender(_this, scene, camera, geometry, material, group);
19776			object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld);
19777			object.normalMatrix.getNormalMatrix(object.modelViewMatrix);
19778			material.onBeforeRender(_this, scene, camera, geometry, object, group);
19779
19780			if (material.transparent === true && material.side === DoubleSide) {
19781				material.side = BackSide;
19782				material.needsUpdate = true;
19783
19784				_this.renderBufferDirect(camera, scene, geometry, material, object, group);
19785
19786				material.side = FrontSide;
19787				material.needsUpdate = true;
19788
19789				_this.renderBufferDirect(camera, scene, geometry, material, object, group);
19790
19791				material.side = DoubleSide;
19792			} else {
19793				_this.renderBufferDirect(camera, scene, geometry, material, object, group);
19794			}
19795
19796			object.onAfterRender(_this, scene, camera, geometry, material, group);
19797		}
19798
19799		function getProgram(material, scene, object) {
19800			if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
19801
19802			const materialProperties = properties.get(material);
19803			const lights = currentRenderState.state.lights;
19804			const shadowsArray = currentRenderState.state.shadowsArray;
19805			const lightsStateVersion = lights.state.version;
19806			const parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object);
19807			const programCacheKey = programCache.getProgramCacheKey(parameters);
19808			let programs = materialProperties.programs; // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change
19809
19810			materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
19811			materialProperties.fog = scene.fog;
19812			materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment);
19813
19814			if (programs === undefined) {
19815				// new material
19816				material.addEventListener('dispose', onMaterialDispose);
19817				programs = new Map();
19818				materialProperties.programs = programs;
19819			}
19820
19821			let program = programs.get(programCacheKey);
19822
19823			if (program !== undefined) {
19824				// early out if program and light state is identical
19825				if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) {
19826					updateCommonMaterialProperties(material, parameters);
19827					return program;
19828				}
19829			} else {
19830				parameters.uniforms = programCache.getUniforms(material);
19831				material.onBuild(object, parameters, _this);
19832				material.onBeforeCompile(parameters, _this);
19833				program = programCache.acquireProgram(parameters, programCacheKey);
19834				programs.set(programCacheKey, program);
19835				materialProperties.uniforms = parameters.uniforms;
19836			}
19837
19838			const uniforms = materialProperties.uniforms;
19839
19840			if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) {
19841				uniforms.clippingPlanes = clipping.uniform;
19842			}
19843
19844			updateCommonMaterialProperties(material, parameters); // store the light setup it was created for
19845
19846			materialProperties.needsLights = materialNeedsLights(material);
19847			materialProperties.lightsStateVersion = lightsStateVersion;
19848
19849			if (materialProperties.needsLights) {
19850				// wire up the material to this renderer's lighting state
19851				uniforms.ambientLightColor.value = lights.state.ambient;
19852				uniforms.lightProbe.value = lights.state.probe;
19853				uniforms.directionalLights.value = lights.state.directional;
19854				uniforms.directionalLightShadows.value = lights.state.directionalShadow;
19855				uniforms.spotLights.value = lights.state.spot;
19856				uniforms.spotLightShadows.value = lights.state.spotShadow;
19857				uniforms.rectAreaLights.value = lights.state.rectArea;
19858				uniforms.ltc_1.value = lights.state.rectAreaLTC1;
19859				uniforms.ltc_2.value = lights.state.rectAreaLTC2;
19860				uniforms.pointLights.value = lights.state.point;
19861				uniforms.pointLightShadows.value = lights.state.pointShadow;
19862				uniforms.hemisphereLights.value = lights.state.hemi;
19863				uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
19864				uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
19865				uniforms.spotShadowMap.value = lights.state.spotShadowMap;
19866				uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix;
19867				uniforms.pointShadowMap.value = lights.state.pointShadowMap;
19868				uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms
19869			}
19870
19871			const progUniforms = program.getUniforms();
19872			const uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, uniforms);
19873			materialProperties.currentProgram = program;
19874			materialProperties.uniformsList = uniformsList;
19875			return program;
19876		}
19877
19878		function updateCommonMaterialProperties(material, parameters) {
19879			const materialProperties = properties.get(material);
19880			materialProperties.outputEncoding = parameters.outputEncoding;
19881			materialProperties.instancing = parameters.instancing;
19882			materialProperties.skinning = parameters.skinning;
19883			materialProperties.morphTargets = parameters.morphTargets;
19884			materialProperties.morphNormals = parameters.morphNormals;
19885			materialProperties.morphTargetsCount = parameters.morphTargetsCount;
19886			materialProperties.numClippingPlanes = parameters.numClippingPlanes;
19887			materialProperties.numIntersection = parameters.numClipIntersection;
19888			materialProperties.vertexAlphas = parameters.vertexAlphas;
19889			materialProperties.vertexTangents = parameters.vertexTangents;
19890			materialProperties.toneMapping = parameters.toneMapping;
19891		}
19892
19893		function setProgram(camera, scene, geometry, material, object) {
19894			if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
19895
19896			textures.resetTextureUnits();
19897			const fog = scene.fog;
19898			const environment = material.isMeshStandardMaterial ? scene.environment : null;
19899			const encoding = _currentRenderTarget === null ? _this.outputEncoding : _currentRenderTarget.texture.encoding;
19900			const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
19901			const vertexAlphas = material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4;
19902			const vertexTangents = !!material.normalMap && !!geometry.attributes.tangent;
19903			const morphTargets = !!geometry.morphAttributes.position;
19904			const morphNormals = !!geometry.morphAttributes.normal;
vendor: 5,161 bytes, lines 19905-20019
19905			const morphTargetsCount = !!geometry.morphAttributes.position ? geometry.morphAttributes.position.length : 0;
19906			const toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping;
19907			const materialProperties = properties.get(material);
19908			const lights = currentRenderState.state.lights;
19909
19910			if (_clippingEnabled === true) {
19911				if (_localClippingEnabled === true || camera !== _currentCamera) {
19912					const useCache = camera === _currentCamera && material.id === _currentMaterialId; // we might want to call this function with some ClippingGroup
19913					// object instead of the material, once it becomes feasible
19914					// (#8465, #8379)
19915
19916					clipping.setState(material, camera, useCache);
19917				}
19918			} //
19919
19920
19921			let needsProgramChange = false;
19922
19923			if (material.version === materialProperties.__version) {
19924				if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) {
19925					needsProgramChange = true;
19926				} else if (materialProperties.outputEncoding !== encoding) {
19927					needsProgramChange = true;
19928				} else if (object.isInstancedMesh && materialProperties.instancing === false) {
19929					needsProgramChange = true;
19930				} else if (!object.isInstancedMesh && materialProperties.instancing === true) {
19931					needsProgramChange = true;
19932				} else if (object.isSkinnedMesh && materialProperties.skinning === false) {
19933					needsProgramChange = true;
19934				} else if (!object.isSkinnedMesh && materialProperties.skinning === true) {
19935					needsProgramChange = true;
19936				} else if (materialProperties.envMap !== envMap) {
19937					needsProgramChange = true;
19938				} else if (material.fog && materialProperties.fog !== fog) {
19939					needsProgramChange = true;
19940				} else if (materialProperties.numClippingPlanes !== undefined && (materialProperties.numClippingPlanes !== clipping.numPlanes || materialProperties.numIntersection !== clipping.numIntersection)) {
19941					needsProgramChange = true;
19942				} else if (materialProperties.vertexAlphas !== vertexAlphas) {
19943					needsProgramChange = true;
19944				} else if (materialProperties.vertexTangents !== vertexTangents) {
19945					needsProgramChange = true;
19946				} else if (materialProperties.morphTargets !== morphTargets) {
19947					needsProgramChange = true;
19948				} else if (materialProperties.morphNormals !== morphNormals) {
19949					needsProgramChange = true;
19950				} else if (materialProperties.toneMapping !== toneMapping) {
19951					needsProgramChange = true;
19952				} else if (capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount) {
19953					needsProgramChange = true;
19954				}
19955			} else {
19956				needsProgramChange = true;
19957				materialProperties.__version = material.version;
19958			} //
19959
19960
19961			let program = materialProperties.currentProgram;
19962
19963			if (needsProgramChange === true) {
19964				program = getProgram(material, scene, object);
19965			}
19966
19967			let refreshProgram = false;
19968			let refreshMaterial = false;
19969			let refreshLights = false;
19970			const p_uniforms = program.getUniforms(),
19971						m_uniforms = materialProperties.uniforms;
19972
19973			if (state.useProgram(program.program)) {
19974				refreshProgram = true;
19975				refreshMaterial = true;
19976				refreshLights = true;
19977			}
19978
19979			if (material.id !== _currentMaterialId) {
19980				_currentMaterialId = material.id;
19981				refreshMaterial = true;
19982			}
19983
19984			if (refreshProgram || _currentCamera !== camera) {
19985				p_uniforms.setValue(_gl, 'projectionMatrix', camera.projectionMatrix);
19986
19987				if (capabilities.logarithmicDepthBuffer) {
19988					p_uniforms.setValue(_gl, 'logDepthBufFC', 2.0 / (Math.log(camera.far + 1.0) / Math.LN2));
19989				}
19990
19991				if (_currentCamera !== camera) {
19992					_currentCamera = camera; // lighting uniforms depend on the camera so enforce an update
19993					// now, in case this material supports lights - or later, when
19994					// the next material that does gets activated:
19995
19996					refreshMaterial = true; // set to true on material change
19997
19998					refreshLights = true; // remains set until update done
19999				} // load material specific uniforms
20000				// (shader material also gets them for the sake of genericity)
20001
20002
20003				if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) {
20004					const uCamPos = p_uniforms.map.cameraPosition;
20005
20006					if (uCamPos !== undefined) {
20007						uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld));
20008					}
20009				}
20010
20011				if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) {
20012					p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true);
20013				}
20014
20015				if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh) {
20016					p_uniforms.setValue(_gl, 'viewMatrix', camera.matrixWorldInverse);
20017				}
20018			} // skinning and morph target uniforms must be set even if material didn't change
20019			// auto-setting of texture unit for bone and morph texture must go before other textures
20020			// otherwise textures used for skinning and morphing can take over texture units reserved for other material textures
20021
20022
20023			if (object.isSkinnedMesh) {
20024				p_uniforms.setOptional(_gl, object, 'bindMatrix');
20025				p_uniforms.setOptional(_gl, object, 'bindMatrixInverse');
20026				const skeleton = object.skeleton;
20027
20028				if (skeleton) {
20029					if (capabilities.floatVertexTextures) {
20030						if (skeleton.boneTexture === null) skeleton.computeBoneTexture();
20031						p_uniforms.setValue(_gl, 'boneTexture', skeleton.boneTexture, textures);
20032						p_uniforms.setValue(_gl, 'boneTextureSize', skeleton.boneTextureSize);
20033					} else {
20034						p_uniforms.setOptional(_gl, skeleton, 'boneMatrices');
20035					}
20036				}
20037			}
20038
20039			if (!!geometry && (geometry.morphAttributes.position !== undefined || geometry.morphAttributes.normal !== undefined)) {
20040				morphtargets.update(object, geometry, material, program);
20041			}
20042
20043			if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) {
20044				materialProperties.receiveShadow = object.receiveShadow;
20045				p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow);
20046			}
20047
20048			if (refreshMaterial) {
20049				p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure);
20050
20051				if (materialProperties.needsLights) {
20052					// the current material requires lighting info
20053					// note: all lighting uniforms are always set correctly
20054					// they simply reference the renderer's state for their
20055					// values
20056					//
20057					// use the current material's .needsUpdate flags to set
20058					// the GL state when required
20059					markUniformsLightsNeedsUpdate(m_uniforms, refreshLights);
20060				} // refresh uniforms common to several materials
20061
20062
20063				if (fog && material.fog) {
20064					materials.refreshFogUniforms(m_uniforms, fog);
20065				}
20066
20067				materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget);
20068				WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures);
20069			}
20070
20071			if (material.isShaderMaterial && material.uniformsNeedUpdate === true) {
20072				WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures);
20073				material.uniformsNeedUpdate = false;
20074			}
20075
20076			if (material.isSpriteMaterial) {
20077				p_uniforms.setValue(_gl, 'center', object.center);
20078			} // common matrices
20079
20080
20081			p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix);
20082			p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix);
20083			p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld);
20084			return program;
20085		} // If uniforms are marked as clean, they don't need to be loaded to the GPU.
20086
20087
20088		function markUniformsLightsNeedsUpdate(uniforms, value) {
20089			uniforms.ambientLightColor.needsUpdate = value;
20090			uniforms.lightProbe.needsUpdate = value;
20091			uniforms.directionalLights.needsUpdate = value;
20092			uniforms.directionalLightShadows.needsUpdate = value;
20093			uniforms.pointLights.needsUpdate = value;
20094			uniforms.pointLightShadows.needsUpdate = value;
20095			uniforms.spotLights.needsUpdate = value;
20096			uniforms.spotLightShadows.needsUpdate = value;
20097			uniforms.rectAreaLights.needsUpdate = value;
20098			uniforms.hemisphereLights.needsUpdate = value;
20099		}
20100
20101		function materialNeedsLights(material) {
20102			return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true;
20103		}
20104
20105		this.getActiveCubeFace = function () {
20106			return _currentActiveCubeFace;
20107		};
20108
20109		this.getActiveMipmapLevel = function () {
20110			return _currentActiveMipmapLevel;
20111		};
20112
20113		this.getRenderTarget = function () {
20114			return _currentRenderTarget;
20115		};
20116
20117		this.setRenderTargetTextures = function (renderTarget, colorTexture, depthTexture) {
20118			properties.get(renderTarget.texture).__webglTexture = colorTexture;
20119			properties.get(renderTarget.depthTexture).__webglTexture = depthTexture;
20120			const renderTargetProperties = properties.get(renderTarget);
20121			renderTargetProperties.__hasExternalTextures = true;
20122
20123			if (renderTargetProperties.__hasExternalTextures) {
20124				renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
20125
20126				if (!renderTargetProperties.__autoAllocateDepthBuffer) {
20127					// The multisample_render_to_texture extension doesn't work properly if there
20128					// are midframe flushes and an external depth buffer. Disable use of the extension.
20129					if (renderTarget.useRenderToTexture) {
20130						console.warn('render-to-texture extension was disabled because an external texture was provided');
20131						renderTarget.useRenderToTexture = false;
20132						renderTarget.useRenderbuffer = true;
20133					}
20134				}
20135			}
20136		};
20137
20138		this.setRenderTargetFramebuffer = function (renderTarget, defaultFramebuffer) {
20139			const renderTargetProperties = properties.get(renderTarget);
20140			renderTargetProperties.__webglFramebuffer = defaultFramebuffer;
20141			renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined;
20142		};
20143
20144		this.setRenderTarget = function (renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) {
20145			_currentRenderTarget = renderTarget;
20146			_currentActiveCubeFace = activeCubeFace;
20147			_currentActiveMipmapLevel = activeMipmapLevel;
20148			let useDefaultFramebuffer = true;
20149
20150			if (renderTarget) {
20151				const renderTargetProperties = properties.get(renderTarget);
20152
20153				if (renderTargetProperties.__useDefaultFramebuffer !== undefined) {
20154					// We need to make sure to rebind the framebuffer.
20155					state.bindFramebuffer(_gl.FRAMEBUFFER, null);
20156					useDefaultFramebuffer = false;
20157				} else if (renderTargetProperties.__webglFramebuffer === undefined) {
20158					textures.setupRenderTarget(renderTarget);
20159				} else if (renderTargetProperties.__hasExternalTextures) {
20160					// Color and depth texture must be rebound in order for the swapchain to update.
20161					textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture);
20162				}
20163			}
20164
20165			let framebuffer = null;
20166			let isCube = false;
20167			let isRenderTarget3D = false;
20168
20169			if (renderTarget) {
20170				const texture = renderTarget.texture;
20171
20172				if (texture.isDataTexture3D || texture.isDataTexture2DArray) {
20173					isRenderTarget3D = true;
20174				}
20175
20176				const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer;
20177
20178				if (renderTarget.isWebGLCubeRenderTarget) {
20179					framebuffer = __webglFramebuffer[activeCubeFace];
20180					isCube = true;
20181				} else if (renderTarget.useRenderbuffer) {
20182					framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer;
20183				} else {
20184					framebuffer = __webglFramebuffer;
20185				}
20186
20187				_currentViewport.copy(renderTarget.viewport);
20188
20189				_currentScissor.copy(renderTarget.scissor);
20190
20191				_currentScissorTest = renderTarget.scissorTest;
20192			} else {
20193				_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor();
20194
20195				_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor();
20196
20197				_currentScissorTest = _scissorTest;
20198			}
20199
20200			const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
20201
20202			if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) {
20203				let needsUpdate = false;
20204
20205				if (renderTarget) {
20206					if (renderTarget.isWebGLMultipleRenderTargets) {
20207						const textures = renderTarget.texture;
20208
20209						if (_currentDrawBuffers.length !== textures.length || _currentDrawBuffers[0] !== _gl.COLOR_ATTACHMENT0) {
20210							for (let i = 0, il = textures.length; i < il; i++) {
20211								_currentDrawBuffers[i] = _gl.COLOR_ATTACHMENT0 + i;
20212							}
20213
20214							_currentDrawBuffers.length = textures.length;
20215							needsUpdate = true;
20216						}
20217					} else {
20218						if (_currentDrawBuffers.length !== 1 || _currentDrawBuffers[0] !== _gl.COLOR_ATTACHMENT0) {
20219							_currentDrawBuffers[0] = _gl.COLOR_ATTACHMENT0;
20220							_currentDrawBuffers.length = 1;
20221							needsUpdate = true;
20222						}
20223					}
20224				} else {
20225					if (_currentDrawBuffers.length !== 1 || _currentDrawBuffers[0] !== _gl.BACK) {
20226						_currentDrawBuffers[0] = _gl.BACK;
20227						_currentDrawBuffers.length = 1;
20228						needsUpdate = true;
20229					}
20230				}
20231
20232				if (needsUpdate) {
20233					if (capabilities.isWebGL2) {
20234						_gl.drawBuffers(_currentDrawBuffers);
20235					} else {
20236						extensions.get('WEBGL_draw_buffers').drawBuffersWEBGL(_currentDrawBuffers);
20237					}
20238				}
20239			}
20240
20241			state.viewport(_currentViewport);
20242			state.scissor(_currentScissor);
20243			state.setScissorTest(_currentScissorTest);
20244
20245			if (isCube) {
20246				const textureProperties = properties.get(renderTarget.texture);
20247
20248				_gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel);
20249			} else if (isRenderTarget3D) {
20250				const textureProperties = properties.get(renderTarget.texture);
20251				const layer = activeCubeFace || 0;
20252
20253				_gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer);
20254			}
20255
20256			_currentMaterialId = -1; // reset current material to ensure correct uniform bindings
20257		};
20258
20259		this.readRenderTargetPixels = function (renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) {
20260			if (!(renderTarget && renderTarget.isWebGLRenderTarget)) {
20261				console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.');
20262				return;
20263			}
20264
20265			let framebuffer = properties.get(renderTarget).__webglFramebuffer;
20266
20267			if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) {
20268				framebuffer = framebuffer[activeCubeFaceIndex];
20269			}
20270
20271			if (framebuffer) {
20272				state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
20273
20274				try {
20275					const texture = renderTarget.texture;
20276					const textureFormat = texture.format;
20277					const textureType = texture.type;
20278
20279					if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_FORMAT)) {
20280						console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.');
20281						return;
20282					}
20283
20284					const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has('EXT_color_buffer_half_float') || capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float'));
20285
20286					if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513)
20287					!(textureType === FloatType && (capabilities.isWebGL2 || extensions.has('OES_texture_float') || extensions.has('WEBGL_color_buffer_float'))) && // Chrome Mac >= 52 and Firefox
20288					!halfFloatSupportedByExt) {
20289						console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.');
20290						return;
20291					}
20292
20293					if (_gl.checkFramebufferStatus(_gl.FRAMEBUFFER) === _gl.FRAMEBUFFER_COMPLETE) {
20294						// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
20295						if (x >= 0 && x <= renderTarget.width - width && y >= 0 && y <= renderTarget.height - height) {
20296							_gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer);
20297						}
20298					} else {
20299						console.error('THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.');
20300					}
20301				} finally {
20302					// restore framebuffer of current render target if necessary
20303					const framebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null;
20304					state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
20305				}
20306			}
20307		};
20308
20309		this.copyFramebufferToTexture = function (position, texture, level = 0) {
20310			if (texture.isFramebufferTexture !== true) {
20311				console.error('THREE.WebGLRenderer: copyFramebufferToTexture() can only be used with FramebufferTexture.');
20312				return;
20313			}
20314
20315			const levelScale = Math.pow(2, -level);
20316			const width = Math.floor(texture.image.width * levelScale);
20317			const height = Math.floor(texture.image.height * levelScale);
20318			textures.setTexture2D(texture, 0);
20319
20320			_gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, position.x, position.y, width, height);
20321
20322			state.unbindTexture();
20323		};
20324
20325		this.copyTextureToTexture = function (position, srcTexture, dstTexture, level = 0) {
20326			const width = srcTexture.image.width;
20327			const height = srcTexture.image.height;
20328			const glFormat = utils.convert(dstTexture.format);
20329			const glType = utils.convert(dstTexture.type);
20330			textures.setTexture2D(dstTexture, 0); // As another texture upload may have changed pixelStorei
20331			// parameters, make sure they are correct for the dstTexture
20332
20333			_gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY);
20334
20335			_gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha);
20336
20337			_gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment);
20338
20339			if (srcTexture.isDataTexture) {
20340				_gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data);
20341			} else {
20342				if (srcTexture.isCompressedTexture) {
20343					_gl.compressedTexSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[0].width, srcTexture.mipmaps[0].height, glFormat, srcTexture.mipmaps[0].data);
20344				} else {
20345					_gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image);
20346				}
20347			} // Generate mipmaps only when copying level 0
20348
20349
20350			if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(_gl.TEXTURE_2D);
20351			state.unbindTexture();
20352		};
20353
20354		this.copyTextureToTexture3D = function (sourceBox, position, srcTexture, dstTexture, level = 0) {
20355			if (_this.isWebGL1Renderer) {
20356				console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.');
20357				return;
20358			}
20359
20360			const width = sourceBox.max.x - sourceBox.min.x + 1;
20361			const height = sourceBox.max.y - sourceBox.min.y + 1;
20362			const depth = sourceBox.max.z - sourceBox.min.z + 1;
20363			const glFormat = utils.convert(dstTexture.format);
20364			const glType = utils.convert(dstTexture.type);
20365			let glTarget;
20366
20367			if (dstTexture.isDataTexture3D) {
20368				textures.setTexture3D(dstTexture, 0);
20369				glTarget = _gl.TEXTURE_3D;
20370			} else if (dstTexture.isDataTexture2DArray) {
20371				textures.setTexture2DArray(dstTexture, 0);
20372				glTarget = _gl.TEXTURE_2D_ARRAY;
20373			} else {
20374				console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.');
20375				return;
20376			}
20377
20378			_gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY);
20379
20380			_gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha);
20381
20382			_gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment);
20383
20384			const unpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH);
20385
20386			const unpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT);
20387
20388			const unpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS);
20389
20390			const unpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS);
20391
20392			const unpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES);
20393
20394			const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image;
20395
20396			_gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width);
20397
20398			_gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height);
20399
20400			_gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, sourceBox.min.x);
20401
20402			_gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, sourceBox.min.y);
20403
20404			_gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, sourceBox.min.z);
20405
20406			if (srcTexture.isDataTexture || srcTexture.isDataTexture3D) {
20407				_gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image.data);
20408			} else {
20409				if (srcTexture.isCompressedTexture) {
20410					console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.');
20411
20412					_gl.compressedTexSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data);
20413				} else {
20414					_gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image);
20415				}
20416			}
20417
20418			_gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, unpackRowLen);
20419
20420			_gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight);
20421
20422			_gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, unpackSkipPixels);
20423
20424			_gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, unpackSkipRows);
20425
20426			_gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); // Generate mipmaps only when copying level 0
20427
20428
20429			if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget);
20430			state.unbindTexture();
20431		};
20432
20433		this.initTexture = function (texture) {
20434			textures.setTexture2D(texture, 0);
20435			state.unbindTexture();
20436		};
20437
20438		this.resetState = function () {
20439			_currentActiveCubeFace = 0;
20440			_currentActiveMipmapLevel = 0;
20441			_currentRenderTarget = null;
20442			state.reset();
20443			bindingStates.reset();
20444		};
20445
20446		if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
20447			__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', {
20448				detail: this
20449			}));
20450		}
20451	}
20452
20453	WebGLRenderer.prototype.isWebGLRenderer = true;
20454
20455	class WebGL1Renderer extends WebGLRenderer {}
20456
20457	WebGL1Renderer.prototype.isWebGL1Renderer = true;
20458
20459	class FogExp2 {
20460		constructor(color, density = 0.00025) {
20461			this.name = '';
20462			this.color = new Color(color);
20463			this.density = density;
20464		}
20465
20466		clone() {
20467			return new FogExp2(this.color, this.density);
20468		}
20469
20470		toJSON() {
20471			return {
20472				type: 'FogExp2',
20473				color: this.color.getHex(),
20474				density: this.density
20475			};
20476		}
20477
20478	}
20479
20480	FogExp2.prototype.isFogExp2 = true;
20481
20482	class Fog {
20483		constructor(color, near = 1, far = 1000) {
20484			this.name = '';
20485			this.color = new Color(color);
20486			this.near = near;
20487			this.far = far;
20488		}
20489
20490		clone() {
20491			return new Fog(this.color, this.near, this.far);
20492		}
20493
20494		toJSON() {
20495			return {
20496				type: 'Fog',
20497				color: this.color.getHex(),
20498				near: this.near,
20499				far: this.far
20500			};
20501		}
20502
20503	}
20504
20505	Fog.prototype.isFog = true;
20506
20507	class Scene extends Object3D {
20508		constructor() {
20509			super();
20510			this.type = 'Scene';
20511			this.background = null;
20512			this.environment = null;
20513			this.fog = null;
20514			this.overrideMaterial = null;
20515			this.autoUpdate = true; // checked by the renderer
20516
20517			if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
20518				__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', {
20519					detail: this
20520				}));
20521			}
20522		}
20523
20524		copy(source, recursive) {
20525			super.copy(source, recursive);
20526			if (source.background !== null) this.background = source.background.clone();
20527			if (source.environment !== null) this.environment = source.environment.clone();
vendor: 18,633 bytes, lines 20528-21290
20528			if (source.fog !== null) this.fog = source.fog.clone();
20529			if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone();
20530			this.autoUpdate = source.autoUpdate;
20531			this.matrixAutoUpdate = source.matrixAutoUpdate;
20532			return this;
20533		}
20534
20535		toJSON(meta) {
20536			const data = super.toJSON(meta);
20537			if (this.fog !== null) data.object.fog = this.fog.toJSON();
20538			return data;
20539		}
20540
20541	}
20542
20543	Scene.prototype.isScene = true;
20544
20545	class InterleavedBuffer {
20546		constructor(array, stride) {
20547			this.array = array;
20548			this.stride = stride;
20549			this.count = array !== undefined ? array.length / stride : 0;
20550			this.usage = StaticDrawUsage;
20551			this.updateRange = {
20552				offset: 0,
20553				count: -1
20554			};
20555			this.version = 0;
20556			this.uuid = generateUUID();
20557		}
20558
20559		onUploadCallback() {}
20560
20561		set needsUpdate(value) {
20562			if (value === true) this.version++;
20563		}
20564
20565		setUsage(value) {
20566			this.usage = value;
20567			return this;
20568		}
20569
20570		copy(source) {
20571			this.array = new source.array.constructor(source.array);
20572			this.count = source.count;
20573			this.stride = source.stride;
20574			this.usage = source.usage;
20575			return this;
20576		}
20577
20578		copyAt(index1, attribute, index2) {
20579			index1 *= this.stride;
20580			index2 *= attribute.stride;
20581
20582			for (let i = 0, l = this.stride; i < l; i++) {
20583				this.array[index1 + i] = attribute.array[index2 + i];
20584			}
20585
20586			return this;
20587		}
20588
20589		set(value, offset = 0) {
20590			this.array.set(value, offset);
20591			return this;
20592		}
20593
20594		clone(data) {
20595			if (data.arrayBuffers === undefined) {
20596				data.arrayBuffers = {};
20597			}
20598
20599			if (this.array.buffer._uuid === undefined) {
20600				this.array.buffer._uuid = generateUUID();
20601			}
20602
20603			if (data.arrayBuffers[this.array.buffer._uuid] === undefined) {
20604				data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer;
20605			}
20606
20607			const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]);
20608			const ib = new this.constructor(array, this.stride);
20609			ib.setUsage(this.usage);
20610			return ib;
20611		}
20612
20613		onUpload(callback) {
20614			this.onUploadCallback = callback;
20615			return this;
20616		}
20617
20618		toJSON(data) {
20619			if (data.arrayBuffers === undefined) {
20620				data.arrayBuffers = {};
20621			} // generate UUID for array buffer if necessary
20622
20623
20624			if (this.array.buffer._uuid === undefined) {
20625				this.array.buffer._uuid = generateUUID();
20626			}
20627
20628			if (data.arrayBuffers[this.array.buffer._uuid] === undefined) {
20629				data.arrayBuffers[this.array.buffer._uuid] = Array.prototype.slice.call(new Uint32Array(this.array.buffer));
20630			} //
20631
20632
20633			return {
20634				uuid: this.uuid,
20635				buffer: this.array.buffer._uuid,
20636				type: this.array.constructor.name,
20637				stride: this.stride
20638			};
20639		}
20640
20641	}
20642
20643	InterleavedBuffer.prototype.isInterleavedBuffer = true;
20644
20645	const _vector$6 = /*@__PURE__*/new Vector3();
20646
20647	class InterleavedBufferAttribute {
20648		constructor(interleavedBuffer, itemSize, offset, normalized = false) {
20649			this.name = '';
20650			this.data = interleavedBuffer;
20651			this.itemSize = itemSize;
20652			this.offset = offset;
20653			this.normalized = normalized === true;
20654		}
20655
20656		get count() {
20657			return this.data.count;
20658		}
20659
20660		get array() {
20661			return this.data.array;
20662		}
20663
20664		set needsUpdate(value) {
20665			this.data.needsUpdate = value;
20666		}
20667
20668		applyMatrix4(m) {
20669			for (let i = 0, l = this.data.count; i < l; i++) {
20670				_vector$6.x = this.getX(i);
20671				_vector$6.y = this.getY(i);
20672				_vector$6.z = this.getZ(i);
20673
20674				_vector$6.applyMatrix4(m);
20675
20676				this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z);
20677			}
20678
20679			return this;
20680		}
20681
20682		applyNormalMatrix(m) {
20683			for (let i = 0, l = this.count; i < l; i++) {
20684				_vector$6.x = this.getX(i);
20685				_vector$6.y = this.getY(i);
20686				_vector$6.z = this.getZ(i);
20687
20688				_vector$6.applyNormalMatrix(m);
20689
20690				this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z);
20691			}
20692
20693			return this;
20694		}
20695
20696		transformDirection(m) {
20697			for (let i = 0, l = this.count; i < l; i++) {
20698				_vector$6.x = this.getX(i);
20699				_vector$6.y = this.getY(i);
20700				_vector$6.z = this.getZ(i);
20701
20702				_vector$6.transformDirection(m);
20703
20704				this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z);
20705			}
20706
20707			return this;
20708		}
20709
20710		setX(index, x) {
20711			this.data.array[index * this.data.stride + this.offset] = x;
20712			return this;
20713		}
20714
20715		setY(index, y) {
20716			this.data.array[index * this.data.stride + this.offset + 1] = y;
20717			return this;
20718		}
20719
20720		setZ(index, z) {
20721			this.data.array[index * this.data.stride + this.offset + 2] = z;
20722			return this;
20723		}
20724
20725		setW(index, w) {
20726			this.data.array[index * this.data.stride + this.offset + 3] = w;
20727			return this;
20728		}
20729
20730		getX(index) {
20731			return this.data.array[index * this.data.stride + this.offset];
20732		}
20733
20734		getY(index) {
20735			return this.data.array[index * this.data.stride + this.offset + 1];
20736		}
20737
20738		getZ(index) {
20739			return this.data.array[index * this.data.stride + this.offset + 2];
20740		}
20741
20742		getW(index) {
20743			return this.data.array[index * this.data.stride + this.offset + 3];
20744		}
20745
20746		setXY(index, x, y) {
20747			index = index * this.data.stride + this.offset;
20748			this.data.array[index + 0] = x;
20749			this.data.array[index + 1] = y;
20750			return this;
20751		}
20752
20753		setXYZ(index, x, y, z) {
20754			index = index * this.data.stride + this.offset;
20755			this.data.array[index + 0] = x;
20756			this.data.array[index + 1] = y;
20757			this.data.array[index + 2] = z;
20758			return this;
20759		}
20760
20761		setXYZW(index, x, y, z, w) {
20762			index = index * this.data.stride + this.offset;
20763			this.data.array[index + 0] = x;
20764			this.data.array[index + 1] = y;
20765			this.data.array[index + 2] = z;
20766			this.data.array[index + 3] = w;
20767			return this;
20768		}
20769
20770		clone(data) {
20771			if (data === undefined) {
20772				console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.');
20773				const array = [];
20774
20775				for (let i = 0; i < this.count; i++) {
20776					const index = i * this.data.stride + this.offset;
20777
20778					for (let j = 0; j < this.itemSize; j++) {
20779						array.push(this.data.array[index + j]);
20780					}
20781				}
20782
20783				return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized);
20784			} else {
20785				if (data.interleavedBuffers === undefined) {
20786					data.interleavedBuffers = {};
20787				}
20788
20789				if (data.interleavedBuffers[this.data.uuid] === undefined) {
20790					data.interleavedBuffers[this.data.uuid] = this.data.clone(data);
20791				}
20792
20793				return new InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized);
20794			}
20795		}
20796
20797		toJSON(data) {
20798			if (data === undefined) {
20799				console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.');
20800				const array = [];
20801
20802				for (let i = 0; i < this.count; i++) {
20803					const index = i * this.data.stride + this.offset;
20804
20805					for (let j = 0; j < this.itemSize; j++) {
20806						array.push(this.data.array[index + j]);
20807					}
20808				} // deinterleave data and save it as an ordinary buffer attribute for now
20809
20810
20811				return {
20812					itemSize: this.itemSize,
20813					type: this.array.constructor.name,
20814					array: array,
20815					normalized: this.normalized
20816				};
20817			} else {
20818				// save as true interlaved attribtue
20819				if (data.interleavedBuffers === undefined) {
20820					data.interleavedBuffers = {};
20821				}
20822
20823				if (data.interleavedBuffers[this.data.uuid] === undefined) {
20824					data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data);
20825				}
20826
20827				return {
20828					isInterleavedBufferAttribute: true,
20829					itemSize: this.itemSize,
20830					data: this.data.uuid,
20831					offset: this.offset,
20832					normalized: this.normalized
20833				};
20834			}
20835		}
20836
20837	}
20838
20839	InterleavedBufferAttribute.prototype.isInterleavedBufferAttribute = true;
20840
20841	/**
20842	 * parameters = {
20843	 *	color: <hex>,
20844	 *	map: new THREE.Texture( <Image> ),
20845	 *	alphaMap: new THREE.Texture( <Image> ),
20846	 *	rotation: <float>,
20847	 *	sizeAttenuation: <bool>
20848	 * }
20849	 */
20850
20851	class SpriteMaterial extends Material {
20852		constructor(parameters) {
20853			super();
20854			this.type = 'SpriteMaterial';
20855			this.color = new Color(0xffffff);
20856			this.map = null;
20857			this.alphaMap = null;
20858			this.rotation = 0;
20859			this.sizeAttenuation = true;
20860			this.transparent = true;
20861			this.setValues(parameters);
20862		}
20863
20864		copy(source) {
20865			super.copy(source);
20866			this.color.copy(source.color);
20867			this.map = source.map;
20868			this.alphaMap = source.alphaMap;
20869			this.rotation = source.rotation;
20870			this.sizeAttenuation = source.sizeAttenuation;
20871			return this;
20872		}
20873
20874	}
20875
20876	SpriteMaterial.prototype.isSpriteMaterial = true;
20877
20878	let _geometry;
20879
20880	const _intersectPoint = /*@__PURE__*/new Vector3();
20881
20882	const _worldScale = /*@__PURE__*/new Vector3();
20883
20884	const _mvPosition = /*@__PURE__*/new Vector3();
20885
20886	const _alignedPosition = /*@__PURE__*/new Vector2();
20887
20888	const _rotatedPosition = /*@__PURE__*/new Vector2();
20889
20890	const _viewWorldMatrix = /*@__PURE__*/new Matrix4();
20891
20892	const _vA = /*@__PURE__*/new Vector3();
20893
20894	const _vB = /*@__PURE__*/new Vector3();
20895
20896	const _vC = /*@__PURE__*/new Vector3();
20897
20898	const _uvA = /*@__PURE__*/new Vector2();
20899
20900	const _uvB = /*@__PURE__*/new Vector2();
20901
20902	const _uvC = /*@__PURE__*/new Vector2();
20903
20904	class Sprite extends Object3D {
20905		constructor(material) {
20906			super();
20907			this.type = 'Sprite';
20908
20909			if (_geometry === undefined) {
20910				_geometry = new BufferGeometry();
20911				const float32Array = new Float32Array([-0.5, -0.5, 0, 0, 0, 0.5, -0.5, 0, 1, 0, 0.5, 0.5, 0, 1, 1, -0.5, 0.5, 0, 0, 1]);
20912				const interleavedBuffer = new InterleavedBuffer(float32Array, 5);
20913
20914				_geometry.setIndex([0, 1, 2, 0, 2, 3]);
20915
20916				_geometry.setAttribute('position', new InterleavedBufferAttribute(interleavedBuffer, 3, 0, false));
20917
20918				_geometry.setAttribute('uv', new InterleavedBufferAttribute(interleavedBuffer, 2, 3, false));
20919			}
20920
20921			this.geometry = _geometry;
20922			this.material = material !== undefined ? material : new SpriteMaterial();
20923			this.center = new Vector2(0.5, 0.5);
20924		}
20925
20926		raycast(raycaster, intersects) {
20927			if (raycaster.camera === null) {
20928				console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.');
20929			}
20930
20931			_worldScale.setFromMatrixScale(this.matrixWorld);
20932
20933			_viewWorldMatrix.copy(raycaster.camera.matrixWorld);
20934
20935			this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld);
20936
20937			_mvPosition.setFromMatrixPosition(this.modelViewMatrix);
20938
20939			if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) {
20940				_worldScale.multiplyScalar(-_mvPosition.z);
20941			}
20942
20943			const rotation = this.material.rotation;
20944			let sin, cos;
20945
20946			if (rotation !== 0) {
20947				cos = Math.cos(rotation);
20948				sin = Math.sin(rotation);
20949			}
20950
20951			const center = this.center;
20952			transformVertex(_vA.set(-0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos);
20953			transformVertex(_vB.set(0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos);
20954			transformVertex(_vC.set(0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos);
20955
20956			_uvA.set(0, 0);
20957
20958			_uvB.set(1, 0);
20959
20960			_uvC.set(1, 1); // check first triangle
20961
20962
20963			let intersect = raycaster.ray.intersectTriangle(_vA, _vB, _vC, false, _intersectPoint);
20964
20965			if (intersect === null) {
20966				// check second triangle
20967				transformVertex(_vB.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos);
20968
20969				_uvB.set(0, 1);
20970
20971				intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint);
20972
20973				if (intersect === null) {
20974					return;
20975				}
20976			}
20977
20978			const distance = raycaster.ray.origin.distanceTo(_intersectPoint);
20979			if (distance < raycaster.near || distance > raycaster.far) return;
20980			intersects.push({
20981				distance: distance,
20982				point: _intersectPoint.clone(),
20983				uv: Triangle.getUV(_intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()),
20984				face: null,
20985				object: this
20986			});
20987		}
20988
20989		copy(source) {
20990			super.copy(source);
20991			if (source.center !== undefined) this.center.copy(source.center);
20992			this.material = source.material;
20993			return this;
20994		}
20995
20996	}
20997
20998	Sprite.prototype.isSprite = true;
20999
21000	function transformVertex(vertexPosition, mvPosition, center, scale, sin, cos) {
21001		// compute position in camera space
21002		_alignedPosition.subVectors(vertexPosition, center).addScalar(0.5).multiply(scale); // to check if rotation is not zero
21003
21004
21005		if (sin !== undefined) {
21006			_rotatedPosition.x = cos * _alignedPosition.x - sin * _alignedPosition.y;
21007			_rotatedPosition.y = sin * _alignedPosition.x + cos * _alignedPosition.y;
21008		} else {
21009			_rotatedPosition.copy(_alignedPosition);
21010		}
21011
21012		vertexPosition.copy(mvPosition);
21013		vertexPosition.x += _rotatedPosition.x;
21014		vertexPosition.y += _rotatedPosition.y; // transform to world space
21015
21016		vertexPosition.applyMatrix4(_viewWorldMatrix);
21017	}
21018
21019	const _v1$2 = /*@__PURE__*/new Vector3();
21020
21021	const _v2$1 = /*@__PURE__*/new Vector3();
21022
21023	class LOD extends Object3D {
21024		constructor() {
21025			super();
21026			this._currentLevel = 0;
21027			this.type = 'LOD';
21028			Object.defineProperties(this, {
21029				levels: {
21030					enumerable: true,
21031					value: []
21032				},
21033				isLOD: {
21034					value: true
21035				}
21036			});
21037			this.autoUpdate = true;
21038		}
21039
21040		copy(source) {
21041			super.copy(source, false);
21042			const levels = source.levels;
21043
21044			for (let i = 0, l = levels.length; i < l; i++) {
21045				const level = levels[i];
21046				this.addLevel(level.object.clone(), level.distance);
21047			}
21048
21049			this.autoUpdate = source.autoUpdate;
21050			return this;
21051		}
21052
21053		addLevel(object, distance = 0) {
21054			distance = Math.abs(distance);
21055			const levels = this.levels;
21056			let l;
21057
21058			for (l = 0; l < levels.length; l++) {
21059				if (distance < levels[l].distance) {
21060					break;
21061				}
21062			}
21063
21064			levels.splice(l, 0, {
21065				distance: distance,
21066				object: object
21067			});
21068			this.add(object);
21069			return this;
21070		}
21071
21072		getCurrentLevel() {
21073			return this._currentLevel;
21074		}
21075
21076		getObjectForDistance(distance) {
21077			const levels = this.levels;
21078
21079			if (levels.length > 0) {
21080				let i, l;
21081
21082				for (i = 1, l = levels.length; i < l; i++) {
21083					if (distance < levels[i].distance) {
21084						break;
21085					}
21086				}
21087
21088				return levels[i - 1].object;
21089			}
21090
21091			return null;
21092		}
21093
21094		raycast(raycaster, intersects) {
21095			const levels = this.levels;
21096
21097			if (levels.length > 0) {
21098				_v1$2.setFromMatrixPosition(this.matrixWorld);
21099
21100				const distance = raycaster.ray.origin.distanceTo(_v1$2);
21101				this.getObjectForDistance(distance).raycast(raycaster, intersects);
21102			}
21103		}
21104
21105		update(camera) {
21106			const levels = this.levels;
21107
21108			if (levels.length > 1) {
21109				_v1$2.setFromMatrixPosition(camera.matrixWorld);
21110
21111				_v2$1.setFromMatrixPosition(this.matrixWorld);
21112
21113				const distance = _v1$2.distanceTo(_v2$1) / camera.zoom;
21114				levels[0].object.visible = true;
21115				let i, l;
21116
21117				for (i = 1, l = levels.length; i < l; i++) {
21118					if (distance >= levels[i].distance) {
21119						levels[i - 1].object.visible = false;
21120						levels[i].object.visible = true;
21121					} else {
21122						break;
21123					}
21124				}
21125
21126				this._currentLevel = i - 1;
21127
21128				for (; i < l; i++) {
21129					levels[i].object.visible = false;
21130				}
21131			}
21132		}
21133
21134		toJSON(meta) {
21135			const data = super.toJSON(meta);
21136			if (this.autoUpdate === false) data.object.autoUpdate = false;
21137			data.object.levels = [];
21138			const levels = this.levels;
21139
21140			for (let i = 0, l = levels.length; i < l; i++) {
21141				const level = levels[i];
21142				data.object.levels.push({
21143					object: level.object.uuid,
21144					distance: level.distance
21145				});
21146			}
21147
21148			return data;
21149		}
21150
21151	}
21152
21153	const _basePosition = /*@__PURE__*/new Vector3();
21154
21155	const _skinIndex = /*@__PURE__*/new Vector4();
21156
21157	const _skinWeight = /*@__PURE__*/new Vector4();
21158
21159	const _vector$5 = /*@__PURE__*/new Vector3();
21160
21161	const _matrix = /*@__PURE__*/new Matrix4();
21162
21163	class SkinnedMesh extends Mesh {
21164		constructor(geometry, material) {
21165			super(geometry, material);
21166			this.type = 'SkinnedMesh';
21167			this.bindMode = 'attached';
21168			this.bindMatrix = new Matrix4();
21169			this.bindMatrixInverse = new Matrix4();
21170		}
21171
21172		copy(source) {
21173			super.copy(source);
21174			this.bindMode = source.bindMode;
21175			this.bindMatrix.copy(source.bindMatrix);
21176			this.bindMatrixInverse.copy(source.bindMatrixInverse);
21177			this.skeleton = source.skeleton;
21178			return this;
21179		}
21180
21181		bind(skeleton, bindMatrix) {
21182			this.skeleton = skeleton;
21183
21184			if (bindMatrix === undefined) {
21185				this.updateMatrixWorld(true);
21186				this.skeleton.calculateInverses();
21187				bindMatrix = this.matrixWorld;
21188			}
21189
21190			this.bindMatrix.copy(bindMatrix);
21191			this.bindMatrixInverse.copy(bindMatrix).invert();
21192		}
21193
21194		pose() {
21195			this.skeleton.pose();
21196		}
21197
21198		normalizeSkinWeights() {
21199			const vector = new Vector4();
21200			const skinWeight = this.geometry.attributes.skinWeight;
21201
21202			for (let i = 0, l = skinWeight.count; i < l; i++) {
21203				vector.x = skinWeight.getX(i);
21204				vector.y = skinWeight.getY(i);
21205				vector.z = skinWeight.getZ(i);
21206				vector.w = skinWeight.getW(i);
21207				const scale = 1.0 / vector.manhattanLength();
21208
21209				if (scale !== Infinity) {
21210					vector.multiplyScalar(scale);
21211				} else {
21212					vector.set(1, 0, 0, 0); // do something reasonable
21213				}
21214
21215				skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w);
21216			}
21217		}
21218
21219		updateMatrixWorld(force) {
21220			super.updateMatrixWorld(force);
21221
21222			if (this.bindMode === 'attached') {
21223				this.bindMatrixInverse.copy(this.matrixWorld).invert();
21224			} else if (this.bindMode === 'detached') {
21225				this.bindMatrixInverse.copy(this.bindMatrix).invert();
21226			} else {
21227				console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode);
21228			}
21229		}
21230
21231		boneTransform(index, target) {
21232			const skeleton = this.skeleton;
21233			const geometry = this.geometry;
21234
21235			_skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index);
21236
21237			_skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index);
21238
21239			_basePosition.copy(target).applyMatrix4(this.bindMatrix);
21240
21241			target.set(0, 0, 0);
21242
21243			for (let i = 0; i < 4; i++) {
21244				const weight = _skinWeight.getComponent(i);
21245
21246				if (weight !== 0) {
21247					const boneIndex = _skinIndex.getComponent(i);
21248
21249					_matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]);
21250
21251					target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight);
21252				}
21253			}
21254
21255			return target.applyMatrix4(this.bindMatrixInverse);
21256		}
21257
21258	}
21259
21260	SkinnedMesh.prototype.isSkinnedMesh = true;
21261
21262	class Bone extends Object3D {
21263		constructor() {
21264			super();
21265			this.type = 'Bone';
21266		}
21267
21268	}
21269
21270	Bone.prototype.isBone = true;
21271
21272	class DataTexture extends Texture {
21273		constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding) {
21274			super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
21275			this.image = {
21276				data: data,
21277				width: width,
21278				height: height
21279			};
21280			this.magFilter = magFilter;
21281			this.minFilter = minFilter;
21282			this.generateMipmaps = false;
21283			this.flipY = false;
21284			this.unpackAlignment = 1;
21285		}
21286
21287	}
21288
21289	DataTexture.prototype.isDataTexture = true;
21290
vendor: 4,315 bytes, lines 21291-21447
21291	const _offsetMatrix = /*@__PURE__*/new Matrix4();
21292
21293	const _identityMatrix = /*@__PURE__*/new Matrix4();
21294
21295	class Skeleton {
21296		constructor(bones = [], boneInverses = []) {
21297			this.uuid = generateUUID();
21298			this.bones = bones.slice(0);
21299			this.boneInverses = boneInverses;
21300			this.boneMatrices = null;
21301			this.boneTexture = null;
21302			this.boneTextureSize = 0;
21303			this.frame = -1;
21304			this.init();
21305		}
21306
21307		init() {
21308			const bones = this.bones;
21309			const boneInverses = this.boneInverses;
21310			this.boneMatrices = new Float32Array(bones.length * 16); // calculate inverse bone matrices if necessary
21311
21312			if (boneInverses.length === 0) {
21313				this.calculateInverses();
21314			} else {
21315				// handle special case
21316				if (bones.length !== boneInverses.length) {
21317					console.warn('THREE.Skeleton: Number of inverse bone matrices does not match amount of bones.');
21318					this.boneInverses = [];
21319
21320					for (let i = 0, il = this.bones.length; i < il; i++) {
21321						this.boneInverses.push(new Matrix4());
21322					}
21323				}
21324			}
21325		}
21326
21327		calculateInverses() {
21328			this.boneInverses.length = 0;
21329
21330			for (let i = 0, il = this.bones.length; i < il; i++) {
21331				const inverse = new Matrix4();
21332
21333				if (this.bones[i]) {
21334					inverse.copy(this.bones[i].matrixWorld).invert();
21335				}
21336
21337				this.boneInverses.push(inverse);
21338			}
21339		}
21340
21341		pose() {
21342			// recover the bind-time world matrices
21343			for (let i = 0, il = this.bones.length; i < il; i++) {
21344				const bone = this.bones[i];
21345
21346				if (bone) {
21347					bone.matrixWorld.copy(this.boneInverses[i]).invert();
21348				}
21349			} // compute the local matrices, positions, rotations and scales
21350
21351
21352			for (let i = 0, il = this.bones.length; i < il; i++) {
21353				const bone = this.bones[i];
21354
21355				if (bone) {
21356					if (bone.parent && bone.parent.isBone) {
21357						bone.matrix.copy(bone.parent.matrixWorld).invert();
21358						bone.matrix.multiply(bone.matrixWorld);
21359					} else {
21360						bone.matrix.copy(bone.matrixWorld);
21361					}
21362
21363					bone.matrix.decompose(bone.position, bone.quaternion, bone.scale);
21364				}
21365			}
21366		}
21367
21368		update() {
21369			const bones = this.bones;
21370			const boneInverses = this.boneInverses;
21371			const boneMatrices = this.boneMatrices;
21372			const boneTexture = this.boneTexture; // flatten bone matrices to array
21373
21374			for (let i = 0, il = bones.length; i < il; i++) {
21375				// compute the offset between the current and the original transform
21376				const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix;
21377
21378				_offsetMatrix.multiplyMatrices(matrix, boneInverses[i]);
21379
21380				_offsetMatrix.toArray(boneMatrices, i * 16);
21381			}
21382
21383			if (boneTexture !== null) {
21384				boneTexture.needsUpdate = true;
21385			}
21386		}
21387
21388		clone() {
21389			return new Skeleton(this.bones, this.boneInverses);
21390		}
21391
21392		computeBoneTexture() {
21393			// layout (1 matrix = 4 pixels)
21394			//			RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
21395			//	with	8x8	pixel texture max	 16 bones * 4 pixels =	(8 * 8)
21396			//			 16x16 pixel texture max	 64 bones * 4 pixels = (16 * 16)
21397			//			 32x32 pixel texture max	256 bones * 4 pixels = (32 * 32)
21398			//			 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
21399			let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix
21400
21401			size = ceilPowerOfTwo(size);
21402			size = Math.max(size, 4);
21403			const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel
21404
21405			boneMatrices.set(this.boneMatrices); // copy current values
21406
21407			const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType);
21408			boneTexture.needsUpdate = true;
21409			this.boneMatrices = boneMatrices;
21410			this.boneTexture = boneTexture;
21411			this.boneTextureSize = size;
21412			return this;
21413		}
21414
21415		getBoneByName(name) {
21416			for (let i = 0, il = this.bones.length; i < il; i++) {
21417				const bone = this.bones[i];
21418
21419				if (bone.name === name) {
21420					return bone;
21421				}
21422			}
21423
21424			return undefined;
21425		}
21426
21427		dispose() {
21428			if (this.boneTexture !== null) {
21429				this.boneTexture.dispose();
21430				this.boneTexture = null;
21431			}
21432		}
21433
21434		fromJSON(json, bones) {
21435			this.uuid = json.uuid;
21436
21437			for (let i = 0, l = json.bones.length; i < l; i++) {
21438				const uuid = json.bones[i];
21439				let bone = bones[uuid];
21440
21441				if (bone === undefined) {
21442					console.warn('THREE.Skeleton: No bone found with UUID:', uuid);
21443					bone = new Bone();
21444				}
21445
21446				this.bones.push(bone);
21447				this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i])
21447);
21448			}
21449
21450			this.init();
21451			return this;
21452		}
21453
21454		toJSON() {
21455			const data = {
21456				metadata: {
21457					version: 4.5,
21458					type: 'Skeleton',
21459					generator: 'Skeleton.toJSON'
21460				},
21461				bones: [],
21462				boneInverses: []
21463			};
21464			data.uuid = this.uuid;
21465			const bones = this.bones;
21466			const boneInverses = this.boneInverses;
21467
21468			for (let i = 0, l = bones.length; i < l; i++) {
21469				const bone = bones[i];
21470				data.bones.push(bone.uuid);
21471				const boneInverse = boneInverses[i];
21472				data.boneInverses.push(boneInverse.toArray());
21473			}
21474
21475			return data;
21476		}
21477
21478	}
21479
21480	class InstancedBufferAttribute extends BufferAttribute {
21481		constructor(array, itemSize, normalized, meshPerAttribute = 1) {
21482			if (typeof normalized === 'number') {
21483				meshPerAttribute = normalized;
21484				normalized = false;
21485				console.error('THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.');
21486			}
21487
21488			super(array, itemSize, normalized);
21489			this.meshPerAttribute = meshPerAttribute;
21490		}
21491
21492		copy(source) {
21493			super.copy(source);
21494			this.meshPerAttribute = source.meshPerAttribute;
21495			return this;
21496		}
21497
21498		toJSON() {
21499			const data = super.toJSON();
21500			data.meshPerAttribute = this.meshPerAttribute;
21501			data.isInstancedBufferAttribute = true;
21502			return data;
21503		}
21504
21505	}
21506
21507	InstancedBufferAttribute.prototype.isInstancedBufferAttribute = true;
21508
21509	const _instanceLocalMatrix = /*@__PURE__*/new Matrix4();
21510
21511	const _instanceWorldMatrix = /*@__PURE__*/new Matrix4();
21512
21513	const _instanceIntersects = [];
21514
21515	const _mesh = /*@__PURE__*/new Mesh();
21516
21517	class InstancedMesh extends Mesh {
21518		constructor(geometry, material, count) {
21519			super(geometry, material);
21520			this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16);
21521			this.instanceColor = null;
21522			this.count = count;
21523			this.frustumCulled = false;
21524		}
21525
21526		copy(source) {
21527			super.copy(source);
21528			this.instanceMatrix.copy(source.instanceMatrix);
21529			if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone();
21530			this.count = source.count;
21531			return this;
21532		}
21533
21534		getColorAt(index, color) {
21535			color.fromArray(this.instanceColor.array, index * 3);
21536		}
21537
21538		getMatrixAt(index, matrix) {
21539			matrix.fromArray(this.instanceMatrix.array, index * 16);
21540		}
21541
21542		raycast(raycaster, intersects) {
21543			const matrixWorld = this.matrixWorld;
21544			const raycastTimes = this.count;
21545			_mesh.geometry = this.geometry;
21546			_mesh.material = this.material;
21547			if (_mesh.material === undefined) return;
21548
21549			for (let instanceId = 0; instanceId < raycastTimes; instanceId++) {
21550				// calculate the world matrix for each instance
21551				this.getMatrixAt(instanceId, _instanceLocalMatrix);
21552
21553				_instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance
21554
21555
21556				_mesh.matrixWorld = _instanceWorldMatrix;
21557
21558				_mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast
21559
21560
21561				for (let i = 0, l = _instanceIntersects.length; i < l; i++) {
21562					const intersect = _instanceIntersects[i];
21563					intersect.instanceId = instanceId;
21564					intersect.object = this;
21565					intersects.push(intersect);
21566				}
21567
21568				_instanceIntersects.length = 0;
21569			}
21570		}
21571
21572		setColorAt(index, color) {
21573			if (this.instanceColor === null) {
21574				this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3);
21575			}
21576
21577			color.toArray(this.instanceColor.array, index * 3);
21578		}
21579
21580		setMatrixAt(index, matrix) {
21581			matrix.toArray(this.instanceMatrix.array, index * 16);
21582		}
21583
21584		updateMorphTargets() {}
21585
21586		dispose() {
21587			this.dispatchEvent({
21588				type: 'dispose'
21589			});
21590		}
21591
21592	}
21593
21594	InstancedMesh.prototype.isInstancedMesh = true;
21595
21596	/**
21597	 * parameters = {
21598	 *	color: <hex>,
21599	 *	opacity: <float>,
21600	 *
21601	 *	linewidth: <float>,
21602	 *	linecap: "round",
21603	 *	linejoin: "round"
21604	 * }
21605	 */
21606
21607	class LineBasicMaterial extends Material {
21608		constructor(parameters) {
21609			super();
21610			this.type = 'LineBasicMaterial';
21611			this.color = new Color(0xffffff);
21612			this.linewidth = 1;
21613			this.linecap = 'round';
21614			this.linejoin = 'round';
21615			this.setValues(parameters);
21616		}
21617
21618		copy(source) {
21619			super.copy(source);
21620			this.color.copy(source.color);
21621			this.linewidth = source.linewidth;
21622			this.linecap = source.linecap;
21623			this.linejoin = source.linejoin;
21624			return this;
21625		}
21626
21627	}
21628
21629	LineBasicMaterial.prototype.isLineBasicMaterial = true;
21630
21631	const _start$1 = /*@__PURE__*/new Vector3();
21632
21633	const _end$1 = /*@__PURE__*/new Vector3();
21634
21635	const _inverseMatrix$1 = /*@__PURE__*/new Matrix4();
21636
21637	const _ray$1 = /*@__PURE__*/new Ray();
21638
21639	const _sphere$1 = /*@__PURE__*/new Sphere();
21640
21641	class Line extends Object3D {
21642		constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) {
21643			super();
21644			this.type = 'Line';
21645			this.geometry = geometry;
21646			this.material = material;
21647			this.updateMorphTargets();
21648		}
21649
21650		copy(source) {
21651			super.copy(source);
21652			this.material = source.material;
21653			this.geometry = source.geometry;
21654			return this;
21655		}
21656
21657		computeLineDistances() {
21658			const geometry = this.geometry;
21659
21660			if (geometry.isBufferGeometry) {
21661				// we assume non-indexed geometry
21662				if (geometry.index === null) {
21663					const positionAttribute = geometry.attributes.position;
21664					const lineDistances = [0];
21665
21666					for (let i = 1, l = positionAttribute.count; i < l; i++) {
21667						_start$1.fromBufferAttribute(positionAttribute, i - 1);
21668
21669						_end$1.fromBufferAttribute(positionAttribute, i);
21670
21671						lineDistances[i] = lineDistances[i - 1];
21672						lineDistances[i] += _start$1.distanceTo(_end$1);
21673					}
21674
21675					geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1));
21676				} else {
21677					console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.');
21678				}
21679			} else if (geometry.isGeometry) {
vendor: 5,604 bytes, lines 21680-21844
21680				console.error('THREE.Line.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.');
21681			}
21682
21683			return this;
21684		}
21685
21686		raycast(raycaster, intersects) {
21687			const geometry = this.geometry;
21688			const matrixWorld = this.matrixWorld;
21689			const threshold = raycaster.params.Line.threshold;
21690			const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray
21691
21692			if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
21693
21694			_sphere$1.copy(geometry.boundingSphere);
21695
21696			_sphere$1.applyMatrix4(matrixWorld);
21697
21698			_sphere$1.radius += threshold;
21699			if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; //
21700
21701			_inverseMatrix$1.copy(matrixWorld).invert();
21702
21703			_ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1);
21704
21705			const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3);
21706			const localThresholdSq = localThreshold * localThreshold;
21707			const vStart = new Vector3();
21708			const vEnd = new Vector3();
21709			const interSegment = new Vector3();
21710			const interRay = new Vector3();
21711			const step = this.isLineSegments ? 2 : 1;
21712
21713			if (geometry.isBufferGeometry) {
21714				const index = geometry.index;
21715				const attributes = geometry.attributes;
21716				const positionAttribute = attributes.position;
21717
21718				if (index !== null) {
21719					const start = Math.max(0, drawRange.start);
21720					const end = Math.min(index.count, drawRange.start + drawRange.count);
21721
21722					for (let i = start, l = end - 1; i < l; i += step) {
21723						const a = index.getX(i);
21724						const b = index.getX(i + 1);
21725						vStart.fromBufferAttribute(positionAttribute, a);
21726						vEnd.fromBufferAttribute(positionAttribute, b);
21727
21728						const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment);
21729
21730						if (distSq > localThresholdSq) continue;
21731						interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation
21732
21733						const distance = raycaster.ray.origin.distanceTo(interRay);
21734						if (distance < raycaster.near || distance > raycaster.far) continue;
21735						intersects.push({
21736							distance: distance,
21737							// What do we want? intersection point on the ray or on the segment??
21738							// point: raycaster.ray.at( distance ),
21739							point: interSegment.clone().applyMatrix4(this.matrixWorld),
21740							index: i,
21741							face: null,
21742							faceIndex: null,
21743							object: this
21744						});
21745					}
21746				} else {
21747					const start = Math.max(0, drawRange.start);
21748					const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count);
21749
21750					for (let i = start, l = end - 1; i < l; i += step) {
21751						vStart.fromBufferAttribute(positionAttribute, i);
21752						vEnd.fromBufferAttribute(positionAttribute, i + 1);
21753
21754						const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment);
21755
21756						if (distSq > localThresholdSq) continue;
21757						interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation
21758
21759						const distance = raycaster.ray.origin.distanceTo(interRay);
21760						if (distance < raycaster.near || distance > raycaster.far) continue;
21761						intersects.push({
21762							distance: distance,
21763							// What do we want? intersection point on the ray or on the segment??
21764							// point: raycaster.ray.at( distance ),
21765							point: interSegment.clone().applyMatrix4(this.matrixWorld),
21766							index: i,
21767							face: null,
21768							faceIndex: null,
21769							object: this
21770						});
21771					}
21772				}
21773			} else if (geometry.isGeometry) {
21774				console.error('THREE.Line.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.');
21775			}
21776		}
21777
21778		updateMorphTargets() {
21779			const geometry = this.geometry;
21780
21781			if (geometry.isBufferGeometry) {
21782				const morphAttributes = geometry.morphAttributes;
21783				const keys = Object.keys(morphAttributes);
21784
21785				if (keys.length > 0) {
21786					const morphAttribute = morphAttributes[keys[0]];
21787
21788					if (morphAttribute !== undefined) {
21789						this.morphTargetInfluences = [];
21790						this.morphTargetDictionary = {};
21791
21792						for (let m = 0, ml = morphAttribute.length; m < ml; m++) {
21793							const name = morphAttribute[m].name || String(m);
21794							this.morphTargetInfluences.push(0);
21795							this.morphTargetDictionary[name] = m;
21796						}
21797					}
21798				}
21799			} else {
21800				const morphTargets = geometry.morphTargets;
21801
21802				if (morphTargets !== undefined && morphTargets.length > 0) {
21803					console.error('THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.');
21804				}
21805			}
21806		}
21807
21808	}
21809
21810	Line.prototype.isLine = true;
21811
21812	const _start = /*@__PURE__*/new Vector3();
21813
21814	const _end = /*@__PURE__*/new Vector3();
21815
21816	class LineSegments extends Line {
21817		constructor(geometry, material) {
21818			super(geometry, material);
21819			this.type = 'LineSegments';
21820		}
21821
21822		computeLineDistances() {
21823			const geometry = this.geometry;
21824
21825			if (geometry.isBufferGeometry) {
21826				// we assume non-indexed geometry
21827				if (geometry.index === null) {
21828					const positionAttribute = geometry.attributes.position;
21829					const lineDistances = [];
21830
21831					for (let i = 0, l = positionAttribute.count; i < l; i += 2) {
21832						_start.fromBufferAttribute(positionAttribute, i);
21833
21834						_end.fromBufferAttribute(positionAttribute, i + 1);
21835
21836						lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1];
21837						lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end);
21838					}
21839
21840					geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1));
21841				} else {
21842					console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.');
21843				}
21844			} else if (geometry.isGeometry) {
21845				console.error('THREE.LineSegments.computeLineDistances() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.');
21846			}
21847
21848			return this;
21849		}
21850
21851	}
21852
21853	LineSegments.prototype.isLineSegments = true;
21854
21855	class LineLoop extends Line {
21856		constructor(geometry, material) {
21857			super(geometry, material);
21858			this.type = 'LineLoop';
21859		}
21860
21861	}
21862
21863	LineLoop.prototype.isLineLoop = true;
21864
21865	/**
21866	 * parameters = {
21867	 *	color: <hex>,
21868	 *	opacity: <float>,
21869	 *	map: new THREE.Texture( <Image> ),
21870	 *	alphaMap: new THREE.Texture( <Image> ),
21871	 *
21872	 *	size: <float>,
21873	 *	sizeAttenuation: <bool>
21874	 *
21875	 * }
21876	 */
21877
21878	class PointsMaterial extends Material {
21879		constructor(parameters) {
21880			super();
21881			this.type = 'PointsMaterial';
21882			this.color = new Color(0xffffff);
21883			this.map = null;
21884			this.alphaMap = null;
21885			this.size = 1;
21886			this.sizeAttenuation = true;
21887			this.setValues(parameters);
21888		}
21889
21890		copy(source) {
21891			super.copy(source);
21892			this.color.copy(source.color);
21893			this.map = source.map;
21894			this.alphaMap = source.alphaMap;
21895			this.size = source.size;
21896			this.sizeAttenuation = source.sizeAttenuation;
21897			return this;
21898		}
21899
21900	}
21901
21902	PointsMaterial.prototype.isPointsMaterial = true;
21903
21904	const _inverseMatrix = /*@__PURE__*/new Matrix4();
21905
21906	const _ray = /*@__PURE__*/new Ray();
21907
21908	const _sphere = /*@__PURE__*/new Sphere();
21909
21910	const _position$2 = /*@__PURE__*/new Vector3();
21911
21912	class Points extends Object3D {
21913		constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) {
21914			super();
21915			this.type = 'Points';
21916			this.geometry = geometry;
21917			this.material = material;
21918			this.updateMorphTargets();
21919		}
21920
21921		copy(source) {
21922			super.copy(source);
21923			this.material = source.material;
21924			this.geometry = source.geometry;
21925			return this;
21926		}
21927
21928		raycast(raycaster, intersects) {
21929			const geometry = this.geometry;
21930			const matrixWorld = this.matrixWorld;
21931			const threshold = raycaster.params.Points.threshold;
21932			const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray
21933
21934			if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
21935
21936			_sphere.copy(geometry.boundingSphere);
21937
21938			_sphere.applyMatrix4(matrixWorld);
21939
21940			_sphere.radius += threshold;
21941			if (raycaster.ray.intersectsSphere(_sphere) === false) return; //
21942
21943			_inverseMatrix.copy(matrixWorld).invert();
21944
21945			_ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix);
21946
21947			const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3);
21948			const localThresholdSq = localThreshold * localThreshold;
21949
21950			if (geometry.isBufferGeometry) {
21951				const index = geometry.index;
21952				const attributes = geometry.attributes;
21953				const positionAttribute = attributes.position;
21954
21955				if (index !== null) {
21956					const start = Math.max(0, drawRange.start);
21957					const end = Math.min(index.count, drawRange.start + drawRange.count);
21958
21959					for (let i = start, il = end; i < il; i++) {
21960						const a = index.getX(i);
21961
21962						_position$2.fromBufferAttribute(positionAttribute, a);
21963
21964						testPoint(_position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this);
21965					}
21966				} else {
21967					const start = Math.max(0, drawRange.start);
21968					const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count);
21969
21970					for (let i = start, l = end; i < l; i++) {
21971						_position$2.fromBufferAttribute(positionAttribute, i);
21972
21973						testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this);
21974					}
21975				}
21976			} else {
21977				console.error('THREE.Points.raycast() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.');
21978			}
21979		}
21980
21981		updateMorphTargets() {
21982			const geometry = this.geometry;
21983
21984			if (geometry.isBufferGeometry) {
21985				const morphAttributes = geometry.morphAttributes;
21986				const keys = Object.keys(morphAttributes);
21987
21988				if (keys.length > 0) {
21989					const morphAttribute = morphAttributes[keys[0]];
21990
21991					if (morphAttribute !== undefined) {
21992						this.morphTargetInfluences = [];
21993						this.morphTargetDictionary = {};
21994
21995						for (let m = 0, ml = morphAttribute.length; m < ml; m++) {
21996							const name = morphAttribute[m].name || String(m);
21997							this.morphTargetInfluences.push(0);
21998							this.morphTargetDictionary[name] = m;
21999						}
22000					}
22001				}
22002			} else {
22003				const morphTargets = geometry.morphTargets;
22004
22005				if (morphTargets !== undefined && morphTargets.length > 0) {
22006					console.error('THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.');
22007				}
22008			}
22009		}
22010
22011	}
22012
22013	Points.prototype.isPoints = true;
22014
22015	function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) {
22016		const rayPointDistanceSq = _ray.distanceSqToPoint(point);
22017
22018		if (rayPointDistanceSq < localThresholdSq) {
22019			const intersectPoint = new Vector3();
22020
22021			_ray.closestPointToPoint(point, intersectPoint);
22022
22023			intersectPoint.applyMatrix4(matrixWorld);
22024			const distance = raycaster.ray.origin.distanceTo(intersectPoint);
22025			if (distance < raycaster.near || distance > raycaster.far) return;
22026			intersects.push({
22027				distance: distance,
22028				distanceToRay: Math.sqrt(rayPointDistanceSq),
22029				point: intersectPoint,
22030				index: index,
22031				face: null,
22032				object: object
22033			});
22034		}
22035	}
22036
22037	class VideoTexture extends Texture {
22038		constructor(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) {
22039			super(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
22040			this.format = format !== undefined ? format : RGBFormat;
22041			this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
22042			this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
22043			this.generateMipmaps = false;
22044			const scope = this;
22045
22046			function updateVideo() {
22047				scope.needsUpdate = true;
22048				video.requestVideoFrameCallback(updateVideo);
22049			}
22050
22051			if ('requestVideoFrameCallback' in video) {
22052				video.requestVideoFrameCallback(updateVideo);
22053			}
22054		}
22055
22056		clone() {
22057			return new this.constructor(this.image).copy(this);
22058		}
22059
22060		update() {
22061			const video = this.image;
22062			const hasVideoFrameCallback = ('requestVideoFrameCallback' in video);
22063
22064			if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) {
22065				this.needsUpdate = true;
22066			}
22067		}
22068
22069	}
22070
22071	VideoTexture.prototype.isVideoTexture = true;
22072
22073	class FramebufferTexture extends Texture {
22074		constructor(width, height, format) {
22075			super({
22076				width,
22077				height
22078			});
22079			this.format = format;
22080			this.magFilter = NearestFilter;
22081			this.minFilter = NearestFilter;
22082			this.generateMipmaps = false;
22083			this.needsUpdate = true;
22084		}
22085
22086	}
22087
22088	FramebufferTexture.prototype.isFramebufferTexture = true;
22089
22090	class CompressedTexture extends Texture {
22091		constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) {
22092			super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
22093			this.image = {
22094				width: width,
22095				height: height
22096			};
22097			this.mipmaps = mipmaps; // no flipping for cube textures
22098			// (also flipping doesn't work for compressed textures )
22099
22100			this.flipY = false; // can't generate mipmaps for compressed textures
22101			// mips must be embedded in DDS files
22102
22103			this.generateMipmaps = false;
22104		}
22105
22106	}
22107
22108	CompressedTexture.prototype.isCompressedTexture = true;
22109
22110	class CanvasTexture extends Texture {
22111		constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) {
22112			super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
22113			this.needsUpdate = true;
22114		}
22115
22116	}
22117
22118	CanvasTexture.prototype.isCanvasTexture = true;
22119
22120	class CircleGeometry extends BufferGeometry {
22121		constructor(radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2) {
22122			super();
22123			this.type = 'CircleGeometry';
22124			this.parameters = {
22125				radius: radius,
22126				segments: segments,
22127				thetaStart: thetaStart,
22128				thetaLength: thetaLength
22129			};
22130			segments = Math.max(3, segments); // buffers
22131
22132			const indices = [];
22133			const vertices = [];
22134			const normals = [];
22135			const uvs = []; // helper variables
22136
22137			const vertex = new Vector3();
22138			const uv = new Vector2(); // center point
22139
22140			vertices.push(0, 0, 0);
22141			normals.push(0, 0, 1);
22142			uvs.push(0.5, 0.5);
22143
22144			for (let s = 0, i = 3; s <= segments; s++, i += 3) {
22145				const segment = thetaStart + s / segments * thetaLength; // vertex
22146
22147				vertex.x = radius * Math.cos(segment);
22148				vertex.y = radius * Math.sin(segment);
22149				vertices.push(vertex.x, vertex.y, vertex.z); // normal
22150
22151				normals.push(0, 0, 1); // uvs
22152
22153				uv.x = (vertices[i] / radius + 1) / 2;
22154				uv.y = (vertices[i + 1] / radius + 1) / 2;
22155				uvs.push(uv.x, uv.y);
22156			} // indices
22157
22158
22159			for (let i = 1; i <= segments; i++) {
22160				indices.push(i, i + 1, 0);
22161			} // build geometry
22162
22163
22164			this.setIndex(indices);
22165			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
22166			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
22167			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
22168		}
22169
22170		static fromJSON(data) {
22171			return new CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength);
22172		}
22173
22174	}
22175
22176	class CylinderGeometry extends BufferGeometry {
22177		constructor(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
22178			super();
22179			this.type = 'CylinderGeometry';
22180			this.parameters = {
22181				radiusTop: radiusTop,
22182				radiusBottom: radiusBottom,
22183				height: height,
22184				radialSegments: radialSegments,
22185				heightSegments: heightSegments,
22186				openEnded: openEnded,
22187				thetaStart: thetaStart,
22188				thetaLength: thetaLength
22189			};
22190			const scope = this;
22191			radialSegments = Math.floor(radialSegments);
22192			heightSegments = Math.floor(heightSegments); // buffers
22193
22194			const indices = [];
22195			const vertices = [];
22196			const normals = [];
22197			const uvs = []; // helper variables
22198
22199			let index = 0;
22200			const indexArray = [];
22201			const halfHeight = height / 2;
22202			let groupStart = 0; // generate geometry
22203
22204			generateTorso();
22205
22206			if (openEnded === false) {
22207				if (radiusTop > 0) generateCap(true);
22208				if (radiusBottom > 0) generateCap(false);
22209			} // build geometry
22210
22211
22212			this.setIndex(indices);
22213			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
22214			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
22215			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
22216
22217			function generateTorso() {
22218				const normal = new Vector3();
22219				const vertex = new Vector3();
22220				let groupCount = 0; // this will be used to calculate the normal
22221
22222				const slope = (radiusBottom - radiusTop) / height; // generate vertices, normals and uvs
22223
22224				for (let y = 0; y <= heightSegments; y++) {
22225					const indexRow = [];
22226					const v = y / heightSegments; // calculate the radius of the current row
22227
22228					const radius = v * (radiusBottom - radiusTop) + radiusTop;
22229
22230					for (let x = 0; x <= radialSegments; x++) {
22231						const u = x / radialSegments;
22232						const theta = u * thetaLength + thetaStart;
22233						const sinTheta = Math.sin(theta);
22234						const cosTheta = Math.cos(theta); // vertex
22235
vendor: 14,486 bytes, lines 22236-22702
22236						vertex.x = radius * sinTheta;
22237						vertex.y = -v * height + halfHeight;
22238						vertex.z = radius * cosTheta;
22239						vertices.push(vertex.x, vertex.y, vertex.z); // normal
22240
22241						normal.set(sinTheta, slope, cosTheta).normalize();
22242						normals.push(normal.x, normal.y, normal.z); // uv
22243
22244						uvs.push(u, 1 - v); // save index of vertex in respective row
22245
22246						indexRow.push(index++);
22247					} // now save vertices of the row in our index array
22248
22249
22250					indexArray.push(indexRow);
22251				} // generate indices
22252
22253
22254				for (let x = 0; x < radialSegments; x++) {
22255					for (let y = 0; y < heightSegments; y++) {
22256						// we use the index array to access the correct indices
22257						const a = indexArray[y][x];
22258						const b = indexArray[y + 1][x];
22259						const c = indexArray[y + 1][x + 1];
22260						const d = indexArray[y][x + 1]; // faces
22261
22262						indices.push(a, b, d);
22263						indices.push(b, c, d); // update group counter
22264
22265						groupCount += 6;
22266					}
22267				} // add a group to the geometry. this will ensure multi material support
22268
22269
22270				scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups
22271
22272				groupStart += groupCount;
22273			}
22274
22275			function generateCap(top) {
22276				// save the index of the first center vertex
22277				const centerIndexStart = index;
22278				const uv = new Vector2();
22279				const vertex = new Vector3();
22280				let groupCount = 0;
22281				const radius = top === true ? radiusTop : radiusBottom;
22282				const sign = top === true ? 1 : -1; // first we generate the center vertex data of the cap.
22283				// because the geometry needs one set of uvs per face,
22284				// we must generate a center vertex per face/segment
22285
22286				for (let x = 1; x <= radialSegments; x++) {
22287					// vertex
22288					vertices.push(0, halfHeight * sign, 0); // normal
22289
22290					normals.push(0, sign, 0); // uv
22291
22292					uvs.push(0.5, 0.5); // increase index
22293
22294					index++;
22295				} // save the index of the last center vertex
22296
22297
22298				const centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs
22299
22300				for (let x = 0; x <= radialSegments; x++) {
22301					const u = x / radialSegments;
22302					const theta = u * thetaLength + thetaStart;
22303					const cosTheta = Math.cos(theta);
22304					const sinTheta = Math.sin(theta); // vertex
22305
22306					vertex.x = radius * sinTheta;
22307					vertex.y = halfHeight * sign;
22308					vertex.z = radius * cosTheta;
22309					vertices.push(vertex.x, vertex.y, vertex.z); // normal
22310
22311					normals.push(0, sign, 0); // uv
22312
22313					uv.x = cosTheta * 0.5 + 0.5;
22314					uv.y = sinTheta * 0.5 * sign + 0.5;
22315					uvs.push(uv.x, uv.y); // increase index
22316
22317					index++;
22318				} // generate indices
22319
22320
22321				for (let x = 0; x < radialSegments; x++) {
22322					const c = centerIndexStart + x;
22323					const i = centerIndexEnd + x;
22324
22325					if (top === true) {
22326						// face top
22327						indices.push(i, i + 1, c);
22328					} else {
22329						// face bottom
22330						indices.push(i + 1, i, c);
22331					}
22332
22333					groupCount += 3;
22334				} // add a group to the geometry. this will ensure multi material support
22335
22336
22337				scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups
22338
22339				groupStart += groupCount;
22340			}
22341		}
22342
22343		static fromJSON(data) {
22344			return new CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength);
22345		}
22346
22347	}
22348
22349	class ConeGeometry extends CylinderGeometry {
22350		constructor(radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
22351			super(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength);
22352			this.type = 'ConeGeometry';
22353			this.parameters = {
22354				radius: radius,
22355				height: height,
22356				radialSegments: radialSegments,
22357				heightSegments: heightSegments,
22358				openEnded: openEnded,
22359				thetaStart: thetaStart,
22360				thetaLength: thetaLength
22361			};
22362		}
22363
22364		static fromJSON(data) {
22365			return new ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength);
22366		}
22367
22368	}
22369
22370	class PolyhedronGeometry extends BufferGeometry {
22371		constructor(vertices = [], indices = [], radius = 1, detail = 0) {
22372			super();
22373			this.type = 'PolyhedronGeometry';
22374			this.parameters = {
22375				vertices: vertices,
22376				indices: indices,
22377				radius: radius,
22378				detail: detail
22379			}; // default buffer data
22380
22381			const vertexBuffer = [];
22382			const uvBuffer = []; // the subdivision creates the vertex buffer data
22383
22384			subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius
22385
22386			applyRadius(radius); // finally, create the uv data
22387
22388			generateUVs(); // build non-indexed geometry
22389
22390			this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3));
22391			this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3));
22392			this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2));
22393
22394			if (detail === 0) {
22395				this.computeVertexNormals(); // flat normals
22396			} else {
22397				this.normalizeNormals(); // smooth normals
22398			} // helper functions
22399
22400
22401			function subdivide(detail) {
22402				const a = new Vector3();
22403				const b = new Vector3();
22404				const c = new Vector3(); // iterate over all faces and apply a subdivison with the given detail value
22405
22406				for (let i = 0; i < indices.length; i += 3) {
22407					// get the vertices of the face
22408					getVertexByIndex(indices[i + 0], a);
22409					getVertexByIndex(indices[i + 1], b);
22410					getVertexByIndex(indices[i + 2], c); // perform subdivision
22411
22412					subdivideFace(a, b, c, detail);
22413				}
22414			}
22415
22416			function subdivideFace(a, b, c, detail) {
22417				const cols = detail + 1; // we use this multidimensional array as a data structure for creating the subdivision
22418
22419				const v = []; // construct all of the vertices for this subdivision
22420
22421				for (let i = 0; i <= cols; i++) {
22422					v[i] = [];
22423					const aj = a.clone().lerp(c, i / cols);
22424					const bj = b.clone().lerp(c, i / cols);
22425					const rows = cols - i;
22426
22427					for (let j = 0; j <= rows; j++) {
22428						if (j === 0 && i === cols) {
22429							v[i][j] = aj;
22430						} else {
22431							v[i][j] = aj.clone().lerp(bj, j / rows);
22432						}
22433					}
22434				} // construct all of the faces
22435
22436
22437				for (let i = 0; i < cols; i++) {
22438					for (let j = 0; j < 2 * (cols - i) - 1; j++) {
22439						const k = Math.floor(j / 2);
22440
22441						if (j % 2 === 0) {
22442							pushVertex(v[i][k + 1]);
22443							pushVertex(v[i + 1][k]);
22444							pushVertex(v[i][k]);
22445						} else {
22446							pushVertex(v[i][k + 1]);
22447							pushVertex(v[i + 1][k + 1]);
22448							pushVertex(v[i + 1][k]);
22449						}
22450					}
22451				}
22452			}
22453
22454			function applyRadius(radius) {
22455				const vertex = new Vector3(); // iterate over the entire buffer and apply the radius to each vertex
22456
22457				for (let i = 0; i < vertexBuffer.length; i += 3) {
22458					vertex.x = vertexBuffer[i + 0];
22459					vertex.y = vertexBuffer[i + 1];
22460					vertex.z = vertexBuffer[i + 2];
22461					vertex.normalize().multiplyScalar(radius);
22462					vertexBuffer[i + 0] = vertex.x;
22463					vertexBuffer[i + 1] = vertex.y;
22464					vertexBuffer[i + 2] = vertex.z;
22465				}
22466			}
22467
22468			function generateUVs() {
22469				const vertex = new Vector3();
22470
22471				for (let i = 0; i < vertexBuffer.length; i += 3) {
22472					vertex.x = vertexBuffer[i + 0];
22473					vertex.y = vertexBuffer[i + 1];
22474					vertex.z = vertexBuffer[i + 2];
22475					const u = azimuth(vertex) / 2 / Math.PI + 0.5;
22476					const v = inclination(vertex) / Math.PI + 0.5;
22477					uvBuffer.push(u, 1 - v);
22478				}
22479
22480				correctUVs();
22481				correctSeam();
22482			}
22483
22484			function correctSeam() {
22485				// handle case when face straddles the seam, see #3269
22486				for (let i = 0; i < uvBuffer.length; i += 6) {
22487					// uv data of a single face
22488					const x0 = uvBuffer[i + 0];
22489					const x1 = uvBuffer[i + 2];
22490					const x2 = uvBuffer[i + 4];
22491					const max = Math.max(x0, x1, x2);
22492					const min = Math.min(x0, x1, x2); // 0.9 is somewhat arbitrary
22493
22494					if (max > 0.9 && min < 0.1) {
22495						if (x0 < 0.2) uvBuffer[i + 0] += 1;
22496						if (x1 < 0.2) uvBuffer[i + 2] += 1;
22497						if (x2 < 0.2) uvBuffer[i + 4] += 1;
22498					}
22499				}
22500			}
22501
22502			function pushVertex(vertex) {
22503				vertexBuffer.push(vertex.x, vertex.y, vertex.z);
22504			}
22505
22506			function getVertexByIndex(index, vertex) {
22507				const stride = index * 3;
22508				vertex.x = vertices[stride + 0];
22509				vertex.y = vertices[stride + 1];
22510				vertex.z = vertices[stride + 2];
22511			}
22512
22513			function correctUVs() {
22514				const a = new Vector3();
22515				const b = new Vector3();
22516				const c = new Vector3();
22517				const centroid = new Vector3();
22518				const uvA = new Vector2();
22519				const uvB = new Vector2();
22520				const uvC = new Vector2();
22521
22522				for (let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6) {
22523					a.set(vertexBuffer[i + 0], vertexBuffer[i + 1], vertexBuffer[i + 2]);
22524					b.set(vertexBuffer[i + 3], vertexBuffer[i + 4], vertexBuffer[i + 5]);
22525					c.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]);
22526					uvA.set(uvBuffer[j + 0], uvBuffer[j + 1]);
22527					uvB.set(uvBuffer[j + 2], uvBuffer[j + 3]);
22528					uvC.set(uvBuffer[j + 4], uvBuffer[j + 5]);
22529					centroid.copy(a).add(b).add(c).divideScalar(3);
22530					const azi = azimuth(centroid);
22531					correctUV(uvA, j + 0, a, azi);
22532					correctUV(uvB, j + 2, b, azi);
22533					correctUV(uvC, j + 4, c, azi);
22534				}
22535			}
22536
22537			function correctUV(uv, stride, vector, azimuth) {
22538				if (azimuth < 0 && uv.x === 1) {
22539					uvBuffer[stride] = uv.x - 1;
22540				}
22541
22542				if (vector.x === 0 && vector.z === 0) {
22543					uvBuffer[stride] = azimuth / 2 / Math.PI + 0.5;
22544				}
22545			} // Angle around the Y axis, counter-clockwise when looking from above.
22546
22547
22548			function azimuth(vector) {
22549				return Math.atan2(vector.z, -vector.x);
22550			} // Angle above the XZ plane.
22551
22552
22553			function inclination(vector) {
22554				return Math.atan2(-vector.y, Math.sqrt(vector.x * vector.x + vector.z * vector.z));
22555			}
22556		}
22557
22558		static fromJSON(data) {
22559			return new PolyhedronGeometry(data.vertices, data.indices, data.radius, data.details);
22560		}
22561
22562	}
22563
22564	class DodecahedronGeometry extends PolyhedronGeometry {
22565		constructor(radius = 1, detail = 0) {
22566			const t = (1 + Math.sqrt(5)) / 2;
22567			const r = 1 / t;
22568			const vertices = [// (±1, ±1, ±1)
22569			-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, ±1/φ, ±φ)
22570			0, -r, -t, 0, -r, t, 0, r, -t, 0, r, t, // (±1/φ, ±φ, 0)
22571			-r, -t, 0, -r, t, 0, r, -t, 0, r, t, 0, // (±φ, 0, ±1/φ)
22572			-t, 0, -r, t, 0, -r, -t, 0, r, t, 0, r];
22573			const indices = [3, 11, 7, 3, 7, 15, 3, 15, 13, 7, 19, 17, 7, 17, 6, 7, 6, 15, 17, 4, 8, 17, 8, 10, 17, 10, 6, 8, 0, 16, 8, 16, 2, 8, 2, 10, 0, 12, 1, 0, 1, 18, 0, 18, 16, 6, 10, 2, 6, 2, 13, 6, 13, 15, 2, 16, 18, 2, 18, 3, 2, 3, 13, 18, 1, 9, 18, 9, 11, 18, 11, 3, 4, 14, 12, 4, 12, 0, 4, 0, 8, 11, 9, 5, 11, 5, 19, 11, 19, 7, 19, 5, 14, 19, 14, 4, 19, 4, 17, 1, 12, 14, 1, 14, 5, 1, 5, 9];
22574			super(vertices, indices, radius, detail);
22575			this.type = 'DodecahedronGeometry';
22576			this.parameters = {
22577				radius: radius,
22578				detail: detail
22579			};
22580		}
22581
22582		static fromJSON(data) {
22583			return new DodecahedronGeometry(data.radius, data.detail);
22584		}
22585
22586	}
22587
22588	const _v0 = new Vector3();
22589
22590	const _v1$1 = new Vector3();
22591
22592	const _normal = new Vector3();
22593
22594	const _triangle = new Triangle();
22595
22596	class EdgesGeometry extends BufferGeometry {
22597		constructor(geometry = null, thresholdAngle = 1) {
22598			super();
22599			this.type = 'EdgesGeometry';
22600			this.parameters = {
22601				geometry: geometry,
22602				thresholdAngle: thresholdAngle
22603			};
22604
22605			if (geometry !== null) {
22606				const precisionPoints = 4;
22607				const precision = Math.pow(10, precisionPoints);
22608				const thresholdDot = Math.cos(DEG2RAD * thresholdAngle);
22609				const indexAttr = geometry.getIndex();
22610				const positionAttr = geometry.getAttribute('position');
22611				const indexCount = indexAttr ? indexAttr.count : positionAttr.count;
22612				const indexArr = [0, 0, 0];
22613				const vertKeys = ['a', 'b', 'c'];
22614				const hashes = new Array(3);
22615				const edgeData = {};
22616				const vertices = [];
22617
22618				for (let i = 0; i < indexCount; i += 3) {
22619					if (indexAttr) {
22620						indexArr[0] = indexAttr.getX(i);
22621						indexArr[1] = indexAttr.getX(i + 1);
22622						indexArr[2] = indexAttr.getX(i + 2);
22623					} else {
22624						indexArr[0] = i;
22625						indexArr[1] = i + 1;
22626						indexArr[2] = i + 2;
22627					}
22628
22629					const {
22630						a,
22631						b,
22632						c
22633					} = _triangle;
22634					a.fromBufferAttribute(positionAttr, indexArr[0]);
22635					b.fromBufferAttribute(positionAttr, indexArr[1]);
22636					c.fromBufferAttribute(positionAttr, indexArr[2]);
22637
22638					_triangle.getNormal(_normal); // create hashes for the edge from the vertices
22639
22640
22641					hashes[0] = `${Math.round(a.x * precision)},${Math.round(a.y * precision)},${Math.round(a.z * precision)}`;
22642					hashes[1] = `${Math.round(b.x * precision)},${Math.round(b.y * precision)},${Math.round(b.z * precision)}`;
22643					hashes[2] = `${Math.round(c.x * precision)},${Math.round(c.y * precision)},${Math.round(c.z * precision)}`; // skip degenerate triangles
22644
22645					if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) {
22646						continue;
22647					} // iterate over every edge
22648
22649
22650					for (let j = 0; j < 3; j++) {
22651						// get the first and next vertex making up the edge
22652						const jNext = (j + 1) % 3;
22653						const vecHash0 = hashes[j];
22654						const vecHash1 = hashes[jNext];
22655						const v0 = _triangle[vertKeys[j]];
22656						const v1 = _triangle[vertKeys[jNext]];
22657						const hash = `${vecHash0}_${vecHash1}`;
22658						const reverseHash = `${vecHash1}_${vecHash0}`;
22659
22660						if (reverseHash in edgeData && edgeData[reverseHash]) {
22661							// if we found a sibling edge add it into the vertex array if
22662							// it meets the angle threshold and delete the edge from the map.
22663							if (_normal.dot(edgeData[reverseHash].normal) <= thresholdDot) {
22664								vertices.push(v0.x, v0.y, v0.z);
22665								vertices.push(v1.x, v1.y, v1.z);
22666							}
22667
22668							edgeData[reverseHash] = null;
22669						} else if (!(hash in edgeData)) {
22670							// if we've already got an edge here then skip adding a new one
22671							edgeData[hash] = {
22672								index0: indexArr[j],
22673								index1: indexArr[jNext],
22674								normal: _normal.clone()
22675							};
22676						}
22677					}
22678				} // iterate over all remaining, unmatched edges and add them to the vertex array
22679
22680
22681				for (const key in edgeData) {
22682					if (edgeData[key]) {
22683						const {
22684							index0,
22685							index1
22686						} = edgeData[key];
22687
22688						_v0.fromBufferAttribute(positionAttr, index0);
22689
22690						_v1$1.fromBufferAttribute(positionAttr, index1);
22691
22692						vertices.push(_v0.x, _v0.y, _v0.z);
22693						vertices.push(_v1$1.x, _v1$1.y, _v1$1.z);
22694					}
22695				}
22696
22697				this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
22698			}
22699		}
22700
22701	}
22702
vendor: 4,783 bytes, lines 22703-22883
22703	/**
22704	 * Extensible curve object.
22705	 *
22706	 * Some common of curve methods:
22707	 * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )
22708	 * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )
22709	 * .getPoints(), .getSpacedPoints()
22710	 * .getLength()
22711	 * .updateArcLengths()
22712	 *
22713	 * This following curves inherit from THREE.Curve:
22714	 *
22715	 * -- 2D curves --
22716	 * THREE.ArcCurve
22717	 * THREE.CubicBezierCurve
22718	 * THREE.EllipseCurve
22719	 * THREE.LineCurve
22720	 * THREE.QuadraticBezierCurve
22721	 * THREE.SplineCurve
22722	 *
22723	 * -- 3D curves --
22724	 * THREE.CatmullRomCurve3
22725	 * THREE.CubicBezierCurve3
22726	 * THREE.LineCurve3
22727	 * THREE.QuadraticBezierCurve3
22728	 *
22729	 * A series of curves can be represented as a THREE.CurvePath.
22730	 *
22731	 **/
22732
22733	class Curve {
22734		constructor() {
22735			this.type = 'Curve';
22736			this.arcLengthDivisions = 200;
22737		} // Virtual base class method to overwrite and implement in subclasses
22738		//	- t [0 .. 1]
22739
22740
22741		getPoint() {
22742			console.warn('THREE.Curve: .getPoint() not implemented.');
22743			return null;
22744		} // Get point at relative position in curve according to arc length
22745		// - u [0 .. 1]
22746
22747
22748		getPointAt(u, optionalTarget) {
22749			const t = this.getUtoTmapping(u);
22750			return this.getPoint(t, optionalTarget);
22751		} // Get sequence of points using getPoint( t )
22752
22753
22754		getPoints(divisions = 5) {
22755			const points = [];
22756
22757			for (let d = 0; d <= divisions; d++) {
22758				points.push(this.getPoint(d / divisions));
22759			}
22760
22761			return points;
22762		} // Get sequence of points using getPointAt( u )
22763
22764
22765		getSpacedPoints(divisions = 5) {
22766			const points = [];
22767
22768			for (let d = 0; d <= divisions; d++) {
22769				points.push(this.getPointAt(d / divisions));
22770			}
22771
22772			return points;
22773		} // Get total curve arc length
22774
22775
22776		getLength() {
22777			const lengths = this.getLengths();
22778			return lengths[lengths.length - 1];
22779		} // Get list of cumulative segment lengths
22780
22781
22782		getLengths(divisions = this.arcLengthDivisions) {
22783			if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) {
22784				return this.cacheArcLengths;
22785			}
22786
22787			this.needsUpdate = false;
22788			const cache = [];
22789			let current,
22790					last = this.getPoint(0);
22791			let sum = 0;
22792			cache.push(0);
22793
22794			for (let p = 1; p <= divisions; p++) {
22795				current = this.getPoint(p / divisions);
22796				sum += current.distanceTo(last);
22797				cache.push(sum);
22798				last = current;
22799			}
22800
22801			this.cacheArcLengths = cache;
22802			return cache; // { sums: cache, sum: sum }; Sum is in the last element.
22803		}
22804
22805		updateArcLengths() {
22806			this.needsUpdate = true;
22807			this.getLengths();
22808		} // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
22809
22810
22811		getUtoTmapping(u, distance) {
22812			const arcLengths = this.getLengths();
22813			let i = 0;
22814			const il = arcLengths.length;
22815			let targetArcLength; // The targeted u distance value to get
22816
22817			if (distance) {
22818				targetArcLength = distance;
22819			} else {
22820				targetArcLength = u * arcLengths[il - 1];
22821			} // binary search for the index with largest value smaller than target u distance
22822
22823
22824			let low = 0,
22825					high = il - 1,
22826					comparison;
22827
22828			while (low <= high) {
22829				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
22830
22831				comparison = arcLengths[i] - targetArcLength;
22832
22833				if (comparison < 0) {
22834					low = i + 1;
22835				} else if (comparison > 0) {
22836					high = i - 1;
22837				} else {
22838					high = i;
22839					break; // DONE
22840				}
22841			}
22842
22843			i = high;
22844
22845			if (arcLengths[i] === targetArcLength) {
22846				return i / (il - 1);
22847			} // we could get finer grain at lengths, or use simple interpolation between two points
22848
22849
22850			const lengthBefore = arcLengths[i];
22851			const lengthAfter = arcLengths[i + 1];
22852			const segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points
22853
22854			const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t
22855
22856			const t = (i + segmentFraction) / (il - 1);
22857			return t;
22858		} // Returns a unit vector tangent at t
22859		// In case any sub curve does not implement its tangent derivation,
22860		// 2 points a small delta apart will be used to find its gradient
22861		// which seems to give a reasonable approximation
22862
22863
22864		getTangent(t, optionalTarget) {
22865			const delta = 0.0001;
22866			let t1 = t - delta;
22867			let t2 = t + delta; // Capping in case of danger
22868
22869			if (t1 < 0) t1 = 0;
22870			if (t2 > 1) t2 = 1;
22871			const pt1 = this.getPoint(t1);
22872			const pt2 = this.getPoint(t2);
22873			const tangent = optionalTarget || (pt1.isVector2 ? new Vector2() : new Vector3());
22874			tangent.copy(pt2).sub(pt1).normalize();
22875			return tangent;
22876		}
22877
22878		getTangentAt(u, optionalTarget) {
22879			const t = this.getUtoTmapping(u);
22880			return this.getTangent(t, optionalTarget);
22881		}
22882
22883		computeFrenetFrames(segments, closed) {
vendor: 4,578 bytes, lines 22884-23053
22884			// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
22885			const normal = new Vector3();
22886			const tangents = [];
22887			const normals = [];
22888			const binormals = [];
22889			const vec = new Vector3();
22890			const mat = new Matrix4(); // compute the tangent vectors for each segment on the curve
22891
22892			for (let i = 0; i <= segments; i++) {
22893				const u = i / segments;
22894				tangents[i] = this.getTangentAt(u, new Vector3());
22895			} // select an initial normal vector perpendicular to the first tangent vector,
22896			// and in the direction of the minimum tangent xyz component
22897
22898
22899			normals[0] = new Vector3();
22900			binormals[0] = new Vector3();
22901			let min = Number.MAX_VALUE;
22902			const tx = Math.abs(tangents[0].x);
22903			const ty = Math.abs(tangents[0].y);
22904			const tz = Math.abs(tangents[0].z);
22905
22906			if (tx <= min) {
22907				min = tx;
22908				normal.set(1, 0, 0);
22909			}
22910
22911			if (ty <= min) {
22912				min = ty;
22913				normal.set(0, 1, 0);
22914			}
22915
22916			if (tz <= min) {
22917				normal.set(0, 0, 1);
22918			}
22919
22920			vec.crossVectors(tangents[0], normal).normalize();
22921			normals[0].crossVectors(tangents[0], vec);
22922			binormals[0].crossVectors(tangents[0], normals[0]); // compute the slowly-varying normal and binormal vectors for each segment on the curve
22923
22924			for (let i = 1; i <= segments; i++) {
22925				normals[i] = normals[i - 1].clone();
22926				binormals[i] = binormals[i - 1].clone();
22927				vec.crossVectors(tangents[i - 1], tangents[i]);
22928
22929				if (vec.length() > Number.EPSILON) {
22930					vec.normalize();
22931					const theta = Math.acos(clamp(tangents[i - 1].dot(tangents[i]), -1, 1)); // clamp for floating pt errors
22932
22933					normals[i].applyMatrix4(mat.makeRotationAxis(vec, theta));
22934				}
22935
22936				binormals[i].crossVectors(tangents[i], normals[i]);
22937			} // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
22938
22939
22940			if (closed === true) {
22941				let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1));
22942				theta /= segments;
22943
22944				if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) {
22945					theta = -theta;
22946				}
22947
22948				for (let i = 1; i <= segments; i++) {
22949					// twist a little...
22950					normals[i].applyMatrix4(mat.makeRotationAxis(tangents[i], theta * i));
22951					binormals[i].crossVectors(tangents[i], normals[i]);
22952				}
22953			}
22954
22955			return {
22956				tangents: tangents,
22957				normals: normals,
22958				binormals: binormals
22959			};
22960		}
22961
22962		clone() {
22963			return new this.constructor().copy(this);
22964		}
22965
22966		copy(source) {
22967			this.arcLengthDivisions = source.arcLengthDivisions;
22968			return this;
22969		}
22970
22971		toJSON() {
22972			const data = {
22973				metadata: {
22974					version: 4.5,
22975					type: 'Curve',
22976					generator: 'Curve.toJSON'
22977				}
22978			};
22979			data.arcLengthDivisions = this.arcLengthDivisions;
22980			data.type = this.type;
22981			return data;
22982		}
22983
22984		fromJSON(json) {
22985			this.arcLengthDivisions = json.arcLengthDivisions;
22986			return this;
22987		}
22988
22989	}
22990
22991	class EllipseCurve extends Curve {
22992		constructor(aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0) {
22993			super();
22994			this.type = 'EllipseCurve';
22995			this.aX = aX;
22996			this.aY = aY;
22997			this.xRadius = xRadius;
22998			this.yRadius = yRadius;
22999			this.aStartAngle = aStartAngle;
23000			this.aEndAngle = aEndAngle;
23001			this.aClockwise = aClockwise;
23002			this.aRotation = aRotation;
23003		}
23004
23005		getPoint(t, optionalTarget) {
23006			const point = optionalTarget || new Vector2();
23007			const twoPi = Math.PI * 2;
23008			let deltaAngle = this.aEndAngle - this.aStartAngle;
23009			const samePoints = Math.abs(deltaAngle) < Number.EPSILON; // ensures that deltaAngle is 0 .. 2 PI
23010
23011			while (deltaAngle < 0) deltaAngle += twoPi;
23012
23013			while (deltaAngle > twoPi) deltaAngle -= twoPi;
23014
23015			if (deltaAngle < Number.EPSILON) {
23016				if (samePoints) {
23017					deltaAngle = 0;
23018				} else {
23019					deltaAngle = twoPi;
23020				}
23021			}
23022
23023			if (this.aClockwise === true && !samePoints) {
23024				if (deltaAngle === twoPi) {
23025					deltaAngle = -twoPi;
23026				} else {
23027					deltaAngle = deltaAngle - twoPi;
23028				}
23029			}
23030
23031			const angle = this.aStartAngle + t * deltaAngle;
23032			let x = this.aX + this.xRadius * Math.cos(angle);
23033			let y = this.aY + this.yRadius * Math.sin(angle);
23034
23035			if (this.aRotation !== 0) {
23036				const cos = Math.cos(this.aRotation);
23037				const sin = Math.sin(this.aRotation);
23038				const tx = x - this.aX;
23039				const ty = y - this.aY; // Rotate the point about the center of the ellipse.
23040
23041				x = tx * cos - ty * sin + this.aX;
23042				y = tx * sin + ty * cos + this.aY;
23043			}
23044
23045			return point.set(x, y);
23046		}
23047
23048		copy(source) {
23049			super.copy(source);
23050			this.aX = source.aX;
23051			this.aY = source.aY;
23052			this.xRadius = source.xRadius;
23053			this.yRadius = source.yRadius;
vendor: 7,926 bytes, lines 23054-23354
23054			this.aStartAngle = source.aStartAngle;
23055			this.aEndAngle = source.aEndAngle;
23056			this.aClockwise = source.aClockwise;
23057			this.aRotation = source.aRotation;
23058			return this;
23059		}
23060
23061		toJSON() {
23062			const data = super.toJSON();
23063			data.aX = this.aX;
23064			data.aY = this.aY;
23065			data.xRadius = this.xRadius;
23066			data.yRadius = this.yRadius;
23067			data.aStartAngle = this.aStartAngle;
23068			data.aEndAngle = this.aEndAngle;
23069			data.aClockwise = this.aClockwise;
23070			data.aRotation = this.aRotation;
23071			return data;
23072		}
23073
23074		fromJSON(json) {
23075			super.fromJSON(json);
23076			this.aX = json.aX;
23077			this.aY = json.aY;
23078			this.xRadius = json.xRadius;
23079			this.yRadius = json.yRadius;
23080			this.aStartAngle = json.aStartAngle;
23081			this.aEndAngle = json.aEndAngle;
23082			this.aClockwise = json.aClockwise;
23083			this.aRotation = json.aRotation;
23084			return this;
23085		}
23086
23087	}
23088
23089	EllipseCurve.prototype.isEllipseCurve = true;
23090
23091	class ArcCurve extends EllipseCurve {
23092		constructor(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) {
23093			super(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise);
23094			this.type = 'ArcCurve';
23095		}
23096
23097	}
23098
23099	ArcCurve.prototype.isArcCurve = true;
23100
23101	/**
23102	 * Centripetal CatmullRom Curve - which is useful for avoiding
23103	 * cusps and self-intersections in non-uniform catmull rom curves.
23104	 * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
23105	 *
23106	 * curve.type accepts centripetal(default), chordal and catmullrom
23107	 * curve.tension is used for catmullrom which defaults to 0.5
23108	 */
23109
23110	/*
23111	Based on an optimized c++ solution in
23112	 - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
23113	 - http://ideone.com/NoEbVM
23114
23115	This CubicPoly class could be used for reusing some variables and calculations,
23116	but for three.js curve use, it could be possible inlined and flatten into a single function call
23117	which can be placed in CurveUtils.
23118	*/
23119
23120	function CubicPoly() {
23121		let c0 = 0,
23122				c1 = 0,
23123				c2 = 0,
23124				c3 = 0;
23125		/*
23126		 * Compute coefficients for a cubic polynomial
23127		 *	 p(s) = c0 + c1*s + c2*s^2 + c3*s^3
23128		 * such that
23129		 *	 p(0) = x0, p(1) = x1
23130		 *	and
23131		 *	 p'(0) = t0, p'(1) = t1.
23132		 */
23133
23134		function init(x0, x1, t0, t1) {
23135			c0 = x0;
23136			c1 = t0;
23137			c2 = -3 * x0 + 3 * x1 - 2 * t0 - t1;
23138			c3 = 2 * x0 - 2 * x1 + t0 + t1;
23139		}
23140
23141		return {
23142			initCatmullRom: function (x0, x1, x2, x3, tension) {
23143				init(x1, x2, tension * (x2 - x0), tension * (x3 - x1));
23144			},
23145			initNonuniformCatmullRom: function (x0, x1, x2, x3, dt0, dt1, dt2) {
23146				// compute tangents when parameterized in [t1,t2]
23147				let t1 = (x1 - x0) / dt0 - (x2 - x0) / (dt0 + dt1) + (x2 - x1) / dt1;
23148				let t2 = (x2 - x1) / dt1 - (x3 - x1) / (dt1 + dt2) + (x3 - x2) / dt2; // rescale tangents for parametrization in [0,1]
23149
23150				t1 *= dt1;
23151				t2 *= dt1;
23152				init(x1, x2, t1, t2);
23153			},
23154			calc: function (t) {
23155				const t2 = t * t;
23156				const t3 = t2 * t;
23157				return c0 + c1 * t + c2 * t2 + c3 * t3;
23158			}
23159		};
23160	} //
23161
23162
23163	const tmp = new Vector3();
23164	const px = new CubicPoly(),
23165				py = new CubicPoly(),
23166				pz = new CubicPoly();
23167
23168	class CatmullRomCurve3 extends Curve {
23169		constructor(points = [], closed = false, curveType = 'centripetal', tension = 0.5) {
23170			super();
23171			this.type = 'CatmullRomCurve3';
23172			this.points = points;
23173			this.closed = closed;
23174			this.curveType = curveType;
23175			this.tension = tension;
23176		}
23177
23178		getPoint(t, optionalTarget = new Vector3()) {
23179			const point = optionalTarget;
23180			const points = this.points;
23181			const l = points.length;
23182			const p = (l - (this.closed ? 0 : 1)) * t;
23183			let intPoint = Math.floor(p);
23184			let weight = p - intPoint;
23185
23186			if (this.closed) {
23187				intPoint += intPoint > 0 ? 0 : (Math.floor(Math.abs(intPoint) / l) + 1) * l;
23188			} else if (weight === 0 && intPoint === l - 1) {
23189				intPoint = l - 2;
23190				weight = 1;
23191			}
23192
23193			let p0, p3; // 4 points (p1 & p2 defined below)
23194
23195			if (this.closed || intPoint > 0) {
23196				p0 = points[(intPoint - 1) % l];
23197			} else {
23198				// extrapolate first point
23199				tmp.subVectors(points[0], points[1]).add(points[0]);
23200				p0 = tmp;
23201			}
23202
23203			const p1 = points[intPoint % l];
23204			const p2 = points[(intPoint + 1) % l];
23205
23206			if (this.closed || intPoint + 2 < l) {
23207				p3 = points[(intPoint + 2) % l];
23208			} else {
23209				// extrapolate last point
23210				tmp.subVectors(points[l - 1], points[l - 2]).add(points[l - 1]);
23211				p3 = tmp;
23212			}
23213
23214			if (this.curveType === 'centripetal' || this.curveType === 'chordal') {
23215				// init Centripetal / Chordal Catmull-Rom
23216				const pow = this.curveType === 'chordal' ? 0.5 : 0.25;
23217				let dt0 = Math.pow(p0.distanceToSquared(p1), pow);
23218				let dt1 = Math.pow(p1.distanceToSquared(p2), pow);
23219				let dt2 = Math.pow(p2.distanceToSquared(p3), pow); // safety check for repeated points
23220
23221				if (dt1 < 1e-4) dt1 = 1.0;
23222				if (dt0 < 1e-4) dt0 = dt1;
23223				if (dt2 < 1e-4) dt2 = dt1;
23224				px.initNonuniformCatmullRom(p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2);
23225				py.initNonuniformCatmullRom(p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2);
23226				pz.initNonuniformCatmullRom(p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2);
23227			} else if (this.curveType === 'catmullrom') {
23228				px.initCatmullRom(p0.x, p1.x, p2.x, p3.x, this.tension);
23229				py.initCatmullRom(p0.y, p1.y, p2.y, p3.y, this.tension);
23230				pz.initCatmullRom(p0.z, p1.z, p2.z, p3.z, this.tension);
23231			}
23232
23233			point.set(px.calc(weight), py.calc(weight), pz.calc(weight));
23234			return point;
23235		}
23236
23237		copy(source) {
23238			super.copy(source);
23239			this.points = [];
23240
23241			for (let i = 0, l = source.points.length; i < l; i++) {
23242				const point = source.points[i];
23243				this.points.push(point.clone());
23244			}
23245
23246			this.closed = source.closed;
23247			this.curveType = source.curveType;
23248			this.tension = source.tension;
23249			return this;
23250		}
23251
23252		toJSON() {
23253			const data = super.toJSON();
23254			data.points = [];
23255
23256			for (let i = 0, l = this.points.length; i < l; i++) {
23257				const point = this.points[i];
23258				data.points.push(point.toArray());
23259			}
23260
23261			data.closed = this.closed;
23262			data.curveType = this.curveType;
23263			data.tension = this.tension;
23264			return data;
23265		}
23266
23267		fromJSON(json) {
23268			super.fromJSON(json);
23269			this.points = [];
23270
23271			for (let i = 0, l = json.points.length; i < l; i++) {
23272				const point = json.points[i];
23273				this.points.push(new Vector3().fromArray(point));
23274			}
23275
23276			this.closed = json.closed;
23277			this.curveType = json.curveType;
23278			this.tension = json.tension;
23279			return this;
23280		}
23281
23282	}
23283
23284	CatmullRomCurve3.prototype.isCatmullRomCurve3 = true;
23285
23286	/**
23287	 * Bezier Curves formulas obtained from
23288	 * https://en.wikipedia.org/wiki/B%C3%A9zier_curve
23289	 */
23290	function CatmullRom(t, p0, p1, p2, p3) {
23291		const v0 = (p2 - p0) * 0.5;
23292		const v1 = (p3 - p1) * 0.5;
23293		const t2 = t * t;
23294		const t3 = t * t2;
23295		return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
23296	} //
23297
23298
23299	function QuadraticBezierP0(t, p) {
23300		const k = 1 - t;
23301		return k * k * p;
23302	}
23303
23304	function QuadraticBezierP1(t, p) {
23305		return 2 * (1 - t) * t * p;
23306	}
23307
23308	function QuadraticBezierP2(t, p) {
23309		return t * t * p;
23310	}
23311
23312	function QuadraticBezier(t, p0, p1, p2) {
23313		return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2);
23314	} //
23315
23316
23317	function CubicBezierP0(t, p) {
23318		const k = 1 - t;
23319		return k * k * k * p;
23320	}
23321
23322	function CubicBezierP1(t, p) {
23323		const k = 1 - t;
23324		return 3 * k * k * t * p;
23325	}
23326
23327	function CubicBezierP2(t, p) {
23328		return 3 * (1 - t) * t * t * p;
23329	}
23330
23331	function CubicBezierP3(t, p) {
23332		return t * t * t * p;
23333	}
23334
23335	function CubicBezier(t, p0, p1, p2, p3) {
23336		return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3);
23337	}
23338
23339	class CubicBezierCurve extends Curve {
23340		constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2()) {
23341			super();
23342			this.type = 'CubicBezierCurve';
23343			this.v0 = v0;
23344			this.v1 = v1;
23345			this.v2 = v2;
23346			this.v3 = v3;
23347		}
23348
23349		getPoint(t, optionalTarget = new Vector2()) {
23350			const point = optionalTarget;
23351			const v0 = this.v0,
23352						v1 = this.v1,
23353						v2 = this.v2,
23354						v3 = this.v3;
vendor: 6,400 bytes, lines 23355-23650
23355			point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y));
23356			return point;
23357		}
23358
23359		copy(source) {
23360			super.copy(source);
23361			this.v0.copy(source.v0);
23362			this.v1.copy(source.v1);
23363			this.v2.copy(source.v2);
23364			this.v3.copy(source.v3);
23365			return this;
23366		}
23367
23368		toJSON() {
23369			const data = super.toJSON();
23370			data.v0 = this.v0.toArray();
23371			data.v1 = this.v1.toArray();
23372			data.v2 = this.v2.toArray();
23373			data.v3 = this.v3.toArray();
23374			return data;
23375		}
23376
23377		fromJSON(json) {
23378			super.fromJSON(json);
23379			this.v0.fromArray(json.v0);
23380			this.v1.fromArray(json.v1);
23381			this.v2.fromArray(json.v2);
23382			this.v3.fromArray(json.v3);
23383			return this;
23384		}
23385
23386	}
23387
23388	CubicBezierCurve.prototype.isCubicBezierCurve = true;
23389
23390	class CubicBezierCurve3 extends Curve {
23391		constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3()) {
23392			super();
23393			this.type = 'CubicBezierCurve3';
23394			this.v0 = v0;
23395			this.v1 = v1;
23396			this.v2 = v2;
23397			this.v3 = v3;
23398		}
23399
23400		getPoint(t, optionalTarget = new Vector3()) {
23401			const point = optionalTarget;
23402			const v0 = this.v0,
23403						v1 = this.v1,
23404						v2 = this.v2,
23405						v3 = this.v3;
23406			point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y), CubicBezier(t, v0.z, v1.z, v2.z, v3.z));
23407			return point;
23408		}
23409
23410		copy(source) {
23411			super.copy(source);
23412			this.v0.copy(source.v0);
23413			this.v1.copy(source.v1);
23414			this.v2.copy(source.v2);
23415			this.v3.copy(source.v3);
23416			return this;
23417		}
23418
23419		toJSON() {
23420			const data = super.toJSON();
23421			data.v0 = this.v0.toArray();
23422			data.v1 = this.v1.toArray();
23423			data.v2 = this.v2.toArray();
23424			data.v3 = this.v3.toArray();
23425			return data;
23426		}
23427
23428		fromJSON(json) {
23429			super.fromJSON(json);
23430			this.v0.fromArray(json.v0);
23431			this.v1.fromArray(json.v1);
23432			this.v2.fromArray(json.v2);
23433			this.v3.fromArray(json.v3);
23434			return this;
23435		}
23436
23437	}
23438
23439	CubicBezierCurve3.prototype.isCubicBezierCurve3 = true;
23440
23441	class LineCurve extends Curve {
23442		constructor(v1 = new Vector2(), v2 = new Vector2()) {
23443			super();
23444			this.type = 'LineCurve';
23445			this.v1 = v1;
23446			this.v2 = v2;
23447		}
23448
23449		getPoint(t, optionalTarget = new Vector2()) {
23450			const point = optionalTarget;
23451
23452			if (t === 1) {
23453				point.copy(this.v2);
23454			} else {
23455				point.copy(this.v2).sub(this.v1);
23456				point.multiplyScalar(t).add(this.v1);
23457			}
23458
23459			return point;
23460		} // Line curve is linear, so we can overwrite default getPointAt
23461
23462
23463		getPointAt(u, optionalTarget) {
23464			return this.getPoint(u, optionalTarget);
23465		}
23466
23467		getTangent(t, optionalTarget) {
23468			const tangent = optionalTarget || new Vector2();
23469			tangent.copy(this.v2).sub(this.v1).normalize();
23470			return tangent;
23471		}
23472
23473		copy(source) {
23474			super.copy(source);
23475			this.v1.copy(source.v1);
23476			this.v2.copy(source.v2);
23477			return this;
23478		}
23479
23480		toJSON() {
23481			const data = super.toJSON();
23482			data.v1 = this.v1.toArray();
23483			data.v2 = this.v2.toArray();
23484			return data;
23485		}
23486
23487		fromJSON(json) {
23488			super.fromJSON(json);
23489			this.v1.fromArray(json.v1);
23490			this.v2.fromArray(json.v2);
23491			return this;
23492		}
23493
23494	}
23495
23496	LineCurve.prototype.isLineCurve = true;
23497
23498	class LineCurve3 extends Curve {
23499		constructor(v1 = new Vector3(), v2 = new Vector3()) {
23500			super();
23501			this.type = 'LineCurve3';
23502			this.isLineCurve3 = true;
23503			this.v1 = v1;
23504			this.v2 = v2;
23505		}
23506
23507		getPoint(t, optionalTarget = new Vector3()) {
23508			const point = optionalTarget;
23509
23510			if (t === 1) {
23511				point.copy(this.v2);
23512			} else {
23513				point.copy(this.v2).sub(this.v1);
23514				point.multiplyScalar(t).add(this.v1);
23515			}
23516
23517			return point;
23518		} // Line curve is linear, so we can overwrite default getPointAt
23519
23520
23521		getPointAt(u, optionalTarget) {
23522			return this.getPoint(u, optionalTarget);
23523		}
23524
23525		copy(source) {
23526			super.copy(source);
23527			this.v1.copy(source.v1);
23528			this.v2.copy(source.v2);
23529			return this;
23530		}
23531
23532		toJSON() {
23533			const data = super.toJSON();
23534			data.v1 = this.v1.toArray();
23535			data.v2 = this.v2.toArray();
23536			return data;
23537		}
23538
23539		fromJSON(json) {
23540			super.fromJSON(json);
23541			this.v1.fromArray(json.v1);
23542			this.v2.fromArray(json.v2);
23543			return this;
23544		}
23545
23546	}
23547
23548	class QuadraticBezierCurve extends Curve {
23549		constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2()) {
23550			super();
23551			this.type = 'QuadraticBezierCurve';
23552			this.v0 = v0;
23553			this.v1 = v1;
23554			this.v2 = v2;
23555		}
23556
23557		getPoint(t, optionalTarget = new Vector2()) {
23558			const point = optionalTarget;
23559			const v0 = this.v0,
23560						v1 = this.v1,
23561						v2 = this.v2;
23562			point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y));
23563			return point;
23564		}
23565
23566		copy(source) {
23567			super.copy(source);
23568			this.v0.copy(source.v0);
23569			this.v1.copy(source.v1);
23570			this.v2.copy(source.v2);
23571			return this;
23572		}
23573
23574		toJSON() {
23575			const data = super.toJSON();
23576			data.v0 = this.v0.toArray();
23577			data.v1 = this.v1.toArray();
23578			data.v2 = this.v2.toArray();
23579			return data;
23580		}
23581
23582		fromJSON(json) {
23583			super.fromJSON(json);
23584			this.v0.fromArray(json.v0);
23585			this.v1.fromArray(json.v1);
23586			this.v2.fromArray(json.v2);
23587			return this;
23588		}
23589
23590	}
23591
23592	QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true;
23593
23594	class QuadraticBezierCurve3 extends Curve {
23595		constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3()) {
23596			super();
23597			this.type = 'QuadraticBezierCurve3';
23598			this.v0 = v0;
23599			this.v1 = v1;
23600			this.v2 = v2;
23601		}
23602
23603		getPoint(t, optionalTarget = new Vector3()) {
23604			const point = optionalTarget;
23605			const v0 = this.v0,
23606						v1 = this.v1,
23607						v2 = this.v2;
23608			point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y), QuadraticBezier(t, v0.z, v1.z, v2.z));
23609			return point;
23610		}
23611
23612		copy(source) {
23613			super.copy(source);
23614			this.v0.copy(source.v0);
23615			this.v1.copy(source.v1);
23616			this.v2.copy(source.v2);
23617			return this;
23618		}
23619
23620		toJSON() {
23621			const data = super.toJSON();
23622			data.v0 = this.v0.toArray();
23623			data.v1 = this.v1.toArray();
23624			data.v2 = this.v2.toArray();
23625			return data;
23626		}
23627
23628		fromJSON(json) {
23629			super.fromJSON(json);
23630			this.v0.fromArray(json.v0);
23631			this.v1.fromArray(json.v1);
23632			this.v2.fromArray(json.v2);
23633			return this;
23634		}
23635
23636	}
23637
23638	QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true;
23639
23640	class SplineCurve extends Curve {
23641		constructor(points = []) {
23642			super();
23643			this.type = 'SplineCurve';
23644			this.points = points;
23645		}
23646
23647		getPoint(t, optionalTarget = new Vector2()) {
23648			const point = optionalTarget;
23649			const points = this.points;
23650			const p = (points.length - 1) * t;
vendor: 10,353 bytes, lines 23651-24066
23651			const intPoint = Math.floor(p);
23652			const weight = p - intPoint;
23653			const p0 = points[intPoint === 0 ? intPoint : intPoint - 1];
23654			const p1 = points[intPoint];
23655			const p2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1];
23656			const p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2];
23657			point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y));
23658			return point;
23659		}
23660
23661		copy(source) {
23662			super.copy(source);
23663			this.points = [];
23664
23665			for (let i = 0, l = source.points.length; i < l; i++) {
23666				const point = source.points[i];
23667				this.points.push(point.clone());
23668			}
23669
23670			return this;
23671		}
23672
23673		toJSON() {
23674			const data = super.toJSON();
23675			data.points = [];
23676
23677			for (let i = 0, l = this.points.length; i < l; i++) {
23678				const point = this.points[i];
23679				data.points.push(point.toArray());
23680			}
23681
23682			return data;
23683		}
23684
23685		fromJSON(json) {
23686			super.fromJSON(json);
23687			this.points = [];
23688
23689			for (let i = 0, l = json.points.length; i < l; i++) {
23690				const point = json.points[i];
23691				this.points.push(new Vector2().fromArray(point));
23692			}
23693
23694			return this;
23695		}
23696
23697	}
23698
23699	SplineCurve.prototype.isSplineCurve = true;
23700
23701	var Curves = /*#__PURE__*/Object.freeze({
23702		__proto__: null,
23703		ArcCurve: ArcCurve,
23704		CatmullRomCurve3: CatmullRomCurve3,
23705		CubicBezierCurve: CubicBezierCurve,
23706		CubicBezierCurve3: CubicBezierCurve3,
23707		EllipseCurve: EllipseCurve,
23708		LineCurve: LineCurve,
23709		LineCurve3: LineCurve3,
23710		QuadraticBezierCurve: QuadraticBezierCurve,
23711		QuadraticBezierCurve3: QuadraticBezierCurve3,
23712		SplineCurve: SplineCurve
23713	});
23714
23715	/**************************************************************
23716	 *	Curved Path - a curve path is simply a array of connected
23717	 *	curves, but retains the api of a curve
23718	 **************************************************************/
23719
23720	class CurvePath extends Curve {
23721		constructor() {
23722			super();
23723			this.type = 'CurvePath';
23724			this.curves = [];
23725			this.autoClose = false; // Automatically closes the path
23726		}
23727
23728		add(curve) {
23729			this.curves.push(curve);
23730		}
23731
23732		closePath() {
23733			// Add a line curve if start and end of lines are not connected
23734			const startPoint = this.curves[0].getPoint(0);
23735			const endPoint = this.curves[this.curves.length - 1].getPoint(1);
23736
23737			if (!startPoint.equals(endPoint)) {
23738				this.curves.push(new LineCurve(endPoint, startPoint));
23739			}
23740		} // To get accurate point with reference to
23741		// entire path distance at time t,
23742		// following has to be done:
23743		// 1. Length of each sub path have to be known
23744		// 2. Locate and identify type of curve
23745		// 3. Get t for the curve
23746		// 4. Return curve.getPointAt(t')
23747
23748
23749		getPoint(t, optionalTarget) {
23750			const d = t * this.getLength();
23751			const curveLengths = this.getCurveLengths();
23752			let i = 0; // To think about boundaries points.
23753
23754			while (i < curveLengths.length) {
23755				if (curveLengths[i] >= d) {
23756					const diff = curveLengths[i] - d;
23757					const curve = this.curves[i];
23758					const segmentLength = curve.getLength();
23759					const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
23760					return curve.getPointAt(u, optionalTarget);
23761				}
23762
23763				i++;
23764			}
23765
23766			return null; // loop where sum != 0, sum > d , sum+1 <d
23767		} // We cannot use the default THREE.Curve getPoint() with getLength() because in
23768		// THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
23769		// getPoint() depends on getLength
23770
23771
23772		getLength() {
23773			const lens = this.getCurveLengths();
23774			return lens[lens.length - 1];
23775		} // cacheLengths must be recalculated.
23776
23777
23778		updateArcLengths() {
23779			this.needsUpdate = true;
23780			this.cacheLengths = null;
23781			this.getCurveLengths();
23782		} // Compute lengths and cache them
23783		// We cannot overwrite getLengths() because UtoT mapping uses it.
23784
23785
23786		getCurveLengths() {
23787			// We use cache values if curves and cache array are same length
23788			if (this.cacheLengths && this.cacheLengths.length === this.curves.length) {
23789				return this.cacheLengths;
23790			} // Get length of sub-curve
23791			// Push sums into cached array
23792
23793
23794			const lengths = [];
23795			let sums = 0;
23796
23797			for (let i = 0, l = this.curves.length; i < l; i++) {
23798				sums += this.curves[i].getLength();
23799				lengths.push(sums);
23800			}
23801
23802			this.cacheLengths = lengths;
23803			return lengths;
23804		}
23805
23806		getSpacedPoints(divisions = 40) {
23807			const points = [];
23808
23809			for (let i = 0; i <= divisions; i++) {
23810				points.push(this.getPoint(i / divisions));
23811			}
23812
23813			if (this.autoClose) {
23814				points.push(points[0]);
23815			}
23816
23817			return points;
23818		}
23819
23820		getPoints(divisions = 12) {
23821			const points = [];
23822			let last;
23823
23824			for (let i = 0, curves = this.curves; i < curves.length; i++) {
23825				const curve = curves[i];
23826				const resolution = curve && curve.isEllipseCurve ? divisions * 2 : curve && (curve.isLineCurve || curve.isLineCurve3) ? 1 : curve && curve.isSplineCurve ? divisions * curve.points.length : divisions;
23827				const pts = curve.getPoints(resolution);
23828
23829				for (let j = 0; j < pts.length; j++) {
23830					const point = pts[j];
23831					if (last && last.equals(point)) continue; // ensures no consecutive points are duplicates
23832
23833					points.push(point);
23834					last = point;
23835				}
23836			}
23837
23838			if (this.autoClose && points.length > 1 && !points[points.length - 1].equals(points[0])) {
23839				points.push(points[0]);
23840			}
23841
23842			return points;
23843		}
23844
23845		copy(source) {
23846			super.copy(source);
23847			this.curves = [];
23848
23849			for (let i = 0, l = source.curves.length; i < l; i++) {
23850				const curve = source.curves[i];
23851				this.curves.push(curve.clone());
23852			}
23853
23854			this.autoClose = source.autoClose;
23855			return this;
23856		}
23857
23858		toJSON() {
23859			const data = super.toJSON();
23860			data.autoClose = this.autoClose;
23861			data.curves = [];
23862
23863			for (let i = 0, l = this.curves.length; i < l; i++) {
23864				const curve = this.curves[i];
23865				data.curves.push(curve.toJSON());
23866			}
23867
23868			return data;
23869		}
23870
23871		fromJSON(json) {
23872			super.fromJSON(json);
23873			this.autoClose = json.autoClose;
23874			this.curves = [];
23875
23876			for (let i = 0, l = json.curves.length; i < l; i++) {
23877				const curve = json.curves[i];
23878				this.curves.push(new Curves[curve.type]().fromJSON(curve));
23879			}
23880
23881			return this;
23882		}
23883
23884	}
23885
23886	class Path extends CurvePath {
23887		constructor(points) {
23888			super();
23889			this.type = 'Path';
23890			this.currentPoint = new Vector2();
23891
23892			if (points) {
23893				this.setFromPoints(points);
23894			}
23895		}
23896
23897		setFromPoints(points) {
23898			this.moveTo(points[0].x, points[0].y);
23899
23900			for (let i = 1, l = points.length; i < l; i++) {
23901				this.lineTo(points[i].x, points[i].y);
23902			}
23903
23904			return this;
23905		}
23906
23907		moveTo(x, y) {
23908			this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying?
23909
23910			return this;
23911		}
23912
23913		lineTo(x, y) {
23914			const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y));
23915			this.curves.push(curve);
23916			this.currentPoint.set(x, y);
23917			return this;
23918		}
23919
23920		quadraticCurveTo(aCPx, aCPy, aX, aY) {
23921			const curve = new QuadraticBezierCurve(this.currentPoint.clone(), new Vector2(aCPx, aCPy), new Vector2(aX, aY));
23922			this.curves.push(curve);
23923			this.currentPoint.set(aX, aY);
23924			return this;
23925		}
23926
23927		bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) {
23928			const curve = new CubicBezierCurve(this.currentPoint.clone(), new Vector2(aCP1x, aCP1y), new Vector2(aCP2x, aCP2y), new Vector2(aX, aY));
23929			this.curves.push(curve);
23930			this.currentPoint.set(aX, aY);
23931			return this;
23932		}
23933
23934		splineThru(pts
23935		/*Array of Vector*/
23936		) {
23937			const npts = [this.currentPoint.clone()].concat(pts);
23938			const curve = new SplineCurve(npts);
23939			this.curves.push(curve);
23940			this.currentPoint.copy(pts[pts.length - 1]);
23941			return this;
23942		}
23943
23944		arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) {
23945			const x0 = this.currentPoint.x;
23946			const y0 = this.currentPoint.y;
23947			this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise);
23948			return this;
23949		}
23950
23951		absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) {
23952			this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise);
23953			return this;
23954		}
23955
23956		ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) {
23957			const x0 = this.currentPoint.x;
23958			const y0 = this.currentPoint.y;
23959			this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation);
23960			return this;
23961		}
23962
23963		absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) {
23964			const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation);
23965
23966			if (this.curves.length > 0) {
23967				// if a previous curve is present, attempt to join
23968				const firstPoint = curve.getPoint(0);
23969
23970				if (!firstPoint.equals(this.currentPoint)) {
23971					this.lineTo(firstPoint.x, firstPoint.y);
23972				}
23973			}
23974
23975			this.curves.push(curve);
23976			const lastPoint = curve.getPoint(1);
23977			this.currentPoint.copy(lastPoint);
23978			return this;
23979		}
23980
23981		copy(source) {
23982			super.copy(source);
23983			this.currentPoint.copy(source.currentPoint);
23984			return this;
23985		}
23986
23987		toJSON() {
23988			const data = super.toJSON();
23989			data.currentPoint = this.currentPoint.toArray();
23990			return data;
23991		}
23992
23993		fromJSON(json) {
23994			super.fromJSON(json);
23995			this.currentPoint.fromArray(json.currentPoint);
23996			return this;
23997		}
23998
23999	}
24000
24001	class Shape extends Path {
24002		constructor(points) {
24003			super(points);
24004			this.uuid = generateUUID();
24005			this.type = 'Shape';
24006			this.holes = [];
24007		}
24008
24009		getPointsHoles(divisions) {
24010			const holesPts = [];
24011
24012			for (let i = 0, l = this.holes.length; i < l; i++) {
24013				holesPts[i] = this.holes[i].getPoints(divisions);
24014			}
24015
24016			return holesPts;
24017		} // get points of shape and holes (keypoints based on segments parameter)
24018
24019
24020		extractPoints(divisions) {
24021			return {
24022				shape: this.getPoints(divisions),
24023				holes: this.getPointsHoles(divisions)
24024			};
24025		}
24026
24027		copy(source) {
24028			super.copy(source);
24029			this.holes = [];
24030
24031			for (let i = 0, l = source.holes.length; i < l; i++) {
24032				const hole = source.holes[i];
24033				this.holes.push(hole.clone());
24034			}
24035
24036			return this;
24037		}
24038
24039		toJSON() {
24040			const data = super.toJSON();
24041			data.uuid = this.uuid;
24042			data.holes = [];
24043
24044			for (let i = 0, l = this.holes.length; i < l; i++) {
24045				const hole = this.holes[i];
24046				data.holes.push(hole.toJSON());
24047			}
24048
24049			return data;
24050		}
24051
24052		fromJSON(json) {
24053			super.fromJSON(json);
24054			this.uuid = json.uuid;
24055			this.holes = [];
24056
24057			for (let i = 0, l = json.holes.length; i < l; i++) {
24058				const hole = json.holes[i];
24059				this.holes.push(new Path().fromJSON(hole));
24060			}
24061
24062			return this;
24063		}
24064
24065	}
24066
vendor: 14,892 bytes, lines 24067-24570
24067	/**
24068	 * Port from https://github.com/mapbox/earcut (v2.2.2)
24069	 */
24070	const Earcut = {
24071		triangulate: function (data, holeIndices, dim = 2) {
24072			const hasHoles = holeIndices && holeIndices.length;
24073			const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
24074			let outerNode = linkedList(data, 0, outerLen, dim, true);
24075			const triangles = [];
24076			if (!outerNode || outerNode.next === outerNode.prev) return triangles;
24077			let minX, minY, maxX, maxY, x, y, invSize;
24078			if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
24079
24080			if (data.length > 80 * dim) {
24081				minX = maxX = data[0];
24082				minY = maxY = data[1];
24083
24084				for (let i = dim; i < outerLen; i += dim) {
24085					x = data[i];
24086					y = data[i + 1];
24087					if (x < minX) minX = x;
24088					if (y < minY) minY = y;
24089					if (x > maxX) maxX = x;
24090					if (y > maxY) maxY = y;
24091				} // minX, minY and invSize are later used to transform coords into integers for z-order calculation
24092
24093
24094				invSize = Math.max(maxX - minX, maxY - minY);
24095				invSize = invSize !== 0 ? 1 / invSize : 0;
24096			}
24097
24098			earcutLinked(outerNode, triangles, dim, minX, minY, invSize);
24099			return triangles;
24100		}
24101	}; // create a circular doubly linked list from polygon points in the specified winding order
24102
24103	function linkedList(data, start, end, dim, clockwise) {
24104		let i, last;
24105
24106		if (clockwise === signedArea(data, start, end, dim) > 0) {
24107			for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
24108		} else {
24109			for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
24110		}
24111
24112		if (last && equals(last, last.next)) {
24113			removeNode(last);
24114			last = last.next;
24115		}
24116
24117		return last;
24118	} // eliminate colinear or duplicate points
24119
24120
24121	function filterPoints(start, end) {
24122		if (!start) return start;
24123		if (!end) end = start;
24124		let p = start,
24125				again;
24126
24127		do {
24128			again = false;
24129
24130			if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
24131				removeNode(p);
24132				p = end = p.prev;
24133				if (p === p.next) break;
24134				again = true;
24135			} else {
24136				p = p.next;
24137			}
24138		} while (again || p !== end);
24139
24140		return end;
24141	} // main ear slicing loop which triangulates a polygon (given as a linked list)
24142
24143
24144	function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
24145		if (!ear) return; // interlink polygon nodes in z-order
24146
24147		if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
24148		let stop = ear,
24149				prev,
24150				next; // iterate through ears, slicing them one by one
24151
24152		while (ear.prev !== ear.next) {
24153			prev = ear.prev;
24154			next = ear.next;
24155
24156			if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
24157				// cut off the triangle
24158				triangles.push(prev.i / dim);
24159				triangles.push(ear.i / dim);
24160				triangles.push(next.i / dim);
24161				removeNode(ear); // skipping the next vertex leads to less sliver triangles
24162
24163				ear = next.next;
24164				stop = next.next;
24165				continue;
24166			}
24167
24168			ear = next; // if we looped through the whole remaining polygon and can't find any more ears
24169
24170			if (ear === stop) {
24171				// try filtering points and slicing again
24172				if (!pass) {
24173					earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally
24174				} else if (pass === 1) {
24175					ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
24176					earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two
24177				} else if (pass === 2) {
24178					splitEarcut(ear, triangles, dim, minX, minY, invSize);
24179				}
24180
24181				break;
24182			}
24183		}
24184	} // check whether a polygon node forms a valid ear with adjacent nodes
24185
24186
24187	function isEar(ear) {
24188		const a = ear.prev,
24189					b = ear,
24190					c = ear.next;
24191		if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
24192		// now make sure we don't have other points inside the potential ear
24193
24194		let p = ear.next.next;
24195
24196		while (p !== ear.prev) {
24197			if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
24198			p = p.next;
24199		}
24200
24201		return true;
24202	}
24203
24204	function isEarHashed(ear, minX, minY, invSize) {
24205		const a = ear.prev,
24206					b = ear,
24207					c = ear.next;
24208		if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
24209		// triangle bbox; min & max are calculated like this for speed
24210
24211		const minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x,
24212					minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y,
24213					maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x,
24214					maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y; // z-order range for the current triangle bbox;
24215
24216		const minZ = zOrder(minTX, minTY, minX, minY, invSize),
24217					maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);
24218		let p = ear.prevZ,
24219				n = ear.nextZ; // look for points inside the triangle in both directions
24220
24221		while (p && p.z >= minZ && n && n.z <= maxZ) {
24222			if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
24223			p = p.prevZ;
24224			if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
24225			n = n.nextZ;
24226		} // look for remaining points in decreasing z-order
24227
24228
24229		while (p && p.z >= minZ) {
24230			if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
24231			p = p.prevZ;
24232		} // look for remaining points in increasing z-order
24233
24234
24235		while (n && n.z <= maxZ) {
24236			if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
24237			n = n.nextZ;
24238		}
24239
24240		return true;
24241	} // go through all polygon nodes and cure small local self-intersections
24242
24243
24244	function cureLocalIntersections(start, triangles, dim) {
24245		let p = start;
24246
24247		do {
24248			const a = p.prev,
24249						b = p.next.next;
24250
24251			if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
24252				triangles.push(a.i / dim);
24253				triangles.push(p.i / dim);
24254				triangles.push(b.i / dim); // remove two nodes involved
24255
24256				removeNode(p);
24257				removeNode(p.next);
24258				p = start = b;
24259			}
24260
24261			p = p.next;
24262		} while (p !== start);
24263
24264		return filterPoints(p);
24265	} // try splitting polygon into two and triangulate them independently
24266
24267
24268	function splitEarcut(start, triangles, dim, minX, minY, invSize) {
24269		// look for a valid diagonal that divides the polygon into two
24270		let a = start;
24271
24272		do {
24273			let b = a.next.next;
24274
24275			while (b !== a.prev) {
24276				if (a.i !== b.i && isValidDiagonal(a, b)) {
24277					// split the polygon in two by the diagonal
24278					let c = splitPolygon(a, b); // filter colinear points around the cuts
24279
24280					a = filterPoints(a, a.next);
24281					c = filterPoints(c, c.next); // run earcut on each half
24282
24283					earcutLinked(a, triangles, dim, minX, minY, invSize);
24284					earcutLinked(c, triangles, dim, minX, minY, invSize);
24285					return;
24286				}
24287
24288				b = b.next;
24289			}
24290
24291			a = a.next;
24292		} while (a !== start);
24293	} // link every hole into the outer loop, producing a single-ring polygon without holes
24294
24295
24296	function eliminateHoles(data, holeIndices, outerNode, dim) {
24297		const queue = [];
24298		let i, len, start, end, list;
24299
24300		for (i = 0, len = holeIndices.length; i < len; i++) {
24301			start = holeIndices[i] * dim;
24302			end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
24303			list = linkedList(data, start, end, dim, false);
24304			if (list === list.next) list.steiner = true;
24305			queue.push(getLeftmost(list));
24306		}
24307
24308		queue.sort(compareX); // process holes from left to right
24309
24310		for (i = 0; i < queue.length; i++) {
24311			eliminateHole(queue[i], outerNode);
24312			outerNode = filterPoints(outerNode, outerNode.next);
24313		}
24314
24315		return outerNode;
24316	}
24317
24318	function compareX(a, b) {
24319		return a.x - b.x;
24320	} // find a bridge between vertices that connects hole with an outer ring and and link it
24321
24322
24323	function eliminateHole(hole, outerNode) {
24324		outerNode = findHoleBridge(hole, outerNode);
24325
24326		if (outerNode) {
24327			const b = splitPolygon(outerNode, hole); // filter collinear points around the cuts
24328
24329			filterPoints(outerNode, outerNode.next);
24330			filterPoints(b, b.next);
24331		}
24332	} // David Eberly's algorithm for finding a bridge between hole and outer polygon
24333
24334
24335	function findHoleBridge(hole, outerNode) {
24336		let p = outerNode;
24337		const hx = hole.x;
24338		const hy = hole.y;
24339		let qx = -Infinity,
24340				m; // find a segment intersected by a ray from the hole's leftmost point to the left;
24341		// segment's endpoint with lesser x will be potential connection point
24342
24343		do {
24344			if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
24345				const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
24346
24347				if (x <= hx && x > qx) {
24348					qx = x;
24349
24350					if (x === hx) {
24351						if (hy === p.y) return p;
24352						if (hy === p.next.y) return p.next;
24353					}
24354
24355					m = p.x < p.next.x ? p : p.next;
24356				}
24357			}
24358
24359			p = p.next;
24360		} while (p !== outerNode);
24361
24362		if (!m) return null;
24363		if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint
24364		// look for points inside the triangle of hole point, segment intersection and endpoint;
24365		// if there are no points found, we have a valid connection;
24366		// otherwise choose the point of the minimum angle with the ray as connection point
24367
24368		const stop = m,
24369					mx = m.x,
24370					my = m.y;
24371		let tanMin = Infinity,
24372				tan;
24373		p = m;
24374
24375		do {
24376			if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
24377				tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
24378
24379				if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
24380					m = p;
24381					tanMin = tan;
24382				}
24383			}
24384
24385			p = p.next;
24386		} while (p !== stop);
24387
24388		return m;
24389	} // whether sector in vertex m contains sector in vertex p in the same coordinates
24390
24391
24392	function sectorContainsSector(m, p) {
24393		return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
24394	} // interlink polygon nodes in z-order
24395
24396
24397	function indexCurve(start, minX, minY, invSize) {
24398		let p = start;
24399
24400		do {
24401			if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);
24402			p.prevZ = p.prev;
24403			p.nextZ = p.next;
24404			p = p.next;
24405		} while (p !== start);
24406
24407		p.prevZ.nextZ = null;
24408		p.prevZ = null;
24409		sortLinked(p);
24410	} // Simon Tatham's linked list merge sort algorithm
24411	// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
24412
24413
24414	function sortLinked(list) {
24415		let i,
24416				p,
24417				q,
24418				e,
24419				tail,
24420				numMerges,
24421				pSize,
24422				qSize,
24423				inSize = 1;
24424
24425		do {
24426			p = list;
24427			list = null;
24428			tail = null;
24429			numMerges = 0;
24430
24431			while (p) {
24432				numMerges++;
24433				q = p;
24434				pSize = 0;
24435
24436				for (i = 0; i < inSize; i++) {
24437					pSize++;
24438					q = q.nextZ;
24439					if (!q) break;
24440				}
24441
24442				qSize = inSize;
24443
24444				while (pSize > 0 || qSize > 0 && q) {
24445					if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
24446						e = p;
24447						p = p.nextZ;
24448						pSize--;
24449					} else {
24450						e = q;
24451						q = q.nextZ;
24452						qSize--;
24453					}
24454
24455					if (tail) tail.nextZ = e;else list = e;
24456					e.prevZ = tail;
24457					tail = e;
24458				}
24459
24460				p = q;
24461			}
24462
24463			tail.nextZ = null;
24464			inSize *= 2;
24465		} while (numMerges > 1);
24466
24467		return list;
24468	} // z-order of a point given coords and inverse of the longer side of data bbox
24469
24470
24471	function zOrder(x, y, minX, minY, invSize) {
24472		// coords are transformed into non-negative 15-bit integer range
24473		x = 32767 * (x - minX) * invSize;
24474		y = 32767 * (y - minY) * invSize;
24475		x = (x | x << 8) & 0x00FF00FF;
24476		x = (x | x << 4) & 0x0F0F0F0F;
24477		x = (x | x << 2) & 0x33333333;
24478		x = (x | x << 1) & 0x55555555;
24479		y = (y | y << 8) & 0x00FF00FF;
24480		y = (y | y << 4) & 0x0F0F0F0F;
24481		y = (y | y << 2) & 0x33333333;
24482		y = (y | y << 1) & 0x55555555;
24483		return x | y << 1;
24484	} // find the leftmost node of a polygon ring
24485
24486
24487	function getLeftmost(start) {
24488		let p = start,
24489				leftmost = start;
24490
24491		do {
24492			if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
24493			p = p.next;
24494		} while (p !== start);
24495
24496		return leftmost;
24497	} // check if a point lies within a convex triangle
24498
24499
24500	function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
24501		return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
24502	} // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
24503
24504
24505	function isValidDiagonal(a, b) {
24506		return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && ( // dones't intersect other edges
24507		locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && ( // locally visible
24508		area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
24509		equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case
24510	} // signed area of a triangle
24511
24512
24513	function area(p, q, r) {
24514		return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
24515	} // check if two points are equal
24516
24517
24518	function equals(p1, p2) {
24519		return p1.x === p2.x && p1.y === p2.y;
24520	} // check if two segments intersect
24521
24522
24523	function intersects(p1, q1, p2, q2) {
24524		const o1 = sign(area(p1, q1, p2));
24525		const o2 = sign(area(p1, q1, q2));
24526		const o3 = sign(area(p2, q2, p1));
24527		const o4 = sign(area(p2, q2, q1));
24528		if (o1 !== o2 && o3 !== o4) return true; // general case
24529
24530		if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
24531
24532		if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
24533
24534		if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
24535
24536		if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2
24537
24538		return false;
24539	} // for collinear points p, q, r, check if point q lies on segment pr
24540
24541
24542	function onSegment(p, q, r) {
24543		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);
24544	}
24545
24546	function sign(num) {
24547		return num > 0 ? 1 : num < 0 ? -1 : 0;
24548	} // check if a polygon diagonal intersects any polygon segments
24549
24550
24551	function intersectsPolygon(a, b) {
24552		let p = a;
24553
24554		do {
24555			if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true;
24556			p = p.next;
24557		} while (p !== a);
24558
24559		return false;
24560	} // check if a polygon diagonal is locally inside the polygon
24561
24562
24563	function locallyInside(a, b) {
24564		return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
24565	} // check if the middle point of a polygon diagonal is inside the polygon
24566
24567
24568	function middleInside(a, b) {
24569		let p = a,
24570				inside = false;
vendor: 5,948 bytes, lines 24571-24782
24571		const px = (a.x + b.x) / 2,
24572					py = (a.y + b.y) / 2;
24573
24574		do {
24575			if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside;
24576			p = p.next;
24577		} while (p !== a);
24578
24579		return inside;
24580	} // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
24581	// if one belongs to the outer ring and another to a hole, it merges it into a single ring
24582
24583
24584	function splitPolygon(a, b) {
24585		const a2 = new Node(a.i, a.x, a.y),
24586					b2 = new Node(b.i, b.x, b.y),
24587					an = a.next,
24588					bp = b.prev;
24589		a.next = b;
24590		b.prev = a;
24591		a2.next = an;
24592		an.prev = a2;
24593		b2.next = a2;
24594		a2.prev = b2;
24595		bp.next = b2;
24596		b2.prev = bp;
24597		return b2;
24598	} // create a node and optionally link it with previous one (in a circular doubly linked list)
24599
24600
24601	function insertNode(i, x, y, last) {
24602		const p = new Node(i, x, y);
24603
24604		if (!last) {
24605			p.prev = p;
24606			p.next = p;
24607		} else {
24608			p.next = last.next;
24609			p.prev = last;
24610			last.next.prev = p;
24611			last.next = p;
24612		}
24613
24614		return p;
24615	}
24616
24617	function removeNode(p) {
24618		p.next.prev = p.prev;
24619		p.prev.next = p.next;
24620		if (p.prevZ) p.prevZ.nextZ = p.nextZ;
24621		if (p.nextZ) p.nextZ.prevZ = p.prevZ;
24622	}
24623
24624	function Node(i, x, y) {
24625		// vertex index in coordinates array
24626		this.i = i; // vertex coordinates
24627
24628		this.x = x;
24629		this.y = y; // previous and next vertex nodes in a polygon ring
24630
24631		this.prev = null;
24632		this.next = null; // z-order curve value
24633
24634		this.z = null; // previous and next nodes in z-order
24635
24636		this.prevZ = null;
24637		this.nextZ = null; // indicates whether this is a steiner point
24638
24639		this.steiner = false;
24640	}
24641
24642	function signedArea(data, start, end, dim) {
24643		let sum = 0;
24644
24645		for (let i = start, j = end - dim; i < end; i += dim) {
24646			sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
24647			j = i;
24648		}
24649
24650		return sum;
24651	}
24652
24653	class ShapeUtils {
24654		// calculate area of the contour polygon
24655		static area(contour) {
24656			const n = contour.length;
24657			let a = 0.0;
24658
24659			for (let p = n - 1, q = 0; q < n; p = q++) {
24660				a += contour[p].x * contour[q].y - contour[q].x * contour[p].y;
24661			}
24662
24663			return a * 0.5;
24664		}
24665
24666		static isClockWise(pts) {
24667			return ShapeUtils.area(pts) < 0;
24668		}
24669
24670		static triangulateShape(contour, holes) {
24671			const vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ]
24672
24673			const holeIndices = []; // array of hole indices
24674
24675			const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ]
24676
24677			removeDupEndPts(contour);
24678			addContour(vertices, contour); //
24679
24680			let holeIndex = contour.length;
24681			holes.forEach(removeDupEndPts);
24682
24683			for (let i = 0; i < holes.length; i++) {
24684				holeIndices.push(holeIndex);
24685				holeIndex += holes[i].length;
24686				addContour(vertices, holes[i]);
24687			} //
24688
24689
24690			const triangles = Earcut.triangulate(vertices, holeIndices); //
24691
24692			for (let i = 0; i < triangles.length; i += 3) {
24693				faces.push(triangles.slice(i, i + 3));
24694			}
24695
24696			return faces;
24697		}
24698
24699	}
24700
24701	function removeDupEndPts(points) {
24702		const l = points.length;
24703
24704		if (l > 2 && points[l - 1].equals(points[0])) {
24705			points.pop();
24706		}
24707	}
24708
24709	function addContour(vertices, contour) {
24710		for (let i = 0; i < contour.length; i++) {
24711			vertices.push(contour[i].x);
24712			vertices.push(contour[i].y);
24713		}
24714	}
24715
24716	/**
24717	 * Creates extruded geometry from a path shape.
24718	 *
24719	 * parameters = {
24720	 *
24721	 *	curveSegments: <int>, // number of points on the curves
24722	 *	steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
24723	 *	depth: <float>, // Depth to extrude the shape
24724	 *
24725	 *	bevelEnabled: <bool>, // turn on bevel
24726	 *	bevelThickness: <float>, // how deep into the original shape bevel goes
24727	 *	bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel
24728	 *	bevelOffset: <float>, // how far from shape outline does bevel start
24729	 *	bevelSegments: <int>, // number of bevel layers
24730	 *
24731	 *	extrudePath: <THREE.Curve> // curve to extrude shape along
24732	 *
24733	 *	UVGenerator: <Object> // object that provides UV generator functions
24734	 *
24735	 * }
24736	 */
24737
24738	class ExtrudeGeometry extends BufferGeometry {
24739		constructor(shapes = new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), options = {}) {
24740			super();
24741			this.type = 'ExtrudeGeometry';
24742			this.parameters = {
24743				shapes: shapes,
24744				options: options
24745			};
24746			shapes = Array.isArray(shapes) ? shapes : [shapes];
24747			const scope = this;
24748			const verticesArray = [];
24749			const uvArray = [];
24750
24751			for (let i = 0, l = shapes.length; i < l; i++) {
24752				const shape = shapes[i];
24753				addShape(shape);
24754			} // build geometry
24755
24756
24757			this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3));
24758			this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2));
24759			this.computeVertexNormals(); // functions
24760
24761			function addShape(shape) {
24762				const placeholder = []; // options
24763
24764				const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
24765				const steps = options.steps !== undefined ? options.steps : 1;
24766				let depth = options.depth !== undefined ? options.depth : 1;
24767				let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
24768				let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2;
24769				let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1;
24770				let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;
24771				let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
24772				const extrudePath = options.extrudePath;
24773				const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; // deprecated options
24774
24775				if (options.amount !== undefined) {
24776					console.warn('THREE.ExtrudeBufferGeometry: amount has been renamed to depth.');
24777					depth = options.amount;
24778				} //
24779
24780
24781				let extrudePts,
24782						extrudeByPath = false;
vendor: 8,050 bytes, lines 24783-25007
24783				let splineTube, binormal, normal, position2;
24784
24785				if (extrudePath) {
24786					extrudePts = extrudePath.getSpacedPoints(steps);
24787					extrudeByPath = true;
24788					bevelEnabled = false; // bevels not supported for path extrusion
24789					// SETUP TNB variables
24790					// TODO1 - have a .isClosed in spline?
24791
24792					splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
24793
24794					binormal = new Vector3();
24795					normal = new Vector3();
24796					position2 = new Vector3();
24797				} // Safeguards if bevels are not enabled
24798
24799
24800				if (!bevelEnabled) {
24801					bevelSegments = 0;
24802					bevelThickness = 0;
24803					bevelSize = 0;
24804					bevelOffset = 0;
24805				} // Variables initialization
24806
24807
24808				const shapePoints = shape.extractPoints(curveSegments);
24809				let vertices = shapePoints.shape;
24810				const holes = shapePoints.holes;
24811				const reverse = !ShapeUtils.isClockWise(vertices);
24812
24813				if (reverse) {
24814					vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ...
24815
24816					for (let h = 0, hl = holes.length; h < hl; h++) {
24817						const ahole = holes[h];
24818
24819						if (ShapeUtils.isClockWise(ahole)) {
24820							holes[h] = ahole.reverse();
24821						}
24822					}
24823				}
24824
24825				const faces = ShapeUtils.triangulateShape(vertices, holes);
24826				/* Vertices */
24827
24828				const contour = vertices; // vertices has all points but contour has only points of circumference
24829
24830				for (let h = 0, hl = holes.length; h < hl; h++) {
24831					const ahole = holes[h];
24832					vertices = vertices.concat(ahole);
24833				}
24834
24835				function scalePt2(pt, vec, size) {
24836					if (!vec) console.error('THREE.ExtrudeGeometry: vec does not exist');
24837					return vec.clone().multiplyScalar(size).add(pt);
24838				}
24839
24840				const vlen = vertices.length,
24841							flen = faces.length; // Find directions for point movement
24842
24843				function getBevelVec(inPt, inPrev, inNext) {
24844					// computes for inPt the corresponding point inPt' on a new contour
24845					//	 shifted by 1 unit (length of normalized vector) to the left
24846					// if we walk along contour clockwise, this new contour is outside the old one
24847					//
24848					// inPt' is the intersection of the two lines parallel to the two
24849					//	adjacent edges of inPt at a distance of 1 unit on the left side.
24850					let v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
24851					// good reading for geometry algorithms (here: line-line intersection)
24852					// http://geomalgorithms.com/a05-_intersect-1.html
24853
24854					const v_prev_x = inPt.x - inPrev.x,
24855								v_prev_y = inPt.y - inPrev.y;
24856					const v_next_x = inNext.x - inPt.x,
24857								v_next_y = inNext.y - inPt.y;
24858					const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; // check for collinear edges
24859
24860					const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x;
24861
24862					if (Math.abs(collinear0) > Number.EPSILON) {
24863						// not collinear
24864						// length of vectors for normalizing
24865						const v_prev_len = Math.sqrt(v_prev_lensq);
24866						const v_next_len = Math.sqrt(v_next_x * v_next_x + v_next_y * v_next_y); // shift adjacent points by unit vectors to the left
24867
24868						const ptPrevShift_x = inPrev.x - v_prev_y / v_prev_len;
24869						const ptPrevShift_y = inPrev.y + v_prev_x / v_prev_len;
24870						const ptNextShift_x = inNext.x - v_next_y / v_next_len;
24871						const ptNextShift_y = inNext.y + v_next_x / v_next_len; // scaling factor for v_prev to intersection point
24872
24873						const sf = ((ptNextShift_x - ptPrevShift_x) * v_next_y - (ptNextShift_y - ptPrevShift_y) * v_next_x) / (v_prev_x * v_next_y - v_prev_y * v_next_x); // vector from inPt to intersection point
24874
24875						v_trans_x = ptPrevShift_x + v_prev_x * sf - inPt.x;
24876						v_trans_y = ptPrevShift_y + v_prev_y * sf - inPt.y; // Don't normalize!, otherwise sharp corners become ugly
24877						//	but prevent crazy spikes
24878
24879						const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y;
24880
24881						if (v_trans_lensq <= 2) {
24882							return new Vector2(v_trans_x, v_trans_y);
24883						} else {
24884							shrink_by = Math.sqrt(v_trans_lensq / 2);
24885						}
24886					} else {
24887						// handle special case of collinear edges
24888						let direction_eq = false; // assumes: opposite
24889
24890						if (v_prev_x > Number.EPSILON) {
24891							if (v_next_x > Number.EPSILON) {
24892								direction_eq = true;
24893							}
24894						} else {
24895							if (v_prev_x < -Number.EPSILON) {
24896								if (v_next_x < -Number.EPSILON) {
24897									direction_eq = true;
24898								}
24899							} else {
24900								if (Math.sign(v_prev_y) === Math.sign(v_next_y)) {
24901									direction_eq = true;
24902								}
24903							}
24904						}
24905
24906						if (direction_eq) {
24907							// console.log("Warning: lines are a straight sequence");
24908							v_trans_x = -v_prev_y;
24909							v_trans_y = v_prev_x;
24910							shrink_by = Math.sqrt(v_prev_lensq);
24911						} else {
24912							// console.log("Warning: lines are a straight spike");
24913							v_trans_x = v_prev_x;
24914							v_trans_y = v_prev_y;
24915							shrink_by = Math.sqrt(v_prev_lensq / 2);
24916						}
24917					}
24918
24919					return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by);
24920				}
24921
24922				const contourMovements = [];
24923
24924				for (let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {
24925					if (j === il) j = 0;
24926					if (k === il) k = 0; //	(j)---(i)---(k)
24927					// console.log('i,j,k', i, j , k)
24928
24929					contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]);
24930				}
24931
24932				const holesMovements = [];
24933				let oneHoleMovements,
24934						verticesMovements = contourMovements.concat();
24935
24936				for (let h = 0, hl = holes.length; h < hl; h++) {
24937					const ahole = holes[h];
24938					oneHoleMovements = [];
24939
24940					for (let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {
24941						if (j === il) j = 0;
24942						if (k === il) k = 0; //	(j)---(i)---(k)
24943
24944						oneHoleMovements[i] = getBevelVec(ahole[i], ahole[j], ahole[k]);
24945					}
24946
24947					holesMovements.push(oneHoleMovements);
24948					verticesMovements = verticesMovements.concat(oneHoleMovements);
24949				} // Loop bevelSegments, 1 for the front, 1 for the back
24950
24951
24952				for (let b = 0; b < bevelSegments; b++) {
24953					//for ( b = bevelSegments; b > 0; b -- ) {
24954					const t = b / bevelSegments;
24955					const z = bevelThickness * Math.cos(t * Math.PI / 2);
24956					const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape
24957
24958					for (let i = 0, il = contour.length; i < il; i++) {
24959						const vert = scalePt2(contour[i], contourMovements[i], bs);
24960						v(vert.x, vert.y, -z);
24961					} // expand holes
24962
24963
24964					for (let h = 0, hl = holes.length; h < hl; h++) {
24965						const ahole = holes[h];
24966						oneHoleMovements = holesMovements[h];
24967
24968						for (let i = 0, il = ahole.length; i < il; i++) {
24969							const vert = scalePt2(ahole[i], oneHoleMovements[i], bs);
24970							v(vert.x, vert.y, -z);
24971						}
24972					}
24973				}
24974
24975				const bs = bevelSize + bevelOffset; // Back facing vertices
24976
24977				for (let i = 0; i < vlen; i++) {
24978					const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
24979
24980					if (!extrudeByPath) {
24981						v(vert.x, vert.y, 0);
24982					} else {
24983						// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
24984						normal.copy(splineTube.normals[0]).multiplyScalar(vert.x);
24985						binormal.copy(splineTube.binormals[0]).multiplyScalar(vert.y);
24986						position2.copy(extrudePts[0]).add(normal).add(binormal);
24987						v(position2.x, position2.y, position2.z);
24988					}
24989				} // Add stepped vertices...
24990				// Including front facing vertices
24991
24992
24993				for (let s = 1; s <= steps; s++) {
24994					for (let i = 0; i < vlen; i++) {
24995						const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
24996
24997						if (!extrudeByPath) {
24998							v(vert.x, vert.y, depth / steps * s);
24999						} else {
25000							// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
25001							normal.copy(splineTube.normals[s]).multiplyScalar(vert.x);
25002							binormal.copy(splineTube.binormals[s]).multiplyScalar(vert.y);
25003							position2.copy(extrudePts[s]).add(normal).add(binormal);
25004							v(position2.x, position2.y, position2.z);
25005						}
25006					}
25007				}
vendor: 32,102 bytes, lines 25007-26047
25007 // Add bevel segments planes
25008				//for ( b = 1; b <= bevelSegments; b ++ ) {
25009
25010
25011				for (let b = bevelSegments - 1; b >= 0; b--) {
25012					const t = b / bevelSegments;
25013					const z = bevelThickness * Math.cos(t * Math.PI / 2);
25014					const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape
25015
25016					for (let i = 0, il = contour.length; i < il; i++) {
25017						const vert = scalePt2(contour[i], contourMovements[i], bs);
25018						v(vert.x, vert.y, depth + z);
25019					} // expand holes
25020
25021
25022					for (let h = 0, hl = holes.length; h < hl; h++) {
25023						const ahole = holes[h];
25024						oneHoleMovements = holesMovements[h];
25025
25026						for (let i = 0, il = ahole.length; i < il; i++) {
25027							const vert = scalePt2(ahole[i], oneHoleMovements[i], bs);
25028
25029							if (!extrudeByPath) {
25030								v(vert.x, vert.y, depth + z);
25031							} else {
25032								v(vert.x, vert.y + extrudePts[steps - 1].y, extrudePts[steps - 1].x + z);
25033							}
25034						}
25035					}
25036				}
25037				/* Faces */
25038				// Top and bottom faces
25039
25040
25041				buildLidFaces(); // Sides faces
25042
25043				buildSideFaces(); /////	Internal functions
25044
25045				function buildLidFaces() {
25046					const start = verticesArray.length / 3;
25047
25048					if (bevelEnabled) {
25049						let layer = 0; // steps + 1
25050
25051						let offset = vlen * layer; // Bottom faces
25052
25053						for (let i = 0; i < flen; i++) {
25054							const face = faces[i];
25055							f3(face[2] + offset, face[1] + offset, face[0] + offset);
25056						}
25057
25058						layer = steps + bevelSegments * 2;
25059						offset = vlen * layer; // Top faces
25060
25061						for (let i = 0; i < flen; i++) {
25062							const face = faces[i];
25063							f3(face[0] + offset, face[1] + offset, face[2] + offset);
25064						}
25065					} else {
25066						// Bottom faces
25067						for (let i = 0; i < flen; i++) {
25068							const face = faces[i];
25069							f3(face[2], face[1], face[0]);
25070						} // Top faces
25071
25072
25073						for (let i = 0; i < flen; i++) {
25074							const face = faces[i];
25075							f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps);
25076						}
25077					}
25078
25079					scope.addGroup(start, verticesArray.length / 3 - start, 0);
25080				} // Create faces for the z-sides of the shape
25081
25082
25083				function buildSideFaces() {
25084					const start = verticesArray.length / 3;
25085					let layeroffset = 0;
25086					sidewalls(contour, layeroffset);
25087					layeroffset += contour.length;
25088
25089					for (let h = 0, hl = holes.length; h < hl; h++) {
25090						const ahole = holes[h];
25091						sidewalls(ahole, layeroffset); //, true
25092
25093						layeroffset += ahole.length;
25094					}
25095
25096					scope.addGroup(start, verticesArray.length / 3 - start, 1);
25097				}
25098
25099				function sidewalls(contour, layeroffset) {
25100					let i = contour.length;
25101
25102					while (--i >= 0) {
25103						const j = i;
25104						let k = i - 1;
25105						if (k < 0) k = contour.length - 1; //console.log('b', i,j, i-1, k,vertices.length);
25106
25107						for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) {
25108							const slen1 = vlen * s;
25109							const slen2 = vlen * (s + 1);
25110							const a = layeroffset + j + slen1,
25111										b = layeroffset + k + slen1,
25112										c = layeroffset + k + slen2,
25113										d = layeroffset + j + slen2;
25114							f4(a, b, c, d);
25115						}
25116					}
25117				}
25118
25119				function v(x, y, z) {
25120					placeholder.push(x);
25121					placeholder.push(y);
25122					placeholder.push(z);
25123				}
25124
25125				function f3(a, b, c) {
25126					addVertex(a);
25127					addVertex(b);
25128					addVertex(c);
25129					const nextIndex = verticesArray.length / 3;
25130					const uvs = uvgen.generateTopUV(scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1);
25131					addUV(uvs[0]);
25132					addUV(uvs[1]);
25133					addUV(uvs[2]);
25134				}
25135
25136				function f4(a, b, c, d) {
25137					addVertex(a);
25138					addVertex(b);
25139					addVertex(d);
25140					addVertex(b);
25141					addVertex(c);
25142					addVertex(d);
25143					const nextIndex = verticesArray.length / 3;
25144					const uvs = uvgen.generateSideWallUV(scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1);
25145					addUV(uvs[0]);
25146					addUV(uvs[1]);
25147					addUV(uvs[3]);
25148					addUV(uvs[1]);
25149					addUV(uvs[2]);
25150					addUV(uvs[3]);
25151				}
25152
25153				function addVertex(index) {
25154					verticesArray.push(placeholder[index * 3 + 0]);
25155					verticesArray.push(placeholder[index * 3 + 1]);
25156					verticesArray.push(placeholder[index * 3 + 2]);
25157				}
25158
25159				function addUV(vector2) {
25160					uvArray.push(vector2.x);
25161					uvArray.push(vector2.y);
25162				}
25163			}
25164		}
25165
25166		toJSON() {
25167			const data = super.toJSON();
25168			const shapes = this.parameters.shapes;
25169			const options = this.parameters.options;
25170			return toJSON$1(shapes, options, data);
25171		}
25172
25173		static fromJSON(data, shapes) {
25174			const geometryShapes = [];
25175
25176			for (let j = 0, jl = data.shapes.length; j < jl; j++) {
25177				const shape = shapes[data.shapes[j]];
25178				geometryShapes.push(shape);
25179			}
25180
25181			const extrudePath = data.options.extrudePath;
25182
25183			if (extrudePath !== undefined) {
25184				data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath);
25185			}
25186
25187			return new ExtrudeGeometry(geometryShapes, data.options);
25188		}
25189
25190	}
25191
25192	const WorldUVGenerator = {
25193		generateTopUV: function (geometry, vertices, indexA, indexB, indexC) {
25194			const a_x = vertices[indexA * 3];
25195			const a_y = vertices[indexA * 3 + 1];
25196			const b_x = vertices[indexB * 3];
25197			const b_y = vertices[indexB * 3 + 1];
25198			const c_x = vertices[indexC * 3];
25199			const c_y = vertices[indexC * 3 + 1];
25200			return [new Vector2(a_x, a_y), new Vector2(b_x, b_y), new Vector2(c_x, c_y)];
25201		},
25202		generateSideWallUV: function (geometry, vertices, indexA, indexB, indexC, indexD) {
25203			const a_x = vertices[indexA * 3];
25204			const a_y = vertices[indexA * 3 + 1];
25205			const a_z = vertices[indexA * 3 + 2];
25206			const b_x = vertices[indexB * 3];
25207			const b_y = vertices[indexB * 3 + 1];
25208			const b_z = vertices[indexB * 3 + 2];
25209			const c_x = vertices[indexC * 3];
25210			const c_y = vertices[indexC * 3 + 1];
25211			const c_z = vertices[indexC * 3 + 2];
25212			const d_x = vertices[indexD * 3];
25213			const d_y = vertices[indexD * 3 + 1];
25214			const d_z = vertices[indexD * 3 + 2];
25215
25216			if (Math.abs(a_y - b_y) < Math.abs(a_x - b_x)) {
25217				return [new Vector2(a_x, 1 - a_z), new Vector2(b_x, 1 - b_z), new Vector2(c_x, 1 - c_z), new Vector2(d_x, 1 - d_z)];
25218			} else {
25219				return [new Vector2(a_y, 1 - a_z), new Vector2(b_y, 1 - b_z), new Vector2(c_y, 1 - c_z), new Vector2(d_y, 1 - d_z)];
25220			}
25221		}
25222	};
25223
25224	function toJSON$1(shapes, options, data) {
25225		data.shapes = [];
25226
25227		if (Array.isArray(shapes)) {
25228			for (let i = 0, l = shapes.length; i < l; i++) {
25229				const shape = shapes[i];
25230				data.shapes.push(shape.uuid);
25231			}
25232		} else {
25233			data.shapes.push(shapes.uuid);
25234		}
25235
25236		if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON();
25237		return data;
25238	}
25239
25240	class IcosahedronGeometry extends PolyhedronGeometry {
25241		constructor(radius = 1, detail = 0) {
25242			const t = (1 + Math.sqrt(5)) / 2;
25243			const vertices = [-1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1];
25244			const indices = [0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1];
25245			super(vertices, indices, radius, detail);
25246			this.type = 'IcosahedronGeometry';
25247			this.parameters = {
25248				radius: radius,
25249				detail: detail
25250			};
25251		}
25252
25253		static fromJSON(data) {
25254			return new IcosahedronGeometry(data.radius, data.detail);
25255		}
25256
25257	}
25258
25259	class LatheGeometry extends BufferGeometry {
25260		constructor(points = [new Vector2(0, 0.5), new Vector2(0.5, 0), new Vector2(0, -0.5)], segments = 12, phiStart = 0, phiLength = Math.PI * 2) {
25261			super();
25262			this.type = 'LatheGeometry';
25263			this.parameters = {
25264				points: points,
25265				segments: segments,
25266				phiStart: phiStart,
25267				phiLength: phiLength
25268			};
25269			segments = Math.floor(segments); // clamp phiLength so it's in range of [ 0, 2PI ]
25270
25271			phiLength = clamp(phiLength, 0, Math.PI * 2); // buffers
25272
25273			const indices = [];
25274			const vertices = [];
25275			const uvs = [];
25276			const initNormals = [];
25277			const normals = []; // helper variables
25278
25279			const inverseSegments = 1.0 / segments;
25280			const vertex = new Vector3();
25281			const uv = new Vector2();
25282			const normal = new Vector3();
25283			const curNormal = new Vector3();
25284			const prevNormal = new Vector3();
25285			let dx = 0;
25286			let dy = 0; // pre-compute normals for initial "meridian"
25287
25288			for (let j = 0; j <= points.length - 1; j++) {
25289				switch (j) {
25290					case 0:
25291						// special handling for 1st vertex on path
25292						dx = points[j + 1].x - points[j].x;
25293						dy = points[j + 1].y - points[j].y;
25294						normal.x = dy * 1.0;
25295						normal.y = -dx;
25296						normal.z = dy * 0.0;
25297						prevNormal.copy(normal);
25298						normal.normalize();
25299						initNormals.push(normal.x, normal.y, normal.z);
25300						break;
25301
25302					case points.length - 1:
25303						// special handling for last Vertex on path
25304						initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z);
25305						break;
25306
25307					default:
25308						// default handling for all vertices in between
25309						dx = points[j + 1].x - points[j].x;
25310						dy = points[j + 1].y - points[j].y;
25311						normal.x = dy * 1.0;
25312						normal.y = -dx;
25313						normal.z = dy * 0.0;
25314						curNormal.copy(normal);
25315						normal.x += prevNormal.x;
25316						normal.y += prevNormal.y;
25317						normal.z += prevNormal.z;
25318						normal.normalize();
25319						initNormals.push(normal.x, normal.y, normal.z);
25320						prevNormal.copy(curNormal);
25321				}
25322			} // generate vertices, uvs and normals
25323
25324
25325			for (let i = 0; i <= segments; i++) {
25326				const phi = phiStart + i * inverseSegments * phiLength;
25327				const sin = Math.sin(phi);
25328				const cos = Math.cos(phi);
25329
25330				for (let j = 0; j <= points.length - 1; j++) {
25331					// vertex
25332					vertex.x = points[j].x * sin;
25333					vertex.y = points[j].y;
25334					vertex.z = points[j].x * cos;
25335					vertices.push(vertex.x, vertex.y, vertex.z); // uv
25336
25337					uv.x = i / segments;
25338					uv.y = j / (points.length - 1);
25339					uvs.push(uv.x, uv.y); // normal
25340
25341					const x = initNormals[3 * j + 0] * sin;
25342					const y = initNormals[3 * j + 1];
25343					const z = initNormals[3 * j + 0] * cos;
25344					normals.push(x, y, z);
25345				}
25346			} // indices
25347
25348
25349			for (let i = 0; i < segments; i++) {
25350				for (let j = 0; j < points.length - 1; j++) {
25351					const base = j + i * points.length;
25352					const a = base;
25353					const b = base + points.length;
25354					const c = base + points.length + 1;
25355					const d = base + 1; // faces
25356
25357					indices.push(a, b, d);
25358					indices.push(b, c, d);
25359				}
25360			} // build geometry
25361
25362
25363			this.setIndex(indices);
25364			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
25365			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
25366			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
25367		}
25368
25369		static fromJSON(data) {
25370			return new LatheGeometry(data.points, data.segments, data.phiStart, data.phiLength);
25371		}
25372
25373	}
25374
25375	class OctahedronGeometry extends PolyhedronGeometry {
25376		constructor(radius = 1, detail = 0) {
25377			const vertices = [1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1];
25378			const indices = [0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2];
25379			super(vertices, indices, radius, detail);
25380			this.type = 'OctahedronGeometry';
25381			this.parameters = {
25382				radius: radius,
25383				detail: detail
25384			};
25385		}
25386
25387		static fromJSON(data) {
25388			return new OctahedronGeometry(data.radius, data.detail);
25389		}
25390
25391	}
25392
25393	class RingGeometry extends BufferGeometry {
25394		constructor(innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2) {
25395			super();
25396			this.type = 'RingGeometry';
25397			this.parameters = {
25398				innerRadius: innerRadius,
25399				outerRadius: outerRadius,
25400				thetaSegments: thetaSegments,
25401				phiSegments: phiSegments,
25402				thetaStart: thetaStart,
25403				thetaLength: thetaLength
25404			};
25405			thetaSegments = Math.max(3, thetaSegments);
25406			phiSegments = Math.max(1, phiSegments); // buffers
25407
25408			const indices = [];
25409			const vertices = [];
25410			const normals = [];
25411			const uvs = []; // some helper variables
25412
25413			let radius = innerRadius;
25414			const radiusStep = (outerRadius - innerRadius) / phiSegments;
25415			const vertex = new Vector3();
25416			const uv = new Vector2(); // generate vertices, normals and uvs
25417
25418			for (let j = 0; j <= phiSegments; j++) {
25419				for (let i = 0; i <= thetaSegments; i++) {
25420					// values are generate from the inside of the ring to the outside
25421					const segment = thetaStart + i / thetaSegments * thetaLength; // vertex
25422
25423					vertex.x = radius * Math.cos(segment);
25424					vertex.y = radius * Math.sin(segment);
25425					vertices.push(vertex.x, vertex.y, vertex.z); // normal
25426
25427					normals.push(0, 0, 1); // uv
25428
25429					uv.x = (vertex.x / outerRadius + 1) / 2;
25430					uv.y = (vertex.y / outerRadius + 1) / 2;
25431					uvs.push(uv.x, uv.y);
25432				} // increase the radius for next row of vertices
25433
25434
25435				radius += radiusStep;
25436			} // indices
25437
25438
25439			for (let j = 0; j < phiSegments; j++) {
25440				const thetaSegmentLevel = j * (thetaSegments + 1);
25441
25442				for (let i = 0; i < thetaSegments; i++) {
25443					const segment = i + thetaSegmentLevel;
25444					const a = segment;
25445					const b = segment + thetaSegments + 1;
25446					const c = segment + thetaSegments + 2;
25447					const d = segment + 1; // faces
25448
25449					indices.push(a, b, d);
25450					indices.push(b, c, d);
25451				}
25452			} // build geometry
25453
25454
25455			this.setIndex(indices);
25456			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
25457			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
25458			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
25459		}
25460
25461		static fromJSON(data) {
25462			return new RingGeometry(data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength);
25463		}
25464
25465	}
25466
25467	class ShapeGeometry extends BufferGeometry {
25468		constructor(shapes = new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), curveSegments = 12) {
25469			super();
25470			this.type = 'ShapeGeometry';
25471			this.parameters = {
25472				shapes: shapes,
25473				curveSegments: curveSegments
25474			}; // buffers
25475
25476			const indices = [];
25477			const vertices = [];
25478			const normals = [];
25479			const uvs = []; // helper variables
25480
25481			let groupStart = 0;
25482			let groupCount = 0; // allow single and array values for "shapes" parameter
25483
25484			if (Array.isArray(shapes) === false) {
25485				addShape(shapes);
25486			} else {
25487				for (let i = 0; i < shapes.length; i++) {
25488					addShape(shapes[i]);
25489					this.addGroup(groupStart, groupCount, i); // enables MultiMaterial support
25490
25491					groupStart += groupCount;
25492					groupCount = 0;
25493				}
25494			} // build geometry
25495
25496
25497			this.setIndex(indices);
25498			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
25499			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
25500			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // helper functions
25501
25502			function addShape(shape) {
25503				const indexOffset = vertices.length / 3;
25504				const points = shape.extractPoints(curveSegments);
25505				let shapeVertices = points.shape;
25506				const shapeHoles = points.holes; // check direction of vertices
25507
25508				if (ShapeUtils.isClockWise(shapeVertices) === false) {
25509					shapeVertices = shapeVertices.reverse();
25510				}
25511
25512				for (let i = 0, l = shapeHoles.length; i < l; i++) {
25513					const shapeHole = shapeHoles[i];
25514
25515					if (ShapeUtils.isClockWise(shapeHole) === true) {
25516						shapeHoles[i] = shapeHole.reverse();
25517					}
25518				}
25519
25520				const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array
25521
25522				for (let i = 0, l = shapeHoles.length; i < l; i++) {
25523					const shapeHole = shapeHoles[i];
25524					shapeVertices = shapeVertices.concat(shapeHole);
25525				} // vertices, normals, uvs
25526
25527
25528				for (let i = 0, l = shapeVertices.length; i < l; i++) {
25529					const vertex = shapeVertices[i];
25530					vertices.push(vertex.x, vertex.y, 0);
25531					normals.push(0, 0, 1);
25532					uvs.push(vertex.x, vertex.y); // world uvs
25533				} // incides
25534
25535
25536				for (let i = 0, l = faces.length; i < l; i++) {
25537					const face = faces[i];
25538					const a = face[0] + indexOffset;
25539					const b = face[1] + indexOffset;
25540					const c = face[2] + indexOffset;
25541					indices.push(a, b, c);
25542					groupCount += 3;
25543				}
25544			}
25545		}
25546
25547		toJSON() {
25548			const data = super.toJSON();
25549			const shapes = this.parameters.shapes;
25550			return toJSON(shapes, data);
25551		}
25552
25553		static fromJSON(data, shapes) {
25554			const geometryShapes = [];
25555
25556			for (let j = 0, jl = data.shapes.length; j < jl; j++) {
25557				const shape = shapes[data.shapes[j]];
25558				geometryShapes.push(shape);
25559			}
25560
25561			return new ShapeGeometry(geometryShapes, data.curveSegments);
25562		}
25563
25564	}
25565
25566	function toJSON(shapes, data) {
25567		data.shapes = [];
25568
25569		if (Array.isArray(shapes)) {
25570			for (let i = 0, l = shapes.length; i < l; i++) {
25571				const shape = shapes[i];
25572				data.shapes.push(shape.uuid);
25573			}
25574		} else {
25575			data.shapes.push(shapes.uuid);
25576		}
25577
25578		return data;
25579	}
25580
25581	class SphereGeometry extends BufferGeometry {
25582		constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) {
25583			super();
25584			this.type = 'SphereGeometry';
25585			this.parameters = {
25586				radius: radius,
25587				widthSegments: widthSegments,
25588				heightSegments: heightSegments,
25589				phiStart: phiStart,
25590				phiLength: phiLength,
25591				thetaStart: thetaStart,
25592				thetaLength: thetaLength
25593			};
25594			widthSegments = Math.max(3, Math.floor(widthSegments));
25595			heightSegments = Math.max(2, Math.floor(heightSegments));
25596			const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI);
25597			let index = 0;
25598			const grid = [];
25599			const vertex = new Vector3();
25600			const normal = new Vector3(); // buffers
25601
25602			const indices = [];
25603			const vertices = [];
25604			const normals = [];
25605			const uvs = []; // generate vertices, normals and uvs
25606
25607			for (let iy = 0; iy <= heightSegments; iy++) {
25608				const verticesRow = [];
25609				const v = iy / heightSegments; // special case for the poles
25610
25611				let uOffset = 0;
25612
25613				if (iy == 0 && thetaStart == 0) {
25614					uOffset = 0.5 / widthSegments;
25615				} else if (iy == heightSegments && thetaEnd == Math.PI) {
25616					uOffset = -0.5 / widthSegments;
25617				}
25618
25619				for (let ix = 0; ix <= widthSegments; ix++) {
25620					const u = ix / widthSegments; // vertex
25621
25622					vertex.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
25623					vertex.y = radius * Math.cos(thetaStart + v * thetaLength);
25624					vertex.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
25625					vertices.push(vertex.x, vertex.y, vertex.z); // normal
25626
25627					normal.copy(vertex).normalize();
25628					normals.push(normal.x, normal.y, normal.z); // uv
25629
25630					uvs.push(u + uOffset, 1 - v);
25631					verticesRow.push(index++);
25632				}
25633
25634				grid.push(verticesRow);
25635			} // indices
25636
25637
25638			for (let iy = 0; iy < heightSegments; iy++) {
25639				for (let ix = 0; ix < widthSegments; ix++) {
25640					const a = grid[iy][ix + 1];
25641					const b = grid[iy][ix];
25642					const c = grid[iy + 1][ix];
25643					const d = grid[iy + 1][ix + 1];
25644					if (iy !== 0 || thetaStart > 0) indices.push(a, b, d);
25645					if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d);
25646				}
25647			} // build geometry
25648
25649
25650			this.setIndex(indices);
25651			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
25652			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
25653			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
25654		}
25655
25656		static fromJSON(data) {
25657			return new SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength);
25658		}
25659
25660	}
25661
25662	class TetrahedronGeometry extends PolyhedronGeometry {
25663		constructor(radius = 1, detail = 0) {
25664			const vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1];
25665			const indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1];
25666			super(vertices, indices, radius, detail);
25667			this.type = 'TetrahedronGeometry';
25668			this.parameters = {
25669				radius: radius,
25670				detail: detail
25671			};
25672		}
25673
25674		static fromJSON(data) {
25675			return new TetrahedronGeometry(data.radius, data.detail);
25676		}
25677
25678	}
25679
25680	class TorusGeometry extends BufferGeometry {
25681		constructor(radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2) {
25682			super();
25683			this.type = 'TorusGeometry';
25684			this.parameters = {
25685				radius: radius,
25686				tube: tube,
25687				radialSegments: radialSegments,
25688				tubularSegments: tubularSegments,
25689				arc: arc
25690			};
25691			radialSegments = Math.floor(radialSegments);
25692			tubularSegments = Math.floor(tubularSegments); // buffers
25693
25694			const indices = [];
25695			const vertices = [];
25696			const normals = [];
25697			const uvs = []; // helper variables
25698
25699			const center = new Vector3();
25700			const vertex = new Vector3();
25701			const normal = new Vector3(); // generate vertices, normals and uvs
25702
25703			for (let j = 0; j <= radialSegments; j++) {
25704				for (let i = 0; i <= tubularSegments; i++) {
25705					const u = i / tubularSegments * arc;
25706					const v = j / radialSegments * Math.PI * 2; // vertex
25707
25708					vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u);
25709					vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u);
25710					vertex.z = tube * Math.sin(v);
25711					vertices.push(vertex.x, vertex.y, vertex.z); // normal
25712
25713					center.x = radius * Math.cos(u);
25714					center.y = radius * Math.sin(u);
25715					normal.subVectors(vertex, center).normalize();
25716					normals.push(normal.x, normal.y, normal.z); // uv
25717
25718					uvs.push(i / tubularSegments);
25719					uvs.push(j / radialSegments);
25720				}
25721			} // generate indices
25722
25723
25724			for (let j = 1; j <= radialSegments; j++) {
25725				for (let i = 1; i <= tubularSegments; i++) {
25726					// indices
25727					const a = (tubularSegments + 1) * j + i - 1;
25728					const b = (tubularSegments + 1) * (j - 1) + i - 1;
25729					const c = (tubularSegments + 1) * (j - 1) + i;
25730					const d = (tubularSegments + 1) * j + i; // faces
25731
25732					indices.push(a, b, d);
25733					indices.push(b, c, d);
25734				}
25735			} // build geometry
25736
25737
25738			this.setIndex(indices);
25739			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
25740			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
25741			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
25742		}
25743
25744		static fromJSON(data) {
25745			return new TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc);
25746		}
25747
25748	}
25749
25750	class TorusKnotGeometry extends BufferGeometry {
25751		constructor(radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3) {
25752			super();
25753			this.type = 'TorusKnotGeometry';
25754			this.parameters = {
25755				radius: radius,
25756				tube: tube,
25757				tubularSegments: tubularSegments,
25758				radialSegments: radialSegments,
25759				p: p,
25760				q: q
25761			};
25762			tubularSegments = Math.floor(tubularSegments);
25763			radialSegments = Math.floor(radialSegments); // buffers
25764
25765			const indices = [];
25766			const vertices = [];
25767			const normals = [];
25768			const uvs = []; // helper variables
25769
25770			const vertex = new Vector3();
25771			const normal = new Vector3();
25772			const P1 = new Vector3();
25773			const P2 = new Vector3();
25774			const B = new Vector3();
25775			const T = new Vector3();
25776			const N = new Vector3(); // generate vertices, normals and uvs
25777
25778			for (let i = 0; i <= tubularSegments; ++i) {
25779				// the radian "u" is used to calculate the position on the torus curve of the current tubular segement
25780				const u = i / tubularSegments * p * Math.PI * 2; // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.
25781				// these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions
25782
25783				calculatePositionOnCurve(u, p, q, radius, P1);
25784				calculatePositionOnCurve(u + 0.01, p, q, radius, P2); // calculate orthonormal basis
25785
25786				T.subVectors(P2, P1);
25787				N.addVectors(P2, P1);
25788				B.crossVectors(T, N);
25789				N.crossVectors(B, T); // normalize B, N. T can be ignored, we don't use it
25790
25791				B.normalize();
25792				N.normalize();
25793
25794				for (let j = 0; j <= radialSegments; ++j) {
25795					// now calculate the vertices. they are nothing more than an extrusion of the torus curve.
25796					// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.
25797					const v = j / radialSegments * Math.PI * 2;
25798					const cx = -tube * Math.cos(v);
25799					const cy = tube * Math.sin(v); // now calculate the final vertex position.
25800					// first we orient the extrusion with our basis vectos, then we add it to the current position on the curve
25801
25802					vertex.x = P1.x + (cx * N.x + cy * B.x);
25803					vertex.y = P1.y + (cx * N.y + cy * B.y);
25804					vertex.z = P1.z + (cx * N.z + cy * B.z);
25805					vertices.push(vertex.x, vertex.y, vertex.z); // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)
25806
25807					normal.subVectors(vertex, P1).normalize();
25808					normals.push(normal.x, normal.y, normal.z); // uv
25809
25810					uvs.push(i / tubularSegments);
25811					uvs.push(j / radialSegments);
25812				}
25813			} // generate indices
25814
25815
25816			for (let j = 1; j <= tubularSegments; j++) {
25817				for (let i = 1; i <= radialSegments; i++) {
25818					// indices
25819					const a = (radialSegments + 1) * (j - 1) + (i - 1);
25820					const b = (radialSegments + 1) * j + (i - 1);
25821					const c = (radialSegments + 1) * j + i;
25822					const d = (radialSegments + 1) * (j - 1) + i; // faces
25823
25824					indices.push(a, b, d);
25825					indices.push(b, c, d);
25826				}
25827			} // build geometry
25828
25829
25830			this.setIndex(indices);
25831			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
25832			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
25833			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // this function calculates the current position on the torus curve
25834
25835			function calculatePositionOnCurve(u, p, q, radius, position) {
25836				const cu = Math.cos(u);
25837				const su = Math.sin(u);
25838				const quOverP = q / p * u;
25839				const cs = Math.cos(quOverP);
25840				position.x = radius * (2 + cs) * 0.5 * cu;
25841				position.y = radius * (2 + cs) * su * 0.5;
25842				position.z = radius * Math.sin(quOverP) * 0.5;
25843			}
25844		}
25845
25846		static fromJSON(data) {
25847			return new TorusKnotGeometry(data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q);
25848		}
25849
25850	}
25851
25852	class TubeGeometry extends BufferGeometry {
25853		constructor(path = new QuadraticBezierCurve3(new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0)), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false) {
25854			super();
25855			this.type = 'TubeGeometry';
25856			this.parameters = {
25857				path: path,
25858				tubularSegments: tubularSegments,
25859				radius: radius,
25860				radialSegments: radialSegments,
25861				closed: closed
25862			};
25863			const frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals
25864
25865			this.tangents = frames.tangents;
25866			this.normals = frames.normals;
25867			this.binormals = frames.binormals; // helper variables
25868
25869			const vertex = new Vector3();
25870			const normal = new Vector3();
25871			const uv = new Vector2();
25872			let P = new Vector3(); // buffer
25873
25874			const vertices = [];
25875			const normals = [];
25876			const uvs = [];
25877			const indices = []; // create buffer data
25878
25879			generateBufferData(); // build geometry
25880
25881			this.setIndex(indices);
25882			this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
25883			this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
25884			this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // functions
25885
25886			function generateBufferData() {
25887				for (let i = 0; i < tubularSegments; i++) {
25888					generateSegment(i);
25889				} // if the geometry is not closed, generate the last row of vertices and normals
25890				// at the regular position on the given path
25891				//
25892				// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
25893
25894
25895				generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function.
25896				// this makes it easy compute correct values for closed geometries
25897
25898				generateUVs(); // finally create faces
25899
25900				generateIndices();
25901			}
25902
25903			function generateSegment(i) {
25904				// we use getPointAt to sample evenly distributed points from the given path
25905				P = path.getPointAt(i / tubularSegments, P); // retrieve corresponding normal and binormal
25906
25907				const N = frames.normals[i];
25908				const B = frames.binormals[i]; // generate normals and vertices for the current segment
25909
25910				for (let j = 0; j <= radialSegments; j++) {
25911					const v = j / radialSegments * Math.PI * 2;
25912					const sin = Math.sin(v);
25913					const cos = -Math.cos(v); // normal
25914
25915					normal.x = cos * N.x + sin * B.x;
25916					normal.y = cos * N.y + sin * B.y;
25917					normal.z = cos * N.z + sin * B.z;
25918					normal.normalize();
25919					normals.push(normal.x, normal.y, normal.z); // vertex
25920
25921					vertex.x = P.x + radius * normal.x;
25922					vertex.y = P.y + radius * normal.y;
25923					vertex.z = P.z + radius * normal.z;
25924					vertices.push(vertex.x, vertex.y, vertex.z);
25925				}
25926			}
25927
25928			function generateIndices() {
25929				for (let j = 1; j <= tubularSegments; j++) {
25930					for (let i = 1; i <= radialSegments; i++) {
25931						const a = (radialSegments + 1) * (j - 1) + (i - 1);
25932						const b = (radialSegments + 1) * j + (i - 1);
25933						const c = (radialSegments + 1) * j + i;
25934						const d = (radialSegments + 1) * (j - 1) + i; // faces
25935
25936						indices.push(a, b, d);
25937						indices.push(b, c, d);
25938					}
25939				}
25940			}
25941
25942			function generateUVs() {
25943				for (let i = 0; i <= tubularSegments; i++) {
25944					for (let j = 0; j <= radialSegments; j++) {
25945						uv.x = i / tubularSegments;
25946						uv.y = j / radialSegments;
25947						uvs.push(uv.x, uv.y);
25948					}
25949				}
25950			}
25951		}
25952
25953		toJSON() {
25954			const data = super.toJSON();
25955			data.path = this.parameters.path.toJSON();
25956			return data;
25957		}
25958
25959		static fromJSON(data) {
25960			// This only works for built-in curves (e.g. CatmullRomCurve3).
25961			// User defined curves or instances of CurvePath will not be deserialized.
25962			return new TubeGeometry(new Curves[data.path.type]().fromJSON(data.path), data.tubularSegments, data.radius, data.radialSegments, data.closed);
25963		}
25964
25965	}
25966
25967	class WireframeGeometry extends BufferGeometry {
25968		constructor(geometry = null) {
25969			super();
25970			this.type = 'WireframeGeometry';
25971			this.parameters = {
25972				geometry: geometry
25973			};
25974
25975			if (geometry !== null) {
25976				// buffer
25977				const vertices = [];
25978				const edges = new Set(); // helper variables
25979
25980				const start = new Vector3();
25981				const end = new Vector3();
25982
25983				if (geometry.index !== null) {
25984					// indexed BufferGeometry
25985					const position = geometry.attributes.position;
25986					const indices = geometry.index;
25987					let groups = geometry.groups;
25988
25989					if (groups.length === 0) {
25990						groups = [{
25991							start: 0,
25992							count: indices.count,
25993							materialIndex: 0
25994						}];
25995					} // create a data structure that contains all eges without duplicates
25996
25997
25998					for (let o = 0, ol = groups.length; o < ol; ++o) {
25999						const group = groups[o];
26000						const groupStart = group.start;
26001						const groupCount = group.count;
26002
26003						for (let i = groupStart, l = groupStart + groupCount; i < l; i += 3) {
26004							for (let j = 0; j < 3; j++) {
26005								const index1 = indices.getX(i + j);
26006								const index2 = indices.getX(i + (j + 1) % 3);
26007								start.fromBufferAttribute(position, index1);
26008								end.fromBufferAttribute(position, index2);
26009
26010								if (isUniqueEdge(start, end, edges) === true) {
26011									vertices.push(start.x, start.y, start.z);
26012									vertices.push(end.x, end.y, end.z);
26013								}
26014							}
26015						}
26016					}
26017				} else {
26018					// non-indexed BufferGeometry
26019					const position = geometry.attributes.position;
26020
26021					for (let i = 0, l = position.count / 3; i < l; i++) {
26022						for (let j = 0; j < 3; j++) {
26023							// three edges per triangle, an edge is represented as (index1, index2)
26024							// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
26025							const index1 = 3 * i + j;
26026							const index2 = 3 * i + (j + 1) % 3;
26027							start.fromBufferAttribute(position, index1);
26028							end.fromBufferAttribute(position, index2);
26029
26030							if (isUniqueEdge(start, end, edges) === true) {
26031								vertices.push(start.x, start.y, start.z);
26032								vertices.push(end.x, end.y, end.z);
26033							}
26034						}
26035					}
26036				} // build geometry
26037
26038
26039				this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
26040			}
26041		}
26042
26043	}
26044
26045	function isUniqueEdge(start, end, edges) {
26046		const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`;
26047		const hash2 = `${end.x}
26047,${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge
26048
26049		if (edges.has(hash1) === true || edges.has(hash2) === true) {
26050			return false;
26051		} else {
26052			edges.add(hash1, hash2);
26053			return true;
26054		}
26055	}
26056
26057	var Geometries = /*#__PURE__*/Object.freeze({
26058		__proto__: null,
26059		BoxGeometry: BoxGeometry,
26060		BoxBufferGeometry: BoxGeometry,
26061		CircleGeometry: CircleGeometry,
26062		CircleBufferGeometry: CircleGeometry,
26063		ConeGeometry: ConeGeometry,
26064		ConeBufferGeometry: ConeGeometry,
26065		CylinderGeometry: CylinderGeometry,
26066		CylinderBufferGeometry: CylinderGeometry,
26067		DodecahedronGeometry: DodecahedronGeometry,
26068		DodecahedronBufferGeometry: DodecahedronGeometry,
26069		EdgesGeometry: EdgesGeometry,
26070		ExtrudeGeometry: ExtrudeGeometry,
26071		ExtrudeBufferGeometry: ExtrudeGeometry,
26072		IcosahedronGeometry: IcosahedronGeometry,
26073		IcosahedronBufferGeometry: IcosahedronGeometry,
26074		LatheGeometry: LatheGeometry,
26075		LatheBufferGeometry: LatheGeometry,
26076		OctahedronGeometry: OctahedronGeometry,
26077		OctahedronBufferGeometry: OctahedronGeometry,
26078		PlaneGeometry: PlaneGeometry,
26079		PlaneBufferGeometry: PlaneGeometry,
26080		PolyhedronGeometry: PolyhedronGeometry,
26081		PolyhedronBufferGeometry: PolyhedronGeometry,
26082		RingGeometry: RingGeometry,
26083		RingBufferGeometry: RingGeometry,
26084		ShapeGeometry: ShapeGeometry,
26085		ShapeBufferGeometry: ShapeGeometry,
26086		SphereGeometry: SphereGeometry,
26087		SphereBufferGeometry: SphereGeometry,
26088		TetrahedronGeometry: TetrahedronGeometry,
26089		TetrahedronBufferGeometry: TetrahedronGeometry,
26090		TorusGeometry: TorusGeometry,
26091		TorusBufferGeometry: TorusGeometry,
26092		TorusKnotGeometry: TorusKnotGeometry,
26093		TorusKnotBufferGeometry: TorusKnotGeometry,
26094		TubeGeometry: TubeGeometry,
26095		TubeBufferGeometry: TubeGeometry,
26096		WireframeGeometry: WireframeGeometry
26097	});
26098
26099	/**
26100	 * parameters = {
26101	 *	color: <THREE.Color>
26102	 * }
26103	 */
26104
26105	class ShadowMaterial extends Material {
26106		constructor(parameters) {
26107			super();
26108			this.type = 'ShadowMaterial';
26109			this.color = new Color(0x000000);
26110			this.transparent = true;
26111			this.setValues(parameters);
26112		}
26113
26114		copy(source) {
26115			super.copy(source);
26116			this.color.copy(source.color);
26117			return this;
26118		}
26119
26120	}
26121
26122	ShadowMaterial.prototype.isShadowMaterial = true;
26123
26124	/**
26125	 * parameters = {
26126	 *	color: <hex>,
26127	 *	roughness: <float>,
26128	 *	metalness: <float>,
26129	 *	opacity: <float>,
26130	 *
26131	 *	map: new THREE.Texture( <Image> ),
26132	 *
26133	 *	lightMap: new THREE.Texture( <Image> ),
26134	 *	lightMapIntensity: <float>
26135	 *
26136	 *	aoMap: new THREE.Texture( <Image> ),
26137	 *	aoMapIntensity: <float>
26138	 *
26139	 *	emissive: <hex>,
26140	 *	emissiveIntensity: <float>
26141	 *	emissiveMap: new THREE.Texture( <Image> ),
26142	 *
26143	 *	bumpMap: new THREE.Texture( <Image> ),
26144	 *	bumpScale: <float>,
26145	 *
26146	 *	normalMap: new THREE.Texture( <Image> ),
26147	 *	normalMapType: THREE.TangentSpaceNormalMap,
26148	 *	normalScale: <Vector2>,
26149	 *
26150	 *	displacementMap: new THREE.Texture( <Image> ),
26151	 *	displacementScale: <float>,
26152	 *	displacementBias: <float>,
26153	 *
26154	 *	roughnessMap: new THREE.Texture( <Image> ),
26155	 *
26156	 *	metalnessMap: new THREE.Texture( <Image> ),
26157	 *
26158	 *	alphaMap: new THREE.Texture( <Image> ),
26159	 *
26160	 *	envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
26161	 *	envMapIntensity: <float>
26162	 *
26163	 *	refractionRatio: <float>,
26164	 *
26165	 *	wireframe: <boolean>,
26166	 *	wireframeLinewidth: <float>,
26167	 *
26168	 *	flatShading: <bool>
26169	 * }
26170	 */
26171
26172	class MeshStandardMaterial extends Material {
26173		constructor(parameters) {
26174			super();
26175			this.defines = {
26176				'STANDARD': ''
26177			};
26178			this.type = 'MeshStandardMaterial';
26179			this.color = new Color(0xffffff); // diffuse
26180
26181			this.roughness = 1.0;
26182			this.metalness = 0.0;
26183			this.map = null;
26184			this.lightMap = null;
26185			this.lightMapIntensity = 1.0;
26186			this.aoMap = null;
26187			this.aoMapIntensity = 1.0;
26188			this.emissive = new Color(0x000000);
26189			this.emissiveIntensity = 1.0;
26190			this.emissiveMap = null;
26191			this.bumpMap = null;
26192			this.bumpScale = 1;
26193			this.normalMap = null;
26194			this.normalMapType = TangentSpaceNormalMap;
26195			this.normalScale = new Vector2(1, 1);
26196			this.displacementMap = null;
26197			this.displacementScale = 1;
26198			this.displacementBias = 0;
26199			this.roughnessMap = null;
26200			this.metalnessMap = null;
26201			this.alphaMap = null;
26202			this.envMap = null;
26203			this.envMapIntensity = 1.0;
26204			this.refractionRatio = 0.98;
26205			this.wireframe = false;
vendor: 6,184 bytes, lines 26206-26424
26206			this.wireframeLinewidth = 1;
26207			this.wireframeLinecap = 'round';
26208			this.wireframeLinejoin = 'round';
26209			this.flatShading = false;
26210			this.setValues(parameters);
26211		}
26212
26213		copy(source) {
26214			super.copy(source);
26215			this.defines = {
26216				'STANDARD': ''
26217			};
26218			this.color.copy(source.color);
26219			this.roughness = source.roughness;
26220			this.metalness = source.metalness;
26221			this.map = source.map;
26222			this.lightMap = source.lightMap;
26223			this.lightMapIntensity = source.lightMapIntensity;
26224			this.aoMap = source.aoMap;
26225			this.aoMapIntensity = source.aoMapIntensity;
26226			this.emissive.copy(source.emissive);
26227			this.emissiveMap = source.emissiveMap;
26228			this.emissiveIntensity = source.emissiveIntensity;
26229			this.bumpMap = source.bumpMap;
26230			this.bumpScale = source.bumpScale;
26231			this.normalMap = source.normalMap;
26232			this.normalMapType = source.normalMapType;
26233			this.normalScale.copy(source.normalScale);
26234			this.displacementMap = source.displacementMap;
26235			this.displacementScale = source.displacementScale;
26236			this.displacementBias = source.displacementBias;
26237			this.roughnessMap = source.roughnessMap;
26238			this.metalnessMap = source.metalnessMap;
26239			this.alphaMap = source.alphaMap;
26240			this.envMap = source.envMap;
26241			this.envMapIntensity = source.envMapIntensity;
26242			this.refractionRatio = source.refractionRatio;
26243			this.wireframe = source.wireframe;
26244			this.wireframeLinewidth = source.wireframeLinewidth;
26245			this.wireframeLinecap = source.wireframeLinecap;
26246			this.wireframeLinejoin = source.wireframeLinejoin;
26247			this.flatShading = source.flatShading;
26248			return this;
26249		}
26250
26251	}
26252
26253	MeshStandardMaterial.prototype.isMeshStandardMaterial = true;
26254
26255	/**
26256	 * parameters = {
26257	 *	clearcoat: <float>,
26258	 *	clearcoatMap: new THREE.Texture( <Image> ),
26259	 *	clearcoatRoughness: <float>,
26260	 *	clearcoatRoughnessMap: new THREE.Texture( <Image> ),
26261	 *	clearcoatNormalScale: <Vector2>,
26262	 *	clearcoatNormalMap: new THREE.Texture( <Image> ),
26263	 *
26264	 *	ior: <float>,
26265	 *	reflectivity: <float>,
26266	 *
26267	 *	sheen: <float>,
26268	 *	sheenColor: <Color>,
26269	 *	sheenColorMap: new THREE.Texture( <Image> ),
26270	 *	sheenRoughness: <float>,
26271	 *	sheenRoughnessMap: new THREE.Texture( <Image> ),
26272	 *
26273	 *	transmission: <float>,
26274	 *	transmissionMap: new THREE.Texture( <Image> ),
26275	 *
26276	 *	thickness: <float>,
26277	 *	thicknessMap: new THREE.Texture( <Image> ),
26278	 *	attenuationDistance: <float>,
26279	 *	attenuationColor: <Color>,
26280	 *
26281	 *	specularIntensity: <float>,
26282	 *	specularIntensityMap: new THREE.Texture( <Image> ),
26283	 *	specularColor: <Color>,
26284	 *	specularColorMap: new THREE.Texture( <Image> )
26285	 * }
26286	 */
26287
26288	class MeshPhysicalMaterial extends MeshStandardMaterial {
26289		constructor(parameters) {
26290			super();
26291			this.defines = {
26292				'STANDARD': '',
26293				'PHYSICAL': ''
26294			};
26295			this.type = 'MeshPhysicalMaterial';
26296			this.clearcoatMap = null;
26297			this.clearcoatRoughness = 0.0;
26298			this.clearcoatRoughnessMap = null;
26299			this.clearcoatNormalScale = new Vector2(1, 1);
26300			this.clearcoatNormalMap = null;
26301			this.ior = 1.5;
26302			Object.defineProperty(this, 'reflectivity', {
26303				get: function () {
26304					return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
26305				},
26306				set: function (reflectivity) {
26307					this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity);
26308				}
26309			});
26310			this.sheenColor = new Color(0x000000);
26311			this.sheenColorMap = null;
26312			this.sheenRoughness = 1.0;
26313			this.sheenRoughnessMap = null;
26314			this.transmissionMap = null;
26315			this.thickness = 0;
26316			this.thicknessMap = null;
26317			this.attenuationDistance = 0.0;
26318			this.attenuationColor = new Color(1, 1, 1);
26319			this.specularIntensity = 1.0;
26320			this.specularIntensityMap = null;
26321			this.specularColor = new Color(1, 1, 1);
26322			this.specularColorMap = null;
26323			this._sheen = 0.0;
26324			this._clearcoat = 0;
26325			this._transmission = 0;
26326			this.setValues(parameters);
26327		}
26328
26329		get sheen() {
26330			return this._sheen;
26331		}
26332
26333		set sheen(value) {
26334			if (this._sheen > 0 !== value > 0) {
26335				this.version++;
26336			}
26337
26338			this._sheen = value;
26339		}
26340
26341		get clearcoat() {
26342			return this._clearcoat;
26343		}
26344
26345		set clearcoat(value) {
26346			if (this._clearcoat > 0 !== value > 0) {
26347				this.version++;
26348			}
26349
26350			this._clearcoat = value;
26351		}
26352
26353		get transmission() {
26354			return this._transmission;
26355		}
26356
26357		set transmission(value) {
26358			if (this._transmission > 0 !== value > 0) {
26359				this.version++;
26360			}
26361
26362			this._transmission = value;
26363		}
26364
26365		copy(source) {
26366			super.copy(source);
26367			this.defines = {
26368				'STANDARD': '',
26369				'PHYSICAL': ''
26370			};
26371			this.clearcoat = source.clearcoat;
26372			this.clearcoatMap = source.clearcoatMap;
26373			this.clearcoatRoughness = source.clearcoatRoughness;
26374			this.clearcoatRoughnessMap = source.clearcoatRoughnessMap;
26375			this.clearcoatNormalMap = source.clearcoatNormalMap;
26376			this.clearcoatNormalScale.copy(source.clearcoatNormalScale);
26377			this.ior = source.ior;
26378			this.sheen = source.sheen;
26379			this.sheenColor.copy(source.sheenColor);
26380			this.sheenColorMap = source.sheenColorMap;
26381			this.sheenRoughness = source.sheenRoughness;
26382			this.sheenRoughnessMap = source.sheenRoughnessMap;
26383			this.transmission = source.transmission;
26384			this.transmissionMap = source.transmissionMap;
26385			this.thickness = source.thickness;
26386			this.thicknessMap = source.thicknessMap;
26387			this.attenuationDistance = source.attenuationDistance;
26388			this.attenuationColor.copy(source.attenuationColor);
26389			this.specularIntensity = source.specularIntensity;
26390			this.specularIntensityMap = source.specularIntensityMap;
26391			this.specularColor.copy(source.specularColor);
26392			this.specularColorMap = source.specularColorMap;
26393			return this;
26394		}
26395
26396	}
26397
26398	MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;
26399
26400	/**
26401	 * parameters = {
26402	 *	color: <hex>,
26403	 *	specular: <hex>,
26404	 *	shininess: <float>,
26405	 *	opacity: <float>,
26406	 *
26407	 *	map: new THREE.Texture( <Image> ),
26408	 *
26409	 *	lightMap: new THREE.Texture( <Image> ),
26410	 *	lightMapIntensity: <float>
26411	 *
26412	 *	aoMap: new THREE.Texture( <Image> ),
26413	 *	aoMapIntensity: <float>
26414	 *
26415	 *	emissive: <hex>,
26416	 *	emissiveIntensity: <float>
26417	 *	emissiveMap: new THREE.Texture( <Image> ),
26418	 *
26419	 *	bumpMap: new THREE.Texture( <Image> ),
26420	 *	bumpScale: <float>,
26421	 *
26422	 *	normalMap: new THREE.Texture( <Image> ),
26423	 *	normalMapType: THREE.TangentSpaceNormalMap,
26424	 *	normalScale: <Vector2>,
26425	 *
26426	 *	displacementMap: new THREE.Texture( <Image> ),
26427	 *	displacementScale: <float>,
26428	 *	displacementBias: <float>,
26429	 *
26430	 *	specularMap: new THREE.Texture( <Image> ),
26431	 *
26432	 *	alphaMap: new THREE.Texture( <Image> ),
26433	 *
26434	 *	envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
26435	 *	combine: THREE.MultiplyOperation,
26436	 *	reflectivity: <float>,
26437	 *	refractionRatio: <float>,
26438	 *
26439	 *	wireframe: <boolean>,
26440	 *	wireframeLinewidth: <float>,
26441	 *
26442	 *	flatShading: <bool>
26443	 * }
26444	 */
26445
26446	class MeshPhongMaterial extends Material {
26447		constructor(parameters) {
26448			super();
26449			this.type = 'MeshPhongMaterial';
26450			this.color = new Color(0xffffff); // diffuse
26451
26452			this.specular = new Color(0x111111);
26453			this.shininess = 30;
26454			this.map = null;
26455			this.lightMap = null;
26456			this.lightMapIntensity = 1.0;
26457			this.aoMap = null;
26458			this.aoMapIntensity = 1.0;
26459			this.emissive = new Color(0x000000);
26460			this.emissiveIntensity = 1.0;
26461			this.emissiveMap = null;
26462			this.bumpMap = null;
26463			this.bumpScale = 1;
26464			this.normalMap = null;
26465			this.normalMapType = TangentSpaceNormalMap;
26466			this.normalScale = new Vector2(1, 1);
26467			this.displacementMap = null;
26468			this.displacementScale = 1;
26469			this.displacementBias = 0;
26470			this.specularMap = null;
26471			this.alphaMap = null;
26472			this.envMap = null;
26473			this.combine = MultiplyOperation;
26474			this.reflectivity = 1;
26475			this.refractionRatio = 0.98;
26476			this.wireframe = false;
26477			this.wireframeLinewidth = 1;
26478			this.wireframeLinecap = 'round';
26479			this.wireframeLinejoin = 'round';
26480			this.flatShading = false;
26481			this.setValues(parameters);
26482		}
26483
26484		copy(source) {
26485			super.copy(source);
26486			this.color.copy(source.color);
26487			this.specular.copy(source.specular);
26488			this.shininess = source.shininess;
26489			this.map = source.map;
26490			this.lightMap = source.lightMap;
26491			this.lightMapIntensity = source.lightMapIntensity;
26492			this.aoMap = source.aoMap;
26493			this.aoMapIntensity = source.aoMapIntensity;
26494			this.emissive.copy(source.emissive);
26495			this.emissiveMap = source.emissiveMap;
26496			this.emissiveIntensity = source.emissiveIntensity;
26497			this.bumpMap = source.bumpMap;
26498			this.bumpScale = source.bumpScale;
26499			this.normalMap = source.normalMap;
26500			this.normalMapType = source.normalMapType;
26501			this.normalScale.copy(source.normalScale);
26502			this.displacementMap = source.displacementMap;
26503			this.displacementScale = source.displacementScale;
26504			this.displacementBias = source.displacementBias;
26505			this.specularMap = source.specularMap;
26506			this.alphaMap = source.alphaMap;
26507			this.envMap = source.envMap;
26508			this.combine = source.combine;
26509			this.reflectivity = source.reflectivity;
26510			this.refractionRatio = source.refractionRatio;
26511			this.wireframe = source.wireframe;
26512			this.wireframeLinewidth = source.wireframeLinewidth;
26513			this.wireframeLinecap = source.wireframeLinecap;
26514			this.wireframeLinejoin = source.wireframeLinejoin;
26515			this.flatShading = source.flatShading;
26516			return this;
26517		}
26518
26519	}
26520
26521	MeshPhongMaterial.prototype.isMeshPhongMaterial = true;
26522
26523	/**
26524	 * parameters = {
26525	 *	color: <hex>,
26526	 *
26527	 *	map: new THREE.Texture( <Image> ),
26528	 *	gradientMap: new THREE.Texture( <Image> ),
26529	 *
26530	 *	lightMap: new THREE.Texture( <Image> ),
26531	 *	lightMapIntensity: <float>
26532	 *
26533	 *	aoMap: new THREE.Texture( <Image> ),
26534	 *	aoMapIntensity: <float>
26535	 *
26536	 *	emissive: <hex>,
26537	 *	emissiveIntensity: <float>
26538	 *	emissiveMap: new THREE.Texture( <Image> ),
26539	 *
26540	 *	bumpMap: new THREE.Texture( <Image> ),
26541	 *	bumpScale: <float>,
26542	 *
26543	 *	normalMap: new THREE.Texture( <Image> ),
26544	 *	normalMapType: THREE.TangentSpaceNormalMap,
26545	 *	normalScale: <Vector2>,
26546	 *
26547	 *	displacementMap: new THREE.Texture( <Image> ),
26548	 *	displacementScale: <float>,
26549	 *	displacementBias: <float>,
26550	 *
26551	 *	alphaMap: new THREE.Texture( <Image> ),
26552	 *
26553	 *	wireframe: <boolean>,
26554	 *	wireframeLinewidth: <float>,
26555	 *
26556	 * }
26557	 */
26558
26559	class MeshToonMaterial extends Material {
26560		constructor(parameters) {
26561			super();
26562			this.defines = {
26563				'TOON': ''
26564			};
26565			this.type = 'MeshToonMaterial';
26566			this.color = new Color(0xffffff);
26567			this.map = null;
26568			this.gradientMap = null;
26569			this.lightMap = null;
26570			this.lightMapIntensity = 1.0;
26571			this.aoMap = null;
26572			this.aoMapIntensity = 1.0;
26573			this.emissive = new Color(0x000000);
26574			this.emissiveIntensity = 1.0;
26575			this.emissiveMap = null;
26576			this.bumpMap = null;
26577			this.bumpScale = 1;
26578			this.normalMap = null;
26579			this.normalMapType = TangentSpaceNormalMap;
26580			this.normalScale = new Vector2(1, 1);
26581			this.displacementMap = null;
26582			this.displacementScale = 1;
26583			this.displacementBias = 0;
26584			this.alphaMap = null;
26585			this.wireframe = false;
26586			this.wireframeLinewidth = 1;
26587			this.wireframeLinecap = 'round';
26588			this.wireframeLinejoin = 'round';
26589			this.setValues(parameters);
26590		}
26591
26592		copy(source) {
26593			super.copy(source);
26594			this.color.copy(source.color);
26595			this.map = source.map;
26596			this.gradientMap = source.gradientMap;
26597			this.lightMap = source.lightMap;
26598			this.lightMapIntensity = source.lightMapIntensity;
26599			this.aoMap = source.aoMap;
26600			this.aoMapIntensity = source.aoMapIntensity;
26601			this.emissive.copy(source.emissive);
26602			this.emissiveMap = source.emissiveMap;
26603			this.emissiveIntensity = source.emissiveIntensity;
26604			this.bumpMap = source.bumpMap;
26605			this.bumpScale = source.bumpScale;
26606			this.normalMap = source.normalMap;
26607			this.normalMapType = source.normalMapType;
26608			this.normalScale.copy(source.normalScale);
26609			this.displacementMap = source.displacementMap;
26610			this.displacementScale = source.displacementScale;
26611			this.displacementBias = source.displacementBias;
26612			this.alphaMap = source.alphaMap;
26613			this.wireframe = source.wireframe;
26614			this.wireframeLinewidth = source.wireframeLinewidth;
26615			this.wireframeLinecap = source.wireframeLinecap;
26616			this.wireframeLinejoin = source.wireframeLinejoin;
26617			return this;
26618		}
26619
26620	}
26621
26622	MeshToonMaterial.prototype.isMeshToonMaterial = true;
26623
26624	/**
26625	 * parameters = {
26626	 *	opacity: <float>,
26627	 *
26628	 *	bumpMap: new THREE.Texture( <Image> ),
26629	 *	bumpScale: <float>,
26630	 *
26631	 *	normalMap: new THREE.Texture( <Image> ),
26632	 *	normalMapType: THREE.TangentSpaceNormalMap,
26633	 *	normalScale: <Vector2>,
26634	 *
26635	 *	displacementMap: new THREE.Texture( <Image> ),
26636	 *	displacementScale: <float>,
26637	 *	displacementBias: <float>,
26638	 *
26639	 *	wireframe: <boolean>,
26640	 *	wireframeLinewidth: <float>
26641	 *
26642	 *	flatShading: <bool>
26643	 * }
26644	 */
26645
26646	class MeshNormalMaterial extends Material {
26647		constructor(parameters) {
26648			super();
26649			this.type = 'MeshNormalMaterial';
26650			this.bumpMap = null;
26651			this.bumpScale = 1;
26652			this.normalMap = null;
26653			this.normalMapType = TangentSpaceNormalMap;
26654			this.normalScale = new Vector2(1, 1);
26655			this.displacementMap = null;
26656			this.displacementScale = 1;
26657			this.displacementBias = 0;
26658			this.wireframe = false;
26659			this.wireframeLinewidth = 1;
26660			this.fog = false;
26661			this.flatShading = false;
26662			this.setValues(parameters);
26663		}
26664
26665		copy(source) {
26666			super.copy(source);
26667			this.bumpMap = source.bumpMap;
26668			this.bumpScale = source.bumpScale;
26669			this.normalMap = source.normalMap;
26670			this.normalMapType = source.normalMapType;
26671			this.normalScale.copy(source.normalScale);
26672			this.displacementMap = source.displacementMap;
26673			this.displacementScale = source.displacementScale;
26674			this.displacementBias = source.displacementBias;
26675			this.wireframe = source.wireframe;
26676			this.wireframeLinewidth = source.wireframeLinewidth;
26677			this.flatShading = source.flatShading;
26678			return this;
26679		}
26680
26681	}
26682
26683	MeshNormalMaterial.prototype.isMeshNormalMaterial = true;
26684
26685	/**
26686	 * parameters = {
26687	 *	color: <hex>,
26688	 *	opacity: <float>,
26689	 *
26690	 *	map: new THREE.Texture( <Image> ),
26691	 *
26692	 *	lightMap: new THREE.Texture( <Image> ),
26693	 *	lightMapIntensity: <float>
26694	 *
26695	 *	aoMap: new THREE.Texture( <Image> ),
26696	 *	aoMapIntensity: <float>
26697	 *
26698	 *	emissive: <hex>,
26699	 *	emissiveIntensity: <float>
26700	 *	emissiveMap: new THREE.Texture( <Image> ),
26701	 *
26702	 *	specularMap: new THREE.Texture( <Image> ),
26703	 *
26704	 *	alphaMap: new THREE.Texture( <Image> ),
26705	 *
26706	 *	envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
26707	 *	combine: THREE.Multiply,
26708	 *	reflectivity: <float>,
26709	 *	refractionRatio: <float>,
26710	 *
26711	 *	wireframe: <boolean>,
26712	 *	wireframeLinewidth: <float>,
26713	 *
26714	 * }
26715	 */
26716
26717	class MeshLambertMaterial extends Material {
26718		constructor(parameters) {
26719			super();
26720			this.type = 'MeshLambertMaterial';
26721			this.color = new Color(0xffffff); // diffuse
26722
26723			this.map = null;
26724			this.lightMap = null;
26725			this.lightMapIntensity = 1.0;
26726			this.aoMap = null;
26727			this.aoMapIntensity = 1.0;
26728			this.emissive = new Color(0x000000);
26729			this.emissiveIntensity = 1.0;
26730			this.emissiveMap = null;
26731			this.specularMap = null;
26732			this.alphaMap = null;
26733			this.envMap = null;
26734			this.combine = MultiplyOperation;
26735			this.reflectivity = 1;
26736			this.refractionRatio = 0.98;
26737			this.wireframe = false;
26738			this.wireframeLinewidth = 1;
26739			this.wireframeLinecap = 'round';
26740			this.wireframeLinejoin = 'round';
26741			this.setValues(parameters);
26742		}
26743
26744		copy(source) {
26745			super.copy(source);
26746			this.color.copy(source.color);
26747			this.map = source.map;
26748			this.lightMap = source.lightMap;
26749			this.lightMapIntensity = source.lightMapIntensity;
26750			this.aoMap = source.aoMap;
26751			this.aoMapIntensity = source.aoMapIntensity;
26752			this.emissive.copy(source.emissive);
26753			this.emissiveMap = source.emissiveMap;
26754			this.emissiveIntensity = source.emissiveIntensity;
26755			this.specularMap = source.specularMap;
26756			this.alphaMap = source.alphaMap;
26757			this.envMap = source.envMap;
26758			this.combine = source.combine;
26759			this.reflectivity = source.reflectivity;
26760			this.refractionRatio = source.refractionRatio;
26761			this.wireframe = source.wireframe;
26762			this.wireframeLinewidth = source.wireframeLinewidth;
26763			this.wireframeLinecap = source.wireframeLinecap;
26764			this.wireframeLinejoin = source.wireframeLinejoin;
26765			return this;
26766		}
26767
26768	}
26769
26770	MeshLambertMaterial.prototype.isMeshLambertMaterial = true;
26771
26772	/**
26773	 * parameters = {
26774	 *	color: <hex>,
26775	 *	opacity: <float>,
26776	 *
26777	 *	matcap: new THREE.Texture( <Image> ),
26778	 *
26779	 *	map: new THREE.Texture( <Image> ),
26780	 *
26781	 *	bumpMap: new THREE.Texture( <Image> ),
26782	 *	bumpScale: <float>,
26783	 *
26784	 *	normalMap: new THREE.Texture( <Image> ),
26785	 *	normalMapType: THREE.TangentSpaceNormalMap,
26786	 *	normalScale: <Vector2>,
26787	 *
26788	 *	displacementMap: new THREE.Texture( <Image> ),
26789	 *	displacementScale: <float>,
26790	 *	displacementBias: <float>,
26791	 *
26792	 *	alphaMap: new THREE.Texture( <Image> ),
26793	 *
26794	 *	flatShading: <bool>
26795	 * }
26796	 */
26797
26798	class MeshMatcapMaterial extends Material {
26799		constructor(parameters) {
26800			super();
26801			this.defines = {
26802				'MATCAP': ''
26803			};
26804			this.type = 'MeshMatcapMaterial';
26805			this.color = new Color(0xffffff); // diffuse
26806
26807			this.matcap = null;
26808			this.map = null;
26809			this.bumpMap = null;
26810			this.bumpScale = 1;
26811			this.normalMap = null;
26812			this.normalMapType = TangentSpaceNormalMap;
26813			this.normalScale = new Vector2(1, 1);
26814			this.displacementMap = null;
26815			this.displacementScale = 1;
26816			this.displacementBias = 0;
26817			this.alphaMap = null;
26818			this.flatShading = false;
26819			this.setValues(parameters);
26820		}
26821
26822		copy(source) {
26823			super.copy(source);
26824			this.defines = {
26825				'MATCAP': ''
26826			};
26827			this.color.copy(source.color);
26828			this.matcap = source.matcap;
26829			this.map = source.map;
26830			this.bumpMap = source.bumpMap;
26831			this.bumpScale = source.bumpScale;
26832			this.normalMap = source.normalMap;
26833			this.normalMapType = source.normalMapType;
26834			this.normalScale.copy(source.normalScale);
26835			this.displacementMap = source.displacementMap;
26836			this.displacementScale = source.displacementScale;
26837			this.displacementBias = source.displacementBias;
26838			this.alphaMap = source.alphaMap;
26839			this.flatShading = source.flatShading;
26840			return this;
26841		}
26842
26843	}
26844
26845	MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true;
26846
26847	/**
26848	 * parameters = {
26849	 *	color: <hex>,
26850	 *	opacity: <float>,
26851	 *
26852	 *	linewidth: <float>,
26853	 *
26854	 *	scale: <float>,
26855	 *	dashSize: <float>,
26856	 *	gapSize: <float>
26857	 * }
26858	 */
26859
26860	class LineDashedMaterial extends LineBasicMaterial {
26861		constructor(parameters) {
26862			super();
26863			this.type = 'LineDashedMaterial';
26864			this.scale = 1;
26865			this.dashSize = 3;
26866			this.gapSize = 1;
26867			this.setValues(parameters);
26868		}
26869
26870		copy(source) {
26871			super.copy(source);
26872			this.scale = source.scale;
26873			this.dashSize = source.dashSize;
26874			this.gapSize = source.gapSize;
26875			return this;
26876		}
26877
26878	}
26879
26880	LineDashedMaterial.prototype.isLineDashedMaterial = true;
26881
26882	var Materials = /*#__PURE__*/Object.freeze({
26883		__proto__: null,
26884		ShadowMaterial: ShadowMaterial,
26885		SpriteMaterial: SpriteMaterial,
26886		RawShaderMaterial: RawShaderMaterial,
26887		ShaderMaterial: ShaderMaterial,
26888		PointsMaterial: PointsMaterial,
26889		MeshPhysicalMaterial: MeshPhysicalMaterial,
26890		MeshStandardMaterial: MeshStandardMaterial,
26891		MeshPhongMaterial: MeshPhongMaterial,
26892		MeshToonMaterial: MeshToonMaterial,
26893		MeshNormalMaterial: MeshNormalMaterial,
26894		MeshLambertMaterial: MeshLambertMaterial,
26895		MeshDepthMaterial: MeshDepthMaterial,
26896		MeshDistanceMaterial: MeshDistanceMaterial,
26897		MeshBasicMaterial: MeshBasicMaterial,
26898		MeshMatcapMaterial: MeshMatcapMaterial,
26899		LineDashedMaterial: LineDashedMaterial,
26900		LineBasicMaterial: LineBasicMaterial,
26901		Material: Material
26902	});
26903
26904	const AnimationUtils = {
26905		// same as Array.prototype.slice, but also works on typed arrays
26906		arraySlice: function (array, from, to) {
26907			if (AnimationUtils.isTypedArray(array)) {
26908				// in ios9 array.subarray(from, undefined) will return empty array
26909				// but array.subarray(from) or array.subarray(from, len) is correct
26910				return new array.constructor(array.subarray(from, to !== undefined ? to : array.length));
26911			}
26912
26913			return array.slice(from, to);
26914		},
26915		// converts an array to a specific type
26916		convertArray: function (array, type, forceClone) {
26917			if (!array || // let 'undefined' and 'null' pass
vendor: 8,141 bytes, lines 26918-27159
26918			!forceClone && array.constructor === type) return array;
26919
26920			if (typeof type.BYTES_PER_ELEMENT === 'number') {
26921				return new type(array); // create typed array
26922			}
26923
26924			return Array.prototype.slice.call(array); // create Array
26925		},
26926		isTypedArray: function (object) {
26927			return ArrayBuffer.isView(object) && !(object instanceof DataView);
26928		},
26929		// returns an array by which times and values can be sorted
26930		getKeyframeOrder: function (times) {
26931			function compareTime(i, j) {
26932				return times[i] - times[j];
26933			}
26934
26935			const n = times.length;
26936			const result = new Array(n);
26937
26938			for (let i = 0; i !== n; ++i) result[i] = i;
26939
26940			result.sort(compareTime);
26941			return result;
26942		},
26943		// uses the array previously returned by 'getKeyframeOrder' to sort data
26944		sortedArray: function (values, stride, order) {
26945			const nValues = values.length;
26946			const result = new values.constructor(nValues);
26947
26948			for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) {
26949				const srcOffset = order[i] * stride;
26950
26951				for (let j = 0; j !== stride; ++j) {
26952					result[dstOffset++] = values[srcOffset + j];
26953				}
26954			}
26955
26956			return result;
26957		},
26958		// function for parsing AOS keyframe formats
26959		flattenJSON: function (jsonKeys, times, values, valuePropertyName) {
26960			let i = 1,
26961					key = jsonKeys[0];
26962
26963			while (key !== undefined && key[valuePropertyName] === undefined) {
26964				key = jsonKeys[i++];
26965			}
26966
26967			if (key === undefined) return; // no data
26968
26969			let value = key[valuePropertyName];
26970			if (value === undefined) return; // no data
26971
26972			if (Array.isArray(value)) {
26973				do {
26974					value = key[valuePropertyName];
26975
26976					if (value !== undefined) {
26977						times.push(key.time);
26978						values.push.apply(values, value); // push all elements
26979					}
26980
26981					key = jsonKeys[i++];
26982				} while (key !== undefined);
26983			} else if (value.toArray !== undefined) {
26984				// ...assume THREE.Math-ish
26985				do {
26986					value = key[valuePropertyName];
26987
26988					if (value !== undefined) {
26989						times.push(key.time);
26990						value.toArray(values, values.length);
26991					}
26992
26993					key = jsonKeys[i++];
26994				} while (key !== undefined);
26995			} else {
26996				// otherwise push as-is
26997				do {
26998					value = key[valuePropertyName];
26999
27000					if (value !== undefined) {
27001						times.push(key.time);
27002						values.push(value);
27003					}
27004
27005					key = jsonKeys[i++];
27006				} while (key !== undefined);
27007			}
27008		},
27009		subclip: function (sourceClip, name, startFrame, endFrame, fps = 30) {
27010			const clip = sourceClip.clone();
27011			clip.name = name;
27012			const tracks = [];
27013
27014			for (let i = 0; i < clip.tracks.length; ++i) {
27015				const track = clip.tracks[i];
27016				const valueSize = track.getValueSize();
27017				const times = [];
27018				const values = [];
27019
27020				for (let j = 0; j < track.times.length; ++j) {
27021					const frame = track.times[j] * fps;
27022					if (frame < startFrame || frame >= endFrame) continue;
27023					times.push(track.times[j]);
27024
27025					for (let k = 0; k < valueSize; ++k) {
27026						values.push(track.values[j * valueSize + k]);
27027					}
27028				}
27029
27030				if (times.length === 0) continue;
27031				track.times = AnimationUtils.convertArray(times, track.times.constructor);
27032				track.values = AnimationUtils.convertArray(values, track.values.constructor);
27033				tracks.push(track);
27034			}
27035
27036			clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip
27037
27038			let minStartTime = Infinity;
27039
27040			for (let i = 0; i < clip.tracks.length; ++i) {
27041				if (minStartTime > clip.tracks[i].times[0]) {
27042					minStartTime = clip.tracks[i].times[0];
27043				}
27044			} // shift all tracks such that clip begins at t=0
27045
27046
27047			for (let i = 0; i < clip.tracks.length; ++i) {
27048				clip.tracks[i].shift(-1 * minStartTime);
27049			}
27050
27051			clip.resetDuration();
27052			return clip;
27053		},
27054		makeClipAdditive: function (targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30) {
27055			if (fps <= 0) fps = 30;
27056			const numTracks = referenceClip.tracks.length;
27057			const referenceTime = referenceFrame / fps; // Make each track's values relative to the values at the reference frame
27058
27059			for (let i = 0; i < numTracks; ++i) {
27060				const referenceTrack = referenceClip.tracks[i];
27061				const referenceTrackType = referenceTrack.ValueTypeName; // Skip this track if it's non-numeric
27062
27063				if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; // Find the track in the target clip whose name and type matches the reference track
27064
27065				const targetTrack = targetClip.tracks.find(function (track) {
27066					return track.name === referenceTrack.name && track.ValueTypeName === referenceTrackType;
27067				});
27068				if (targetTrack === undefined) continue;
27069				let referenceOffset = 0;
27070				const referenceValueSize = referenceTrack.getValueSize();
27071
27072				if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
27073					referenceOffset = referenceValueSize / 3;
27074				}
27075
27076				let targetOffset = 0;
27077				const targetValueSize = targetTrack.getValueSize();
27078
27079				if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
27080					targetOffset = targetValueSize / 3;
27081				}
27082
27083				const lastIndex = referenceTrack.times.length - 1;
27084				let referenceValue; // Find the value to subtract out of the track
27085
27086				if (referenceTime <= referenceTrack.times[0]) {
27087					// Reference frame is earlier than the first keyframe, so just use the first keyframe
27088					const startIndex = referenceOffset;
27089					const endIndex = referenceValueSize - referenceOffset;
27090					referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex);
27091				} else if (referenceTime >= referenceTrack.times[lastIndex]) {
27092					// Reference frame is after the last keyframe, so just use the last keyframe
27093					const startIndex = lastIndex * referenceValueSize + referenceOffset;
27094					const endIndex = startIndex + referenceValueSize - referenceOffset;
27095					referenceValue = AnimationUtils.arraySlice(referenceTrack.values, startIndex, endIndex);
27096				} else {
27097					// Interpolate to the reference value
27098					const interpolant = referenceTrack.createInterpolant();
27099					const startIndex = referenceOffset;
27100					const endIndex = referenceValueSize - referenceOffset;
27101					interpolant.evaluate(referenceTime);
27102					referenceValue = AnimationUtils.arraySlice(interpolant.resultBuffer, startIndex, endIndex);
27103				} // Conjugate the quaternion
27104
27105
27106				if (referenceTrackType === 'quaternion') {
27107					const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate();
27108					referenceQuat.toArray(referenceValue);
27109				} // Subtract the reference value from all of the track values
27110
27111
27112				const numTimes = targetTrack.times.length;
27113
27114				for (let j = 0; j < numTimes; ++j) {
27115					const valueStart = j * targetValueSize + targetOffset;
27116
27117					if (referenceTrackType === 'quaternion') {
27118						// Multiply the conjugate for quaternion track types
27119						Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart, referenceValue, 0, targetTrack.values, valueStart);
27120					} else {
27121						const valueEnd = targetValueSize - targetOffset * 2; // Subtract each value for all other numeric track types
27122
27123						for (let k = 0; k < valueEnd; ++k) {
27124							targetTrack.values[valueStart + k] -= referenceValue[k];
27125						}
27126					}
27127				}
27128			}
27129
27130			targetClip.blendMode = AdditiveAnimationBlendMode;
27131			return targetClip;
27132		}
27133	};
27134
27135	/**
27136	 * Abstract base class of interpolants over parametric samples.
27137	 *
27138	 * The parameter domain is one dimensional, typically the time or a path
27139	 * along a curve defined by the data.
27140	 *
27141	 * The sample values can have any dimensionality and derived classes may
27142	 * apply special interpretations to the data.
27143	 *
27144	 * This class provides the interval seek in a Template Method, deferring
27145	 * the actual interpolation to derived classes.
27146	 *
27147	 * Time complexity is O(1) for linear access crossing at most two points
27148	 * and O(log N) for random access, where N is the number of positions.
27149	 *
27150	 * References:
27151	 *
27152	 * 		http://www.oodesign.com/template-method-pattern.html
27153	 *
27154	 */
27155	class Interpolant {
27156		constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
27157			this.parameterPositions = parameterPositions;
27158			this._cachedIndex = 0;
27159			this.resultBuffer = resultBuffer !== undefined ? resultBuffer : new s
vendor: 6,015 bytes, lines 27159-27413
27159ampleValues.constructor(sampleSize);
27160			this.sampleValues = sampleValues;
27161			this.valueSize = sampleSize;
27162			this.settings = null;
27163			this.DefaultSettings_ = {};
27164		}
27165
27166		evaluate(t) {
27167			const pp = this.parameterPositions;
27168			let i1 = this._cachedIndex,
27169					t1 = pp[i1],
27170					t0 = pp[i1 - 1];
27171
27172			validate_interval: {
27173				seek: {
27174					let right;
27175
27176					linear_scan: {
27177						//- See http://jsperf.com/comparison-to-undefined/3
27178						//- slower code:
27179						//-
27180						//- 				if ( t >= t1 || t1 === undefined ) {
27181						forward_scan: if (!(t < t1)) {
27182							for (let giveUpAt = i1 + 2;;) {
27183								if (t1 === undefined) {
27184									if (t < t0) break forward_scan; // after end
27185
27186									i1 = pp.length;
27187									this._cachedIndex = i1;
27188									return this.afterEnd_(i1 - 1, t, t0);
27189								}
27190
27191								if (i1 === giveUpAt) break; // this loop
27192
27193								t0 = t1;
27194								t1 = pp[++i1];
27195
27196								if (t < t1) {
27197									// we have arrived at the sought interval
27198									break seek;
27199								}
27200							} // prepare binary search on the right side of the index
27201
27202
27203							right = pp.length;
27204							break linear_scan;
27205						} //- slower code:
27206						//-					if ( t < t0 || t0 === undefined ) {
27207
27208
27209						if (!(t >= t0)) {
27210							// looping?
27211							const t1global = pp[1];
27212
27213							if (t < t1global) {
27214								i1 = 2; // + 1, using the scan for the details
27215
27216								t0 = t1global;
27217							} // linear reverse scan
27218
27219
27220							for (let giveUpAt = i1 - 2;;) {
27221								if (t0 === undefined) {
27222									// before start
27223									this._cachedIndex = 0;
27224									return this.beforeStart_(0, t, t1);
27225								}
27226
27227								if (i1 === giveUpAt) break; // this loop
27228
27229								t1 = t0;
27230								t0 = pp[--i1 - 1];
27231
27232								if (t >= t0) {
27233									// we have arrived at the sought interval
27234									break seek;
27235								}
27236							} // prepare binary search on the left side of the index
27237
27238
27239							right = i1;
27240							i1 = 0;
27241							break linear_scan;
27242						} // the interval is valid
27243
27244
27245						break validate_interval;
27246					} // linear scan
27247					// binary search
27248
27249
27250					while (i1 < right) {
27251						const mid = i1 + right >>> 1;
27252
27253						if (t < pp[mid]) {
27254							right = mid;
27255						} else {
27256							i1 = mid + 1;
27257						}
27258					}
27259
27260					t1 = pp[i1];
27261					t0 = pp[i1 - 1]; // check boundary cases, again
27262
27263					if (t0 === undefined) {
27264						this._cachedIndex = 0;
27265						return this.beforeStart_(0, t, t1);
27266					}
27267
27268					if (t1 === undefined) {
27269						i1 = pp.length;
27270						this._cachedIndex = i1;
27271						return this.afterEnd_(i1 - 1, t0, t);
27272					}
27273				} // seek
27274
27275
27276				this._cachedIndex = i1;
27277				this.intervalChanged_(i1, t0, t1);
27278			} // validate_interval
27279
27280
27281			return this.interpolate_(i1, t0, t, t1);
27282		}
27283
27284		getSettings_() {
27285			return this.settings || this.DefaultSettings_;
27286		}
27287
27288		copySampleValue_(index) {
27289			// copies a sample value to the result buffer
27290			const result = this.resultBuffer,
27291						values = this.sampleValues,
27292						stride = this.valueSize,
27293						offset = index * stride;
27294
27295			for (let i = 0; i !== stride; ++i) {
27296				result[i] = values[offset + i];
27297			}
27298
27299			return result;
27300		} // Template methods for derived classes:
27301
27302
27303		interpolate_() {
27304			throw new Error('call to abstract method'); // implementations shall return this.resultBuffer
27305		}
27306
27307		intervalChanged_() {// empty
27308		}
27309
27310	} // ALIAS DEFINITIONS
27311
27312
27313	Interpolant.prototype.beforeStart_ = Interpolant.prototype.copySampleValue_;
27314	Interpolant.prototype.afterEnd_ = Interpolant.prototype.copySampleValue_;
27315
27316	/**
27317	 * Fast and simple cubic spline interpolant.
27318	 *
27319	 * It was derived from a Hermitian construction setting the first derivative
27320	 * at each sample position to the linear slope between neighboring positions
27321	 * over their parameter interval.
27322	 */
27323
27324	class CubicInterpolant extends Interpolant {
27325		constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
27326			super(parameterPositions, sampleValues, sampleSize, resultBuffer);
27327			this._weightPrev = -0;
27328			this._offsetPrev = -0;
27329			this._weightNext = -0;
27330			this._offsetNext = -0;
27331			this.DefaultSettings_ = {
27332				endingStart: ZeroCurvatureEnding,
27333				endingEnd: ZeroCurvatureEnding
27334			};
27335		}
27336
27337		intervalChanged_(i1, t0, t1) {
27338			const pp = this.parameterPositions;
27339			let iPrev = i1 - 2,
27340					iNext = i1 + 1,
27341					tPrev = pp[iPrev],
27342					tNext = pp[iNext];
27343
27344			if (tPrev === undefined) {
27345				switch (this.getSettings_().endingStart) {
27346					case ZeroSlopeEnding:
27347						// f'(t0) = 0
27348						iPrev = i1;
27349						tPrev = 2 * t0 - t1;
27350						break;
27351
27352					case WrapAroundEnding:
27353						// use the other end of the curve
27354						iPrev = pp.length - 2;
27355						tPrev = t0 + pp[iPrev] - pp[iPrev + 1];
27356						break;
27357
27358					default:
27359						// ZeroCurvatureEnding
27360						// f''(t0) = 0 a.k.a. Natural Spline
27361						iPrev = i1;
27362						tPrev = t1;
27363				}
27364			}
27365
27366			if (tNext === undefined) {
27367				switch (this.getSettings_().endingEnd) {
27368					case ZeroSlopeEnding:
27369						// f'(tN) = 0
27370						iNext = i1;
27371						tNext = 2 * t1 - t0;
27372						break;
27373
27374					case WrapAroundEnding:
27375						// use the other end of the curve
27376						iNext = 1;
27377						tNext = t1 + pp[1] - pp[0];
27378						break;
27379
27380					default:
27381						// ZeroCurvatureEnding
27382						// f''(tN) = 0, a.k.a. Natural Spline
27383						iNext = i1 - 1;
27384						tNext = t0;
27385				}
27386			}
27387
27388			const halfDt = (t1 - t0) * 0.5,
27389						stride = this.valueSize;
27390			this._weightPrev = halfDt / (t0 - tPrev);
27391			this._weightNext = halfDt / (tNext - t1);
27392			this._offsetPrev = iPrev * stride;
27393			this._offsetNext = iNext * stride;
27394		}
27395
27396		interpolate_(i1, t0, t, t1) {
27397			const result = this.resultBuffer,
27398						values = this.sampleValues,
27399						stride = this.valueSize,
27400						o1 = i1 * stride,
27401						o0 = o1 - stride,
27402						oP = this._offsetPrev,
27403						oN = this._offsetNext,
27404						wP = this._weightPrev,
27405						wN = this._weightNext,
27406						p = (t - t0) / (t1 - t0),
27407						pp = p * p,
27408						ppp = pp * p; // evaluate polynomials
27409
27410			const sP = -wP * ppp + 2 * wP * pp - wP * p;
27411			const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1;
27412			const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p;
27413			const sN = wN * ppp - wN * pp;
vendor: 1,511 bytes, lines 27413-27469
27413 // combine data linearly
27414
27415			for (let i = 0; i !== stride; ++i) {
27416				result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i];
27417			}
27418
27419			return result;
27420		}
27421
27422	}
27423
27424	class LinearInterpolant extends Interpolant {
27425		constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
27426			super(parameterPositions, sampleValues, sampleSize, resultBuffer);
27427		}
27428
27429		interpolate_(i1, t0, t, t1) {
27430			const result = this.resultBuffer,
27431						values = this.sampleValues,
27432						stride = this.valueSize,
27433						offset1 = i1 * stride,
27434						offset0 = offset1 - stride,
27435						weight1 = (t - t0) / (t1 - t0),
27436						weight0 = 1 - weight1;
27437
27438			for (let i = 0; i !== stride; ++i) {
27439				result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1;
27440			}
27441
27442			return result;
27443		}
27444
27445	}
27446
27447	/**
27448	 *
27449	 * Interpolant that evaluates to the sample value at the position preceeding
27450	 * the parameter.
27451	 */
27452
27453	class DiscreteInterpolant extends Interpolant {
27454		constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
27455			super(parameterPositions, sampleValues, sampleSize, resultBuffer);
27456		}
27457
27458		interpolate_(i1
27459		/*, t0, t, t1 */
27460		) {
27461			return this.copySampleValue_(i1 - 1);
27462		}
27463
27464	}
27465
27466	class KeyframeTrack {
27467		constructor(name, times, values, interpolation) {
27468			if (name === undefined) throw new Error('THREE.KeyframeTrack: track name is undefined');
27469			if (times === undefined || times.length === 0) throw new Error('THREE.KeyframeTrack: no keyframes in track named ' + n
vendor: 4,655 bytes, lines 27469-27635
27469ame);
27470			this.name = name;
27471			this.times = AnimationUtils.convertArray(times, this.TimeBufferType);
27472			this.values = AnimationUtils.convertArray(values, this.ValueBufferType);
27473			this.setInterpolation(interpolation || this.DefaultInterpolation);
27474		} // Serialization (in static context, because of constructor invocation
27475		// and automatic invocation of .toJSON):
27476
27477
27478		static toJSON(track) {
27479			const trackType = track.constructor;
27480			let json; // derived classes can define a static toJSON method
27481
27482			if (trackType.toJSON !== this.toJSON) {
27483				json = trackType.toJSON(track);
27484			} else {
27485				// by default, we assume the data can be serialized as-is
27486				json = {
27487					'name': track.name,
27488					'times': AnimationUtils.convertArray(track.times, Array),
27489					'values': AnimationUtils.convertArray(track.values, Array)
27490				};
27491				const interpolation = track.getInterpolation();
27492
27493				if (interpolation !== track.DefaultInterpolation) {
27494					json.interpolation = interpolation;
27495				}
27496			}
27497
27498			json.type = track.ValueTypeName; // mandatory
27499
27500			return json;
27501		}
27502
27503		InterpolantFactoryMethodDiscrete(result) {
27504			return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result);
27505		}
27506
27507		InterpolantFactoryMethodLinear(result) {
27508			return new LinearInterpolant(this.times, this.values, this.getValueSize(), result);
27509		}
27510
27511		InterpolantFactoryMethodSmooth(result) {
27512			return new CubicInterpolant(this.times, this.values, this.getValueSize(), result);
27513		}
27514
27515		setInterpolation(interpolation) {
27516			let factoryMethod;
27517
27518			switch (interpolation) {
27519				case InterpolateDiscrete:
27520					factoryMethod = this.InterpolantFactoryMethodDiscrete;
27521					break;
27522
27523				case InterpolateLinear:
27524					factoryMethod = this.InterpolantFactoryMethodLinear;
27525					break;
27526
27527				case InterpolateSmooth:
27528					factoryMethod = this.InterpolantFactoryMethodSmooth;
27529					break;
27530			}
27531
27532			if (factoryMethod === undefined) {
27533				const message = 'unsupported interpolation for ' + this.ValueTypeName + ' keyframe track named ' + this.name;
27534
27535				if (this.createInterpolant === undefined) {
27536					// fall back to default, unless the default itself is messed up
27537					if (interpolation !== this.DefaultInterpolation) {
27538						this.setInterpolation(this.DefaultInterpolation);
27539					} else {
27540						throw new Error(message); // fatal, in this case
27541					}
27542				}
27543
27544				console.warn('THREE.KeyframeTrack:', message);
27545				return this;
27546			}
27547
27548			this.createInterpolant = factoryMethod;
27549			return this;
27550		}
27551
27552		getInterpolation() {
27553			switch (this.createInterpolant) {
27554				case this.InterpolantFactoryMethodDiscrete:
27555					return InterpolateDiscrete;
27556
27557				case this.InterpolantFactoryMethodLinear:
27558					return InterpolateLinear;
27559
27560				case this.InterpolantFactoryMethodSmooth:
27561					return InterpolateSmooth;
27562			}
27563		}
27564
27565		getValueSize() {
27566			return this.values.length / this.times.length;
27567		} // move all keyframes either forwards or backwards in time
27568
27569
27570		shift(timeOffset) {
27571			if (timeOffset !== 0.0) {
27572				const times = this.times;
27573
27574				for (let i = 0, n = times.length; i !== n; ++i) {
27575					times[i] += timeOffset;
27576				}
27577			}
27578
27579			return this;
27580		} // scale all keyframe times by a factor (useful for frame <-> seconds conversions)
27581
27582
27583		scale(timeScale) {
27584			if (timeScale !== 1.0) {
27585				const times = this.times;
27586
27587				for (let i = 0, n = times.length; i !== n; ++i) {
27588					times[i] *= timeScale;
27589				}
27590			}
27591
27592			return this;
27593		} // removes keyframes before and after animation without changing any values within the range [startTime, endTime].
27594		// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
27595
27596
27597		trim(startTime, endTime) {
27598			const times = this.times,
27599						nKeys = times.length;
27600			let from = 0,
27601					to = nKeys - 1;
27602
27603			while (from !== nKeys && times[from] < startTime) {
27604				++from;
27605			}
27606
27607			while (to !== -1 && times[to] > endTime) {
27608				--to;
27609			}
27610
27611			++to; // inclusive -> exclusive bound
27612
27613			if (from !== 0 || to !== nKeys) {
27614				// empty tracks are forbidden, so keep at least one keyframe
27615				if (from >= to) {
27616					to = Math.max(to, 1);
27617					from = to - 1;
27618				}
27619
27620				const stride = this.getValueSize();
27621				this.times = AnimationUtils.arraySlice(times, from, to);
27622				this.values = AnimationUtils.arraySlice(this.values, from * stride, to * stride);
27623			}
27624
27625			return this;
27626		} // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
27627
27628
27629		validate() {
27630			let valid = true;
27631			const valueSize = this.getValueSize();
27632
27633			if (valueSize - Math.floor(valueSize) !== 0) {
27634				console.error('THREE.KeyframeTrack: Invalid value size in track.', this);
27635				valid = false;
vendor: 4,479 bytes, lines 27636-27792
27636			}
27637
27638			const times = this.times,
27639						values = this.values,
27640						nKeys = times.length;
27641
27642			if (nKeys === 0) {
27643				console.error('THREE.KeyframeTrack: Track is empty.', this);
27644				valid = false;
27645			}
27646
27647			let prevTime = null;
27648
27649			for (let i = 0; i !== nKeys; i++) {
27650				const currTime = times[i];
27651
27652				if (typeof currTime === 'number' && isNaN(currTime)) {
27653					console.error('THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime);
27654					valid = false;
27655					break;
27656				}
27657
27658				if (prevTime !== null && prevTime > currTime) {
27659					console.error('THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime);
27660					valid = false;
27661					break;
27662				}
27663
27664				prevTime = currTime;
27665			}
27666
27667			if (values !== undefined) {
27668				if (AnimationUtils.isTypedArray(values)) {
27669					for (let i = 0, n = values.length; i !== n; ++i) {
27670						const value = values[i];
27671
27672						if (isNaN(value)) {
27673							console.error('THREE.KeyframeTrack: Value is not a valid number.', this, i, value);
27674							valid = false;
27675							break;
27676						}
27677					}
27678				}
27679			}
27680
27681			return valid;
27682		} // removes equivalent sequential keys as common in morph target sequences
27683		// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
27684
27685
27686		optimize() {
27687			// times or values may be shared with other tracks, so overwriting is unsafe
27688			const times = AnimationUtils.arraySlice(this.times),
27689						values = AnimationUtils.arraySlice(this.values),
27690						stride = this.getValueSize(),
27691						smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
27692						lastIndex = times.length - 1;
27693			let writeIndex = 1;
27694
27695			for (let i = 1; i < lastIndex; ++i) {
27696				let keep = false;
27697				const time = times[i];
27698				const timeNext = times[i + 1]; // remove adjacent keyframes scheduled at the same time
27699
27700				if (time !== timeNext && (i !== 1 || time !== times[0])) {
27701					if (!smoothInterpolation) {
27702						// remove unnecessary keyframes same as their neighbors
27703						const offset = i * stride,
27704									offsetP = offset - stride,
27705									offsetN = offset + stride;
27706
27707						for (let j = 0; j !== stride; ++j) {
27708							const value = values[offset + j];
27709
27710							if (value !== values[offsetP + j] || value !== values[offsetN + j]) {
27711								keep = true;
27712								break;
27713							}
27714						}
27715					} else {
27716						keep = true;
27717					}
27718				} // in-place compaction
27719
27720
27721				if (keep) {
27722					if (i !== writeIndex) {
27723						times[writeIndex] = times[i];
27724						const readOffset = i * stride,
27725									writeOffset = writeIndex * stride;
27726
27727						for (let j = 0; j !== stride; ++j) {
27728							values[writeOffset + j] = values[readOffset + j];
27729						}
27730					}
27731
27732					++writeIndex;
27733				}
27734			} // flush last keyframe (compaction looks ahead)
27735
27736
27737			if (lastIndex > 0) {
27738				times[writeIndex] = times[lastIndex];
27739
27740				for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) {
27741					values[writeOffset + j] = values[readOffset + j];
27742				}
27743
27744				++writeIndex;
27745			}
27746
27747			if (writeIndex !== times.length) {
27748				this.times = AnimationUtils.arraySlice(times, 0, writeIndex);
27749				this.values = AnimationUtils.arraySlice(values, 0, writeIndex * stride);
27750			} else {
27751				this.times = times;
27752				this.values = values;
27753			}
27754
27755			return this;
27756		}
27757
27758		clone() {
27759			const times = AnimationUtils.arraySlice(this.times, 0);
27760			const values = AnimationUtils.arraySlice(this.values, 0);
27761			const TypedKeyframeTrack = this.constructor;
27762			const track = new TypedKeyframeTrack(this.name, times, values); // Interpolant argument to constructor is not saved, so copy the factory method directly.
27763
27764			track.createInterpolant = this.createInterpolant;
27765			return track;
27766		}
27767
27768	}
27769
27770	KeyframeTrack.prototype.TimeBufferType = Float32Array;
27771	KeyframeTrack.prototype.ValueBufferType = Float32Array;
27772	KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
27773
27774	/**
27775	 * A Track of Boolean keyframe values.
27776	 */
27777
27778	class BooleanKeyframeTrack extends KeyframeTrack {}
27779
27780	BooleanKeyframeTrack.prototype.ValueTypeName = 'bool';
27781	BooleanKeyframeTrack.prototype.ValueBufferType = Array;
27782	BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
27783	BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
27784	BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; // Note: Actually this track could have a optimized / compressed
27785
27786	/**
27787	 * A Track of keyframe values that represent color.
27788	 */
27789
27790	class ColorKeyframeTrack extends KeyframeTrack {}
27791
27792	ColorKeyframeTrack.prototype.ValueTypeName = 'color';
vendor: 6,272 bytes, lines 27792-28003
27792 // ValueBufferType is inherited
27793
27794	/**
27795	 * A Track of numeric keyframe values.
27796	 */
27797
27798	class NumberKeyframeTrack extends KeyframeTrack {}
27799
27800	NumberKeyframeTrack.prototype.ValueTypeName = 'number'; // ValueBufferType is inherited
27801
27802	/**
27803	 * Spherical linear unit quaternion interpolant.
27804	 */
27805
27806	class QuaternionLinearInterpolant extends Interpolant {
27807		constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
27808			super(parameterPositions, sampleValues, sampleSize, resultBuffer);
27809		}
27810
27811		interpolate_(i1, t0, t, t1) {
27812			const result = this.resultBuffer,
27813						values = this.sampleValues,
27814						stride = this.valueSize,
27815						alpha = (t - t0) / (t1 - t0);
27816			let offset = i1 * stride;
27817
27818			for (let end = offset + stride; offset !== end; offset += 4) {
27819				Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha);
27820			}
27821
27822			return result;
27823		}
27824
27825	}
27826
27827	/**
27828	 * A Track of quaternion keyframe values.
27829	 */
27830
27831	class QuaternionKeyframeTrack extends KeyframeTrack {
27832		InterpolantFactoryMethodLinear(result) {
27833			return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result);
27834		}
27835
27836	}
27837
27838	QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; // ValueBufferType is inherited
27839
27840	QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
27841	QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
27842
27843	/**
27844	 * A Track that interpolates Strings
27845	 */
27846
27847	class StringKeyframeTrack extends KeyframeTrack {}
27848
27849	StringKeyframeTrack.prototype.ValueTypeName = 'string';
27850	StringKeyframeTrack.prototype.ValueBufferType = Array;
27851	StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
27852	StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
27853	StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
27854
27855	/**
27856	 * A Track of vectored keyframe values.
27857	 */
27858
27859	class VectorKeyframeTrack extends KeyframeTrack {}
27860
27861	VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; // ValueBufferType is inherited
27862
27863	class AnimationClip {
27864		constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) {
27865			this.name = name;
27866			this.tracks = tracks;
27867			this.duration = duration;
27868			this.blendMode = blendMode;
27869			this.uuid = generateUUID(); // this means it should figure out its duration by scanning the tracks
27870
27871			if (this.duration < 0) {
27872				this.resetDuration();
27873			}
27874		}
27875
27876		static parse(json) {
27877			const tracks = [],
27878						jsonTracks = json.tracks,
27879						frameTime = 1.0 / (json.fps || 1.0);
27880
27881			for (let i = 0, n = jsonTracks.length; i !== n; ++i) {
27882				tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime));
27883			}
27884
27885			const clip = new this(json.name, json.duration, tracks, json.blendMode);
27886			clip.uuid = json.uuid;
27887			return clip;
27888		}
27889
27890		static toJSON(clip) {
27891			const tracks = [],
27892						clipTracks = clip.tracks;
27893			const json = {
27894				'name': clip.name,
27895				'duration': clip.duration,
27896				'tracks': tracks,
27897				'uuid': clip.uuid,
27898				'blendMode': clip.blendMode
27899			};
27900
27901			for (let i = 0, n = clipTracks.length; i !== n; ++i) {
27902				tracks.push(KeyframeTrack.toJSON(clipTracks[i]));
27903			}
27904
27905			return json;
27906		}
27907
27908		static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) {
27909			const numMorphTargets = morphTargetSequence.length;
27910			const tracks = [];
27911
27912			for (let i = 0; i < numMorphTargets; i++) {
27913				let times = [];
27914				let values = [];
27915				times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets);
27916				values.push(0, 1, 0);
27917				const order = AnimationUtils.getKeyframeOrder(times);
27918				times = AnimationUtils.sortedArray(times, 1, order);
27919				values = AnimationUtils.sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the
27920				// last frame as well for perfect loop.
27921
27922				if (!noLoop && times[0] === 0) {
27923					times.push(numMorphTargets);
27924					values.push(values[0]);
27925				}
27926
27927				tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetSequence[i].name + ']', times, values).scale(1.0 / fps));
27928			}
27929
27930			return new this(name, -1, tracks);
27931		}
27932
27933		static findByName(objectOrClipArray, name) {
27934			let clipArray = objectOrClipArray;
27935
27936			if (!Array.isArray(objectOrClipArray)) {
27937				const o = objectOrClipArray;
27938				clipArray = o.geometry && o.geometry.animations || o.animations;
27939			}
27940
27941			for (let i = 0; i < clipArray.length; i++) {
27942				if (clipArray[i].name === name) {
27943					return clipArray[i];
27944				}
27945			}
27946
27947			return null;
27948		}
27949
27950		static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) {
27951			const animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences
27952			// such flamingo_flyA_003, flamingo_run1_003, crdeath0059
27953
27954			const pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based
27955			// patterns like Walk_001, Walk_002, Run_001, Run_002
27956
27957			for (let i = 0, il = morphTargets.length; i < il; i++) {
27958				const morphTarget = morphTargets[i];
27959				const parts = morphTarget.name.match(pattern);
27960
27961				if (parts && parts.length > 1) {
27962					const name = parts[1];
27963					let animationMorphTargets = animationToMorphTargets[name];
27964
27965					if (!animationMorphTargets) {
27966						animationToMorphTargets[name] = animationMorphTargets = [];
27967					}
27968
27969					animationMorphTargets.push(morphTarget);
27970				}
27971			}
27972
27973			const clips = [];
27974
27975			for (const name in animationToMorphTargets) {
27976				clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop));
27977			}
27978
27979			return clips;
27980		} // parse the animation.hierarchy format
27981
27982
27983		static parseAnimation(animation, bones) {
27984			if (!animation) {
27985				console.error('THREE.AnimationClip: No animation in JSONLoader data.');
27986				return null;
27987			}
27988
27989			const addNonemptyTrack = function (trackType, trackName, animationKeys, propertyName, destTracks) {
27990				// only return track if there are actually keys.
27991				if (animationKeys.length !== 0) {
27992					const times = [];
27993					const values = [];
27994					AnimationUtils.flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again
27995
27996					if (times.length !== 0) {
27997						destTracks.push(new trackType(trackName, times, values));
27998					}
27999				}
28000			};
28001
28002			const tracks = [];
28003			const clipName = animation.name || 'default';
vendor: 12,829 bytes, lines 28004-28544
28004			const fps = animation.fps || 30;
28005			const blendMode = animation.blendMode; // automatic length determination in AnimationClip.
28006
28007			let duration = animation.length || -1;
28008			const hierarchyTracks = animation.hierarchy || [];
28009
28010			for (let h = 0; h < hierarchyTracks.length; h++) {
28011				const animationKeys = hierarchyTracks[h].keys; // skip empty tracks
28012
28013				if (!animationKeys || animationKeys.length === 0) continue; // process morph targets
28014
28015				if (animationKeys[0].morphTargets) {
28016					// figure out all morph targets used in this track
28017					const morphTargetNames = {};
28018					let k;
28019
28020					for (k = 0; k < animationKeys.length; k++) {
28021						if (animationKeys[k].morphTargets) {
28022							for (let m = 0; m < animationKeys[k].morphTargets.length; m++) {
28023								morphTargetNames[animationKeys[k].morphTargets[m]] = -1;
28024							}
28025						}
28026					} // create a track for each morph target with all zero
28027					// morphTargetInfluences except for the keys in which
28028					// the morphTarget is named.
28029
28030
28031					for (const morphTargetName in morphTargetNames) {
28032						const times = [];
28033						const values = [];
28034
28035						for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) {
28036							const animationKey = animationKeys[k];
28037							times.push(animationKey.time);
28038							values.push(animationKey.morphTarget === morphTargetName ? 1 : 0);
28039						}
28040
28041						tracks.push(new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values));
28042					}
28043
28044					duration = morphTargetNames.length * (fps || 1.0);
28045				} else {
28046					// ...assume skeletal animation
28047					const boneName = '.bones[' + bones[h].name + ']';
28048					addNonemptyTrack(VectorKeyframeTrack, boneName + '.position', animationKeys, 'pos', tracks);
28049					addNonemptyTrack(QuaternionKeyframeTrack, boneName + '.quaternion', animationKeys, 'rot', tracks);
28050					addNonemptyTrack(VectorKeyframeTrack, boneName + '.scale', animationKeys, 'scl', tracks);
28051				}
28052			}
28053
28054			if (tracks.length === 0) {
28055				return null;
28056			}
28057
28058			const clip = new this(clipName, duration, tracks, blendMode);
28059			return clip;
28060		}
28061
28062		resetDuration() {
28063			const tracks = this.tracks;
28064			let duration = 0;
28065
28066			for (let i = 0, n = tracks.length; i !== n; ++i) {
28067				const track = this.tracks[i];
28068				duration = Math.max(duration, track.times[track.times.length - 1]);
28069			}
28070
28071			this.duration = duration;
28072			return this;
28073		}
28074
28075		trim() {
28076			for (let i = 0; i < this.tracks.length; i++) {
28077				this.tracks[i].trim(0, this.duration);
28078			}
28079
28080			return this;
28081		}
28082
28083		validate() {
28084			let valid = true;
28085
28086			for (let i = 0; i < this.tracks.length; i++) {
28087				valid = valid && this.tracks[i].validate();
28088			}
28089
28090			return valid;
28091		}
28092
28093		optimize() {
28094			for (let i = 0; i < this.tracks.length; i++) {
28095				this.tracks[i].optimize();
28096			}
28097
28098			return this;
28099		}
28100
28101		clone() {
28102			const tracks = [];
28103
28104			for (let i = 0; i < this.tracks.length; i++) {
28105				tracks.push(this.tracks[i].clone());
28106			}
28107
28108			return new this.constructor(this.name, this.duration, tracks, this.blendMode);
28109		}
28110
28111		toJSON() {
28112			return this.constructor.toJSON(this);
28113		}
28114
28115	}
28116
28117	function getTrackTypeForValueTypeName(typeName) {
28118		switch (typeName.toLowerCase()) {
28119			case 'scalar':
28120			case 'double':
28121			case 'float':
28122			case 'number':
28123			case 'integer':
28124				return NumberKeyframeTrack;
28125
28126			case 'vector':
28127			case 'vector2':
28128			case 'vector3':
28129			case 'vector4':
28130				return VectorKeyframeTrack;
28131
28132			case 'color':
28133				return ColorKeyframeTrack;
28134
28135			case 'quaternion':
28136				return QuaternionKeyframeTrack;
28137
28138			case 'bool':
28139			case 'boolean':
28140				return BooleanKeyframeTrack;
28141
28142			case 'string':
28143				return StringKeyframeTrack;
28144		}
28145
28146		throw new Error('THREE.KeyframeTrack: Unsupported typeName: ' + typeName);
28147	}
28148
28149	function parseKeyframeTrack(json) {
28150		if (json.type === undefined) {
28151			throw new Error('THREE.KeyframeTrack: track type undefined, can not parse');
28152		}
28153
28154		const trackType = getTrackTypeForValueTypeName(json.type);
28155
28156		if (json.times === undefined) {
28157			const times = [],
28158						values = [];
28159			AnimationUtils.flattenJSON(json.keys, times, values, 'value');
28160			json.times = times;
28161			json.values = values;
28162		} // derived classes can define a static parse method
28163
28164
28165		if (trackType.parse !== undefined) {
28166			return trackType.parse(json);
28167		} else {
28168			// by default, we assume a constructor compatible with the base
28169			return new trackType(json.name, json.times, json.values, json.interpolation);
28170		}
28171	}
28172
28173	const Cache = {
28174		enabled: false,
28175		files: {},
28176		add: function (key, file) {
28177			if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key );
28178
28179			this.files[key] = file;
28180		},
28181		get: function (key) {
28182			if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key );
28183
28184			return this.files[key];
28185		},
28186		remove: function (key) {
28187			delete this.files[key];
28188		},
28189		clear: function () {
28190			this.files = {};
28191		}
28192	};
28193
28194	class LoadingManager {
28195		constructor(onLoad, onProgress, onError) {
28196			const scope = this;
28197			let isLoading = false;
28198			let itemsLoaded = 0;
28199			let itemsTotal = 0;
28200			let urlModifier = undefined;
28201			const handlers = []; // Refer to #5689 for the reason why we don't set .onStart
28202			// in the constructor
28203
28204			this.onStart = undefined;
28205			this.onLoad = onLoad;
28206			this.onProgress = onProgress;
28207			this.onError = onError;
28208
28209			this.itemStart = function (url) {
28210				itemsTotal++;
28211
28212				if (isLoading === false) {
28213					if (scope.onStart !== undefined) {
28214						scope.onStart(url, itemsLoaded, itemsTotal);
28215					}
28216				}
28217
28218				isLoading = true;
28219			};
28220
28221			this.itemEnd = function (url) {
28222				itemsLoaded++;
28223
28224				if (scope.onProgress !== undefined) {
28225					scope.onProgress(url, itemsLoaded, itemsTotal);
28226				}
28227
28228				if (itemsLoaded === itemsTotal) {
28229					isLoading = false;
28230
28231					if (scope.onLoad !== undefined) {
28232						scope.onLoad();
28233					}
28234				}
28235			};
28236
28237			this.itemError = function (url) {
28238				if (scope.onError !== undefined) {
28239					scope.onError(url);
28240				}
28241			};
28242
28243			this.resolveURL = function (url) {
28244				if (urlModifier) {
28245					return urlModifier(url);
28246				}
28247
28248				return url;
28249			};
28250
28251			this.setURLModifier = function (transform) {
28252				urlModifier = transform;
28253				return this;
28254			};
28255
28256			this.addHandler = function (regex, loader) {
28257				handlers.push(regex, loader);
28258				return this;
28259			};
28260
28261			this.removeHandler = function (regex) {
28262				const index = handlers.indexOf(regex);
28263
28264				if (index !== -1) {
28265					handlers.splice(index, 2);
28266				}
28267
28268				return this;
28269			};
28270
28271			this.getHandler = function (file) {
28272				for (let i = 0, l = handlers.length; i < l; i += 2) {
28273					const regex = handlers[i];
28274					const loader = handlers[i + 1];
28275					if (regex.global) regex.lastIndex = 0; // see #17920
28276
28277					if (regex.test(file)) {
28278						return loader;
28279					}
28280				}
28281
28282				return null;
28283			};
28284		}
28285
28286	}
28287
28288	const DefaultLoadingManager = new LoadingManager();
28289
28290	class Loader {
28291		constructor(manager) {
28292			this.manager = manager !== undefined ? manager : DefaultLoadingManager;
28293			this.crossOrigin = 'anonymous';
28294			this.withCredentials = false;
28295			this.path = '';
28296			this.resourcePath = '';
28297			this.requestHeader = {};
28298		}
28299
28300		load() {}
28301
28302		loadAsync(url, onProgress) {
28303			const scope = this;
28304			return new Promise(function (resolve, reject) {
28305				scope.load(url, resolve, onProgress, reject);
28306			});
28307		}
28308
28309		parse() {}
28310
28311		setCrossOrigin(crossOrigin) {
28312			this.crossOrigin = crossOrigin;
28313			return this;
28314		}
28315
28316		setWithCredentials(value) {
28317			this.withCredentials = value;
28318			return this;
28319		}
28320
28321		setPath(path) {
28322			this.path = path;
28323			return this;
28324		}
28325
28326		setResourcePath(resourcePath) {
28327			this.resourcePath = resourcePath;
28328			return this;
28329		}
28330
28331		setRequestHeader(requestHeader) {
28332			this.requestHeader = requestHeader;
28333			return this;
28334		}
28335
28336	}
28337
28338	const loading = {};
28339
28340	class FileLoader extends Loader {
28341		constructor(manager) {
28342			super(manager);
28343		}
28344
28345		load(url, onLoad, onProgress, onError) {
28346			if (url === undefined) url = '';
28347			if (this.path !== undefined) url = this.path + url;
28348			url = this.manager.resolveURL(url);
28349			const cached = Cache.get(url);
28350
28351			if (cached !== undefined) {
28352				this.manager.itemStart(url);
28353				setTimeout(() => {
28354					if (onLoad) onLoad(cached);
28355					this.manager.itemEnd(url);
28356				}, 0);
28357				return cached;
28358			} // Check if request is duplicate
28359
28360
28361			if (loading[url] !== undefined) {
28362				loading[url].push({
28363					onLoad: onLoad,
28364					onProgress: onProgress,
28365					onError: onError
28366				});
28367				return;
28368			} // Initialise array for duplicate requests
28369
28370
28371			loading[url] = [];
28372			loading[url].push({
28373				onLoad: onLoad,
28374				onProgress: onProgress,
28375				onError: onError
28376			}); // create request
28377
28378			const req = new Request(url, {
28379				headers: new Headers(this.requestHeader),
28380				credentials: this.withCredentials ? 'include' : 'same-origin' // An abort controller could be added within a future PR
28381
28382			}); // start the fetch
28383
28384			fetch(req).then(response => {
28385				if (response.status === 200 || response.status === 0) {
28386					// Some browsers return HTTP Status 0 when using non-http protocol
28387					// e.g. 'file://' or 'data://'. Handle as success.
28388					if (response.status === 0) {
28389						console.warn('THREE.FileLoader: HTTP Status 0 received.');
28390					}
28391
28392					if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) {
28393						return response;
28394					}
28395
28396					const callbacks = loading[url];
28397					const reader = response.body.getReader();
28398					const contentLength = response.headers.get('Content-Length');
28399					const total = contentLength ? parseInt(contentLength) : 0;
28400					const lengthComputable = total !== 0;
28401					let loaded = 0; // periodically read data into the new stream tracking while download progress
28402
28403					const stream = new ReadableStream({
28404						start(controller) {
28405							readData();
28406
28407							function readData() {
28408								reader.read().then(({
28409									done,
28410									value
28411								}) => {
28412									if (done) {
28413										controller.close();
28414									} else {
28415										loaded += value.byteLength;
28416										const event = new ProgressEvent('progress', {
28417											lengthComputable,
28418											loaded,
28419											total
28420										});
28421
28422										for (let i = 0, il = callbacks.length; i < il; i++) {
28423											const callback = callbacks[i];
28424											if (callback.onProgress) callback.onProgress(event);
28425										}
28426
28427										controller.enqueue(value);
28428										readData();
28429									}
28430								});
28431							}
28432						}
28433
28434					});
28435					return new Response(stream);
28436				} else {
28437					throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`);
28438				}
28439			}).then(response => {
28440				switch (this.responseType) {
28441					case 'arraybuffer':
28442						return response.arrayBuffer();
28443
28444					case 'blob':
28445						return response.blob();
28446
28447					case 'document':
28448						return response.text().then(text => {
28449							const parser = new DOMParser();
28450							return parser.parseFromString(text, this.mimeType);
28451						});
28452
28453					case 'json':
28454						return response.json();
28455
28456					default:
28457						return response.text();
28458				}
28459			}).then(data => {
28460				// Add to cache only on HTTP success, so that we do not cache
28461				// error response bodies as proper responses to requests.
28462				Cache.add(url, data);
28463				const callbacks = loading[url];
28464				delete loading[url];
28465
28466				for (let i = 0, il = callbacks.length; i < il; i++) {
28467					const callback = callbacks[i];
28468					if (callback.onLoad) callback.onLoad(data);
28469				}
28470			}).catch(err => {
28471				// Abort errors and other errors are handled the same
28472				const callbacks = loading[url];
28473
28474				if (callbacks === undefined) {
28475					// When onLoad was called and url was deleted in `loading`
28476					this.manager.itemError(url);
28477					throw err;
28478				}
28479
28480				delete loading[url];
28481
28482				for (let i = 0, il = callbacks.length; i < il; i++) {
28483					const callback = callbacks[i];
28484					if (callback.onError) callback.onError(err);
28485				}
28486
28487				this.manager.itemError(url);
28488			}).finally(() => {
28489				this.manager.itemEnd(url);
28490			});
28491			this.manager.itemStart(url);
28492		}
28493
28494		setResponseType(value) {
28495			this.responseType = value;
28496			return this;
28497		}
28498
28499		setMimeType(value) {
28500			this.mimeType = value;
28501			return this;
28502		}
28503
28504	}
28505
28506	class AnimationLoader extends Loader {
28507		constructor(manager) {
28508			super(manager);
28509		}
28510
28511		load(url, onLoad, onProgress, onError) {
28512			const scope = this;
28513			const loader = new FileLoader(this.manager);
28514			loader.setPath(this.path);
28515			loader.setRequestHeader(this.requestHeader);
28516			loader.setWithCredentials(this.withCredentials);
28517			loader.load(url, function (text) {
28518				try {
28519					onLoad(scope.parse(JSON.parse(text)));
28520				} catch (e) {
28521					if (onError) {
28522						onError(e);
28523					} else {
28524						console.error(e);
28525					}
28526
28527					scope.manager.itemError(url);
28528				}
28529			}, onProgress, onError);
28530		}
28531
28532		parse(json) {
28533			const animations = [];
28534
28535			for (let i = 0; i < json.length; i++) {
28536				const clip = AnimationClip.parse(json[i]);
28537				animations.push(clip);
28538			}
28539
28540			return animations;
28541		}
28542
28543	}
28544
vendor: 4,379 bytes, lines 28545-28722
28545	/**
28546	 * Abstract Base class to block based textures loader (dds, pvr, ...)
28547	 *
28548	 * Sub classes have to implement the parse() method which will be used in load().
28549	 */
28550
28551	class CompressedTextureLoader extends Loader {
28552		constructor(manager) {
28553			super(manager);
28554		}
28555
28556		load(url, onLoad, onProgress, onError) {
28557			const scope = this;
28558			const images = [];
28559			const texture = new CompressedTexture();
28560			const loader = new FileLoader(this.manager);
28561			loader.setPath(this.path);
28562			loader.setResponseType('arraybuffer');
28563			loader.setRequestHeader(this.requestHeader);
28564			loader.setWithCredentials(scope.withCredentials);
28565			let loaded = 0;
28566
28567			function loadTexture(i) {
28568				loader.load(url[i], function (buffer) {
28569					const texDatas = scope.parse(buffer, true);
28570					images[i] = {
28571						width: texDatas.width,
28572						height: texDatas.height,
28573						format: texDatas.format,
28574						mipmaps: texDatas.mipmaps
28575					};
28576					loaded += 1;
28577
28578					if (loaded === 6) {
28579						if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter;
28580						texture.image = images;
28581						texture.format = texDatas.format;
28582						texture.needsUpdate = true;
28583						if (onLoad) onLoad(texture);
28584					}
28585				}, onProgress, onError);
28586			}
28587
28588			if (Array.isArray(url)) {
28589				for (let i = 0, il = url.length; i < il; ++i) {
28590					loadTexture(i);
28591				}
28592			} else {
28593				// compressed cubemap texture stored in a single DDS file
28594				loader.load(url, function (buffer) {
28595					const texDatas = scope.parse(buffer, true);
28596
28597					if (texDatas.isCubemap) {
28598						const faces = texDatas.mipmaps.length / texDatas.mipmapCount;
28599
28600						for (let f = 0; f < faces; f++) {
28601							images[f] = {
28602								mipmaps: []
28603							};
28604
28605							for (let i = 0; i < texDatas.mipmapCount; i++) {
28606								images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]);
28607								images[f].format = texDatas.format;
28608								images[f].width = texDatas.width;
28609								images[f].height = texDatas.height;
28610							}
28611						}
28612
28613						texture.image = images;
28614					} else {
28615						texture.image.width = texDatas.width;
28616						texture.image.height = texDatas.height;
28617						texture.mipmaps = texDatas.mipmaps;
28618					}
28619
28620					if (texDatas.mipmapCount === 1) {
28621						texture.minFilter = LinearFilter;
28622					}
28623
28624					texture.format = texDatas.format;
28625					texture.needsUpdate = true;
28626					if (onLoad) onLoad(texture);
28627				}, onProgress, onError);
28628			}
28629
28630			return texture;
28631		}
28632
28633	}
28634
28635	class ImageLoader extends Loader {
28636		constructor(manager) {
28637			super(manager);
28638		}
28639
28640		load(url, onLoad, onProgress, onError) {
28641			if (this.path !== undefined) url = this.path + url;
28642			url = this.manager.resolveURL(url);
28643			const scope = this;
28644			const cached = Cache.get(url);
28645
28646			if (cached !== undefined) {
28647				scope.manager.itemStart(url);
28648				setTimeout(function () {
28649					if (onLoad) onLoad(cached);
28650					scope.manager.itemEnd(url);
28651				}, 0);
28652				return cached;
28653			}
28654
28655			const image = createElementNS('img');
28656
28657			function onImageLoad() {
28658				removeEventListeners();
28659				Cache.add(url, this);
28660				if (onLoad) onLoad(this);
28661				scope.manager.itemEnd(url);
28662			}
28663
28664			function onImageError(event) {
28665				removeEventListeners();
28666				if (onError) onError(event);
28667				scope.manager.itemError(url);
28668				scope.manager.itemEnd(url);
28669			}
28670
28671			function removeEventListeners() {
28672				image.removeEventListener('load', onImageLoad, false);
28673				image.removeEventListener('error', onImageError, false);
28674			}
28675
28676			image.addEventListener('load', onImageLoad, false);
28677			image.addEventListener('error', onImageError, false);
28678
28679			if (url.substr(0, 5) !== 'data:') {
28680				if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin;
28681			}
28682
28683			scope.manager.itemStart(url);
28684			image.src = url;
28685			return image;
28686		}
28687
28688	}
28689
28690	class CubeTextureLoader extends Loader {
28691		constructor(manager) {
28692			super(manager);
28693		}
28694
28695		load(urls, onLoad, onProgress, onError) {
28696			const texture = new CubeTexture();
28697			const loader = new ImageLoader(this.manager);
28698			loader.setCrossOrigin(this.crossOrigin);
28699			loader.setPath(this.path);
28700			let loaded = 0;
28701
28702			function loadTexture(i) {
28703				loader.load(urls[i], function (image) {
28704					texture.images[i] = image;
28705					loaded++;
28706
28707					if (loaded === 6) {
28708						texture.needsUpdate = true;
28709						if (onLoad) onLoad(texture);
28710					}
28711				}, undefined, onError);
28712			}
28713
28714			for (let i = 0; i < urls.length; ++i) {
28715				loadTexture(i);
28716			}
28717
28718			return texture;
28719		}
28720
28721	}
28722
28723	/**
28724	 * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
28725	 *
28726	 * Sub classes have to implement the parse() method which will be used in load().
28727	 */
28728
28729	class DataTextureLoader extends Loader {
28730		constructor(manager) {
28731			super(manager);
28732		}
28733
28734		load(url, onLoad, onProgress, onError) {
28735			const scope = this;
28736			const texture = new DataTexture();
28737			const loader = new FileLoader(this.manager);
28738			loader.setResponseType('arraybuffer');
28739			loader.setRequestHeader(this.requestHeader);
28740			loader.setPath(this.path);
28741			loader.setWithCredentials(scope.withCredentials);
28742			loader.load(url, function (buffer) {
28743				const texData = scope.parse(buffer);
28744				if (!texData) return;
28745
28746				if (texData.image !== undefined) {
28747					texture.image = texData.image;
28748				} else if (texData.data !== undefined) {
28749					texture.image.width = texData.width;
28750					texture.image.height = texData.height;
28751					texture.image.data = texData.data;
28752				}
28753
28754				texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
28755				texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
28756				texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
28757				texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
28758				texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
28759
28760				if (texData.encoding !== undefined) {
28761					texture.encoding = texData.encoding;
28762				}
28763
28764				if (texData.flipY !== undefined) {
28765					texture.flipY = texData.flipY;
28766				}
28767
28768				if (texData.format !== undefined) {
28769					texture.format = texData.format;
28770				}
28771
28772				if (texData.type !== undefined) {
28773					texture.type = texData.type;
28774				}
28775
28776				if (texData.mipmaps !== undefined) {
28777					texture.mipmaps = texData.mipmaps;
28778					texture.minFilter = LinearMipmapLinearFilter; // presumably...
28779				}
28780
28781				if (texData.mipmapCount === 1) {
28782					texture.minFilter = LinearFilter;
28783				}
28784
28785				if (texData.generateMipmaps !== undefined) {
28786					texture.generateMipmaps = texData.generateMipmaps;
28787				}
28788
28789				texture.needsUpdate = true;
28790				if (onLoad) onLoad(texture, texData);
28791			}, onProgress, onError);
28792			return texture;
28793		}
28794
28795	}
28796
28797	class TextureLoader extends Loader {
28798		constructor(manager) {
28799			super(manager);
28800		}
28801
28802		load(url, onLoad, onProgress, onError) {
28803			const texture = new Texture();
28804			const loader = new ImageLoader(this.manager);
28805			loader.setCrossOrigin(this.crossOrigin);
28806			loader.setPath(this.path);
28807			loader.load(url, function (image) {
28808				texture.image = image;
28809				texture.needsUpdate = true;
28810
28811				if (onLoad !== undefined) {
28812					onLoad(texture);
28813				}
28814			}, onProgress, onError);
28815			return texture;
28816		}
28817
28818	}
28819
28820	class Light extends Object3D {
28821		constructor(color, intensity = 1) {
28822			super();
28823			this.type = 'Light';
28824			this.color = new Color(color);
28825			this.intensity = intensity;
28826		}
28827
28828		dispose() {// Empty here in base class; some subclasses override.
28829		}
28830
28831		copy(source) {
28832			super.copy(source);
28833			this.color.copy(source.color);
28834			this.intensity = source.intensity;
28835			return this;
28836		}
28837
28838		toJSON(meta) {
28839			const data = super.toJSON(meta);
28840			data.object.color = this.color.getHex();
28841			data.object.intensity = this.intensity;
28842			if (this.groundColor !== undefined) data.object.groundColor = this.groundColor.getHex();
28843			if (this.distance !== undefined) data.object.distance = this.distance;
28844			if (this.angle !== undefined) data.object.angle = this.angle;
28845			if (this.decay !== undefined) data.object.decay = this.decay;
28846			if (this.penumbra !== undefined) data.object.penumbra = this.penumbra;
28847			if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON();
28848			return data;
28849		}
28850
28851	}
28852
28853	Light.prototype.isLight = true;
28854
28855	class HemisphereLight extends Light {
28856		constructor(skyColor, groundColor, intensity) {
28857			super(skyColor, intensity);
28858			this.type = 'HemisphereLight';
28859			this.position.copy(Object3D.DefaultUp);
28860			this.updateMatrix();
28861			this.groundColor = new Color(groundColor);
28862		}
28863
28864		copy(source) {
28865			Light.prototype.copy.call(this, source);
28866			this.groundColor.copy(source.groundColor);
28867			return this;
28868		}
28869
28870	}
28871
28872	HemisphereLight.prototype.isHemisphereLight = true;
28873
28874	const _projScreenMatrix$1 = /*@__PURE__*/new Matrix4();
28875
28876	const _lightPositionWorld$1 = /*@__PURE__*/new Vector3();
28877
28878	const _lookTarget$1 = /*@__PURE__*/new Vector3();
28879
28880	class LightShadow {
28881		constructor(camera) {
28882			this.camera = camera;
28883			this.bias = 0;
28884			this.normalBias = 0;
28885			this.radius = 1;
28886			this.blurSamples = 8;
28887			this.mapSize = new Vector2(512, 512);
28888			this.map = null;
28889			this.mapPass = null;
28890			this.matrix = new Matrix4();
28891			this.autoUpdate = true;
28892			this.needsUpdate = false;
vendor: 7,073 bytes, lines 28893-29153
28893			this._frustum = new Frustum();
28894			this._frameExtents = new Vector2(1, 1);
28895			this._viewportCount = 1;
28896			this._viewports = [new Vector4(0, 0, 1, 1)];
28897		}
28898
28899		getViewportCount() {
28900			return this._viewportCount;
28901		}
28902
28903		getFrustum() {
28904			return this._frustum;
28905		}
28906
28907		updateMatrices(light) {
28908			const shadowCamera = this.camera;
28909			const shadowMatrix = this.matrix;
28910
28911			_lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld);
28912
28913			shadowCamera.position.copy(_lightPositionWorld$1);
28914
28915			_lookTarget$1.setFromMatrixPosition(light.target.matrixWorld);
28916
28917			shadowCamera.lookAt(_lookTarget$1);
28918			shadowCamera.updateMatrixWorld();
28919
28920			_projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse);
28921
28922			this._frustum.setFromProjectionMatrix(_projScreenMatrix$1);
28923
28924			shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
28925			shadowMatrix.multiply(shadowCamera.projectionMatrix);
28926			shadowMatrix.multiply(shadowCamera.matrixWorldInverse);
28927		}
28928
28929		getViewport(viewportIndex) {
28930			return this._viewports[viewportIndex];
28931		}
28932
28933		getFrameExtents() {
28934			return this._frameExtents;
28935		}
28936
28937		dispose() {
28938			if (this.map) {
28939				this.map.dispose();
28940			}
28941
28942			if (this.mapPass) {
28943				this.mapPass.dispose();
28944			}
28945		}
28946
28947		copy(source) {
28948			this.camera = source.camera.clone();
28949			this.bias = source.bias;
28950			this.radius = source.radius;
28951			this.mapSize.copy(source.mapSize);
28952			return this;
28953		}
28954
28955		clone() {
28956			return new this.constructor().copy(this);
28957		}
28958
28959		toJSON() {
28960			const object = {};
28961			if (this.bias !== 0) object.bias = this.bias;
28962			if (this.normalBias !== 0) object.normalBias = this.normalBias;
28963			if (this.radius !== 1) object.radius = this.radius;
28964			if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray();
28965			object.camera = this.camera.toJSON(false).object;
28966			delete object.camera.matrix;
28967			return object;
28968		}
28969
28970	}
28971
28972	class SpotLightShadow extends LightShadow {
28973		constructor() {
28974			super(new PerspectiveCamera(50, 1, 0.5, 500));
28975			this.focus = 1;
28976		}
28977
28978		updateMatrices(light) {
28979			const camera = this.camera;
28980			const fov = RAD2DEG * 2 * light.angle * this.focus;
28981			const aspect = this.mapSize.width / this.mapSize.height;
28982			const far = light.distance || camera.far;
28983
28984			if (fov !== camera.fov || aspect !== camera.aspect || far !== camera.far) {
28985				camera.fov = fov;
28986				camera.aspect = aspect;
28987				camera.far = far;
28988				camera.updateProjectionMatrix();
28989			}
28990
28991			super.updateMatrices(light);
28992		}
28993
28994		copy(source) {
28995			super.copy(source);
28996			this.focus = source.focus;
28997			return this;
28998		}
28999
29000	}
29001
29002	SpotLightShadow.prototype.isSpotLightShadow = true;
29003
29004	class SpotLight extends Light {
29005		constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) {
29006			super(color, intensity);
29007			this.type = 'SpotLight';
29008			this.position.copy(Object3D.DefaultUp);
29009			this.updateMatrix();
29010			this.target = new Object3D();
29011			this.distance = distance;
29012			this.angle = angle;
29013			this.penumbra = penumbra;
29014			this.decay = decay; // for physically correct lights, should be 2.
29015
29016			this.shadow = new SpotLightShadow();
29017		}
29018
29019		get power() {
29020			// compute the light's luminous power (in lumens) from its intensity (in candela)
29021			// by convention for a spotlight, luminous power (lm) = π * luminous intensity (cd)
29022			return this.intensity * Math.PI;
29023		}
29024
29025		set power(power) {
29026			// set the light's intensity (in candela) from the desired luminous power (in lumens)
29027			this.intensity = power / Math.PI;
29028		}
29029
29030		dispose() {
29031			this.shadow.dispose();
29032		}
29033
29034		copy(source) {
29035			super.copy(source);
29036			this.distance = source.distance;
29037			this.angle = source.angle;
29038			this.penumbra = source.penumbra;
29039			this.decay = source.decay;
29040			this.target = source.target.clone();
29041			this.shadow = source.shadow.clone();
29042			return this;
29043		}
29044
29045	}
29046
29047	SpotLight.prototype.isSpotLight = true;
29048
29049	const _projScreenMatrix = /*@__PURE__*/new Matrix4();
29050
29051	const _lightPositionWorld = /*@__PURE__*/new Vector3();
29052
29053	const _lookTarget = /*@__PURE__*/new Vector3();
29054
29055	class PointLightShadow extends LightShadow {
29056		constructor() {
29057			super(new PerspectiveCamera(90, 1, 0.5, 500));
29058			this._frameExtents = new Vector2(4, 2);
29059			this._viewportCount = 6;
29060			this._viewports = [// These viewports map a cube-map onto a 2D texture with the
29061			// following orientation:
29062			//
29063			//	xzXZ
29064			//	 y Y
29065			//
29066			// X - Positive x direction
29067			// x - Negative x direction
29068			// Y - Positive y direction
29069			// y - Negative y direction
29070			// Z - Positive z direction
29071			// z - Negative z direction
29072			// positive X
29073			new Vector4(2, 1, 1, 1), // negative X
29074			new Vector4(0, 1, 1, 1), // positive Z
29075			new Vector4(3, 1, 1, 1), // negative Z
29076			new Vector4(1, 1, 1, 1), // positive Y
29077			new Vector4(3, 0, 1, 1), // negative Y
29078			new Vector4(1, 0, 1, 1)];
29079			this._cubeDirections = [new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0)];
29080			this._cubeUps = [new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1)];
29081		}
29082
29083		updateMatrices(light, viewportIndex = 0) {
29084			const camera = this.camera;
29085			const shadowMatrix = this.matrix;
29086			const far = light.distance || camera.far;
29087
29088			if (far !== camera.far) {
29089				camera.far = far;
29090				camera.updateProjectionMatrix();
29091			}
29092
29093			_lightPositionWorld.setFromMatrixPosition(light.matrixWorld);
29094
29095			camera.position.copy(_lightPositionWorld);
29096
29097			_lookTarget.copy(camera.position);
29098
29099			_lookTarget.add(this._cubeDirections[viewportIndex]);
29100
29101			camera.up.copy(this._cubeUps[viewportIndex]);
29102			camera.lookAt(_lookTarget);
29103			camera.updateMatrixWorld();
29104			shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z);
29105
29106			_projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
29107
29108			this._frustum.setFromProjectionMatrix(_projScreenMatrix);
29109		}
29110
29111	}
29112
29113	PointLightShadow.prototype.isPointLightShadow = true;
29114
29115	class PointLight extends Light {
29116		constructor(color, intensity, distance = 0, decay = 1) {
29117			super(color, intensity);
29118			this.type = 'PointLight';
29119			this.distance = distance;
29120			this.decay = decay; // for physically correct lights, should be 2.
29121
29122			this.shadow = new PointLightShadow();
29123		}
29124
29125		get power() {
29126			// compute the light's luminous power (in lumens) from its intensity (in candela)
29127			// for an isotropic light source, luminous power (lm) = 4 π luminous intensity (cd)
29128			return this.intensity * 4 * Math.PI;
29129		}
29130
29131		set power(power) {
29132			// set the light's intensity (in candela) from the desired luminous power (in lumens)
29133			this.intensity = power / (4 * Math.PI);
29134		}
29135
29136		dispose() {
29137			this.shadow.dispose();
29138		}
29139
29140		copy(source) {
29141			super.copy(source);
29142			this.distance = source.distance;
29143			this.decay = source.decay;
29144			this.shadow = source.shadow.clone();
29145			return this;
29146		}
29147
29148	}
29149
29150	PointLight.prototype.isPointLight = true;
29151
29152	class DirectionalLightShadow extends LightShadow {
29153		constructor() {
vendor: 26,967 bytes, lines 29154-29954
29154			super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500));
29155		}
29156
29157	}
29158
29159	DirectionalLightShadow.prototype.isDirectionalLightShadow = true;
29160
29161	class DirectionalLight extends Light {
29162		constructor(color, intensity) {
29163			super(color, intensity);
29164			this.type = 'DirectionalLight';
29165			this.position.copy(Object3D.DefaultUp);
29166			this.updateMatrix();
29167			this.target = new Object3D();
29168			this.shadow = new DirectionalLightShadow();
29169		}
29170
29171		dispose() {
29172			this.shadow.dispose();
29173		}
29174
29175		copy(source) {
29176			super.copy(source);
29177			this.target = source.target.clone();
29178			this.shadow = source.shadow.clone();
29179			return this;
29180		}
29181
29182	}
29183
29184	DirectionalLight.prototype.isDirectionalLight = true;
29185
29186	class AmbientLight extends Light {
29187		constructor(color, intensity) {
29188			super(color, intensity);
29189			this.type = 'AmbientLight';
29190		}
29191
29192	}
29193
29194	AmbientLight.prototype.isAmbientLight = true;
29195
29196	class RectAreaLight extends Light {
29197		constructor(color, intensity, width = 10, height = 10) {
29198			super(color, intensity);
29199			this.type = 'RectAreaLight';
29200			this.width = width;
29201			this.height = height;
29202		}
29203
29204		get power() {
29205			// compute the light's luminous power (in lumens) from its intensity (in nits)
29206			return this.intensity * this.width * this.height * Math.PI;
29207		}
29208
29209		set power(power) {
29210			// set the light's intensity (in nits) from the desired luminous power (in lumens)
29211			this.intensity = power / (this.width * this.height * Math.PI);
29212		}
29213
29214		copy(source) {
29215			super.copy(source);
29216			this.width = source.width;
29217			this.height = source.height;
29218			return this;
29219		}
29220
29221		toJSON(meta) {
29222			const data = super.toJSON(meta);
29223			data.object.width = this.width;
29224			data.object.height = this.height;
29225			return data;
29226		}
29227
29228	}
29229
29230	RectAreaLight.prototype.isRectAreaLight = true;
29231
29232	/**
29233	 * Primary reference:
29234	 *	 https://graphics.stanford.edu/papers/envmap/envmap.pdf
29235	 *
29236	 * Secondary reference:
29237	 *	 https://www.ppsloan.org/publications/StupidSH36.pdf
29238	 */
29239	// 3-band SH defined by 9 coefficients
29240
29241	class SphericalHarmonics3 {
29242		constructor() {
29243			this.coefficients = [];
29244
29245			for (let i = 0; i < 9; i++) {
29246				this.coefficients.push(new Vector3());
29247			}
29248		}
29249
29250		set(coefficients) {
29251			for (let i = 0; i < 9; i++) {
29252				this.coefficients[i].copy(coefficients[i]);
29253			}
29254
29255			return this;
29256		}
29257
29258		zero() {
29259			for (let i = 0; i < 9; i++) {
29260				this.coefficients[i].set(0, 0, 0);
29261			}
29262
29263			return this;
29264		} // get the radiance in the direction of the normal
29265		// target is a Vector3
29266
29267
29268		getAt(normal, target) {
29269			// normal is assumed to be unit length
29270			const x = normal.x,
29271						y = normal.y,
29272						z = normal.z;
29273			const coeff = this.coefficients; // band 0
29274
29275			target.copy(coeff[0]).multiplyScalar(0.282095); // band 1
29276
29277			target.addScaledVector(coeff[1], 0.488603 * y);
29278			target.addScaledVector(coeff[2], 0.488603 * z);
29279			target.addScaledVector(coeff[3], 0.488603 * x); // band 2
29280
29281			target.addScaledVector(coeff[4], 1.092548 * (x * y));
29282			target.addScaledVector(coeff[5], 1.092548 * (y * z));
29283			target.addScaledVector(coeff[6], 0.315392 * (3.0 * z * z - 1.0));
29284			target.addScaledVector(coeff[7], 1.092548 * (x * z));
29285			target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y));
29286			return target;
29287		} // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal
29288		// target is a Vector3
29289		// https://graphics.stanford.edu/papers/envmap/envmap.pdf
29290
29291
29292		getIrradianceAt(normal, target) {
29293			// normal is assumed to be unit length
29294			const x = normal.x,
29295						y = normal.y,
29296						z = normal.z;
29297			const coeff = this.coefficients; // band 0
29298
29299			target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095
29300			// band 1
29301
29302			target.addScaledVector(coeff[1], 2.0 * 0.511664 * y); // ( 2 * π / 3 ) * 0.488603
29303
29304			target.addScaledVector(coeff[2], 2.0 * 0.511664 * z);
29305			target.addScaledVector(coeff[3], 2.0 * 0.511664 * x); // band 2
29306
29307			target.addScaledVector(coeff[4], 2.0 * 0.429043 * x * y); // ( π / 4 ) * 1.092548
29308
29309			target.addScaledVector(coeff[5], 2.0 * 0.429043 * y * z);
29310			target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); // ( π / 4 ) * 0.315392 * 3
29311
29312			target.addScaledVector(coeff[7], 2.0 * 0.429043 * x * z);
29313			target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); // ( π / 4 ) * 0.546274
29314
29315			return target;
29316		}
29317
29318		add(sh) {
29319			for (let i = 0; i < 9; i++) {
29320				this.coefficients[i].add(sh.coefficients[i]);
29321			}
29322
29323			return this;
29324		}
29325
29326		addScaledSH(sh, s) {
29327			for (let i = 0; i < 9; i++) {
29328				this.coefficients[i].addScaledVector(sh.coefficients[i], s);
29329			}
29330
29331			return this;
29332		}
29333
29334		scale(s) {
29335			for (let i = 0; i < 9; i++) {
29336				this.coefficients[i].multiplyScalar(s);
29337			}
29338
29339			return this;
29340		}
29341
29342		lerp(sh, alpha) {
29343			for (let i = 0; i < 9; i++) {
29344				this.coefficients[i].lerp(sh.coefficients[i], alpha);
29345			}
29346
29347			return this;
29348		}
29349
29350		equals(sh) {
29351			for (let i = 0; i < 9; i++) {
29352				if (!this.coefficients[i].equals(sh.coefficients[i])) {
29353					return false;
29354				}
29355			}
29356
29357			return true;
29358		}
29359
29360		copy(sh) {
29361			return this.set(sh.coefficients);
29362		}
29363
29364		clone() {
29365			return new this.constructor().copy(this);
29366		}
29367
29368		fromArray(array, offset = 0) {
29369			const coefficients = this.coefficients;
29370
29371			for (let i = 0; i < 9; i++) {
29372				coefficients[i].fromArray(array, offset + i * 3);
29373			}
29374
29375			return this;
29376		}
29377
29378		toArray(array = [], offset = 0) {
29379			const coefficients = this.coefficients;
29380
29381			for (let i = 0; i < 9; i++) {
29382				coefficients[i].toArray(array, offset + i * 3);
29383			}
29384
29385			return array;
29386		} // evaluate the basis functions
29387		// shBasis is an Array[ 9 ]
29388
29389
29390		static getBasisAt(normal, shBasis) {
29391			// normal is assumed to be unit length
29392			const x = normal.x,
29393						y = normal.y,
29394						z = normal.z; // band 0
29395
29396			shBasis[0] = 0.282095; // band 1
29397
29398			shBasis[1] = 0.488603 * y;
29399			shBasis[2] = 0.488603 * z;
29400			shBasis[3] = 0.488603 * x; // band 2
29401
29402			shBasis[4] = 1.092548 * x * y;
29403			shBasis[5] = 1.092548 * y * z;
29404			shBasis[6] = 0.315392 * (3 * z * z - 1);
29405			shBasis[7] = 1.092548 * x * z;
29406			shBasis[8] = 0.546274 * (x * x - y * y);
29407		}
29408
29409	}
29410
29411	SphericalHarmonics3.prototype.isSphericalHarmonics3 = true;
29412
29413	class LightProbe extends Light {
29414		constructor(sh = new SphericalHarmonics3(), intensity = 1) {
29415			super(undefined, intensity);
29416			this.sh = sh;
29417		}
29418
29419		copy(source) {
29420			super.copy(source);
29421			this.sh.copy(source.sh);
29422			return this;
29423		}
29424
29425		fromJSON(json) {
29426			this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON();
29427
29428			this.sh.fromArray(json.sh);
29429			return this;
29430		}
29431
29432		toJSON(meta) {
29433			const data = super.toJSON(meta);
29434			data.object.sh = this.sh.toArray();
29435			return data;
29436		}
29437
29438	}
29439
29440	LightProbe.prototype.isLightProbe = true;
29441
29442	class MaterialLoader extends Loader {
29443		constructor(manager) {
29444			super(manager);
29445			this.textures = {};
29446		}
29447
29448		load(url, onLoad, onProgress, onError) {
29449			const scope = this;
29450			const loader = new FileLoader(scope.manager);
29451			loader.setPath(scope.path);
29452			loader.setRequestHeader(scope.requestHeader);
29453			loader.setWithCredentials(scope.withCredentials);
29454			loader.load(url, function (text) {
29455				try {
29456					onLoad(scope.parse(JSON.parse(text)));
29457				} catch (e) {
29458					if (onError) {
29459						onError(e);
29460					} else {
29461						console.error(e);
29462					}
29463
29464					scope.manager.itemError(url);
29465				}
29466			}, onProgress, onError);
29467		}
29468
29469		parse(json) {
29470			const textures = this.textures;
29471
29472			function getTexture(name) {
29473				if (textures[name] === undefined) {
29474					console.warn('THREE.MaterialLoader: Undefined texture', name);
29475				}
29476
29477				return textures[name];
29478			}
29479
29480			const material = new Materials[json.type]();
29481			if (json.uuid !== undefined) material.uuid = json.uuid;
29482			if (json.name !== undefined) material.name = json.name;
29483			if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color);
29484			if (json.roughness !== undefined) material.roughness = json.roughness;
29485			if (json.metalness !== undefined) material.metalness = json.metalness;
29486			if (json.sheen !== undefined) material.sheen = json.sheen;
29487			if (json.sheenColor !== undefined) material.sheenColor = new Color().setHex(json.sheenColor);
29488			if (json.sheenRoughness !== undefined) material.sheenRoughness = json.sheenRoughness;
29489			if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive);
29490			if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular);
29491			if (json.specularIntensity !== undefined) material.specularIntensity = json.specularIntensity;
29492			if (json.specularColor !== undefined && material.specularColor !== undefined) material.specularColor.setHex(json.specularColor);
29493			if (json.shininess !== undefined) material.shininess = json.shininess;
29494			if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat;
29495			if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness;
29496			if (json.transmission !== undefined) material.transmission = json.transmission;
29497			if (json.thickness !== undefined) material.thickness = json.thickness;
29498			if (json.attenuationDistance !== undefined) material.attenuationDistance = json.attenuationDistance;
29499			if (json.attenuationColor !== undefined && material.attenuationColor !== undefined) material.attenuationColor.setHex(json.attenuationColor);
29500			if (json.fog !== undefined) material.fog = json.fog;
29501			if (json.flatShading !== undefined) material.flatShading = json.flatShading;
29502			if (json.blending !== undefined) material.blending = json.blending;
29503			if (json.combine !== undefined) material.combine = json.combine;
29504			if (json.side !== undefined) material.side = json.side;
29505			if (json.shadowSide !== undefined) material.shadowSide = json.shadowSide;
29506			if (json.opacity !== undefined) material.opacity = json.opacity;
29507			if (json.format !== undefined) material.format = json.format;
29508			if (json.transparent !== undefined) material.transparent = json.transparent;
29509			if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest;
29510			if (json.depthTest !== undefined) material.depthTest = json.depthTest;
29511			if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite;
29512			if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite;
29513			if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite;
29514			if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask;
29515			if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc;
29516			if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef;
29517			if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask;
29518			if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail;
29519			if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail;
29520			if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass;
29521			if (json.wireframe !== undefined) material.wireframe = json.wireframe;
29522			if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth;
29523			if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap;
29524			if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin;
29525			if (json.rotation !== undefined) material.rotation = json.rotation;
29526			if (json.linewidth !== 1) material.linewidth = json.linewidth;
29527			if (json.dashSize !== undefined) material.dashSize = json.dashSize;
29528			if (json.gapSize !== undefined) material.gapSize = json.gapSize;
29529			if (json.scale !== undefined) material.scale = json.scale;
29530			if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset;
29531			if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor;
29532			if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits;
29533			if (json.dithering !== undefined) material.dithering = json.dithering;
29534			if (json.alphaToCoverage !== undefined) material.alphaToCoverage = json.alphaToCoverage;
29535			if (json.premultipliedAlpha !== undefined) material.premultipliedAlpha = json.premultipliedAlpha;
29536			if (json.visible !== undefined) material.visible = json.visible;
29537			if (json.toneMapped !== undefined) material.toneMapped = json.toneMapped;
29538			if (json.userData !== undefined) material.userData = json.userData;
29539
29540			if (json.vertexColors !== undefined) {
29541				if (typeof json.vertexColors === 'number') {
29542					material.vertexColors = json.vertexColors > 0 ? true : false;
29543				} else {
29544					material.vertexColors = json.vertexColors;
29545				}
29546			} // Shader Material
29547
29548
29549			if (json.uniforms !== undefined) {
29550				for (const name in json.uniforms) {
29551					const uniform = json.uniforms[name];
29552					material.uniforms[name] = {};
29553
29554					switch (uniform.type) {
29555						case 't':
29556							material.uniforms[name].value = getTexture(uniform.value);
29557							break;
29558
29559						case 'c':
29560							material.uniforms[name].value = new Color().setHex(uniform.value);
29561							break;
29562
29563						case 'v2':
29564							material.uniforms[name].value = new Vector2().fromArray(uniform.value);
29565							break;
29566
29567						case 'v3':
29568							material.uniforms[name].value = new Vector3().fromArray(uniform.value);
29569							break;
29570
29571						case 'v4':
29572							material.uniforms[name].value = new Vector4().fromArray(uniform.value);
29573							break;
29574
29575						case 'm3':
29576							material.uniforms[name].value = new Matrix3().fromArray(uniform.value);
29577							break;
29578
29579						case 'm4':
29580							material.uniforms[name].value = new Matrix4().fromArray(uniform.value);
29581							break;
29582
29583						default:
29584							material.uniforms[name].value = uniform.value;
29585					}
29586				}
29587			}
29588
29589			if (json.defines !== undefined) material.defines = json.defines;
29590			if (json.vertexShader !== undefined) material.vertexShader = json.vertexShader;
29591			if (json.fragmentShader !== undefined) material.fragmentShader = json.fragmentShader;
29592
29593			if (json.extensions !== undefined) {
29594				for (const key in json.extensions) {
29595					material.extensions[key] = json.extensions[key];
29596				}
29597			} // Deprecated
29598
29599
29600			if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading
29601			// for PointsMaterial
29602
29603			if (json.size !== undefined) material.size = json.size;
29604			if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps
29605
29606			if (json.map !== undefined) material.map = getTexture(json.map);
29607			if (json.matcap !== undefined) material.matcap = getTexture(json.matcap);
29608			if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap);
29609			if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap);
29610			if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale;
29611			if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap);
29612			if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType;
29613
29614			if (json.normalScale !== undefined) {
29615				let normalScale = json.normalScale;
29616
29617				if (Array.isArray(normalScale) === false) {
29618					// Blender exporter used to export a scalar. See #7459
29619					normalScale = [normalScale, normalScale];
29620				}
29621
29622				material.normalScale = new Vector2().fromArray(normalScale);
29623			}
29624
29625			if (json.displacementMap !== undefined) material.displacementMap = getTexture(json.displacementMap);
29626			if (json.displacementScale !== undefined) material.displacementScale = json.displacementScale;
29627			if (json.displacementBias !== undefined) material.displacementBias = json.displacementBias;
29628			if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap);
29629			if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap);
29630			if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap);
29631			if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity;
29632			if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap);
29633			if (json.specularIntensityMap !== undefined) material.specularIntensityMap = getTexture(json.specularIntensityMap);
29634			if (json.specularColorMap !== undefined) material.specularColorMap = getTexture(json.specularColorMap);
29635			if (json.envMap !== undefined) material.envMap = getTexture(json.envMap);
29636			if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity;
29637			if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity;
29638			if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio;
29639			if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap);
29640			if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity;
29641			if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap);
29642			if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity;
29643			if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap);
29644			if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap);
29645			if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap);
29646			if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap);
29647			if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale);
29648			if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap);
29649			if (json.thicknessMap !== undefined) material.thicknessMap = getTexture(json.thicknessMap);
29650			if (json.sheenColorMap !== undefined) material.sheenColorMap = getTexture(json.sheenColorMap);
29651			if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap);
29652			return material;
29653		}
29654
29655		setTextures(value) {
29656			this.textures = value;
29657			return this;
29658		}
29659
29660	}
29661
29662	class LoaderUtils {
29663		static decodeText(array) {
29664			if (typeof TextDecoder !== 'undefined') {
29665				return new TextDecoder().decode(array);
29666			} // Avoid the String.fromCharCode.apply(null, array) shortcut, which
29667			// throws a "maximum call stack size exceeded" error for large arrays.
29668
29669
29670			let s = '';
29671
29672			for (let i = 0, il = array.length; i < il; i++) {
29673				// Implicitly assumes little-endian.
29674				s += String.fromCharCode(array[i]);
29675			}
29676
29677			try {
29678				// merges multi-byte utf-8 characters.
29679				return decodeURIComponent(escape(s));
29680			} catch (e) {
29681				// see #16358
29682				return s;
29683			}
29684		}
29685
29686		static extractUrlBase(url) {
29687			const index = url.lastIndexOf('/');
29688			if (index === -1) return './';
29689			return url.substr(0, index + 1);
29690		}
29691
29692		static resolveURL(url, path) {
29693			// Invalid URL
29694			if (typeof url !== 'string' || url === '') return ''; // Host Relative URL
29695
29696			if (/^https?:\/\//i.test(path) && /^\//.test(url)) {
29697				path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1');
29698			} // Absolute URL http://,https://,//
29699
29700
29701			if (/^(https?:)?\/\//i.test(url)) return url; // Data URI
29702
29703			if (/^data:.*,.*$/i.test(url)) return url; // Blob URL
29704
29705			if (/^blob:.*$/i.test(url)) return url; // Relative URL
29706
29707			return path + url;
29708		}
29709
29710	}
29711
29712	class InstancedBufferGeometry extends BufferGeometry {
29713		constructor() {
29714			super();
29715			this.type = 'InstancedBufferGeometry';
29716			this.instanceCount = Infinity;
29717		}
29718
29719		copy(source) {
29720			super.copy(source);
29721			this.instanceCount = source.instanceCount;
29722			return this;
29723		}
29724
29725		clone() {
29726			return new this.constructor().copy(this);
29727		}
29728
29729		toJSON() {
29730			const data = super.toJSON(this);
29731			data.instanceCount = this.instanceCount;
29732			data.isInstancedBufferGeometry = true;
29733			return data;
29734		}
29735
29736	}
29737
29738	InstancedBufferGeometry.prototype.isInstancedBufferGeometry = true;
29739
29740	class BufferGeometryLoader extends Loader {
29741		constructor(manager) {
29742			super(manager);
29743		}
29744
29745		load(url, onLoad, onProgress, onError) {
29746			const scope = this;
29747			const loader = new FileLoader(scope.manager);
29748			loader.setPath(scope.path);
29749			loader.setRequestHeader(scope.requestHeader);
29750			loader.setWithCredentials(scope.withCredentials);
29751			loader.load(url, function (text) {
29752				try {
29753					onLoad(scope.parse(JSON.parse(text)));
29754				} catch (e) {
29755					if (onError) {
29756						onError(e);
29757					} else {
29758						console.error(e);
29759					}
29760
29761					scope.manager.itemError(url);
29762				}
29763			}, onProgress, onError);
29764		}
29765
29766		parse(json) {
29767			const interleavedBufferMap = {};
29768			const arrayBufferMap = {};
29769
29770			function getInterleavedBuffer(json, uuid) {
29771				if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid];
29772				const interleavedBuffers = json.interleavedBuffers;
29773				const interleavedBuffer = interleavedBuffers[uuid];
29774				const buffer = getArrayBuffer(json, interleavedBuffer.buffer);
29775				const array = getTypedArray(interleavedBuffer.type, buffer);
29776				const ib = new InterleavedBuffer(array, interleavedBuffer.stride);
29777				ib.uuid = interleavedBuffer.uuid;
29778				interleavedBufferMap[uuid] = ib;
29779				return ib;
29780			}
29781
29782			function getArrayBuffer(json, uuid) {
29783				if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid];
29784				const arrayBuffers = json.arrayBuffers;
29785				const arrayBuffer = arrayBuffers[uuid];
29786				const ab = new Uint32Array(arrayBuffer).buffer;
29787				arrayBufferMap[uuid] = ab;
29788				return ab;
29789			}
29790
29791			const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry();
29792			const index = json.data.index;
29793
29794			if (index !== undefined) {
29795				const typedArray = getTypedArray(index.type, index.array);
29796				geometry.setIndex(new BufferAttribute(typedArray, 1));
29797			}
29798
29799			const attributes = json.data.attributes;
29800
29801			for (const key in attributes) {
29802				const attribute = attributes[key];
29803				let bufferAttribute;
29804
29805				if (attribute.isInterleavedBufferAttribute) {
29806					const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data);
29807					bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized);
29808				} else {
29809					const typedArray = getTypedArray(attribute.type, attribute.array);
29810					const bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute;
29811					bufferAttribute = new bufferAttributeConstr(typedArray, attribute.itemSize, attribute.normalized);
29812				}
29813
29814				if (attribute.name !== undefined) bufferAttribute.name = attribute.name;
29815				if (attribute.usage !== undefined) bufferAttribute.setUsage(attribute.usage);
29816
29817				if (attribute.updateRange !== undefined) {
29818					bufferAttribute.updateRange.offset = attribute.updateRange.offset;
29819					bufferAttribute.updateRange.count = attribute.updateRange.count;
29820				}
29821
29822				geometry.setAttribute(key, bufferAttribute);
29823			}
29824
29825			const morphAttributes = json.data.morphAttributes;
29826
29827			if (morphAttributes) {
29828				for (const key in morphAttributes) {
29829					const attributeArray = morphAttributes[key];
29830					const array = [];
29831
29832					for (let i = 0, il = attributeArray.length; i < il; i++) {
29833						const attribute = attributeArray[i];
29834						let bufferAttribute;
29835
29836						if (attribute.isInterleavedBufferAttribute) {
29837							const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data);
29838							bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized);
29839						} else {
29840							const typedArray = getTypedArray(attribute.type, attribute.array);
29841							bufferAttribute = new BufferAttribute(typedArray, attribute.itemSize, attribute.normalized);
29842						}
29843
29844						if (attribute.name !== undefined) bufferAttribute.name = attribute.name;
29845						array.push(bufferAttribute);
29846					}
29847
29848					geometry.morphAttributes[key] = array;
29849				}
29850			}
29851
29852			const morphTargetsRelative = json.data.morphTargetsRelative;
29853
29854			if (morphTargetsRelative) {
29855				geometry.morphTargetsRelative = true;
29856			}
29857
29858			const groups = json.data.groups || json.data.drawcalls || json.data.offsets;
29859
29860			if (groups !== undefined) {
29861				for (let i = 0, n = groups.length; i !== n; ++i) {
29862					const group = groups[i];
29863					geometry.addGroup(group.start, group.count, group.materialIndex);
29864				}
29865			}
29866
29867			const boundingSphere = json.data.boundingSphere;
29868
29869			if (boundingSphere !== undefined) {
29870				const center = new Vector3();
29871
29872				if (boundingSphere.center !== undefined) {
29873					center.fromArray(boundingSphere.center);
29874				}
29875
29876				geometry.boundingSphere = new Sphere(center, boundingSphere.radius);
29877			}
29878
29879			if (json.name) geometry.name = json.name;
29880			if (json.userData) geometry.userData = json.userData;
29881			return geometry;
29882		}
29883
29884	}
29885
29886	class ObjectLoader extends Loader {
29887		constructor(manager) {
29888			super(manager);
29889		}
29890
29891		load(url, onLoad, onProgress, onError) {
29892			const scope = this;
29893			const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path;
29894			this.resourcePath = this.resourcePath || path;
29895			const loader = new FileLoader(this.manager);
29896			loader.setPath(this.path);
29897			loader.setRequestHeader(this.requestHeader);
29898			loader.setWithCredentials(this.withCredentials);
29899			loader.load(url, function (text) {
29900				let json = null;
29901
29902				try {
29903					json = JSON.parse(text);
29904				} catch (error) {
29905					if (onError !== undefined) onError(error);
29906					console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message);
29907					return;
29908				}
29909
29910				const metadata = json.metadata;
29911
29912				if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') {
29913					console.error('THREE.ObjectLoader: Can\'t load ' + url);
29914					return;
29915				}
29916
29917				scope.parse(json, onLoad);
29918			}, onProgress, onError);
29919		}
29920
29921		async loadAsync(url, onProgress) {
29922			const scope = this;
29923			const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path;
29924			this.resourcePath = this.resourcePath || path;
29925			const loader = new FileLoader(this.manager);
29926			loader.setPath(this.path);
29927			loader.setRequestHeader(this.requestHeader);
29928			loader.setWithCredentials(this.withCredentials);
29929			const text = await loader.loadAsync(url, onProgress);
29930			const json = JSON.parse(text);
29931			const metadata = json.metadata;
29932
29933			if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') {
29934				throw new Error('THREE.ObjectLoader: Can\'t load ' + url);
29935			}
29936
29937			return await scope.parseAsync(json);
29938		}
29939
29940		parse(json, onLoad) {
29941			const animations = this.parseAnimations(json.animations);
29942			const shapes = this.parseShapes(json.shapes);
29943			const geometries = this.parseGeometries(json.geometries, shapes);
29944			const images = this.parseImages(json.images, function () {
29945				if (onLoad !== undefined) onLoad(object);
29946			});
29947			const textures = this.parseTextures(json.textures, images);
29948			const materials = this.parseMaterials(json.materials, textures);
29949			const object = this.parseObject(json.object, geometries, materials, textures, animations);
29950			const skeletons = this.parseSkeletons(json.skeletons, object);
29951			this.bindSkeletons(object, skeletons); //
29952
29953			if (onLoad !== undefined) {
29954				let hasImages = false;
29955
29956				for (const uuid in images) {
29957					if (images[uuid] instanceof HTMLImageElement) {
29958						hasImages = true;
29959						break;
29960					}
29961				}
29962
29963				if (hasImages === false) onLoad(object);
29964			}
29965
29966			return object;
29967		}
29968
29969		async parseAsync(json) {
29970			const animations = this.parseAnimations(json.animations);
29971			const shapes = this.parseShapes(json.shapes);
29972			const geometries = this.parseGeometries(json.geometries, shapes);
29973			const images = await this.parseImagesAsync(json.images);
29974			const textures = this.parseTextures(json.textures, images);
29975			const materials = this.parseMaterials(json.materials, textures);
29976			const object = this.parseObject(json.object, geometries, materials, textures, animations);
29977			const skeletons = this.parseSkeletons(json.skeletons, object);
29978			this.bindSkeletons(object, skeletons);
29979			return object;
29980		}
29981
29982		parseShapes(json) {
29983			const shapes = {};
29984
29985			if (json !== undefined) {
29986				for (let i = 0, l = json.length; i < l; i++) {
29987					const shape = new Shape().fromJSON(json[i]);
29988					shapes[shape.uuid] = shape;
29989				}
29990			}
29991
29992			return shapes;
29993		}
29994
29995		parseSkeletons(json, object) {
29996			const skeletons = {};
29997			const bones = {}; // generate bone lookup table
29998
29999			object.traverse(function (child) {
30000				if (child.isBone) bones[child.uuid] = child;
30001			}); // create skeletons
30002
30003			if (json !== undefined) {
30004				for (let i = 0, l = json.length; i < l; i++) {
30005					const skeleton = new Skeleton().fromJSON(json[i], bones);
30006					skeletons[skeleton.uuid] = skeleton;
30007				}
30008			}
30009
30010			return skeletons;
30011		}
30012
30013		parseGeometries(json, shapes) {
30014			const geometries = {};
30015
30016			if (json !== undefined) {
30017				const bufferGeometryLoader = new BufferGeometryLoader();
30018
30019				for (let i = 0, l = json.length; i < l; i++) {
30020					let geometry;
30021					const data = json[i];
30022
30023					switch (data.type) {
30024						case 'BufferGeometry':
30025						case 'InstancedBufferGeometry':
30026							geometry = bufferGeometryLoader.parse(data);
30027							break;
30028
30029						case 'Geometry':
30030							console.error('THREE.ObjectLoader: The legacy Geometry type is no longer supported.');
30031							break;
30032
30033						default:
30034							if (data.type in Geometries) {
30035								geometry = Geometries[data.type].fromJSON(data, shapes);
30036							} else {
30037								console.warn(`THREE.ObjectLoader: Unsupported geometry type "${data.type}"`);
30038							}
30039
30040					}
30041
30042					geometry.uuid = data.uuid;
30043					if (data.name !== undefined) geometry.name = data.name;
30044					if (geometry.isBufferGeometry === true && data.userData !== undefined) geometry.userData = data.userData;
30045					geometries[data.uuid] = geometry;
30046				}
30047			}
30048
30049			return geometries;
30050		}
30051
30052		parseMaterials(json, textures) {
30053			const cache = {}; // MultiMaterial
30054
30055			const materials = {};
30056
30057			if (json !== undefined) {
30058				const loader = new MaterialLoader();
30059				loader.setTextures(textures);
30060
30061				for (let i = 0, l = json.length; i < l; i++) {
30062					const data = json[i];
30063
30064					if (data.type === 'MultiMaterial') {
30065						// Deprecated
30066						const array = [];
30067
30068						for (let j = 0; j < data.materials.length; j++) {
30069							const material = data.materials[j];
30070
30071							if (cache[material.uuid] === undefined) {
30072								cache[material.uuid] = loader.parse(material);
30073							}
30074
30075							array.push(cache[material.uuid]);
30076						}
30077
30078						materials[data.uuid] = array;
30079					} else {
30080						if (cache[data.uuid] === undefined) {
30081							cache[data.uuid] = loader.parse(data);
30082						}
30083
30084						materials[data.uuid] = cache[data.uuid];
30085					}
30086				}
30087			}
30088
30089			return materials;
30090		}
30091
30092		parseAnimations(json) {
30093			const animations = {};
30094
30095			if (json !== undefined) {
30096				for (let i = 0; i < json.length; i++) {
30097					const data = json[i];
30098					const clip = AnimationClip.parse(data);
30099					animations[clip.uuid] = clip;
30100				}
30101			}
30102
30103			return animations;
30104		}
30105
30106		parseImages(json, onLoad) {
30107			const scope = this;
30108			const images = {};
30109			let loader;
30110
30111			function loadImage(url) {
30112				scope.manager.itemStart(url);
30113				return loader.load(url, function () {
30114					scope.manager.itemEnd(url);
30115				}, undefined, function () {
30116					scope.manager.itemError(url);
30117					scope.manager.itemEnd(url);
30118				});
30119			}
30120
30121			function deserializeImage(image) {
30122				if (typeof image === 'string') {
30123					const url = image;
30124					const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url;
30125					return loadImage(path);
30126				} else {
30127					if (image.data) {
30128						return {
30129							data: getTypedArray(image.type, image.data),
30130							width: image.width,
30131							height: image.height
30132						};
30133					} else {
30134						return null;
30135					}
30136				}
30137			}
30138
30139			if (json !== undefined && json.length > 0) {
30140				const manager = new LoadingManager(onLoad);
30141				loader = new ImageLoader(manager);
30142				loader.setCrossOrigin(this.crossOrigin);
30143
30144				for (let i = 0, il = json.length; i < il; i++) {
30145					const image = json[i];
30146					const url = image.url;
30147
30148					if (Array.isArray(url)) {
30149						// load array of images e.g CubeTexture
30150						images[image.uuid] = [];
30151
30152						for (let j = 0, jl = url.length; j < jl; j++) {
30153							const currentUrl = url[j];
30154							const deserializedImage = deserializeImage(currentUrl);
30155
30156							if (deserializedImage !== null) {
30157								if (deserializedImage instanceof HTMLImageElement) {
30158									images[image.uuid].push(deserializedImage);
30159								} else {
30160									// special case: handle array of data textures for cube textures
30161									images[image.uuid].push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height));
30162								}
30163							}
30164						}
30165					} else {
30166						// load single image
30167						const deserializedImage = deserializeImage(image.url);
30168
30169						if (deserializedImage !== null) {
30170							images[image.uuid] = deserializedImage;
30171						}
30172					}
30173				}
30174			}
30175
30176			return images;
30177		}
30178
30179		async parseImagesAsync(json) {
30180			const scope = this;
30181			const images = {};
30182			let loader;
30183
30184			async function deserializeImage(image) {
30185				if (typeof image === 'string') {
30186					const url = image;
30187					const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url;
30188					return await loader.loadAsync(path);
30189				} else {
30190					if (image.data) {
30191						return {
30192							data: getTypedArray(image.type, image.data),
30193							width: image.width,
30194							height: image.height
30195						};
30196					} else {
30197						return null;
30198					}
30199				}
30200			}
30201
30202			if (json !== undefined && json.length > 0) {
30203				loader = new ImageLoader(this.manager);
30204				loader.setCrossOrigin(this.crossOrigin);
30205
30206				for (let i = 0, il = json.length; i < il; i++) {
30207					const image = json[i];
30208					const url = image.url;
30209
30210					if (Array.isArray(url)) {
30211						// load array of images e.g CubeTexture
30212						images[image.uuid] = [];
30213
30214						for (let j = 0, jl = url.length; j < jl; j++) {
30215							const currentUrl = url[j];
30216							const deserializedImage = await deserializeImage(currentUrl);
30217
30218							if (deserializedImage !== null) {
30219								if (deserializedImage instanceof HTMLImageElement) {
30220									images[image.uuid].push(deserializedImage);
30221								} else {
30222									// special case: handle array of data textures for cube textures
30223									images[image.uuid].push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height));
30224								}
30225							}
30226						}
30227					} else {
30228						// load single image
30229						const deserializedImage = await deserializeImage(image.url);
30230
30231						if (deserializedImage !== null) {
30232							images[image.uuid] = deserializedImage;
30233						}
30234					}
30235				}
30236			}
30237
30238			return images;
30239		}
30240
30241		parseTextures(json, images) {
30242			function parseConstant(value, type) {
30243				if (typeof value === 'number') return value;
30244				console.warn('THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value);
30245				return type[value];
30246			}
30247
30248			const textures = {};
30249
30250			if (json !== undefined) {
30251				for (let i = 0, l = json.length; i < l; i++) {
30252					const data = json[i];
30253
30254					if (data.image === undefined) {
30255						console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid);
30256					}
30257
30258					if (images[data.image] === undefined) {
30259						console.warn('THREE.ObjectLoader: Undefined image', data.image);
30260					}
30261
30262					let texture;
30263					const image = images[data.image];
30264
30265					if (Array.isArray(image)) {
30266						texture = new CubeTexture(image);
30267						if (image.length === 6) texture.needsUpdate = true;
30268					} else {
30269						if (image && image.data) {
30270							texture = new DataTexture(image.data, image.width, image.height);
30271						} else {
30272							texture = new Texture(image);
30273						}
30274
30275						if (image) texture.needsUpdate = true; // textures can have undefined image data
30276					}
30277
30278					texture.uuid = data.uuid;
30279					if (data.name !== undefined) texture.name = data.name;
30280					if (data.mapping !== undefined) texture.mapping = parseConstant(data.mapping, TEXTURE_MAPPING);
30281					if (data.offset !== undefined) texture.offset.fromArray(data.offset);
30282					if (data.repeat !== undefined) texture.repeat.fromArray(data.repeat);
30283					if (data.center !== undefined) texture.center.fromArray(data.center);
30284					if (data.rotation !== undefined) texture.rotation = data.rotation;
30285
30286					if (data.wrap !== undefined) {
30287						texture.wrapS = parseConstant(data.wrap[0], TEXTURE_WRAPPING);
30288						texture.wrapT = parseConstant(data.wrap[1], TEXTURE_WRAPPING);
30289					}
30290
30291					if (data.format !== undefined) texture.format = data.format;
30292					if (data.type !== undefined) texture.type = data.type;
30293					if (data.encoding !== undefined) texture.encoding = data.encoding;
30294					if (data.minFilter !== undefined) texture.minFilter = parseConstant(data.minFilter, TEXTURE_FILTER);
vendor: 4,100 bytes, lines 30295-30428
30295					if (data.magFilter !== undefined) texture.magFilter = parseConstant(data.magFilter, TEXTURE_FILTER);
30296					if (data.anisotropy !== undefined) texture.anisotropy = data.anisotropy;
30297					if (data.flipY !== undefined) texture.flipY = data.flipY;
30298					if (data.premultiplyAlpha !== undefined) texture.premultiplyAlpha = data.premultiplyAlpha;
30299					if (data.unpackAlignment !== undefined) texture.unpackAlignment = data.unpackAlignment;
30300					if (data.userData !== undefined) texture.userData = data.userData;
30301					textures[data.uuid] = texture;
30302				}
30303			}
30304
30305			return textures;
30306		}
30307
30308		parseObject(data, geometries, materials, textures, animations) {
30309			let object;
30310
30311			function getGeometry(name) {
30312				if (geometries[name] === undefined) {
30313					console.warn('THREE.ObjectLoader: Undefined geometry', name);
30314				}
30315
30316				return geometries[name];
30317			}
30318
30319			function getMaterial(name) {
30320				if (name === undefined) return undefined;
30321
30322				if (Array.isArray(name)) {
30323					const array = [];
30324
30325					for (let i = 0, l = name.length; i < l; i++) {
30326						const uuid = name[i];
30327
30328						if (materials[uuid] === undefined) {
30329							console.warn('THREE.ObjectLoader: Undefined material', uuid);
30330						}
30331
30332						array.push(materials[uuid]);
30333					}
30334
30335					return array;
30336				}
30337
30338				if (materials[name] === undefined) {
30339					console.warn('THREE.ObjectLoader: Undefined material', name);
30340				}
30341
30342				return materials[name];
30343			}
30344
30345			function getTexture(uuid) {
30346				if (textures[uuid] === undefined) {
30347					console.warn('THREE.ObjectLoader: Undefined texture', uuid);
30348				}
30349
30350				return textures[uuid];
30351			}
30352
30353			let geometry, material;
30354
30355			switch (data.type) {
30356				case 'Scene':
30357					object = new Scene();
30358
30359					if (data.background !== undefined) {
30360						if (Number.isInteger(data.background)) {
30361							object.background = new Color(data.background);
30362						} else {
30363							object.background = getTexture(data.background);
30364						}
30365					}
30366
30367					if (data.environment !== undefined) {
30368						object.environment = getTexture(data.environment);
30369					}
30370
30371					if (data.fog !== undefined) {
30372						if (data.fog.type === 'Fog') {
30373							object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far);
30374						} else if (data.fog.type === 'FogExp2') {
30375							object.fog = new FogExp2(data.fog.color, data.fog.density);
30376						}
30377					}
30378
30379					break;
30380
30381				case 'PerspectiveCamera':
30382					object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far);
30383					if (data.focus !== undefined) object.focus = data.focus;
30384					if (data.zoom !== undefined) object.zoom = data.zoom;
30385					if (data.filmGauge !== undefined) object.filmGauge = data.filmGauge;
30386					if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset;
30387					if (data.view !== undefined) object.view = Object.assign({}, data.view);
30388					break;
30389
30390				case 'OrthographicCamera':
30391					object = new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far);
30392					if (data.zoom !== undefined) object.zoom = data.zoom;
30393					if (data.view !== undefined) object.view = Object.assign({}, data.view);
30394					break;
30395
30396				case 'AmbientLight':
30397					object = new AmbientLight(data.color, data.intensity);
30398					break;
30399
30400				case 'DirectionalLight':
30401					object = new DirectionalLight(data.color, data.intensity);
30402					break;
30403
30404				case 'PointLight':
30405					object = new PointLight(data.color, data.intensity, data.distance, data.decay);
30406					break;
30407
30408				case 'RectAreaLight':
30409					object = new RectAreaLight(data.color, data.intensity, data.width, data.height);
30410					break;
30411
30412				case 'SpotLight':
30413					object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay);
30414					break;
30415
30416				case 'HemisphereLight':
30417					object = new HemisphereLight(data.color, data.groundColor, data.intensity);
30418					break;
30419
30420				case 'LightProbe':
30421					object = new LightProbe().fromJSON(data);
30422					break;
30423
30424				case 'SkinnedMesh':
30425					geometry = getGeometry(data.geometry);
30426					material = getMaterial(data.material);
30427					object = new SkinnedMesh(geometry, material);
30428					if (data.bindMode !== undefined) object.bindMode = data.bindMode;
30429					if (data.bindMatrix !== undefined) object.bindMatrix.fromArray(data.bindMatrix);
30430					if (data.skeleton !== undefined) object.skeleton = data.skeleton;
30431					break;
30432
30433				case 'Mesh':
30434					geometry = getGeometry(data.geometry);
30435					material = getMaterial(data.material);
30436					object = new Mesh(geometry, material);
30437					break;
30438
30439				case 'InstancedMesh':
30440					geometry = getGeometry(data.geometry);
30441					material = getMaterial(data.material);
30442					const count = data.count;
30443					const instanceMatrix = data.instanceMatrix;
30444					const instanceColor = data.instanceColor;
30445					object = new InstancedMesh(geometry, material, count);
30446					object.instanceMatrix = new InstancedBufferAttribute(new Float32Array(instanceMatrix.array), 16);
30447					if (instanceColor !== undefined) object.instanceColor = new InstancedBufferAttribute(new Float32Array(instanceColor.array), instanceColor.itemSize);
30448					break;
30449
30450				case 'LOD':
30451					object = new LOD();
30452					break;
30453
30454				case 'Line':
30455					object = new Line(getGeometry(data.geometry), getMaterial(data.material));
30456					break;
30457
30458				case 'LineLoop':
30459					object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material));
30460					break;
30461
30462				case 'LineSegments':
30463					object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material));
30464					break;
30465
30466				case 'PointCloud':
30467				case 'Points':
30468					object = new Points(getGeometry(data.geometry), getMaterial(data.material));
30469					break;
30470
30471				case 'Sprite':
30472					object = new Sprite(getMaterial(data.material));
30473					break;
30474
30475				case 'Group':
30476					object = new Group();
30477					break;
30478
30479				case 'Bone':
30480					object = new Bone();
30481					break;
30482
30483				default:
30484					object = new Object3D();
30485			}
30486
30487			object.uuid = data.uuid;
30488			if (data.name !== undefined) object.name = data.name;
30489
30490			if (data.matrix !== undefined) {
30491				object.matrix.fromArray(data.matrix);
30492				if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate;
30493				if (object.matrixAutoUpdate) object.matrix.decompose(object.position, object.quaternion, object.scale);
30494			} else {
30495				if (data.position !== undefined) object.position.fromArray(data.position);
30496				if (data.rotation !== undefined) object.rotation.fromArray(data.rotation);
30497				if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion);
30498				if (data.scale !== undefined) object.scale.fromArray(data.scale);
30499			}
30500
30501			if (data.castShadow !== undefined) object.castShadow = data.castShadow;
30502			if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow;
30503
30504			if (data.shadow) {
30505				if (data.shadow.bias !== undefined) object.shadow.bias = data.shadow.bias;
30506				if (data.shadow.normalBias !== undefined) object.shadow.normalBias = data.shadow.normalBias;
30507				if (data.shadow.radius !== undefined) object.shadow.radius = data.shadow.radius;
30508				if (data.shadow.mapSize !== undefined) object.shadow.mapSize.fromArray(data.shadow.mapSize);
30509				if (data.shadow.camera !== undefined) object.shadow.camera = this.parseObject(data.shadow.camera);
30510			}
30511
30512			if (data.visible !== undefined) object.visible = data.visible;
30513			if (data.frustumCulled !== undefined) object.frustumCulled = data.frustumCulled;
30514			if (data.renderOrder !== undefined) object.renderOrder = data.renderOrder;
30515			if (data.userData !== undefined) object.userData = data.userData;
30516			if (data.layers !== undefined) object.layers.mask = data.layers;
30517
30518			if (data.children !== undefined) {
30519				const children = data.children;
30520
30521				for (let i = 0; i < children.length; i++) {
30522					object.add(this.parseObject(children[i], geometries, materials, textures, animations));
30523				}
30524			}
30525
30526			if (data.animations !== undefined) {
30527				const objectAnimations = data.animations;
30528
30529				for (let i = 0; i < objectAnimations.length; i++) {
30530					const uuid = objectAnimations[i];
30531					object.animations.push(animations[uuid]);
30532				}
30533			}
30534
30535			if (data.type === 'LOD') {
30536				if (data.autoUpdate !== undefined) object.autoUpdate = data.autoUpdate;
30537				const levels = data.levels;
30538
30539				for (let l = 0; l < levels.length; l++) {
30540					const level = levels[l];
30541					const child = object.getObjectByProperty('uuid', level.object);
30542
30543					if (child !== undefined) {
30544						object.addLevel(child, level.distance);
30545					}
30546				}
30547			}
30548
30549			return object;
30550		}
30551
30552		bindSkeletons(object, skeletons) {
30553			if (Object.keys(skeletons).length === 0) return;
30554			object.traverse(function (child) {
30555				if (child.isSkinnedMesh === true && child.skeleton !== undefined) {
30556					const skeleton = skeletons[child.skeleton];
30557
30558					if (skeleton === undefined) {
30559						console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton);
30560					} else {
30561						child.bind(skeleton, child.bindMatrix);
30562					}
30563				}
30564			});
30565		}
30566		/* DEPRECATED */
30567
30568
30569		setTexturePath(value) {
30570			console.warn('THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().');
30571			return this.setResourcePath(value);
30572		}
30573
30574	}
30575
30576	const TEXTURE_MAPPING = {
30577		UVMapping: UVMapping,
30578		CubeReflectionMapping: CubeReflectionMapping,
30579		CubeRefractionMapping: CubeRefractionMapping,
30580		EquirectangularReflectionMapping: EquirectangularReflectionMapping,
30581		EquirectangularRefractionMapping: EquirectangularRefractionMapping,
30582		CubeUVReflectionMapping: CubeUVReflectionMapping,
30583		CubeUVRefractionMapping: CubeUVRefractionMapping
30584	};
30585	const TEXTURE_WRAPPING = {
30586		RepeatWrapping: RepeatWrapping,
30587		ClampToEdgeWrapping: ClampToEdgeWrapping,
30588		MirroredRepeatWrapping: MirroredRepeatWrapping
30589	};
30590	const TEXTURE_FILTER = {
30591		NearestFilter: NearestFilter,
30592		NearestMipmapNearestFilter: NearestMipmapNearestFilter,
30593		NearestMipmapLinearFilter: NearestMipmapLinearFilter,
30594		LinearFilter: LinearFilter,
30595		LinearMipmapNearestFilter: LinearMipmapNearestFilter,
30596		LinearMipmapLinearFilter: LinearMipmapLinearFilter
30597	};
30598
30599	class ImageBitmapLoader extends Loader {
30600		constructor(manager) {
30601			super(manager);
30602
30603			if (typeof createImageBitmap === 'undefined') {
30604				console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.');
30605			}
30606
30607			if (typeof fetch === 'undefined') {
30608				console.warn('THREE.ImageBitmapLoader: fetch() not supported.');
30609			}
30610
30611			this.options = {
30612				premultiplyAlpha: 'none'
30613			};
30614		}
30615
30616		setOptions(options) {
30617			this.options = options;
30618			return this;
30619		}
30620
30621		load(url, onLoad, onProgress, onError) {
30622			if (url === undefined) url = '';
30623			if (this.path !== undefined) url = this.path + url;
30624			url = this.manager.resolveURL(url);
30625			const scope = this;
30626			const cached = Cache.get(url);
30627
30628			if (cached !== undefined) {
30629				scope.manager.itemStart(url);
30630				setTimeout(function () {
30631					if (onLoad) onLoad(cached);
30632					scope.manager.itemEnd(url);
30633				}, 0);
30634				return cached;
30635			}
30636
30637			const fetchOptions = {};
30638			fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include';
30639			fetchOptions.headers = this.requestHeader;
30640			fetch(url, fetchOptions).then(function (res) {
30641				return res.blob();
30642			}).then(function (blob) {
30643				return createImageBitmap(blob, Object.assign(scope.options, {
30644					colorSpaceConversion: 'none'
30645				}));
30646			}).then(function (imageBitmap) {
30647				Cache.add(url, imageBitmap);
30648				if (onLoad) onLoad(imageBitmap);
30649				scope.manager.itemEnd(url);
30650			}).catch(function (e) {
30651				if (onError) onError(e);
30652				scope.manager.itemError(url);
30653				scope.manager.itemEnd(url);
30654			});
30655			scope.manager.itemStart(url);
30656		}
30657
30658	}
30659
30660	ImageBitmapLoader.prototype.isImageBitmapLoader = true;
30661
30662	let _context;
30663
30664	const AudioContext = {
30665		getContext: function () {
30666			if (_context === undefined) {
30667				_context = new (window.AudioContext || window.webkitAudioContext)();
30668			}
30669
30670			return _context;
30671		},
30672		setContext: function (value) {
30673			_context = value;
30674		}
30675	};
30676
30677	class AudioLoader extends Loader {
30678		constructor(manager) {
30679			super(manager);
30680		}
30681
30682		load(url, onLoad, onProgress, onError) {
30683			const scope = this;
30684			const loader = new FileLoader(this.manager);
30685			loader.setResponseType('arraybuffer');
30686			loader.setPath(this.path);
30687			loader.setRequestHeader(this.requestHeader);
30688			loader.setWithCredentials(this.withCredentials);
30689			loader.load(url, function (buffer) {
30690				try {
30691					// Create a copy of the buffer. The `decodeAudioData` method
30692					// detaches the buffer when complete, preventing reuse.
30693					const bufferCopy = buffer.slice(0);
30694					const context = AudioContext.getContext();
30695					context.decodeAudioData(bufferCopy, function (audioBuffer) {
30696						onLoad(audioBuffer);
30697					});
30698				} catch (e) {
30699					if (onError) {
30700						onError(e);
30701					} else {
30702						console.error(e);
30703					}
30704
30705					scope.manager.itemError(url);
30706				}
30707			}, onProgress, onError);
30708		}
30709
30710	}
30711
30712	class HemisphereLightProbe extends LightProbe {
30713		constructor(skyColor, groundColor, intensity = 1) {
30714			super(undefined, intensity);
30715			const color1 = new Color().set(skyColor);
30716			const color2 = new Color().set(groundColor);
30717			const sky = new Vector3(color1.r, color1.g, color1.b);
30718			const ground = new Vector3(color2.r, color2.g, color2.b); // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI );
30719
30720			const c0 = Math.sqrt(Math.PI);
30721			const c1 = c0 * Math.sqrt(0.75);
30722			this.sh.coefficients[0].copy(sky).add(ground).multiplyScalar(c0);
30723			this.sh.coefficients[1].copy(sky).sub(ground).multiplyScalar(c1);
30724		}
30725
30726	}
30727
30728	HemisphereLightProbe.prototype.isHemisphereLightProbe = true;
30729
30730	class AmbientLightProbe extends LightProbe {
30731		constructor(color, intensity = 1) {
30732			super(undefined, intensity);
30733			const color1 = new Color().set(color); // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI );
30734
30735			this.sh.coefficients[0].set(color1.r, color1.g, color1.b).multiplyScalar(2 * Math.sqrt(Math.PI));
30736		}
30737
30738	}
30739
30740	AmbientLightProbe.prototype.isAmbientLightProbe = true;
30741
30742	const _eyeRight = /*@__PURE__*/new Matrix4();
30743
30744	const _eyeLeft = /*@__PURE__*/new Matrix4();
30745
30746	const _projectionMatrix = /*@__PURE__*/new Matrix4();
30747
30748	class StereoCamera {
30749		constructor() {
30750			this.type = 'StereoCamera';
30751			this.aspect = 1;
30752			this.eyeSep = 0.064;
30753			this.cameraL = new PerspectiveCamera();
30754			this.cameraL.layers.enable(1);
30755			this.cameraL.matrixAutoUpdate = false;
vendor: 2,475 bytes, lines 30756-30832
30756			this.cameraR = new PerspectiveCamera();
30757			this.cameraR.layers.enable(2);
30758			this.cameraR.matrixAutoUpdate = false;
30759			this._cache = {
30760				focus: null,
30761				fov: null,
30762				aspect: null,
30763				near: null,
30764				far: null,
30765				zoom: null,
30766				eyeSep: null
30767			};
30768		}
30769
30770		update(camera) {
30771			const cache = this._cache;
30772			const needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov || cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near || cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep;
30773
30774			if (needsUpdate) {
30775				cache.focus = camera.focus;
30776				cache.fov = camera.fov;
30777				cache.aspect = camera.aspect * this.aspect;
30778				cache.near = camera.near;
30779				cache.far = camera.far;
30780				cache.zoom = camera.zoom;
30781				cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on
30782				// http://paulbourke.net/stereographics/stereorender/
30783
30784				_projectionMatrix.copy(camera.projectionMatrix);
30785
30786				const eyeSepHalf = cache.eyeSep / 2;
30787				const eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus;
30788				const ymax = cache.near * Math.tan(DEG2RAD * cache.fov * 0.5) / cache.zoom;
30789				let xmin, xmax; // translate xOffset
30790
30791				_eyeLeft.elements[12] = -eyeSepHalf;
30792				_eyeRight.elements[12] = eyeSepHalf; // for left eye
30793
30794				xmin = -ymax * cache.aspect + eyeSepOnProjection;
30795				xmax = ymax * cache.aspect + eyeSepOnProjection;
30796				_projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin);
30797				_projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin);
30798				this.cameraL.projectionMatrix.copy(_projectionMatrix); // for right eye
30799
30800				xmin = -ymax * cache.aspect - eyeSepOnProjection;
30801				xmax = ymax * cache.aspect - eyeSepOnProjection;
30802				_projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin);
30803				_projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin);
30804				this.cameraR.projectionMatrix.copy(_projectionMatrix);
30805			}
30806
30807			this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft);
30808			this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight);
30809		}
30810
30811	}
30812
30813	class Clock {
30814		constructor(autoStart = true) {
30815			this.autoStart = autoStart;
30816			this.startTime = 0;
30817			this.oldTime = 0;
30818			this.elapsedTime = 0;
30819			this.running = false;
30820		}
30821
30822		start() {
30823			this.startTime = now();
30824			this.oldTime = this.startTime;
30825			this.elapsedTime = 0;
30826			this.running = true;
30827		}
30828
30829		stop() {
30830			this.getElapsedTime();
30831			this.running = false;
30832			this.autoStart = false;
vendor: 4,298 bytes, lines 30833-31004
30833		}
30834
30835		getElapsedTime() {
30836			this.getDelta();
30837			return this.elapsedTime;
30838		}
30839
30840		getDelta() {
30841			let diff = 0;
30842
30843			if (this.autoStart && !this.running) {
30844				this.start();
30845				return 0;
30846			}
30847
30848			if (this.running) {
30849				const newTime = now();
30850				diff = (newTime - this.oldTime) / 1000;
30851				this.oldTime = newTime;
30852				this.elapsedTime += diff;
30853			}
30854
30855			return diff;
30856		}
30857
30858	}
30859
30860	function now() {
30861		return (typeof performance === 'undefined' ? Date : performance).now(); // see #10732
30862	}
30863
30864	const _position$1 = /*@__PURE__*/new Vector3();
30865
30866	const _quaternion$1 = /*@__PURE__*/new Quaternion();
30867
30868	const _scale$1 = /*@__PURE__*/new Vector3();
30869
30870	const _orientation$1 = /*@__PURE__*/new Vector3();
30871
30872	class AudioListener extends Object3D {
30873		constructor() {
30874			super();
30875			this.type = 'AudioListener';
30876			this.context = AudioContext.getContext();
30877			this.gain = this.context.createGain();
30878			this.gain.connect(this.context.destination);
30879			this.filter = null;
30880			this.timeDelta = 0; // private
30881
30882			this._clock = new Clock();
30883		}
30884
30885		getInput() {
30886			return this.gain;
30887		}
30888
30889		removeFilter() {
30890			if (this.filter !== null) {
30891				this.gain.disconnect(this.filter);
30892				this.filter.disconnect(this.context.destination);
30893				this.gain.connect(this.context.destination);
30894				this.filter = null;
30895			}
30896
30897			return this;
30898		}
30899
30900		getFilter() {
30901			return this.filter;
30902		}
30903
30904		setFilter(value) {
30905			if (this.filter !== null) {
30906				this.gain.disconnect(this.filter);
30907				this.filter.disconnect(this.context.destination);
30908			} else {
30909				this.gain.disconnect(this.context.destination);
30910			}
30911
30912			this.filter = value;
30913			this.gain.connect(this.filter);
30914			this.filter.connect(this.context.destination);
30915			return this;
30916		}
30917
30918		getMasterVolume() {
30919			return this.gain.gain.value;
30920		}
30921
30922		setMasterVolume(value) {
30923			this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01);
30924			return this;
30925		}
30926
30927		updateMatrixWorld(force) {
30928			super.updateMatrixWorld(force);
30929			const listener = this.context.listener;
30930			const up = this.up;
30931			this.timeDelta = this._clock.getDelta();
30932			this.matrixWorld.decompose(_position$1, _quaternion$1, _scale$1);
30933
30934			_orientation$1.set(0, 0, -1).applyQuaternion(_quaternion$1);
30935
30936			if (listener.positionX) {
30937				// code path for Chrome (see #14393)
30938				const endTime = this.context.currentTime + this.timeDelta;
30939				listener.positionX.linearRampToValueAtTime(_position$1.x, endTime);
30940				listener.positionY.linearRampToValueAtTime(_position$1.y, endTime);
30941				listener.positionZ.linearRampToValueAtTime(_position$1.z, endTime);
30942				listener.forwardX.linearRampToValueAtTime(_orientation$1.x, endTime);
30943				listener.forwardY.linearRampToValueAtTime(_orientation$1.y, endTime);
30944				listener.forwardZ.linearRampToValueAtTime(_orientation$1.z, endTime);
30945				listener.upX.linearRampToValueAtTime(up.x, endTime);
30946				listener.upY.linearRampToValueAtTime(up.y, endTime);
30947				listener.upZ.linearRampToValueAtTime(up.z, endTime);
30948			} else {
30949				listener.setPosition(_position$1.x, _position$1.y, _position$1.z);
30950				listener.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z);
30951			}
30952		}
30953
30954	}
30955
30956	class Audio extends Object3D {
30957		constructor(listener) {
30958			super();
30959			this.type = 'Audio';
30960			this.listener = listener;
30961			this.context = listener.context;
30962			this.gain = this.context.createGain();
30963			this.gain.connect(listener.getInput());
30964			this.autoplay = false;
30965			this.buffer = null;
30966			this.detune = 0;
30967			this.loop = false;
30968			this.loopStart = 0;
30969			this.loopEnd = 0;
30970			this.offset = 0;
30971			this.duration = undefined;
30972			this.playbackRate = 1;
30973			this.isPlaying = false;
30974			this.hasPlaybackControl = true;
30975			this.source = null;
30976			this.sourceType = 'empty';
30977			this._startedAt = 0;
30978			this._progress = 0;
30979			this._connected = false;
30980			this.filters = [];
30981		}
30982
30983		getOutput() {
30984			return this.gain;
30985		}
30986
30987		setNodeSource(audioNode) {
30988			this.hasPlaybackControl = false;
30989			this.sourceType = 'audioNode';
30990			this.source = audioNode;
30991			this.connect();
30992			return this;
30993		}
30994
30995		setMediaElementSource(mediaElement) {
30996			this.hasPlaybackControl = false;
30997			this.sourceType = 'mediaNode';
30998			this.source = this.context.createMediaElementSource(mediaElement);
30999			this.connect();
31000			return this;
31001		}
31002
31003		setMediaStreamSource(mediaStream) {
31004			this.hasPlaybackControl = false;
vendor: 19,580 bytes, lines 31005-31711
31005			this.sourceType = 'mediaStreamNode';
31006			this.source = this.context.createMediaStreamSource(mediaStream);
31007			this.connect();
31008			return this;
31009		}
31010
31011		setBuffer(audioBuffer) {
31012			this.buffer = audioBuffer;
31013			this.sourceType = 'buffer';
31014			if (this.autoplay) this.play();
31015			return this;
31016		}
31017
31018		play(delay = 0) {
31019			if (this.isPlaying === true) {
31020				console.warn('THREE.Audio: Audio is already playing.');
31021				return;
31022			}
31023
31024			if (this.hasPlaybackControl === false) {
31025				console.warn('THREE.Audio: this Audio has no playback control.');
31026				return;
31027			}
31028
31029			this._startedAt = this.context.currentTime + delay;
31030			const source = this.context.createBufferSource();
31031			source.buffer = this.buffer;
31032			source.loop = this.loop;
31033			source.loopStart = this.loopStart;
31034			source.loopEnd = this.loopEnd;
31035			source.onended = this.onEnded.bind(this);
31036			source.start(this._startedAt, this._progress + this.offset, this.duration);
31037			this.isPlaying = true;
31038			this.source = source;
31039			this.setDetune(this.detune);
31040			this.setPlaybackRate(this.playbackRate);
31041			return this.connect();
31042		}
31043
31044		pause() {
31045			if (this.hasPlaybackControl === false) {
31046				console.warn('THREE.Audio: this Audio has no playback control.');
31047				return;
31048			}
31049
31050			if (this.isPlaying === true) {
31051				// update current progress
31052				this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate;
31053
31054				if (this.loop === true) {
31055					// ensure _progress does not exceed duration with looped audios
31056					this._progress = this._progress % (this.duration || this.buffer.duration);
31057				}
31058
31059				this.source.stop();
31060				this.source.onended = null;
31061				this.isPlaying = false;
31062			}
31063
31064			return this;
31065		}
31066
31067		stop() {
31068			if (this.hasPlaybackControl === false) {
31069				console.warn('THREE.Audio: this Audio has no playback control.');
31070				return;
31071			}
31072
31073			this._progress = 0;
31074			this.source.stop();
31075			this.source.onended = null;
31076			this.isPlaying = false;
31077			return this;
31078		}
31079
31080		connect() {
31081			if (this.filters.length > 0) {
31082				this.source.connect(this.filters[0]);
31083
31084				for (let i = 1, l = this.filters.length; i < l; i++) {
31085					this.filters[i - 1].connect(this.filters[i]);
31086				}
31087
31088				this.filters[this.filters.length - 1].connect(this.getOutput());
31089			} else {
31090				this.source.connect(this.getOutput());
31091			}
31092
31093			this._connected = true;
31094			return this;
31095		}
31096
31097		disconnect() {
31098			if (this.filters.length > 0) {
31099				this.source.disconnect(this.filters[0]);
31100
31101				for (let i = 1, l = this.filters.length; i < l; i++) {
31102					this.filters[i - 1].disconnect(this.filters[i]);
31103				}
31104
31105				this.filters[this.filters.length - 1].disconnect(this.getOutput());
31106			} else {
31107				this.source.disconnect(this.getOutput());
31108			}
31109
31110			this._connected = false;
31111			return this;
31112		}
31113
31114		getFilters() {
31115			return this.filters;
31116		}
31117
31118		setFilters(value) {
31119			if (!value) value = [];
31120
31121			if (this._connected === true) {
31122				this.disconnect();
31123				this.filters = value.slice();
31124				this.connect();
31125			} else {
31126				this.filters = value.slice();
31127			}
31128
31129			return this;
31130		}
31131
31132		setDetune(value) {
31133			this.detune = value;
31134			if (this.source.detune === undefined) return; // only set detune when available
31135
31136			if (this.isPlaying === true) {
31137				this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01);
31138			}
31139
31140			return this;
31141		}
31142
31143		getDetune() {
31144			return this.detune;
31145		}
31146
31147		getFilter() {
31148			return this.getFilters()[0];
31149		}
31150
31151		setFilter(filter) {
31152			return this.setFilters(filter ? [filter] : []);
31153		}
31154
31155		setPlaybackRate(value) {
31156			if (this.hasPlaybackControl === false) {
31157				console.warn('THREE.Audio: this Audio has no playback control.');
31158				return;
31159			}
31160
31161			this.playbackRate = value;
31162
31163			if (this.isPlaying === true) {
31164				this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01);
31165			}
31166
31167			return this;
31168		}
31169
31170		getPlaybackRate() {
31171			return this.playbackRate;
31172		}
31173
31174		onEnded() {
31175			this.isPlaying = false;
31176		}
31177
31178		getLoop() {
31179			if (this.hasPlaybackControl === false) {
31180				console.warn('THREE.Audio: this Audio has no playback control.');
31181				return false;
31182			}
31183
31184			return this.loop;
31185		}
31186
31187		setLoop(value) {
31188			if (this.hasPlaybackControl === false) {
31189				console.warn('THREE.Audio: this Audio has no playback control.');
31190				return;
31191			}
31192
31193			this.loop = value;
31194
31195			if (this.isPlaying === true) {
31196				this.source.loop = this.loop;
31197			}
31198
31199			return this;
31200		}
31201
31202		setLoopStart(value) {
31203			this.loopStart = value;
31204			return this;
31205		}
31206
31207		setLoopEnd(value) {
31208			this.loopEnd = value;
31209			return this;
31210		}
31211
31212		getVolume() {
31213			return this.gain.gain.value;
31214		}
31215
31216		setVolume(value) {
31217			this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01);
31218			return this;
31219		}
31220
31221	}
31222
31223	const _position = /*@__PURE__*/new Vector3();
31224
31225	const _quaternion = /*@__PURE__*/new Quaternion();
31226
31227	const _scale = /*@__PURE__*/new Vector3();
31228
31229	const _orientation = /*@__PURE__*/new Vector3();
31230
31231	class PositionalAudio extends Audio {
31232		constructor(listener) {
31233			super(listener);
31234			this.panner = this.context.createPanner();
31235			this.panner.panningModel = 'HRTF';
31236			this.panner.connect(this.gain);
31237		}
31238
31239		getOutput() {
31240			return this.panner;
31241		}
31242
31243		getRefDistance() {
31244			return this.panner.refDistance;
31245		}
31246
31247		setRefDistance(value) {
31248			this.panner.refDistance = value;
31249			return this;
31250		}
31251
31252		getRolloffFactor() {
31253			return this.panner.rolloffFactor;
31254		}
31255
31256		setRolloffFactor(value) {
31257			this.panner.rolloffFactor = value;
31258			return this;
31259		}
31260
31261		getDistanceModel() {
31262			return this.panner.distanceModel;
31263		}
31264
31265		setDistanceModel(value) {
31266			this.panner.distanceModel = value;
31267			return this;
31268		}
31269
31270		getMaxDistance() {
31271			return this.panner.maxDistance;
31272		}
31273
31274		setMaxDistance(value) {
31275			this.panner.maxDistance = value;
31276			return this;
31277		}
31278
31279		setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) {
31280			this.panner.coneInnerAngle = coneInnerAngle;
31281			this.panner.coneOuterAngle = coneOuterAngle;
31282			this.panner.coneOuterGain = coneOuterGain;
31283			return this;
31284		}
31285
31286		updateMatrixWorld(force) {
31287			super.updateMatrixWorld(force);
31288			if (this.hasPlaybackControl === true && this.isPlaying === false) return;
31289			this.matrixWorld.decompose(_position, _quaternion, _scale);
31290
31291			_orientation.set(0, 0, 1).applyQuaternion(_quaternion);
31292
31293			const panner = this.panner;
31294
31295			if (panner.positionX) {
31296				// code path for Chrome and Firefox (see #14393)
31297				const endTime = this.context.currentTime + this.listener.timeDelta;
31298				panner.positionX.linearRampToValueAtTime(_position.x, endTime);
31299				panner.positionY.linearRampToValueAtTime(_position.y, endTime);
31300				panner.positionZ.linearRampToValueAtTime(_position.z, endTime);
31301				panner.orientationX.linearRampToValueAtTime(_orientation.x, endTime);
31302				panner.orientationY.linearRampToValueAtTime(_orientation.y, endTime);
31303				panner.orientationZ.linearRampToValueAtTime(_orientation.z, endTime);
31304			} else {
31305				panner.setPosition(_position.x, _position.y, _position.z);
31306				panner.setOrientation(_orientation.x, _orientation.y, _orientation.z);
31307			}
31308		}
31309
31310	}
31311
31312	class AudioAnalyser {
31313		constructor(audio, fftSize = 2048) {
31314			this.analyser = audio.context.createAnalyser();
31315			this.analyser.fftSize = fftSize;
31316			this.data = new Uint8Array(this.analyser.frequencyBinCount);
31317			audio.getOutput().connect(this.analyser);
31318		}
31319
31320		getFrequencyData() {
31321			this.analyser.getByteFrequencyData(this.data);
31322			return this.data;
31323		}
31324
31325		getAverageFrequency() {
31326			let value = 0;
31327			const data = this.getFrequencyData();
31328
31329			for (let i = 0; i < data.length; i++) {
31330				value += data[i];
31331			}
31332
31333			return value / data.length;
31334		}
31335
31336	}
31337
31338	class PropertyMixer {
31339		constructor(binding, typeName, valueSize) {
31340			this.binding = binding;
31341			this.valueSize = valueSize;
31342			let mixFunction, mixFunctionAdditive, setIdentity; // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ]
31343			//
31344			// interpolators can use .buffer as their .result
31345			// the data then goes to 'incoming'
31346			//
31347			// 'accu0' and 'accu1' are used frame-interleaved for
31348			// the cumulative result and are compared to detect
31349			// changes
31350			//
31351			// 'orig' stores the original state of the property
31352			//
31353			// 'add' is used for additive cumulative results
31354			//
31355			// 'work' is optional and is only present for quaternion types. It is used
31356			// to store intermediate quaternion multiplication results
31357
31358			switch (typeName) {
31359				case 'quaternion':
31360					mixFunction = this._slerp;
31361					mixFunctionAdditive = this._slerpAdditive;
31362					setIdentity = this._setAdditiveIdentityQuaternion;
31363					this.buffer = new Float64Array(valueSize * 6);
31364					this._workIndex = 5;
31365					break;
31366
31367				case 'string':
31368				case 'bool':
31369					mixFunction = this._select; // Use the regular mix function and for additive on these types,
31370					// additive is not relevant for non-numeric types
31371
31372					mixFunctionAdditive = this._select;
31373					setIdentity = this._setAdditiveIdentityOther;
31374					this.buffer = new Array(valueSize * 5);
31375					break;
31376
31377				default:
31378					mixFunction = this._lerp;
31379					mixFunctionAdditive = this._lerpAdditive;
31380					setIdentity = this._setAdditiveIdentityNumeric;
31381					this.buffer = new Float64Array(valueSize * 5);
31382			}
31383
31384			this._mixBufferRegion = mixFunction;
31385			this._mixBufferRegionAdditive = mixFunctionAdditive;
31386			this._setIdentity = setIdentity;
31387			this._origIndex = 3;
31388			this._addIndex = 4;
31389			this.cumulativeWeight = 0;
31390			this.cumulativeWeightAdditive = 0;
31391			this.useCount = 0;
31392			this.referenceCount = 0;
31393		} // accumulate data in the 'incoming' region into 'accu<i>'
31394
31395
31396		accumulate(accuIndex, weight) {
31397			// note: happily accumulating nothing when weight = 0, the caller knows
31398			// the weight and shouldn't have made the call in the first place
31399			const buffer = this.buffer,
31400						stride = this.valueSize,
31401						offset = accuIndex * stride + stride;
31402			let currentWeight = this.cumulativeWeight;
31403
31404			if (currentWeight === 0) {
31405				// accuN := incoming * weight
31406				for (let i = 0; i !== stride; ++i) {
31407					buffer[offset + i] = buffer[i];
31408				}
31409
31410				currentWeight = weight;
31411			} else {
31412				// accuN := accuN + incoming * weight
31413				currentWeight += weight;
31414				const mix = weight / currentWeight;
31415
31416				this._mixBufferRegion(buffer, offset, 0, mix, stride);
31417			}
31418
31419			this.cumulativeWeight = currentWeight;
31420		} // accumulate data in the 'incoming' region into 'add'
31421
31422
31423		accumulateAdditive(weight) {
31424			const buffer = this.buffer,
31425						stride = this.valueSize,
31426						offset = stride * this._addIndex;
31427
31428			if (this.cumulativeWeightAdditive === 0) {
31429				// add = identity
31430				this._setIdentity();
31431			} // add := add + incoming * weight
31432
31433
31434			this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride);
31435
31436			this.cumulativeWeightAdditive += weight;
31437		} // apply the state of 'accu<i>' to the binding when accus differ
31438
31439
31440		apply(accuIndex) {
31441			const stride = this.valueSize,
31442						buffer = this.buffer,
31443						offset = accuIndex * stride + stride,
31444						weight = this.cumulativeWeight,
31445						weightAdditive = this.cumulativeWeightAdditive,
31446						binding = this.binding;
31447			this.cumulativeWeight = 0;
31448			this.cumulativeWeightAdditive = 0;
31449
31450			if (weight < 1) {
31451				// accuN := accuN + original * ( 1 - cumulativeWeight )
31452				const originalValueOffset = stride * this._origIndex;
31453
31454				this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride);
31455			}
31456
31457			if (weightAdditive > 0) {
31458				// accuN := accuN + additive accuN
31459				this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride);
31460			}
31461
31462			for (let i = stride, e = stride + stride; i !== e; ++i) {
31463				if (buffer[i] !== buffer[i + stride]) {
31464					// value has changed -> update scene graph
31465					binding.setValue(buffer, offset);
31466					break;
31467				}
31468			}
31469		} // remember the state of the bound property and copy it to both accus
31470
31471
31472		saveOriginalState() {
31473			const binding = this.binding;
31474			const buffer = this.buffer,
31475						stride = this.valueSize,
31476						originalValueOffset = stride * this._origIndex;
31477			binding.getValue(buffer, originalValueOffset); // accu[0..1] := orig -- initially detect changes against the original
31478
31479			for (let i = stride, e = originalValueOffset; i !== e; ++i) {
31480				buffer[i] = buffer[originalValueOffset + i % stride];
31481			} // Add to identity for additive
31482
31483
31484			this._setIdentity();
31485
31486			this.cumulativeWeight = 0;
31487			this.cumulativeWeightAdditive = 0;
31488		} // apply the state previously taken via 'saveOriginalState' to the binding
31489
31490
31491		restoreOriginalState() {
31492			const originalValueOffset = this.valueSize * 3;
31493			this.binding.setValue(this.buffer, originalValueOffset);
31494		}
31495
31496		_setAdditiveIdentityNumeric() {
31497			const startIndex = this._addIndex * this.valueSize;
31498			const endIndex = startIndex + this.valueSize;
31499
31500			for (let i = startIndex; i < endIndex; i++) {
31501				this.buffer[i] = 0;
31502			}
31503		}
31504
31505		_setAdditiveIdentityQuaternion() {
31506			this._setAdditiveIdentityNumeric();
31507
31508			this.buffer[this._addIndex * this.valueSize + 3] = 1;
31509		}
31510
31511		_setAdditiveIdentityOther() {
31512			const startIndex = this._origIndex * this.valueSize;
31513			const targetIndex = this._addIndex * this.valueSize;
31514
31515			for (let i = 0; i < this.valueSize; i++) {
31516				this.buffer[targetIndex + i] = this.buffer[startIndex + i];
31517			}
31518		} // mix functions
31519
31520
31521		_select(buffer, dstOffset, srcOffset, t, stride) {
31522			if (t >= 0.5) {
31523				for (let i = 0; i !== stride; ++i) {
31524					buffer[dstOffset + i] = buffer[srcOffset + i];
31525				}
31526			}
31527		}
31528
31529		_slerp(buffer, dstOffset, srcOffset, t) {
31530			Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t);
31531		}
31532
31533		_slerpAdditive(buffer, dstOffset, srcOffset, t, stride) {
31534			const workOffset = this._workIndex * stride; // Store result in intermediate buffer offset
31535
31536			Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result
31537
31538			Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t);
31539		}
31540
31541		_lerp(buffer, dstOffset, srcOffset, t, stride) {
31542			const s = 1 - t;
31543
31544			for (let i = 0; i !== stride; ++i) {
31545				const j = dstOffset + i;
31546				buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t;
31547			}
31548		}
31549
31550		_lerpAdditive(buffer, dstOffset, srcOffset, t, stride) {
31551			for (let i = 0; i !== stride; ++i) {
31552				const j = dstOffset + i;
31553				buffer[j] = buffer[j] + buffer[srcOffset + i] * t;
31554			}
31555		}
31556
31557	}
31558
31559	// Characters [].:/ are reserved for track binding syntax.
31560	const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
31561
31562	const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches
31563	// only latin characters, and the unicode \p{L} is not yet supported. So
31564	// instead, we exclude reserved characters and match everything else.
31565
31566
31567	const _wordChar = '[^' + _RESERVED_CHARS_RE + ']';
31568
31569	const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must
31570	// be matched to parse the rest of the track name.
31571
31572
31573	const _directoryRe = /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
31574
31575
31576	const _nodeRe = /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved
31577	// characters. Accessor may contain any character except closing bracket.
31578
31579
31580	const _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may
31581	// contain any non-bracket characters.
31582
31583
31584	const _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar);
31585
31586	const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$');
31587
31588	const _supportedObjectNames = ['material', 'materials', 'bones'];
31589
31590	class Composite {
31591		constructor(targetGroup, path, optionalParsedPath) {
31592			const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path);
31593			this._targetGroup = targetGroup;
31594			this._bindings = targetGroup.subscribe_(path, parsedPath);
31595		}
31596
31597		getValue(array, offset) {
31598			this.bind(); // bind all binding
31599
31600			const firstValidIndex = this._targetGroup.nCachedObjects_,
31601						binding = this._bindings[firstValidIndex]; // and only call .getValue on the first
31602
31603			if (binding !== undefined) binding.getValue(array, offset);
31604		}
31605
31606		setValue(array, offset) {
31607			const bindings = this._bindings;
31608
31609			for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) {
31610				bindings[i].setValue(array, offset);
31611			}
31612		}
31613
31614		bind() {
31615			const bindings = this._bindings;
31616
31617			for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) {
31618				bindings[i].bind();
31619			}
31620		}
31621
31622		unbind() {
31623			const bindings = this._bindings;
31624
31625			for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) {
31626				bindings[i].unbind();
31627			}
31628		}
31629
31630	} // Note: This class uses a State pattern on a per-method basis:
31631	// 'bind' sets 'this.getValue' / 'setValue' and shadows the
31632	// prototype version of these methods with one that represents
31633	// the bound state. When the property is not found, the methods
31634	// become no-ops.
31635
31636
31637	class PropertyBinding {
31638		constructor(rootNode, path, parsedPath) {
31639			this.path = path;
31640			this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path);
31641			this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName) || rootNode;
31642			this.rootNode = rootNode; // initial state of these methods that calls 'bind'
31643
31644			this.getValue = this._getValue_unbound;
31645			this.setValue = this._setValue_unbound;
31646		}
31647
31648		static create(root, path, parsedPath) {
31649			if (!(root && root.isAnimationObjectGroup)) {
31650				return new PropertyBinding(root, path, parsedPath);
31651			} else {
31652				return new PropertyBinding.Composite(root, path, parsedPath);
31653			}
31654		}
31655		/**
31656		 * Replaces spaces with underscores and removes unsupported characters from
31657		 * node names, to ensure compatibility with parseTrackName().
31658		 *
31659		 * @param {string} name Node name to be sanitized.
31660		 * @return {string}
31661		 */
31662
31663
31664		static sanitizeNodeName(name) {
31665			return name.replace(/\s/g, '_').replace(_reservedRe, '');
31666		}
31667
31668		static parseTrackName(trackName) {
31669			const matches = _trackRe.exec(trackName);
31670
31671			if (!matches) {
31672				throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName);
31673			}
31674
31675			const results = {
31676				// directoryName: matches[ 1 ], // (tschw) currently unused
31677				nodeName: matches[2],
31678				objectName: matches[3],
31679				objectIndex: matches[4],
31680				propertyName: matches[5],
31681				// required
31682				propertyIndex: matches[6]
31683			};
31684			const lastDot = results.nodeName && results.nodeName.lastIndexOf('.');
31685
31686			if (lastDot !== undefined && lastDot !== -1) {
31687				const objectName = results.nodeName.substring(lastDot + 1); // Object names must be checked against an allowlist. Otherwise, there
31688				// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
31689				// 'bar' could be the objectName, or part of a nodeName (which can
31690				// include '.' characters).
31691
31692				if (_supportedObjectNames.indexOf(objectName) !== -1) {
31693					results.nodeName = results.nodeName.substring(0, lastDot);
31694					results.objectName = objectName;
31695				}
31696			}
31697
31698			if (results.propertyName === null || results.propertyName.length === 0) {
31699				throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName);
31700			}
31701
31702			return results;
31703		}
31704
31705		static findNode(root, nodeName) {
31706			if (!nodeName || nodeName === '' || nodeName === '.' || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) {
31707				return root;
31708			} // search into skeleton bones.
31709
31710
31711			if (root.skeleton) {
vendor: 4,641 bytes, lines 31712-31884
31712				const bone = root.skeleton.getBoneByName(nodeName);
31713
31714				if (bone !== undefined) {
31715					return bone;
31716				}
31717			} // search into node subtree.
31718
31719
31720			if (root.children) {
31721				const searchNodeSubtree = function (children) {
31722					for (let i = 0; i < children.length; i++) {
31723						const childNode = children[i];
31724
31725						if (childNode.name === nodeName || childNode.uuid === nodeName) {
31726							return childNode;
31727						}
31728
31729						const result = searchNodeSubtree(childNode.children);
31730						if (result) return result;
31731					}
31732
31733					return null;
31734				};
31735
31736				const subTreeNode = searchNodeSubtree(root.children);
31737
31738				if (subTreeNode) {
31739					return subTreeNode;
31740				}
31741			}
31742
31743			return null;
31744		} // these are used to "bind" a nonexistent property
31745
31746
31747		_getValue_unavailable() {}
31748
31749		_setValue_unavailable() {} // Getters
31750
31751
31752		_getValue_direct(buffer, offset) {
31753			buffer[offset] = this.targetObject[this.propertyName];
31754		}
31755
31756		_getValue_array(buffer, offset) {
31757			const source = this.resolvedProperty;
31758
31759			for (let i = 0, n = source.length; i !== n; ++i) {
31760				buffer[offset++] = source[i];
31761			}
31762		}
31763
31764		_getValue_arrayElement(buffer, offset) {
31765			buffer[offset] = this.resolvedProperty[this.propertyIndex];
31766		}
31767
31768		_getValue_toArray(buffer, offset) {
31769			this.resolvedProperty.toArray(buffer, offset);
31770		} // Direct
31771
31772
31773		_setValue_direct(buffer, offset) {
31774			this.targetObject[this.propertyName] = buffer[offset];
31775		}
31776
31777		_setValue_direct_setNeedsUpdate(buffer, offset) {
31778			this.targetObject[this.propertyName] = buffer[offset];
31779			this.targetObject.needsUpdate = true;
31780		}
31781
31782		_setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) {
31783			this.targetObject[this.propertyName] = buffer[offset];
31784			this.targetObject.matrixWorldNeedsUpdate = true;
31785		} // EntireArray
31786
31787
31788		_setValue_array(buffer, offset) {
31789			const dest = this.resolvedProperty;
31790
31791			for (let i = 0, n = dest.length; i !== n; ++i) {
31792				dest[i] = buffer[offset++];
31793			}
31794		}
31795
31796		_setValue_array_setNeedsUpdate(buffer, offset) {
31797			const dest = this.resolvedProperty;
31798
31799			for (let i = 0, n = dest.length; i !== n; ++i) {
31800				dest[i] = buffer[offset++];
31801			}
31802
31803			this.targetObject.needsUpdate = true;
31804		}
31805
31806		_setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) {
31807			const dest = this.resolvedProperty;
31808
31809			for (let i = 0, n = dest.length; i !== n; ++i) {
31810				dest[i] = buffer[offset++];
31811			}
31812
31813			this.targetObject.matrixWorldNeedsUpdate = true;
31814		} // ArrayElement
31815
31816
31817		_setValue_arrayElement(buffer, offset) {
31818			this.resolvedProperty[this.propertyIndex] = buffer[offset];
31819		}
31820
31821		_setValue_arrayElement_setNeedsUpdate(buffer, offset) {
31822			this.resolvedProperty[this.propertyIndex] = buffer[offset];
31823			this.targetObject.needsUpdate = true;
31824		}
31825
31826		_setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) {
31827			this.resolvedProperty[this.propertyIndex] = buffer[offset];
31828			this.targetObject.matrixWorldNeedsUpdate = true;
31829		} // HasToFromArray
31830
31831
31832		_setValue_fromArray(buffer, offset) {
31833			this.resolvedProperty.fromArray(buffer, offset);
31834		}
31835
31836		_setValue_fromArray_setNeedsUpdate(buffer, offset) {
31837			this.resolvedProperty.fromArray(buffer, offset);
31838			this.targetObject.needsUpdate = true;
31839		}
31840
31841		_setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) {
31842			this.resolvedProperty.fromArray(buffer, offset);
31843			this.targetObject.matrixWorldNeedsUpdate = true;
31844		}
31845
31846		_getValue_unbound(targetArray, offset) {
31847			this.bind();
31848			this.getValue(targetArray, offset);
31849		}
31850
31851		_setValue_unbound(sourceArray, offset) {
31852			this.bind();
31853			this.setValue(sourceArray, offset);
31854		} // create getter / setter pair for a property in the scene graph
31855
31856
31857		bind() {
31858			let targetObject = this.node;
31859			const parsedPath = this.parsedPath;
31860			const objectName = parsedPath.objectName;
31861			const propertyName = parsedPath.propertyName;
31862			let propertyIndex = parsedPath.propertyIndex;
31863
31864			if (!targetObject) {
31865				targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode;
31866				this.node = targetObject;
31867			} // set fail state so we can just 'return' on error
31868
31869
31870			this.getValue = this._getValue_unavailable;
31871			this.setValue = this._setValue_unavailable; // ensure there is a value node
31872
31873			if (!targetObject) {
31874				console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.');
31875				return;
31876			}
31877
31878			if (objectName) {
31879				let objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials....
31880
31881				switch (objectName) {
31882					case 'materials':
31883						if (!targetObject.material) {
31884							console.error('THREE.PropertyBinding: Can not bind to material as no
vendor: 5,355 bytes, lines 31884-32027
31884de does not have a material.', this);
31885							return;
31886						}
31887
31888						if (!targetObject.material.materials) {
31889							console.error('THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this);
31890							return;
31891						}
31892
31893						targetObject = targetObject.material.materials;
31894						break;
31895
31896					case 'bones':
31897						if (!targetObject.skeleton) {
31898							console.error('THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this);
31899							return;
31900						} // potential future optimization: skip this if propertyIndex is already an integer
31901						// and convert the integer string to a true integer.
31902
31903
31904						targetObject = targetObject.skeleton.bones; // support resolving morphTarget names into indices.
31905
31906						for (let i = 0; i < targetObject.length; i++) {
31907							if (targetObject[i].name === objectIndex) {
31908								objectIndex = i;
31909								break;
31910							}
31911						}
31912
31913						break;
31914
31915					default:
31916						if (targetObject[objectName] === undefined) {
31917							console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this);
31918							return;
31919						}
31920
31921						targetObject = targetObject[objectName];
31922				}
31923
31924				if (objectIndex !== undefined) {
31925					if (targetObject[objectIndex] === undefined) {
31926						console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject);
31927						return;
31928					}
31929
31930					targetObject = targetObject[objectIndex];
31931				}
31932			} // resolve property
31933
31934
31935			const nodeProperty = targetObject[propertyName];
31936
31937			if (nodeProperty === undefined) {
31938				const nodeName = parsedPath.nodeName;
31939				console.error('THREE.PropertyBinding: Trying to update property for track: ' + nodeName + '.' + propertyName + ' but it wasn\'t found.', targetObject);
31940				return;
31941			} // determine versioning scheme
31942
31943
31944			let versioning = this.Versioning.None;
31945			this.targetObject = targetObject;
31946
31947			if (targetObject.needsUpdate !== undefined) {
31948				// material
31949				versioning = this.Versioning.NeedsUpdate;
31950			} else if (targetObject.matrixWorldNeedsUpdate !== undefined) {
31951				// node transform
31952				versioning = this.Versioning.MatrixWorldNeedsUpdate;
31953			} // determine how the property gets bound
31954
31955
31956			let bindingType = this.BindingType.Direct;
31957
31958			if (propertyIndex !== undefined) {
31959				// access a sub element of the property array (only primitives are supported right now)
31960				if (propertyName === 'morphTargetInfluences') {
31961					// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
31962					// support resolving morphTarget names into indices.
31963					if (!targetObject.geometry) {
31964						console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this);
31965						return;
31966					}
31967
31968					if (targetObject.geometry.isBufferGeometry) {
31969						if (!targetObject.geometry.morphAttributes) {
31970							console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this);
31971							return;
31972						}
31973
31974						if (targetObject.morphTargetDictionary[propertyIndex] !== undefined) {
31975							propertyIndex = targetObject.morphTargetDictionary[propertyIndex];
31976						}
31977					} else {
31978						console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences on THREE.Geometry. Use THREE.BufferGeometry instead.', this);
31979						return;
31980					}
31981				}
31982
31983				bindingType = this.BindingType.ArrayElement;
31984				this.resolvedProperty = nodeProperty;
31985				this.propertyIndex = propertyIndex;
31986			} else if (nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined) {
31987				// must use copy for Object3D.Euler/Quaternion
31988				bindingType = this.BindingType.HasFromToArray;
31989				this.resolvedProperty = nodeProperty;
31990			} else if (Array.isArray(nodeProperty)) {
31991				bindingType = this.BindingType.EntireArray;
31992				this.resolvedProperty = nodeProperty;
31993			} else {
31994				this.propertyName = propertyName;
31995			} // select getter / setter
31996
31997
31998			this.getValue = this.GetterByBindingType[bindingType];
31999			this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning];
32000		}
32001
32002		unbind() {
32003			this.node = null; // back to the prototype version of getValue / setValue
32004			// note: avoiding to mutate the shape of 'this' via 'delete'
32005
32006			this.getValue = this._getValue_unbound;
32007			this.setValue = this._setValue_unbound;
32008		}
32009
32010	}
32011
32012	PropertyBinding.Composite = Composite;
32013	PropertyBinding.prototype.BindingType = {
32014		Direct: 0,
32015		EntireArray: 1,
32016		ArrayElement: 2,
32017		HasFromToArray: 3
32018	};
32019	PropertyBinding.prototype.Versioning = {
32020		None: 0,
32021		NeedsUpdate: 1,
32022		MatrixWorldNeedsUpdate: 2
32023	};
32024	PropertyBinding.prototype.GetterByBindingType = [PropertyBinding.prototype._getValue_direct, PropertyBinding.prototype._getValue_array, PropertyBinding.prototype._getValue_arrayElement, PropertyBinding.prototype._getValue_toArray];
32025	PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [[// Direct
32026	PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [// EntireArray
32027	PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatr
vendor: 4,194 bytes, lines 32027-32154
32027ixWorldNeedsUpdate], [// ArrayElement
32028	PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [// HasToFromArray
32029	PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]];
32030
32031	/**
32032	 *
32033	 * A group of objects that receives a shared animation state.
32034	 *
32035	 * Usage:
32036	 *
32037	 *	- Add objects you would otherwise pass as 'root' to the
32038	 *		constructor or the .clipAction method of AnimationMixer.
32039	 *
32040	 *	- Instead pass this object as 'root'.
32041	 *
32042	 *	- You can also add and remove objects later when the mixer
32043	 *		is running.
32044	 *
32045	 * Note:
32046	 *
32047	 *		Objects of this class appear as one object to the mixer,
32048	 *		so cache control of the individual objects must be done
32049	 *		on the group.
32050	 *
32051	 * Limitation:
32052	 *
32053	 *	- The animated properties must be compatible among the
32054	 *		all objects in the group.
32055	 *
32056	 *	- A single property can either be controlled through a
32057	 *		target group or directly, but not both.
32058	 */
32059
32060	class AnimationObjectGroup {
32061		constructor() {
32062			this.uuid = generateUUID(); // cached objects followed by the active ones
32063
32064			this._objects = Array.prototype.slice.call(arguments);
32065			this.nCachedObjects_ = 0; // threshold
32066			// note: read by PropertyBinding.Composite
32067
32068			const indices = {};
32069			this._indicesByUUID = indices; // for bookkeeping
32070
32071			for (let i = 0, n = arguments.length; i !== n; ++i) {
32072				indices[arguments[i].uuid] = i;
32073			}
32074
32075			this._paths = []; // inside: string
32076
32077			this._parsedPaths = []; // inside: { we don't care, here }
32078
32079			this._bindings = []; // inside: Array< PropertyBinding >
32080
32081			this._bindingsIndicesByPath = {}; // inside: indices in these arrays
32082
32083			const scope = this;
32084			this.stats = {
32085				objects: {
32086					get total() {
32087						return scope._objects.length;
32088					},
32089
32090					get inUse() {
32091						return this.total - scope.nCachedObjects_;
32092					}
32093
32094				},
32095
32096				get bindingsPerObject() {
32097					return scope._bindings.length;
32098				}
32099
32100			};
32101		}
32102
32103		add() {
32104			const objects = this._objects,
32105						indicesByUUID = this._indicesByUUID,
32106						paths = this._paths,
32107						parsedPaths = this._parsedPaths,
32108						bindings = this._bindings,
32109						nBindings = bindings.length;
32110			let knownObject = undefined,
32111					nObjects = objects.length,
32112					nCachedObjects = this.nCachedObjects_;
32113
32114			for (let i = 0, n = arguments.length; i !== n; ++i) {
32115				const object = arguments[i],
32116							uuid = object.uuid;
32117				let index = indicesByUUID[uuid];
32118
32119				if (index === undefined) {
32120					// unknown object -> add it to the ACTIVE region
32121					index = nObjects++;
32122					indicesByUUID[uuid] = index;
32123					objects.push(object); // accounting is done, now do the same for all bindings
32124
32125					for (let j = 0, m = nBindings; j !== m; ++j) {
32126						bindings[j].push(new PropertyBinding(object, paths[j], parsedPaths[j]));
32127					}
32128				} else if (index < nCachedObjects) {
32129					knownObject = objects[index]; // move existing object to the ACTIVE region
32130
32131					const firstActiveIndex = --nCachedObjects,
32132								lastCachedObject = objects[firstActiveIndex];
32133					indicesByUUID[lastCachedObject.uuid] = index;
32134					objects[index] = lastCachedObject;
32135					indicesByUUID[uuid] = firstActiveIndex;
32136					objects[firstActiveIndex] = object; // accounting is done, now do the same for all bindings
32137
32138					for (let j = 0, m = nBindings; j !== m; ++j) {
32139						const bindingsForPath = bindings[j],
32140									lastCached = bindingsForPath[firstActiveIndex];
32141						let binding = bindingsForPath[index];
32142						bindingsForPath[index] = lastCached;
32143
32144						if (binding === undefined) {
32145							// since we do not bother to create new bindings
32146							// for objects that are cached, the binding may
32147							// or may not exist
32148							binding = new PropertyBinding(object, paths[j], parsedPaths[j]);
32149						}
32150
32151						bindingsForPath[firstActiveIndex] = binding;
32152					}
32153				} else if (objects[index] !== knownObject) {
32154					console.error('THREE.AnimationObjectGroup: Different objects with the same UUID ' + 'detected. Clean the caches or recreate your infrastru
vendor: 7,337 bytes, lines 32154-32389
32154cture when reloading scenes.');
32155				} // else the object is already where we want it to be
32156
32157			} // for arguments
32158
32159
32160			this.nCachedObjects_ = nCachedObjects;
32161		}
32162
32163		remove() {
32164			const objects = this._objects,
32165						indicesByUUID = this._indicesByUUID,
32166						bindings = this._bindings,
32167						nBindings = bindings.length;
32168			let nCachedObjects = this.nCachedObjects_;
32169
32170			for (let i = 0, n = arguments.length; i !== n; ++i) {
32171				const object = arguments[i],
32172							uuid = object.uuid,
32173							index = indicesByUUID[uuid];
32174
32175				if (index !== undefined && index >= nCachedObjects) {
32176					// move existing object into the CACHED region
32177					const lastCachedIndex = nCachedObjects++,
32178								firstActiveObject = objects[lastCachedIndex];
32179					indicesByUUID[firstActiveObject.uuid] = index;
32180					objects[index] = firstActiveObject;
32181					indicesByUUID[uuid] = lastCachedIndex;
32182					objects[lastCachedIndex] = object; // accounting is done, now do the same for all bindings
32183
32184					for (let j = 0, m = nBindings; j !== m; ++j) {
32185						const bindingsForPath = bindings[j],
32186									firstActive = bindingsForPath[lastCachedIndex],
32187									binding = bindingsForPath[index];
32188						bindingsForPath[index] = firstActive;
32189						bindingsForPath[lastCachedIndex] = binding;
32190					}
32191				}
32192			} // for arguments
32193
32194
32195			this.nCachedObjects_ = nCachedObjects;
32196		} // remove & forget
32197
32198
32199		uncache() {
32200			const objects = this._objects,
32201						indicesByUUID = this._indicesByUUID,
32202						bindings = this._bindings,
32203						nBindings = bindings.length;
32204			let nCachedObjects = this.nCachedObjects_,
32205					nObjects = objects.length;
32206
32207			for (let i = 0, n = arguments.length; i !== n; ++i) {
32208				const object = arguments[i],
32209							uuid = object.uuid,
32210							index = indicesByUUID[uuid];
32211
32212				if (index !== undefined) {
32213					delete indicesByUUID[uuid];
32214
32215					if (index < nCachedObjects) {
32216						// object is cached, shrink the CACHED region
32217						const firstActiveIndex = --nCachedObjects,
32218									lastCachedObject = objects[firstActiveIndex],
32219									lastIndex = --nObjects,
32220									lastObject = objects[lastIndex]; // last cached object takes this object's place
32221
32222						indicesByUUID[lastCachedObject.uuid] = index;
32223						objects[index] = lastCachedObject; // last object goes to the activated slot and pop
32224
32225						indicesByUUID[lastObject.uuid] = firstActiveIndex;
32226						objects[firstActiveIndex] = lastObject;
32227						objects.pop(); // accounting is done, now do the same for all bindings
32228
32229						for (let j = 0, m = nBindings; j !== m; ++j) {
32230							const bindingsForPath = bindings[j],
32231										lastCached = bindingsForPath[firstActiveIndex],
32232										last = bindingsForPath[lastIndex];
32233							bindingsForPath[index] = lastCached;
32234							bindingsForPath[firstActiveIndex] = last;
32235							bindingsForPath.pop();
32236						}
32237					} else {
32238						// object is active, just swap with the last and pop
32239						const lastIndex = --nObjects,
32240									lastObject = objects[lastIndex];
32241
32242						if (lastIndex > 0) {
32243							indicesByUUID[lastObject.uuid] = index;
32244						}
32245
32246						objects[index] = lastObject;
32247						objects.pop(); // accounting is done, now do the same for all bindings
32248
32249						for (let j = 0, m = nBindings; j !== m; ++j) {
32250							const bindingsForPath = bindings[j];
32251							bindingsForPath[index] = bindingsForPath[lastIndex];
32252							bindingsForPath.pop();
32253						}
32254					} // cached or active
32255
32256				} // if object is known
32257
32258			} // for arguments
32259
32260
32261			this.nCachedObjects_ = nCachedObjects;
32262		} // Internal interface used by befriended PropertyBinding.Composite:
32263
32264
32265		subscribe_(path, parsedPath) {
32266			// returns an array of bindings for the given path that is changed
32267			// according to the contained objects in the group
32268			const indicesByPath = this._bindingsIndicesByPath;
32269			let index = indicesByPath[path];
32270			const bindings = this._bindings;
32271			if (index !== undefined) return bindings[index];
32272			const paths = this._paths,
32273						parsedPaths = this._parsedPaths,
32274						objects = this._objects,
32275						nObjects = objects.length,
32276						nCachedObjects = this.nCachedObjects_,
32277						bindingsForPath = new Array(nObjects);
32278			index = bindings.length;
32279			indicesByPath[path] = index;
32280			paths.push(path);
32281			parsedPaths.push(parsedPath);
32282			bindings.push(bindingsForPath);
32283
32284			for (let i = nCachedObjects, n = objects.length; i !== n; ++i) {
32285				const object = objects[i];
32286				bindingsForPath[i] = new PropertyBinding(object, path, parsedPath);
32287			}
32288
32289			return bindingsForPath;
32290		}
32291
32292		unsubscribe_(path) {
32293			// tells the group to forget about a property path and no longer
32294			// update the array previously obtained with 'subscribe_'
32295			const indicesByPath = this._bindingsIndicesByPath,
32296						index = indicesByPath[path];
32297
32298			if (index !== undefined) {
32299				const paths = this._paths,
32300							parsedPaths = this._parsedPaths,
32301							bindings = this._bindings,
32302							lastBindingsIndex = bindings.length - 1,
32303							lastBindings = bindings[lastBindingsIndex],
32304							lastBindingsPath = path[lastBindingsIndex];
32305				indicesByPath[lastBindingsPath] = index;
32306				bindings[index] = lastBindings;
32307				bindings.pop();
32308				parsedPaths[index] = parsedPaths[lastBindingsIndex];
32309				parsedPaths.pop();
32310				paths[index] = paths[lastBindingsIndex];
32311				paths.pop();
32312			}
32313		}
32314
32315	}
32316
32317	AnimationObjectGroup.prototype.isAnimationObjectGroup = true;
32318
32319	class AnimationAction {
32320		constructor(mixer, clip, localRoot = null, blendMode = clip.blendMode) {
32321			this._mixer = mixer;
32322			this._clip = clip;
32323			this._localRoot = localRoot;
32324			this.blendMode = blendMode;
32325			const tracks = clip.tracks,
32326						nTracks = tracks.length,
32327						interpolants = new Array(nTracks);
32328			const interpolantSettings = {
32329				endingStart: ZeroCurvatureEnding,
32330				endingEnd: ZeroCurvatureEnding
32331			};
32332
32333			for (let i = 0; i !== nTracks; ++i) {
32334				const interpolant = tracks[i].createInterpolant(null);
32335				interpolants[i] = interpolant;
32336				interpolant.settings = interpolantSettings;
32337			}
32338
32339			this._interpolantSettings = interpolantSettings;
32340			this._interpolants = interpolants; // bound by the mixer
32341			// inside: PropertyMixer (managed by the mixer)
32342
32343			this._propertyBindings = new Array(nTracks);
32344			this._cacheIndex = null; // for the memory manager
32345
32346			this._byClipCacheIndex = null; // for the memory manager
32347
32348			this._timeScaleInterpolant = null;
32349			this._weightInterpolant = null;
32350			this.loop = LoopRepeat;
32351			this._loopCount = -1; // global mixer time when the action is to be started
32352			// it's set back to 'null' upon start of the action
32353
32354			this._startTime = null; // scaled local time of the action
32355			// gets clamped or wrapped to 0..clip.duration according to loop
32356
32357			this.time = 0;
32358			this.timeScale = 1;
32359			this._effectiveTimeScale = 1;
32360			this.weight = 1;
32361			this._effectiveWeight = 1;
32362			this.repetitions = Infinity; // no. of repetitions when looping
32363
32364			this.paused = false; // true -> zero effective time scale
32365
32366			this.enabled = true; // false -> zero effective weight
32367
32368			this.clampWhenFinished = false; // keep feeding the last frame?
32369
32370			this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate
32371
32372			this.zeroSlopeAtEnd = true; // clips for start, loop and end
32373		} // State & Scheduling
32374
32375
32376		play() {
32377			this._mixer._activateAction(this);
32378
32379			return this;
32380		}
32381
32382		stop() {
32383			this._mixer._deactivateAction(this);
32384
32385			return this.reset();
32386		}
32387
32388		reset() {
32389			this.paused = false;
vendor: 10,345 bytes, lines 32390-32814
32390			this.enabled = true;
32391			this.time = 0; // restart clip
32392
32393			this._loopCount = -1; // forget previous loops
32394
32395			this._startTime = null; // forget scheduling
32396
32397			return this.stopFading().stopWarping();
32398		}
32399
32400		isRunning() {
32401			return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this);
32402		} // return true when play has been called
32403
32404
32405		isScheduled() {
32406			return this._mixer._isActiveAction(this);
32407		}
32408
32409		startAt(time) {
32410			this._startTime = time;
32411			return this;
32412		}
32413
32414		setLoop(mode, repetitions) {
32415			this.loop = mode;
32416			this.repetitions = repetitions;
32417			return this;
32418		} // Weight
32419		// set the weight stopping any scheduled fading
32420		// although .enabled = false yields an effective weight of zero, this
32421		// method does *not* change .enabled, because it would be confusing
32422
32423
32424		setEffectiveWeight(weight) {
32425			this.weight = weight; // note: same logic as when updated at runtime
32426
32427			this._effectiveWeight = this.enabled ? weight : 0;
32428			return this.stopFading();
32429		} // return the weight considering fading and .enabled
32430
32431
32432		getEffectiveWeight() {
32433			return this._effectiveWeight;
32434		}
32435
32436		fadeIn(duration) {
32437			return this._scheduleFading(duration, 0, 1);
32438		}
32439
32440		fadeOut(duration) {
32441			return this._scheduleFading(duration, 1, 0);
32442		}
32443
32444		crossFadeFrom(fadeOutAction, duration, warp) {
32445			fadeOutAction.fadeOut(duration);
32446			this.fadeIn(duration);
32447
32448			if (warp) {
32449				const fadeInDuration = this._clip.duration,
32450							fadeOutDuration = fadeOutAction._clip.duration,
32451							startEndRatio = fadeOutDuration / fadeInDuration,
32452							endStartRatio = fadeInDuration / fadeOutDuration;
32453				fadeOutAction.warp(1.0, startEndRatio, duration);
32454				this.warp(endStartRatio, 1.0, duration);
32455			}
32456
32457			return this;
32458		}
32459
32460		crossFadeTo(fadeInAction, duration, warp) {
32461			return fadeInAction.crossFadeFrom(this, duration, warp);
32462		}
32463
32464		stopFading() {
32465			const weightInterpolant = this._weightInterpolant;
32466
32467			if (weightInterpolant !== null) {
32468				this._weightInterpolant = null;
32469
32470				this._mixer._takeBackControlInterpolant(weightInterpolant);
32471			}
32472
32473			return this;
32474		} // Time Scale Control
32475		// set the time scale stopping any scheduled warping
32476		// although .paused = true yields an effective time scale of zero, this
32477		// method does *not* change .paused, because it would be confusing
32478
32479
32480		setEffectiveTimeScale(timeScale) {
32481			this.timeScale = timeScale;
32482			this._effectiveTimeScale = this.paused ? 0 : timeScale;
32483			return this.stopWarping();
32484		} // return the time scale considering warping and .paused
32485
32486
32487		getEffectiveTimeScale() {
32488			return this._effectiveTimeScale;
32489		}
32490
32491		setDuration(duration) {
32492			this.timeScale = this._clip.duration / duration;
32493			return this.stopWarping();
32494		}
32495
32496		syncWith(action) {
32497			this.time = action.time;
32498			this.timeScale = action.timeScale;
32499			return this.stopWarping();
32500		}
32501
32502		halt(duration) {
32503			return this.warp(this._effectiveTimeScale, 0, duration);
32504		}
32505
32506		warp(startTimeScale, endTimeScale, duration) {
32507			const mixer = this._mixer,
32508						now = mixer.time,
32509						timeScale = this.timeScale;
32510			let interpolant = this._timeScaleInterpolant;
32511
32512			if (interpolant === null) {
32513				interpolant = mixer._lendControlInterpolant();
32514				this._timeScaleInterpolant = interpolant;
32515			}
32516
32517			const times = interpolant.parameterPositions,
32518						values = interpolant.sampleValues;
32519			times[0] = now;
32520			times[1] = now + duration;
32521			values[0] = startTimeScale / timeScale;
32522			values[1] = endTimeScale / timeScale;
32523			return this;
32524		}
32525
32526		stopWarping() {
32527			const timeScaleInterpolant = this._timeScaleInterpolant;
32528
32529			if (timeScaleInterpolant !== null) {
32530				this._timeScaleInterpolant = null;
32531
32532				this._mixer._takeBackControlInterpolant(timeScaleInterpolant);
32533			}
32534
32535			return this;
32536		} // Object Accessors
32537
32538
32539		getMixer() {
32540			return this._mixer;
32541		}
32542
32543		getClip() {
32544			return this._clip;
32545		}
32546
32547		getRoot() {
32548			return this._localRoot || this._mixer._root;
32549		} // Interna
32550
32551
32552		_update(time, deltaTime, timeDirection, accuIndex) {
32553			// called by the mixer
32554			if (!this.enabled) {
32555				// call ._updateWeight() to update ._effectiveWeight
32556				this._updateWeight(time);
32557
32558				return;
32559			}
32560
32561			const startTime = this._startTime;
32562
32563			if (startTime !== null) {
32564				// check for scheduled start of action
32565				const timeRunning = (time - startTime) * timeDirection;
32566
32567				if (timeRunning < 0 || timeDirection === 0) {
32568					return; // yet to come / don't decide when delta = 0
32569				} // start
32570
32571
32572				this._startTime = null; // unschedule
32573
32574				deltaTime = timeDirection * timeRunning;
32575			} // apply time scale and advance time
32576
32577
32578			deltaTime *= this._updateTimeScale(time);
32579
32580			const clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in
32581			// an effective weight of 0
32582
32583
32584			const weight = this._updateWeight(time);
32585
32586			if (weight > 0) {
32587				const interpolants = this._interpolants;
32588				const propertyMixers = this._propertyBindings;
32589
32590				switch (this.blendMode) {
32591					case AdditiveAnimationBlendMode:
32592						for (let j = 0, m = interpolants.length; j !== m; ++j) {
32593							interpolants[j].evaluate(clipTime);
32594							propertyMixers[j].accumulateAdditive(weight);
32595						}
32596
32597						break;
32598
32599					case NormalAnimationBlendMode:
32600					default:
32601						for (let j = 0, m = interpolants.length; j !== m; ++j) {
32602							interpolants[j].evaluate(clipTime);
32603							propertyMixers[j].accumulate(accuIndex, weight);
32604						}
32605
32606				}
32607			}
32608		}
32609
32610		_updateWeight(time) {
32611			let weight = 0;
32612
32613			if (this.enabled) {
32614				weight = this.weight;
32615				const interpolant = this._weightInterpolant;
32616
32617				if (interpolant !== null) {
32618					const interpolantValue = interpolant.evaluate(time)[0];
32619					weight *= interpolantValue;
32620
32621					if (time > interpolant.parameterPositions[1]) {
32622						this.stopFading();
32623
32624						if (interpolantValue === 0) {
32625							// faded out, disable
32626							this.enabled = false;
32627						}
32628					}
32629				}
32630			}
32631
32632			this._effectiveWeight = weight;
32633			return weight;
32634		}
32635
32636		_updateTimeScale(time) {
32637			let timeScale = 0;
32638
32639			if (!this.paused) {
32640				timeScale = this.timeScale;
32641				const interpolant = this._timeScaleInterpolant;
32642
32643				if (interpolant !== null) {
32644					const interpolantValue = interpolant.evaluate(time)[0];
32645					timeScale *= interpolantValue;
32646
32647					if (time > interpolant.parameterPositions[1]) {
32648						this.stopWarping();
32649
32650						if (timeScale === 0) {
32651							// motion has halted, pause
32652							this.paused = true;
32653						} else {
32654							// warp done - apply final time scale
32655							this.timeScale = timeScale;
32656						}
32657					}
32658				}
32659			}
32660
32661			this._effectiveTimeScale = timeScale;
32662			return timeScale;
32663		}
32664
32665		_updateTime(deltaTime) {
32666			const duration = this._clip.duration;
32667			const loop = this.loop;
32668			let time = this.time + deltaTime;
32669			let loopCount = this._loopCount;
32670			const pingPong = loop === LoopPingPong;
32671
32672			if (deltaTime === 0) {
32673				if (loopCount === -1) return time;
32674				return pingPong && (loopCount & 1) === 1 ? duration - time : time;
32675			}
32676
32677			if (loop === LoopOnce) {
32678				if (loopCount === -1) {
32679					// just started
32680					this._loopCount = 0;
32681
32682					this._setEndings(true, true, false);
32683				}
32684
32685				handle_stop: {
32686					if (time >= duration) {
32687						time = duration;
32688					} else if (time < 0) {
32689						time = 0;
32690					} else {
32691						this.time = time;
32692						break handle_stop;
32693					}
32694
32695					if (this.clampWhenFinished) this.paused = true;else this.enabled = false;
32696					this.time = time;
32697
32698					this._mixer.dispatchEvent({
32699						type: 'finished',
32700						action: this,
32701						direction: deltaTime < 0 ? -1 : 1
32702					});
32703				}
32704			} else {
32705				// repetitive Repeat or PingPong
32706				if (loopCount === -1) {
32707					// just started
32708					if (deltaTime >= 0) {
32709						loopCount = 0;
32710
32711						this._setEndings(true, this.repetitions === 0, pingPong);
32712					} else {
32713						// when looping in reverse direction, the initial
32714						// transition through zero counts as a repetition,
32715						// so leave loopCount at -1
32716						this._setEndings(this.repetitions === 0, true, pingPong);
32717					}
32718				}
32719
32720				if (time >= duration || time < 0) {
32721					// wrap around
32722					const loopDelta = Math.floor(time / duration); // signed
32723
32724					time -= duration * loopDelta;
32725					loopCount += Math.abs(loopDelta);
32726					const pending = this.repetitions - loopCount;
32727
32728					if (pending <= 0) {
32729						// have to stop (switch state, clamp time, fire event)
32730						if (this.clampWhenFinished) this.paused = true;else this.enabled = false;
32731						time = deltaTime > 0 ? duration : 0;
32732						this.time = time;
32733
32734						this._mixer.dispatchEvent({
32735							type: 'finished',
32736							action: this,
32737							direction: deltaTime > 0 ? 1 : -1
32738						});
32739					} else {
32740						// keep running
32741						if (pending === 1) {
32742							// entering the last round
32743							const atStart = deltaTime < 0;
32744
32745							this._setEndings(atStart, !atStart, pingPong);
32746						} else {
32747							this._setEndings(false, false, pingPong);
32748						}
32749
32750						this._loopCount = loopCount;
32751						this.time = time;
32752
32753						this._mixer.dispatchEvent({
32754							type: 'loop',
32755							action: this,
32756							loopDelta: loopDelta
32757						});
32758					}
32759				} else {
32760					this.time = time;
32761				}
32762
32763				if (pingPong && (loopCount & 1) === 1) {
32764					// invert time for the "pong round"
32765					return duration - time;
32766				}
32767			}
32768
32769			return time;
32770		}
32771
32772		_setEndings(atStart, atEnd, pingPong) {
32773			const settings = this._interpolantSettings;
32774
32775			if (pingPong) {
32776				settings.endingStart = ZeroSlopeEnding;
32777				settings.endingEnd = ZeroSlopeEnding;
32778			} else {
32779				// assuming for LoopOnce atStart == atEnd == true
32780				if (atStart) {
32781					settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
32782				} else {
32783					settings.endingStart = WrapAroundEnding;
32784				}
32785
32786				if (atEnd) {
32787					settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
32788				} else {
32789					settings.endingEnd = WrapAroundEnding;
32790				}
32791			}
32792		}
32793
32794		_scheduleFading(duration, weightNow, weightThen) {
32795			const mixer = this._mixer,
32796						now = mixer.time;
32797			let interpolant = this._weightInterpolant;
32798
32799			if (interpolant === null) {
32800				interpolant = mixer._lendControlInterpolant();
32801				this._weightInterpolant = interpolant;
32802			}
32803
32804			const times = interpolant.parameterPositions,
32805						values = interpolant.sampleValues;
32806			times[0] = now;
32807			values[0] = weightNow;
32808			times[1] = now + duration;
32809			values[1] = weightThen;
32810			return this;
32811		}
32812
32813	}
32814
vendor: 4,399 bytes, lines 32815-32988
32815	class AnimationMixer extends EventDispatcher {
32816		constructor(root) {
32817			super();
32818			this._root = root;
32819
32820			this._initMemoryManager();
32821
32822			this._accuIndex = 0;
32823			this.time = 0;
32824			this.timeScale = 1.0;
32825		}
32826
32827		_bindAction(action, prototypeAction) {
32828			const root = action._localRoot || this._root,
32829						tracks = action._clip.tracks,
32830						nTracks = tracks.length,
32831						bindings = action._propertyBindings,
32832						interpolants = action._interpolants,
32833						rootUuid = root.uuid,
32834						bindingsByRoot = this._bindingsByRootAndName;
32835			let bindingsByName = bindingsByRoot[rootUuid];
32836
32837			if (bindingsByName === undefined) {
32838				bindingsByName = {};
32839				bindingsByRoot[rootUuid] = bindingsByName;
32840			}
32841
32842			for (let i = 0; i !== nTracks; ++i) {
32843				const track = tracks[i],
32844							trackName = track.name;
32845				let binding = bindingsByName[trackName];
32846
32847				if (binding !== undefined) {
32848					bindings[i] = binding;
32849				} else {
32850					binding = bindings[i];
32851
32852					if (binding !== undefined) {
32853						// existing binding, make sure the cache knows
32854						if (binding._cacheIndex === null) {
32855							++binding.referenceCount;
32856
32857							this._addInactiveBinding(binding, rootUuid, trackName);
32858						}
32859
32860						continue;
32861					}
32862
32863					const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath;
32864					binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize());
32865					++binding.referenceCount;
32866
32867					this._addInactiveBinding(binding, rootUuid, trackName);
32868
32869					bindings[i] = binding;
32870				}
32871
32872				interpolants[i].resultBuffer = binding.buffer;
32873			}
32874		}
32875
32876		_activateAction(action) {
32877			if (!this._isActiveAction(action)) {
32878				if (action._cacheIndex === null) {
32879					// this action has been forgotten by the cache, but the user
32880					// appears to be still using it -> rebind
32881					const rootUuid = (action._localRoot || this._root).uuid,
32882								clipUuid = action._clip.uuid,
32883								actionsForClip = this._actionsByClip[clipUuid];
32884
32885					this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]);
32886
32887					this._addInactiveAction(action, clipUuid, rootUuid);
32888				}
32889
32890				const bindings = action._propertyBindings; // increment reference counts / sort out state
32891
32892				for (let i = 0, n = bindings.length; i !== n; ++i) {
32893					const binding = bindings[i];
32894
32895					if (binding.useCount++ === 0) {
32896						this._lendBinding(binding);
32897
32898						binding.saveOriginalState();
32899					}
32900				}
32901
32902				this._lendAction(action);
32903			}
32904		}
32905
32906		_deactivateAction(action) {
32907			if (this._isActiveAction(action)) {
32908				const bindings = action._propertyBindings; // decrement reference counts / sort out state
32909
32910				for (let i = 0, n = bindings.length; i !== n; ++i) {
32911					const binding = bindings[i];
32912
32913					if (--binding.useCount === 0) {
32914						binding.restoreOriginalState();
32915
32916						this._takeBackBinding(binding);
32917					}
32918				}
32919
32920				this._takeBackAction(action);
32921			}
32922		} // Memory manager
32923
32924
32925		_initMemoryManager() {
32926			this._actions = []; // 'nActiveActions' followed by inactive ones
32927
32928			this._nActiveActions = 0;
32929			this._actionsByClip = {}; // inside:
32930			// {
32931			// 	knownActions: Array< AnimationAction > - used as prototypes
32932			// 	actionByRoot: AnimationAction - lookup
32933			// }
32934
32935			this._bindings = []; // 'nActiveBindings' followed by inactive ones
32936
32937			this._nActiveBindings = 0;
32938			this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
32939
32940			this._controlInterpolants = []; // same game as above
32941
32942			this._nActiveControlInterpolants = 0;
32943			const scope = this;
32944			this.stats = {
32945				actions: {
32946					get total() {
32947						return scope._actions.length;
32948					},
32949
32950					get inUse() {
32951						return scope._nActiveActions;
32952					}
32953
32954				},
32955				bindings: {
32956					get total() {
32957						return scope._bindings.length;
32958					},
32959
32960					get inUse() {
32961						return scope._nActiveBindings;
32962					}
32963
32964				},
32965				controlInterpolants: {
32966					get total() {
32967						return scope._controlInterpolants.length;
32968					},
32969
32970					get inUse() {
32971						return scope._nActiveControlInterpolants;
32972					}
32973
32974				}
32975			};
32976		} // Memory management for AnimationAction objects
32977
32978
32979		_isActiveAction(action) {
32980			const index = action._cacheIndex;
32981			return index !== null && index < this._nActiveActions;
32982		}
32983
32984		_addInactiveAction(action, clipUuid, rootUuid) {
32985			const actions = this._actions,
32986						actionsByClip = this._actionsByClip;
32987			let actionsForClip = actionsByClip[clipUuid];
32988
vendor: 6,548 bytes, lines 32989-33181
32989			if (actionsForClip === undefined) {
32990				actionsForClip = {
32991					knownActions: [action],
32992					actionByRoot: {}
32993				};
32994				action._byClipCacheIndex = 0;
32995				actionsByClip[clipUuid] = actionsForClip;
32996			} else {
32997				const knownActions = actionsForClip.knownActions;
32998				action._byClipCacheIndex = knownActions.length;
32999				knownActions.push(action);
33000			}
33001
33002			action._cacheIndex = actions.length;
33003			actions.push(action);
33004			actionsForClip.actionByRoot[rootUuid] = action;
33005		}
33006
33007		_removeInactiveAction(action) {
33008			const actions = this._actions,
33009						lastInactiveAction = actions[actions.length - 1],
33010						cacheIndex = action._cacheIndex;
33011			lastInactiveAction._cacheIndex = cacheIndex;
33012			actions[cacheIndex] = lastInactiveAction;
33013			actions.pop();
33014			action._cacheIndex = null;
33015			const clipUuid = action._clip.uuid,
33016						actionsByClip = this._actionsByClip,
33017						actionsForClip = actionsByClip[clipUuid],
33018						knownActionsForClip = actionsForClip.knownActions,
33019						lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1],
33020						byClipCacheIndex = action._byClipCacheIndex;
33021			lastKnownAction._byClipCacheIndex = byClipCacheIndex;
33022			knownActionsForClip[byClipCacheIndex] = lastKnownAction;
33023			knownActionsForClip.pop();
33024			action._byClipCacheIndex = null;
33025			const actionByRoot = actionsForClip.actionByRoot,
33026						rootUuid = (action._localRoot || this._root).uuid;
33027			delete actionByRoot[rootUuid];
33028
33029			if (knownActionsForClip.length === 0) {
33030				delete actionsByClip[clipUuid];
33031			}
33032
33033			this._removeInactiveBindingsForAction(action);
33034		}
33035
33036		_removeInactiveBindingsForAction(action) {
33037			const bindings = action._propertyBindings;
33038
33039			for (let i = 0, n = bindings.length; i !== n; ++i) {
33040				const binding = bindings[i];
33041
33042				if (--binding.referenceCount === 0) {
33043					this._removeInactiveBinding(binding);
33044				}
33045			}
33046		}
33047
33048		_lendAction(action) {
33049			// [ active actions |	inactive actions	]
33050			// [	active actions >| inactive actions ]
33051			//								 s				a
33052			//									<-swap->
33053			//								 a				s
33054			const actions = this._actions,
33055						prevIndex = action._cacheIndex,
33056						lastActiveIndex = this._nActiveActions++,
33057						firstInactiveAction = actions[lastActiveIndex];
33058			action._cacheIndex = lastActiveIndex;
33059			actions[lastActiveIndex] = action;
33060			firstInactiveAction._cacheIndex = prevIndex;
33061			actions[prevIndex] = firstInactiveAction;
33062		}
33063
33064		_takeBackAction(action) {
33065			// [	active actions	| inactive actions ]
33066			// [ active actions |< inactive actions	]
33067			//				a				s
33068			//				 <-swap->
33069			//				s				a
33070			const actions = this._actions,
33071						prevIndex = action._cacheIndex,
33072						firstInactiveIndex = --this._nActiveActions,
33073						lastActiveAction = actions[firstInactiveIndex];
33074			action._cacheIndex = firstInactiveIndex;
33075			actions[firstInactiveIndex] = action;
33076			lastActiveAction._cacheIndex = prevIndex;
33077			actions[prevIndex] = lastActiveAction;
33078		} // Memory management for PropertyMixer objects
33079
33080
33081		_addInactiveBinding(binding, rootUuid, trackName) {
33082			const bindingsByRoot = this._bindingsByRootAndName,
33083						bindings = this._bindings;
33084			let bindingByName = bindingsByRoot[rootUuid];
33085
33086			if (bindingByName === undefined) {
33087				bindingByName = {};
33088				bindingsByRoot[rootUuid] = bindingByName;
33089			}
33090
33091			bindingByName[trackName] = binding;
33092			binding._cacheIndex = bindings.length;
33093			bindings.push(binding);
33094		}
33095
33096		_removeInactiveBinding(binding) {
33097			const bindings = this._bindings,
33098						propBinding = binding.binding,
33099						rootUuid = propBinding.rootNode.uuid,
33100						trackName = propBinding.path,
33101						bindingsByRoot = this._bindingsByRootAndName,
33102						bindingByName = bindingsByRoot[rootUuid],
33103						lastInactiveBinding = bindings[bindings.length - 1],
33104						cacheIndex = binding._cacheIndex;
33105			lastInactiveBinding._cacheIndex = cacheIndex;
33106			bindings[cacheIndex] = lastInactiveBinding;
33107			bindings.pop();
33108			delete bindingByName[trackName];
33109
33110			if (Object.keys(bindingByName).length === 0) {
33111				delete bindingsByRoot[rootUuid];
33112			}
33113		}
33114
33115		_lendBinding(binding) {
33116			const bindings = this._bindings,
33117						prevIndex = binding._cacheIndex,
33118						lastActiveIndex = this._nActiveBindings++,
33119						firstInactiveBinding = bindings[lastActiveIndex];
33120			binding._cacheIndex = lastActiveIndex;
33121			bindings[lastActiveIndex] = binding;
33122			firstInactiveBinding._cacheIndex = prevIndex;
33123			bindings[prevIndex] = firstInactiveBinding;
33124		}
33125
33126		_takeBackBinding(binding) {
33127			const bindings = this._bindings,
33128						prevIndex = binding._cacheIndex,
33129						firstInactiveIndex = --this._nActiveBindings,
33130						lastActiveBinding = bindings[firstInactiveIndex];
33131			binding._cacheIndex = firstInactiveIndex;
33132			bindings[firstInactiveIndex] = binding;
33133			lastActiveBinding._cacheIndex = prevIndex;
33134			bindings[prevIndex] = lastActiveBinding;
33135		} // Memory management of Interpolants for weight and time scale
33136
33137
33138		_lendControlInterpolant() {
33139			const interpolants = this._controlInterpolants,
33140						lastActiveIndex = this._nActiveControlInterpolants++;
33141			let interpolant = interpolants[lastActiveIndex];
33142
33143			if (interpolant === undefined) {
33144				interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, this._controlInterpolantsResultBuffer);
33145				interpolant.__cacheIndex = lastActiveIndex;
33146				interpolants[lastActiveIndex] = interpolant;
33147			}
33148
33149			return interpolant;
33150		}
33151
33152		_takeBackControlInterpolant(interpolant) {
33153			const interpolants = this._controlInterpolants,
33154						prevIndex = interpolant.__cacheIndex,
33155						firstInactiveIndex = --this._nActiveControlInterpolants,
33156						lastActiveInterpolant = interpolants[firstInactiveIndex];
33157			interpolant.__cacheIndex = firstInactiveIndex;
33158			interpolants[firstInactiveIndex] = interpolant;
33159			lastActiveInterpolant.__cacheIndex = prevIndex;
33160			interpolants[prevIndex] = lastActiveInterpolant;
33161		} // return an action for a clip optionally using a custom root target
33162		// object (this method allocates a lot of dynamic memory in case a
33163		// previously unknown clip/root combination is specified)
33164
33165
33166		clipAction(clip, optionalRoot, blendMode) {
33167			const root = optionalRoot || this._root,
33168						rootUuid = root.uuid;
33169			let clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip;
33170			const clipUuid = clipObject !== null ? clipObject.uuid : clip;
33171			const actionsForClip = this._actionsByClip[clipUuid];
33172			let prototypeAction = null;
33173
33174			if (blendMode === undefined) {
33175				if (clipObject !== null) {
33176					blendMode = clipObject.blendMode;
33177				} else {
33178					blendMode = NormalAnimationBlendMode;
33179				}
33180			}
33181
vendor: 4,717 bytes, lines 33182-33343
33182			if (actionsForClip !== undefined) {
33183				const existingAction = actionsForClip.actionByRoot[rootUuid];
33184
33185				if (existingAction !== undefined && existingAction.blendMode === blendMode) {
33186					return existingAction;
33187				} // we know the clip, so we don't have to parse all
33188				// the bindings again but can just copy
33189
33190
33191				prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action
33192
33193				if (clipObject === null) clipObject = prototypeAction._clip;
33194			} // clip must be known when specified via string
33195
33196
33197			if (clipObject === null) return null; // allocate all resources required to run it
33198
33199			const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode);
33200
33201			this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager
33202
33203
33204			this._addInactiveAction(newAction, clipUuid, rootUuid);
33205
33206			return newAction;
33207		} // get an existing action
33208
33209
33210		existingAction(clip, optionalRoot) {
33211			const root = optionalRoot || this._root,
33212						rootUuid = root.uuid,
33213						clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip,
33214						clipUuid = clipObject ? clipObject.uuid : clip,
33215						actionsForClip = this._actionsByClip[clipUuid];
33216
33217			if (actionsForClip !== undefined) {
33218				return actionsForClip.actionByRoot[rootUuid] || null;
33219			}
33220
33221			return null;
33222		} // deactivates all previously scheduled actions
33223
33224
33225		stopAllAction() {
33226			const actions = this._actions,
33227						nActions = this._nActiveActions;
33228
33229			for (let i = nActions - 1; i >= 0; --i) {
33230				actions[i].stop();
33231			}
33232
33233			return this;
33234		} // advance the time and update apply the animation
33235
33236
33237		update(deltaTime) {
33238			deltaTime *= this.timeScale;
33239			const actions = this._actions,
33240						nActions = this._nActiveActions,
33241						time = this.time += deltaTime,
33242						timeDirection = Math.sign(deltaTime),
33243						accuIndex = this._accuIndex ^= 1; // run active actions
33244
33245			for (let i = 0; i !== nActions; ++i) {
33246				const action = actions[i];
33247
33248				action._update(time, deltaTime, timeDirection, accuIndex);
33249			} // update scene graph
33250
33251
33252			const bindings = this._bindings,
33253						nBindings = this._nActiveBindings;
33254
33255			for (let i = 0; i !== nBindings; ++i) {
33256				bindings[i].apply(accuIndex);
33257			}
33258
33259			return this;
33260		} // Allows you to seek to a specific time in an animation.
33261
33262
33263		setTime(timeInSeconds) {
33264			this.time = 0; // Zero out time attribute for AnimationMixer object;
33265
33266			for (let i = 0; i < this._actions.length; i++) {
33267				this._actions[i].time = 0; // Zero out time attribute for all associated AnimationAction objects.
33268			}
33269
33270			return this.update(timeInSeconds); // Update used to set exact time. Returns "this" AnimationMixer object.
33271		} // return this mixer's root target object
33272
33273
33274		getRoot() {
33275			return this._root;
33276		} // free all resources specific to a particular clip
33277
33278
33279		uncacheClip(clip) {
33280			const actions = this._actions,
33281						clipUuid = clip.uuid,
33282						actionsByClip = this._actionsByClip,
33283						actionsForClip = actionsByClip[clipUuid];
33284
33285			if (actionsForClip !== undefined) {
33286				// note: just calling _removeInactiveAction would mess up the
33287				// iteration state and also require updating the state we can
33288				// just throw away
33289				const actionsToRemove = actionsForClip.knownActions;
33290
33291				for (let i = 0, n = actionsToRemove.length; i !== n; ++i) {
33292					const action = actionsToRemove[i];
33293
33294					this._deactivateAction(action);
33295
33296					const cacheIndex = action._cacheIndex,
33297								lastInactiveAction = actions[actions.length - 1];
33298					action._cacheIndex = null;
33299					action._byClipCacheIndex = null;
33300					lastInactiveAction._cacheIndex = cacheIndex;
33301					actions[cacheIndex] = lastInactiveAction;
33302					actions.pop();
33303
33304					this._removeInactiveBindingsForAction(action);
33305				}
33306
33307				delete actionsByClip[clipUuid];
33308			}
33309		} // free all resources specific to a particular root target object
33310
33311
33312		uncacheRoot(root) {
33313			const rootUuid = root.uuid,
33314						actionsByClip = this._actionsByClip;
33315
33316			for (const clipUuid in actionsByClip) {
33317				const actionByRoot = actionsByClip[clipUuid].actionByRoot,
33318							action = actionByRoot[rootUuid];
33319
33320				if (action !== undefined) {
33321					this._deactivateAction(action);
33322
33323					this._removeInactiveAction(action);
33324				}
33325			}
33326
33327			const bindingsByRoot = this._bindingsByRootAndName,
33328						bindingByName = bindingsByRoot[rootUuid];
33329
33330			if (bindingByName !== undefined) {
33331				for (const trackName in bindingByName) {
33332					const binding = bindingByName[trackName];
33333					binding.restoreOriginalState();
33334
33335					this._removeInactiveBinding(binding);
33336				}
33337			}
33338		} // remove a targeted clip from the cache
33339
33340
33341		uncacheAction(clip, optionalRoot) {
33342			const action = this.existingAction(clip, optionalRoot);
33343
vendor: 4,315 bytes, lines 33344-33523
33344			if (action !== null) {
33345				this._deactivateAction(action);
33346
33347				this._removeInactiveAction(action);
33348			}
33349		}
33350
33351	}
33352
33353	AnimationMixer.prototype._controlInterpolantsResultBuffer = new Float32Array(1);
33354
33355	class Uniform {
33356		constructor(value) {
33357			if (typeof value === 'string') {
33358				console.warn('THREE.Uniform: Type parameter is no longer needed.');
33359				value = arguments[1];
33360			}
33361
33362			this.value = value;
33363		}
33364
33365		clone() {
33366			return new Uniform(this.value.clone === undefined ? this.value : this.value.clone());
33367		}
33368
33369	}
33370
33371	class InstancedInterleavedBuffer extends InterleavedBuffer {
33372		constructor(array, stride, meshPerAttribute = 1) {
33373			super(array, stride);
33374			this.meshPerAttribute = meshPerAttribute;
33375		}
33376
33377		copy(source) {
33378			super.copy(source);
33379			this.meshPerAttribute = source.meshPerAttribute;
33380			return this;
33381		}
33382
33383		clone(data) {
33384			const ib = super.clone(data);
33385			ib.meshPerAttribute = this.meshPerAttribute;
33386			return ib;
33387		}
33388
33389		toJSON(data) {
33390			const json = super.toJSON(data);
33391			json.isInstancedInterleavedBuffer = true;
33392			json.meshPerAttribute = this.meshPerAttribute;
33393			return json;
33394		}
33395
33396	}
33397
33398	InstancedInterleavedBuffer.prototype.isInstancedInterleavedBuffer = true;
33399
33400	class GLBufferAttribute {
33401		constructor(buffer, type, itemSize, elementSize, count) {
33402			this.buffer = buffer;
33403			this.type = type;
33404			this.itemSize = itemSize;
33405			this.elementSize = elementSize;
33406			this.count = count;
33407			this.version = 0;
33408		}
33409
33410		set needsUpdate(value) {
33411			if (value === true) this.version++;
33412		}
33413
33414		setBuffer(buffer) {
33415			this.buffer = buffer;
33416			return this;
33417		}
33418
33419		setType(type, elementSize) {
33420			this.type = type;
33421			this.elementSize = elementSize;
33422			return this;
33423		}
33424
33425		setItemSize(itemSize) {
33426			this.itemSize = itemSize;
33427			return this;
33428		}
33429
33430		setCount(count) {
33431			this.count = count;
33432			return this;
33433		}
33434
33435	}
33436
33437	GLBufferAttribute.prototype.isGLBufferAttribute = true;
33438
33439	class Raycaster {
33440		constructor(origin, direction, near = 0, far = Infinity) {
33441			this.ray = new Ray(origin, direction); // direction is assumed to be normalized (for accurate distance calculations)
33442
33443			this.near = near;
33444			this.far = far;
33445			this.camera = null;
33446			this.layers = new Layers();
33447			this.params = {
33448				Mesh: {},
33449				Line: {
33450					threshold: 1
33451				},
33452				LOD: {},
33453				Points: {
33454					threshold: 1
33455				},
33456				Sprite: {}
33457			};
33458		}
33459
33460		set(origin, direction) {
33461			// direction is assumed to be normalized (for accurate distance calculations)
33462			this.ray.set(origin, direction);
33463		}
33464
33465		setFromCamera(coords, camera) {
33466			if (camera && camera.isPerspectiveCamera) {
33467				this.ray.origin.setFromMatrixPosition(camera.matrixWorld);
33468				this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize();
33469				this.camera = camera;
33470			} else if (camera && camera.isOrthographicCamera) {
33471				this.ray.origin.set(coords.x, coords.y, (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera); // set origin in plane of camera
33472
33473				this.ray.direction.set(0, 0, -1).transformDirection(camera.matrixWorld);
33474				this.camera = camera;
33475			} else {
33476				console.error('THREE.Raycaster: Unsupported camera type: ' + camera.type);
33477			}
33478		}
33479
33480		intersectObject(object, recursive = true, intersects = []) {
33481			intersectObject(object, this, intersects, recursive);
33482			intersects.sort(ascSort);
33483			return intersects;
33484		}
33485
33486		intersectObjects(objects, recursive = true, intersects = []) {
33487			for (let i = 0, l = objects.length; i < l; i++) {
33488				intersectObject(objects[i], this, intersects, recursive);
33489			}
33490
33491			intersects.sort(ascSort);
33492			return intersects;
33493		}
33494
33495	}
33496
33497	function ascSort(a, b) {
33498		return a.distance - b.distance;
33499	}
33500
33501	function intersectObject(object, raycaster, intersects, recursive) {
33502		if (object.layers.test(raycaster.layers)) {
33503			object.raycast(raycaster, intersects);
33504		}
33505
33506		if (recursive === true) {
33507			const children = object.children;
33508
33509			for (let i = 0, l = children.length; i < l; i++) {
33510				intersectObject(children[i], raycaster, intersects, true);
33511			}
33512		}
33513	}
33514
33515	/**
33516	 * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system
33517	 *
33518	 * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up.
33519	 * The azimuthal angle (theta) is measured from the positive z-axis.
33520	 */
33521
33522	class Spherical {
33523		constructor(radius = 1, phi = 0, theta = 0) {
vendor: 5,067 bytes, lines 33524-33760
33524			this.radius = radius;
33525			this.phi = phi; // polar angle
33526
33527			this.theta = theta; // azimuthal angle
33528
33529			return this;
33530		}
33531
33532		set(radius, phi, theta) {
33533			this.radius = radius;
33534			this.phi = phi;
33535			this.theta = theta;
33536			return this;
33537		}
33538
33539		copy(other) {
33540			this.radius = other.radius;
33541			this.phi = other.phi;
33542			this.theta = other.theta;
33543			return this;
33544		} // restrict phi to be betwee EPS and PI-EPS
33545
33546
33547		makeSafe() {
33548			const EPS = 0.000001;
33549			this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi));
33550			return this;
33551		}
33552
33553		setFromVector3(v) {
33554			return this.setFromCartesianCoords(v.x, v.y, v.z);
33555		}
33556
33557		setFromCartesianCoords(x, y, z) {
33558			this.radius = Math.sqrt(x * x + y * y + z * z);
33559
33560			if (this.radius === 0) {
33561				this.theta = 0;
33562				this.phi = 0;
33563			} else {
33564				this.theta = Math.atan2(x, z);
33565				this.phi = Math.acos(clamp(y / this.radius, -1, 1));
33566			}
33567
33568			return this;
33569		}
33570
33571		clone() {
33572			return new this.constructor().copy(this);
33573		}
33574
33575	}
33576
33577	/**
33578	 * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system
33579	 */
33580	class Cylindrical {
33581		constructor(radius = 1, theta = 0, y = 0) {
33582			this.radius = radius; // distance from the origin to a point in the x-z plane
33583
33584			this.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis
33585
33586			this.y = y; // height above the x-z plane
33587
33588			return this;
33589		}
33590
33591		set(radius, theta, y) {
33592			this.radius = radius;
33593			this.theta = theta;
33594			this.y = y;
33595			return this;
33596		}
33597
33598		copy(other) {
33599			this.radius = other.radius;
33600			this.theta = other.theta;
33601			this.y = other.y;
33602			return this;
33603		}
33604
33605		setFromVector3(v) {
33606			return this.setFromCartesianCoords(v.x, v.y, v.z);
33607		}
33608
33609		setFromCartesianCoords(x, y, z) {
33610			this.radius = Math.sqrt(x * x + z * z);
33611			this.theta = Math.atan2(x, z);
33612			this.y = y;
33613			return this;
33614		}
33615
33616		clone() {
33617			return new this.constructor().copy(this);
33618		}
33619
33620	}
33621
33622	const _vector$4 = /*@__PURE__*/new Vector2();
33623
33624	class Box2 {
33625		constructor(min = new Vector2(+Infinity, +Infinity), max = new Vector2(-Infinity, -Infinity)) {
33626			this.min = min;
33627			this.max = max;
33628		}
33629
33630		set(min, max) {
33631			this.min.copy(min);
33632			this.max.copy(max);
33633			return this;
33634		}
33635
33636		setFromPoints(points) {
33637			this.makeEmpty();
33638
33639			for (let i = 0, il = points.length; i < il; i++) {
33640				this.expandByPoint(points[i]);
33641			}
33642
33643			return this;
33644		}
33645
33646		setFromCenterAndSize(center, size) {
33647			const halfSize = _vector$4.copy(size).multiplyScalar(0.5);
33648
33649			this.min.copy(center).sub(halfSize);
33650			this.max.copy(center).add(halfSize);
33651			return this;
33652		}
33653
33654		clone() {
33655			return new this.constructor().copy(this);
33656		}
33657
33658		copy(box) {
33659			this.min.copy(box.min);
33660			this.max.copy(box.max);
33661			return this;
33662		}
33663
33664		makeEmpty() {
33665			this.min.x = this.min.y = +Infinity;
33666			this.max.x = this.max.y = -Infinity;
33667			return this;
33668		}
33669
33670		isEmpty() {
33671			// this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
33672			return this.max.x < this.min.x || this.max.y < this.min.y;
33673		}
33674
33675		getCenter(target) {
33676			return this.isEmpty() ? target.set(0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);
33677		}
33678
33679		getSize(target) {
33680			return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min);
33681		}
33682
33683		expandByPoint(point) {
33684			this.min.min(point);
33685			this.max.max(point);
33686			return this;
33687		}
33688
33689		expandByVector(vector) {
33690			this.min.sub(vector);
33691			this.max.add(vector);
33692			return this;
33693		}
33694
33695		expandByScalar(scalar) {
33696			this.min.addScalar(-scalar);
33697			this.max.addScalar(scalar);
33698			return this;
33699		}
33700
33701		containsPoint(point) {
33702			return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y ? false : true;
33703		}
33704
33705		containsBox(box) {
33706			return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y;
33707		}
33708
33709		getParameter(point, target) {
33710			// This can potentially have a divide by zero if the box
33711			// has a size dimension of 0.
33712			return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y));
33713		}
33714
33715		intersectsBox(box) {
33716			// using 4 splitting planes to rule out intersections
33717			return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
33718		}
33719
33720		clampPoint(point, target) {
33721			return target.copy(point).clamp(this.min, this.max);
33722		}
33723
33724		distanceToPoint(point) {
33725			const clampedPoint = _vector$4.copy(point).clamp(this.min, this.max);
33726
33727			return clampedPoint.sub(point).length();
33728		}
33729
33730		intersect(box) {
33731			this.min.max(box.min);
33732			this.max.min(box.max);
33733			return this;
33734		}
33735
33736		union(box) {
33737			this.min.min(box.min);
33738			this.max.max(box.max);
33739			return this;
33740		}
33741
33742		translate(offset) {
33743			this.min.add(offset);
33744			this.max.add(offset);
33745			return this;
33746		}
33747
33748		equals(box) {
33749			return box.min.equals(this.min) && box.max.equals(this.max);
33750		}
33751
33752	}
33753
33754	Box2.prototype.isBox2 = true;
33755
33756	const _startP = /*@__PURE__*/new Vector3();
33757
33758	const _startEnd = /*@__PURE__*/new Vector3();
33759
33760	class Line3 {
vendor: 15,418 bytes, lines 33761-34329
33761		constructor(start = new Vector3(), end = new Vector3()) {
33762			this.start = start;
33763			this.end = end;
33764		}
33765
33766		set(start, end) {
33767			this.start.copy(start);
33768			this.end.copy(end);
33769			return this;
33770		}
33771
33772		copy(line) {
33773			this.start.copy(line.start);
33774			this.end.copy(line.end);
33775			return this;
33776		}
33777
33778		getCenter(target) {
33779			return target.addVectors(this.start, this.end).multiplyScalar(0.5);
33780		}
33781
33782		delta(target) {
33783			return target.subVectors(this.end, this.start);
33784		}
33785
33786		distanceSq() {
33787			return this.start.distanceToSquared(this.end);
33788		}
33789
33790		distance() {
33791			return this.start.distanceTo(this.end);
33792		}
33793
33794		at(t, target) {
33795			return this.delta(target).multiplyScalar(t).add(this.start);
33796		}
33797
33798		closestPointToPointParameter(point, clampToLine) {
33799			_startP.subVectors(point, this.start);
33800
33801			_startEnd.subVectors(this.end, this.start);
33802
33803			const startEnd2 = _startEnd.dot(_startEnd);
33804
33805			const startEnd_startP = _startEnd.dot(_startP);
33806
33807			let t = startEnd_startP / startEnd2;
33808
33809			if (clampToLine) {
33810				t = clamp(t, 0, 1);
33811			}
33812
33813			return t;
33814		}
33815
33816		closestPointToPoint(point, clampToLine, target) {
33817			const t = this.closestPointToPointParameter(point, clampToLine);
33818			return this.delta(target).multiplyScalar(t).add(this.start);
33819		}
33820
33821		applyMatrix4(matrix) {
33822			this.start.applyMatrix4(matrix);
33823			this.end.applyMatrix4(matrix);
33824			return this;
33825		}
33826
33827		equals(line) {
33828			return line.start.equals(this.start) && line.end.equals(this.end);
33829		}
33830
33831		clone() {
33832			return new this.constructor().copy(this);
33833		}
33834
33835	}
33836
33837	const _vector$3 = /*@__PURE__*/new Vector3();
33838
33839	class SpotLightHelper extends Object3D {
33840		constructor(light, color) {
33841			super();
33842			this.light = light;
33843			this.light.updateMatrixWorld();
33844			this.matrix = light.matrixWorld;
33845			this.matrixAutoUpdate = false;
33846			this.color = color;
33847			const geometry = new BufferGeometry();
33848			const positions = [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 1];
33849
33850			for (let i = 0, j = 1, l = 32; i < l; i++, j++) {
33851				const p1 = i / l * Math.PI * 2;
33852				const p2 = j / l * Math.PI * 2;
33853				positions.push(Math.cos(p1), Math.sin(p1), 1, Math.cos(p2), Math.sin(p2), 1);
33854			}
33855
33856			geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
33857			const material = new LineBasicMaterial({
33858				fog: false,
33859				toneMapped: false
33860			});
33861			this.cone = new LineSegments(geometry, material);
33862			this.add(this.cone);
33863			this.update();
33864		}
33865
33866		dispose() {
33867			this.cone.geometry.dispose();
33868			this.cone.material.dispose();
33869		}
33870
33871		update() {
33872			this.light.updateMatrixWorld();
33873			const coneLength = this.light.distance ? this.light.distance : 1000;
33874			const coneWidth = coneLength * Math.tan(this.light.angle);
33875			this.cone.scale.set(coneWidth, coneWidth, coneLength);
33876
33877			_vector$3.setFromMatrixPosition(this.light.target.matrixWorld);
33878
33879			this.cone.lookAt(_vector$3);
33880
33881			if (this.color !== undefined) {
33882				this.cone.material.color.set(this.color);
33883			} else {
33884				this.cone.material.color.copy(this.light.color);
33885			}
33886		}
33887
33888	}
33889
33890	const _vector$2 = /*@__PURE__*/new Vector3();
33891
33892	const _boneMatrix = /*@__PURE__*/new Matrix4();
33893
33894	const _matrixWorldInv = /*@__PURE__*/new Matrix4();
33895
33896	class SkeletonHelper extends LineSegments {
33897		constructor(object) {
33898			const bones = getBoneList(object);
33899			const geometry = new BufferGeometry();
33900			const vertices = [];
33901			const colors = [];
33902			const color1 = new Color(0, 0, 1);
33903			const color2 = new Color(0, 1, 0);
33904
33905			for (let i = 0; i < bones.length; i++) {
33906				const bone = bones[i];
33907
33908				if (bone.parent && bone.parent.isBone) {
33909					vertices.push(0, 0, 0);
33910					vertices.push(0, 0, 0);
33911					colors.push(color1.r, color1.g, color1.b);
33912					colors.push(color2.r, color2.g, color2.b);
33913				}
33914			}
33915
33916			geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
33917			geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
33918			const material = new LineBasicMaterial({
33919				vertexColors: true,
33920				depthTest: false,
33921				depthWrite: false,
33922				toneMapped: false,
33923				transparent: true
33924			});
33925			super(geometry, material);
33926			this.type = 'SkeletonHelper';
33927			this.isSkeletonHelper = true;
33928			this.root = object;
33929			this.bones = bones;
33930			this.matrix = object.matrixWorld;
33931			this.matrixAutoUpdate = false;
33932		}
33933
33934		updateMatrixWorld(force) {
33935			const bones = this.bones;
33936			const geometry = this.geometry;
33937			const position = geometry.getAttribute('position');
33938
33939			_matrixWorldInv.copy(this.root.matrixWorld).invert();
33940
33941			for (let i = 0, j = 0; i < bones.length; i++) {
33942				const bone = bones[i];
33943
33944				if (bone.parent && bone.parent.isBone) {
33945					_boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld);
33946
33947					_vector$2.setFromMatrixPosition(_boneMatrix);
33948
33949					position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z);
33950
33951					_boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld);
33952
33953					_vector$2.setFromMatrixPosition(_boneMatrix);
33954
33955					position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z);
33956					j += 2;
33957				}
33958			}
33959
33960			geometry.getAttribute('position').needsUpdate = true;
33961			super.updateMatrixWorld(force);
33962		}
33963
33964	}
33965
33966	function getBoneList(object) {
33967		const boneList = [];
33968
33969		if (object && object.isBone) {
33970			boneList.push(object);
33971		}
33972
33973		for (let i = 0; i < object.children.length; i++) {
33974			boneList.push.apply(boneList, getBoneList(object.children[i]));
33975		}
33976
33977		return boneList;
33978	}
33979
33980	class PointLightHelper extends Mesh {
33981		constructor(light, sphereSize, color) {
33982			const geometry = new SphereGeometry(sphereSize, 4, 2);
33983			const material = new MeshBasicMaterial({
33984				wireframe: true,
33985				fog: false,
33986				toneMapped: false
33987			});
33988			super(geometry, material);
33989			this.light = light;
33990			this.light.updateMatrixWorld();
33991			this.color = color;
33992			this.type = 'PointLightHelper';
33993			this.matrix = this.light.matrixWorld;
33994			this.matrixAutoUpdate = false;
33995			this.update();
33996			/*
33997			// TODO: delete this comment?
33998			const distanceGeometry = new THREE.IcosahedronBufferGeometry( 1, 2 );
33999			const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );
34000			this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
34001			this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );
34002			const d = light.distance;
34003			if ( d === 0.0 ) {
34004				this.lightDistance.visible = false;
34005			} else {
34006				this.lightDistance.scale.set( d, d, d );
34007			}
34008			this.add( this.lightDistance );
34009			*/
34010		}
34011
34012		dispose() {
34013			this.geometry.dispose();
34014			this.material.dispose();
34015		}
34016
34017		update() {
34018			if (this.color !== undefined) {
34019				this.material.color.set(this.color);
34020			} else {
34021				this.material.color.copy(this.light.color);
34022			}
34023			/*
34024			const d = this.light.distance;
34025				if ( d === 0.0 ) {
34026					this.lightDistance.visible = false;
34027				} else {
34028					this.lightDistance.visible = true;
34029				this.lightDistance.scale.set( d, d, d );
34030				}
34031			*/
34032
34033		}
34034
34035	}
34036
34037	const _vector$1 = /*@__PURE__*/new Vector3();
34038
34039	const _color1 = /*@__PURE__*/new Color();
34040
34041	const _color2 = /*@__PURE__*/new Color();
34042
34043	class HemisphereLightHelper extends Object3D {
34044		constructor(light, size, color) {
34045			super();
34046			this.light = light;
34047			this.light.updateMatrixWorld();
34048			this.matrix = light.matrixWorld;
34049			this.matrixAutoUpdate = false;
34050			this.color = color;
34051			const geometry = new OctahedronGeometry(size);
34052			geometry.rotateY(Math.PI * 0.5);
34053			this.material = new MeshBasicMaterial({
34054				wireframe: true,
34055				fog: false,
34056				toneMapped: false
34057			});
34058			if (this.color === undefined) this.material.vertexColors = true;
34059			const position = geometry.getAttribute('position');
34060			const colors = new Float32Array(position.count * 3);
34061			geometry.setAttribute('color', new BufferAttribute(colors, 3));
34062			this.add(new Mesh(geometry, this.material));
34063			this.update();
34064		}
34065
34066		dispose() {
34067			this.children[0].geometry.dispose();
34068			this.children[0].material.dispose();
34069		}
34070
34071		update() {
34072			const mesh = this.children[0];
34073
34074			if (this.color !== undefined) {
34075				this.material.color.set(this.color);
34076			} else {
34077				const colors = mesh.geometry.getAttribute('color');
34078
34079				_color1.copy(this.light.color);
34080
34081				_color2.copy(this.light.groundColor);
34082
34083				for (let i = 0, l = colors.count; i < l; i++) {
34084					const color = i < l / 2 ? _color1 : _color2;
34085					colors.setXYZ(i, color.r, color.g, color.b);
34086				}
34087
34088				colors.needsUpdate = true;
34089			}
34090
34091			mesh.lookAt(_vector$1.setFromMatrixPosition(this.light.matrixWorld).negate());
34092		}
34093
34094	}
34095
34096	class GridHelper extends LineSegments {
34097		constructor(size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888) {
34098			color1 = new Color(color1);
34099			color2 = new Color(color2);
34100			const center = divisions / 2;
34101			const step = size / divisions;
34102			const halfSize = size / 2;
34103			const vertices = [],
34104						colors = [];
34105
34106			for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) {
34107				vertices.push(-halfSize, 0, k, halfSize, 0, k);
34108				vertices.push(k, 0, -halfSize, k, 0, halfSize);
34109				const color = i === center ? color1 : color2;
34110				color.toArray(colors, j);
34111				j += 3;
34112				color.toArray(colors, j);
34113				j += 3;
34114				color.toArray(colors, j);
34115				j += 3;
34116				color.toArray(colors, j);
34117				j += 3;
34118			}
34119
34120			const geometry = new BufferGeometry();
34121			geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
34122			geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
34123			const material = new LineBasicMaterial({
34124				vertexColors: true,
34125				toneMapped: false
34126			});
34127			super(geometry, material);
34128			this.type = 'GridHelper';
34129		}
34130
34131	}
34132
34133	class PolarGridHelper extends LineSegments {
34134		constructor(radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) {
34135			color1 = new Color(color1);
34136			color2 = new Color(color2);
34137			const vertices = [];
34138			const colors = []; // create the radials
34139
34140			for (let i = 0; i <= radials; i++) {
34141				const v = i / radials * (Math.PI * 2);
34142				const x = Math.sin(v) * radius;
34143				const z = Math.cos(v) * radius;
34144				vertices.push(0, 0, 0);
34145				vertices.push(x, 0, z);
34146				const color = i & 1 ? color1 : color2;
34147				colors.push(color.r, color.g, color.b);
34148				colors.push(color.r, color.g, color.b);
34149			} // create the circles
34150
34151
34152			for (let i = 0; i <= circles; i++) {
34153				const color = i & 1 ? color1 : color2;
34154				const r = radius - radius / circles * i;
34155
34156				for (let j = 0; j < divisions; j++) {
34157					// first vertex
34158					let v = j / divisions * (Math.PI * 2);
34159					let x = Math.sin(v) * r;
34160					let z = Math.cos(v) * r;
34161					vertices.push(x, 0, z);
34162					colors.push(color.r, color.g, color.b); // second vertex
34163
34164					v = (j + 1) / divisions * (Math.PI * 2);
34165					x = Math.sin(v) * r;
34166					z = Math.cos(v) * r;
34167					vertices.push(x, 0, z);
34168					colors.push(color.r, color.g, color.b);
34169				}
34170			}
34171
34172			const geometry = new BufferGeometry();
34173			geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
34174			geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
34175			const material = new LineBasicMaterial({
34176				vertexColors: true,
34177				toneMapped: false
34178			});
34179			super(geometry, material);
34180			this.type = 'PolarGridHelper';
34181		}
34182
34183	}
34184
34185	const _v1 = /*@__PURE__*/new Vector3();
34186
34187	const _v2 = /*@__PURE__*/new Vector3();
34188
34189	const _v3 = /*@__PURE__*/new Vector3();
34190
34191	class DirectionalLightHelper extends Object3D {
34192		constructor(light, size, color) {
34193			super();
34194			this.light = light;
34195			this.light.updateMatrixWorld();
34196			this.matrix = light.matrixWorld;
34197			this.matrixAutoUpdate = false;
34198			this.color = color;
34199			if (size === undefined) size = 1;
34200			let geometry = new BufferGeometry();
34201			geometry.setAttribute('position', new Float32BufferAttribute([-size, size, 0, size, size, 0, size, -size, 0, -size, -size, 0, -size, size, 0], 3));
34202			const material = new LineBasicMaterial({
34203				fog: false,
34204				toneMapped: false
34205			});
34206			this.lightPlane = new Line(geometry, material);
34207			this.add(this.lightPlane);
34208			geometry = new BufferGeometry();
34209			geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 0, 1], 3));
34210			this.targetLine = new Line(geometry, material);
34211			this.add(this.targetLine);
34212			this.update();
34213		}
34214
34215		dispose() {
34216			this.lightPlane.geometry.dispose();
34217			this.lightPlane.material.dispose();
34218			this.targetLine.geometry.dispose();
34219			this.targetLine.material.dispose();
34220		}
34221
34222		update() {
34223			_v1.setFromMatrixPosition(this.light.matrixWorld);
34224
34225			_v2.setFromMatrixPosition(this.light.target.matrixWorld);
34226
34227			_v3.subVectors(_v2, _v1);
34228
34229			this.lightPlane.lookAt(_v2);
34230
34231			if (this.color !== undefined) {
34232				this.lightPlane.material.color.set(this.color);
34233				this.targetLine.material.color.set(this.color);
34234			} else {
34235				this.lightPlane.material.color.copy(this.light.color);
34236				this.targetLine.material.color.copy(this.light.color);
34237			}
34238
34239			this.targetLine.lookAt(_v2);
34240			this.targetLine.scale.z = _v3.length();
34241		}
34242
34243	}
34244
34245	const _vector = /*@__PURE__*/new Vector3();
34246
34247	const _camera = /*@__PURE__*/new Camera();
34248	/**
34249	 *	- shows frustum, line of sight and up of the camera
34250	 *	- suitable for fast updates
34251	 * 	- based on frustum visualization in lightgl.js shadowmap example
34252	 *		https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html
34253	 */
34254
34255
34256	class CameraHelper extends LineSegments {
34257		constructor(camera) {
34258			const geometry = new BufferGeometry();
34259			const material = new LineBasicMaterial({
34260				color: 0xffffff,
34261				vertexColors: true,
34262				toneMapped: false
34263			});
34264			const vertices = [];
34265			const colors = [];
34266			const pointMap = {}; // colors
34267
34268			const colorFrustum = new Color(0xffaa00);
34269			const colorCone = new Color(0xff0000);
34270			const colorUp = new Color(0x00aaff);
34271			const colorTarget = new Color(0xffffff);
34272			const colorCross = new Color(0x333333); // near
34273
34274			addLine('n1', 'n2', colorFrustum);
34275			addLine('n2', 'n4', colorFrustum);
34276			addLine('n4', 'n3', colorFrustum);
34277			addLine('n3', 'n1', colorFrustum); // far
34278
34279			addLine('f1', 'f2', colorFrustum);
34280			addLine('f2', 'f4', colorFrustum);
34281			addLine('f4', 'f3', colorFrustum);
34282			addLine('f3', 'f1', colorFrustum); // sides
34283
34284			addLine('n1', 'f1', colorFrustum);
34285			addLine('n2', 'f2', colorFrustum);
34286			addLine('n3', 'f3', colorFrustum);
34287			addLine('n4', 'f4', colorFrustum); // cone
34288
34289			addLine('p', 'n1', colorCone);
34290			addLine('p', 'n2', colorCone);
34291			addLine('p', 'n3', colorCone);
34292			addLine('p', 'n4', colorCone); // up
34293
34294			addLine('u1', 'u2', colorUp);
34295			addLine('u2', 'u3', colorUp);
34296			addLine('u3', 'u1', colorUp); // target
34297
34298			addLine('c', 't', colorTarget);
34299			addLine('p', 'c', colorCross); // cross
34300
34301			addLine('cn1', 'cn2', colorCross);
34302			addLine('cn3', 'cn4', colorCross);
34303			addLine('cf1', 'cf2', colorCross);
34304			addLine('cf3', 'cf4', colorCross);
34305
34306			function addLine(a, b, color) {
34307				addPoint(a, color);
34308				addPoint(b, color);
34309			}
34310
34311			function addPoint(id, color) {
34312				vertices.push(0, 0, 0);
34313				colors.push(color.r, color.g, color.b);
34314
34315				if (pointMap[id] === undefined) {
34316					pointMap[id] = [];
34317				}
34318
34319				pointMap[id].push(vertices.length / 3 - 1);
34320			}
34321
34322			geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
34323			geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
34324			super(geometry, material);
34325			this.type = 'CameraHelper';
34326			this.camera = camera;
34327			if (this.camera.updateProjectionMatrix) this.camera.updateProjectionMatrix();
34328			this.matrix = camera.matrixWorld;
34329			this.matrixAutoUpdate = false;
34330			this.pointMap = pointMap;
34331			this.update();
34332		}
34333
34334		update() {
34335			const geometry = this.geometry;
34336			const pointMap = this.pointMap;
34337			const w = 1,
34338						h = 1; // we need just camera projection matrix inverse
34339			// world matrix must be identity
34340
34341			_camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target
34342
34343
34344			setPoint('c', pointMap, geometry, _camera, 0, 0, -1);
34345			setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near
34346
34347			setPoint('n1', pointMap, geometry, _camera, -w, -h, -1);
34348			setPoint('n2', pointMap, geometry, _camera, w, -h, -1);
34349			setPoint('n3', pointMap, geometry, _camera, -w, h, -1);
34350			setPoint('n4', pointMap, geometry, _camera, w, h, -1); // far
34351
34352			setPoint('f1', pointMap, geometry, _camera, -w, -h, 1);
34353			setPoint('f2', pointMap, geometry, _camera, w, -h, 1);
34354			setPoint('f3', pointMap, geometry, _camera, -w, h, 1);
34355			setPoint('f4', pointMap, geometry, _camera, w, h, 1); // up
34356
34357			setPoint('u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, -1);
34358			setPoint('u2', pointMap, geometry, _camera, -w * 0.7, h * 1.1, -1);
34359			setPoint('u3', pointMap, geometry, _camera, 0, h * 2, -1); // cross
34360
34361			setPoint('cf1', pointMap, geometry, _camera, -w, 0, 1);
34362			setPoint('cf2', pointMap, geometry, _camera, w, 0, 1);
34363			setPoint('cf3', pointMap, geometry, _camera, 0, -h, 1);
34364			setPoint('cf4', pointMap, geometry, _camera, 0, h, 1);
34365			setPoint('cn1', pointMap, geometry, _camera, -w, 0, -1);
34366			setPoint('cn2', pointMap, geometry, _camera, w, 0, -1);
34367			setPoint('cn3', pointMap, geometry, _camera, 0, -h, -1);
34368			setPoint('cn4', pointMap, geometry, _camera, 0, h, -1);
34369			geometry.getAttribute('position').needsUpdate = true;
34370		}
34371
34372		dispose() {
34373			this.geometry.dispose();
34374			this.material.dispose();
34375		}
34376
34377	}
34378
34379	function setPoint(point, pointMap, geometry, camera, x, y, z) {
34380		_vector.set(x, y, z).unproject(camera);
34381
34382		const points = pointMap[point];
34383
34384		if (points !== undefined) {
34385			const position = geometry.getAttribute('position');
34386
34387			for (let i = 0, l = points.length; i < l; i++) {
34388				position.setXYZ(points[i], _vector.x, _vector.y, _vector.z);
34389			}
34390		}
34391	}
34392
34393	const _box = /*@__PURE__*/new Box3();
34394
34395	class BoxHelper extends LineSegments {
34396		constructor(object, color = 0xffff00) {
34397			const 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]);
34398			const positions = new Float32Array(8 * 3);
34399			const geometry = new BufferGeometry();
34400			geometry.setIndex(new BufferAttribute(indices, 1));
34401			geometry.setAttribute('position', new BufferAttribute(positions, 3));
34402			super(geometry, new LineBasicMaterial({
34403				color: color,
34404				toneMapped: false
34405			}));
34406			this.object = object;
34407			this.type = 'BoxHelper';
34408			this.matrixAutoUpdate = false;
34409			this.update();
34410		}
34411
34412		update(object) {
34413			if (object !== undefined) {
34414				console.warn('THREE.BoxHelper: .update() has no longer arguments.');
34415			}
34416
34417			if (this.object !== undefined) {
34418				_box.setFromObject(this.object);
34419			}
34420
34421			if (_box.isEmpty()) return;
34422			const min = _box.min;
34423			const max = _box.max;
34424			/*
34425				5____4
34426			1/___0/|
34427			| 6__|_7
34428			2/___3/
34429				0: max.x, max.y, max.z
34430			1: min.x, max.y, max.z
34431			2: min.x, min.y, max.z
34432			3: max.x, min.y, max.z
34433			4: max.x, max.y, min.z
34434			5: min.x, max.y, min.z
34435			6: min.x, min.y, min.z
34436			7: max.x, min.y, min.z
34437			*/
34438
34439			const position = this.geometry.attributes.position;
34440			const array = position.array;
34441			array[0] = max.x;
34442			array[1] = max.y;
34443			array[2] = max.z;
34444			array[3] = min.x;
34445			array[4] = max.y;
34446			array[5] = max.z;
34447			array[6] = min.x;
34448			array[7] = min.y;
34449			array[8] = max.z;
34450			array[9] = max.x;
34451			array[10] = min.y;
34452			array[11] = max.z;
34453			array[12] = max.x;
34454			array[13] = max.y;
34455			array[14] = min.z;
34456			array[15] = min.x;
34457			array[16] = max.y;
34458			array[17] = min.z;
34459			array[18] = min.x;
34460			array[19] = min.y;
34461			array[20] = min.z;
34462			array[21] = max.x;
34463			array[22] = min.y;
34464			array[23] = min.z;
34465			position.needsUpdate = true;
34466			this.geometry.computeBoundingSphere();
34467		}
34468
34469		setFromObject(object) {
34470			this.object = object;
34471			this.update();
34472			return this;
34473		}
34474
34475		copy(source) {
34476			LineSegments.prototype.copy.call(this, source);
34477			this.object = source.object;
34478			return this;
34479		}
34480
34481	}
34482
34483	class Box3Helper extends LineSegments {
34484		constructor(box, color = 0xffff00) {
34485			const 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]);
34486			const 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];
34487			const geometry = new BufferGeometry();
34488			geometry.setIndex(new BufferAttribute(indices, 1));
34489			geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
34490			super(geometry, new LineBasicMaterial({
34491				color: color,
34492				toneMapped: false
34493			}));
34494			this.box = box;
34495			this.type = 'Box3Helper';
34496			this.geometry.computeBoundingSphere();
34497		}
34498
34499		updateMatrixWorld(force) {
34500			const box = this.box;
34501			if (box.isEmpty()) return;
34502			box.getCenter(this.position);
34503			box.getSize(this.scale);
34504			this.scale.multiplyScalar(0.5);
34505			super.updateMatrixWorld(force);
34506		}
34507
34508	}
34509
34510	class PlaneHelper extends Line {
34511		constructor(plane, size = 1, hex = 0xffff00) {
34512			const color = hex;
34513			const 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];
34514			const geometry = new BufferGeometry();
34515			geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
34516			geometry.computeBoundingSphere();
34517			super(geometry, new LineBasicMaterial({
34518				color: color,
34519				toneMapped: false
34520			}));
34521			this.type = 'PlaneHelper';
34522			this.plane = plane;
34523			this.size = size;
34524			const positions2 = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1];
34525			const geometry2 = new BufferGeometry();
34526			geometry2.setAttribute('position', new Float32BufferAttribute(positions2, 3));
34527			geometry2.computeBoundingSphere();
34528			this.add(new Mesh(geometry2, new MeshBasicMaterial({
34529				color: color,
34530				opacity: 0.2,
34531				transparent: true,
34532				depthWrite: false,
34533				toneMapped: false
34534			})));
34535		}
34536
34537		updateMatrixWorld(force) {
34538			let scale = -this.plane.constant;
34539			if (Math.abs(scale) < 1e-8) scale = 1e-8; // sign does not matter
34540
34541			this.scale.set(0.5 * this.size, 0.5 * this.size, scale);
34542			this.children[0].material.side = scale < 0 ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here
34543
34544			this.lookAt(this.plane.normal);
34545			super.updateMatrixWorld(force);
34546		}
34547
34548	}
34549
34550	const _axis = /*@__PURE__*/new Vector3();
34551
34552	let _lineGeometry, _coneGeometry;
34553
34554	class ArrowHelper extends Object3D {
34555		// dir is assumed to be normalized
34556		constructor(dir = new Vector3(0, 0, 1), origin = new Vector3(0, 0, 0), length = 1, color = 0xffff00, headLength = length * 0.2, headWidth = headLength * 0.2) {
34557			super();
34558			this.type = 'ArrowHelper';
34559
34560			if (_lineGeometry === undefined) {
34561				_lineGeometry = new BufferGeometry();
34562
34563				_lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3));
34564
34565				_coneGeometry = new CylinderGeometry(0, 0.5, 1, 5, 1);
34566
34567				_coneGeometry.translate(0, -0.5, 0);
34568			}
34569
34570			this.position.copy(origin);
34571			this.line = new Line(_lineGeometry, new LineBasicMaterial({
34572				color: color,
34573				toneMapped: false
34574			}));
34575			this.line.matrixAutoUpdate = false;
vendor: 3,735 bytes, lines 34576-34717
34576			this.add(this.line);
34577			this.cone = new Mesh(_coneGeometry, new MeshBasicMaterial({
34578				color: color,
34579				toneMapped: false
34580			}));
34581			this.cone.matrixAutoUpdate = false;
34582			this.add(this.cone);
34583			this.setDirection(dir);
34584			this.setLength(length, headLength, headWidth);
34585		}
34586
34587		setDirection(dir) {
34588			// dir is assumed to be normalized
34589			if (dir.y > 0.99999) {
34590				this.quaternion.set(0, 0, 0, 1);
34591			} else if (dir.y < -0.99999) {
34592				this.quaternion.set(1, 0, 0, 0);
34593			} else {
34594				_axis.set(dir.z, 0, -dir.x).normalize();
34595
34596				const radians = Math.acos(dir.y);
34597				this.quaternion.setFromAxisAngle(_axis, radians);
34598			}
34599		}
34600
34601		setLength(length, headLength = length * 0.2, headWidth = headLength * 0.2) {
34602			this.line.scale.set(1, Math.max(0.0001, length - headLength), 1); // see #17458
34603
34604			this.line.updateMatrix();
34605			this.cone.scale.set(headWidth, headLength, headWidth);
34606			this.cone.position.y = length;
34607			this.cone.updateMatrix();
34608		}
34609
34610		setColor(color) {
34611			this.line.material.color.set(color);
34612			this.cone.material.color.set(color);
34613		}
34614
34615		copy(source) {
34616			super.copy(source, false);
34617			this.line.copy(source.line);
34618			this.cone.copy(source.cone);
34619			return this;
34620		}
34621
34622	}
34623
34624	class AxesHelper extends LineSegments {
34625		constructor(size = 1) {
34626			const vertices = [0, 0, 0, size, 0, 0, 0, 0, 0, 0, size, 0, 0, 0, 0, 0, 0, size];
34627			const colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0, 0, 0, 1, 0, 0.6, 1];
34628			const geometry = new BufferGeometry();
34629			geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
34630			geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
34631			const material = new LineBasicMaterial({
34632				vertexColors: true,
34633				toneMapped: false
34634			});
34635			super(geometry, material);
34636			this.type = 'AxesHelper';
34637		}
34638
34639		setColors(xAxisColor, yAxisColor, zAxisColor) {
34640			const color = new Color();
34641			const array = this.geometry.attributes.color.array;
34642			color.set(xAxisColor);
34643			color.toArray(array, 0);
34644			color.toArray(array, 3);
34645			color.set(yAxisColor);
34646			color.toArray(array, 6);
34647			color.toArray(array, 9);
34648			color.set(zAxisColor);
34649			color.toArray(array, 12);
34650			color.toArray(array, 15);
34651			this.geometry.attributes.color.needsUpdate = true;
34652			return this;
34653		}
34654
34655		dispose() {
34656			this.geometry.dispose();
34657			this.material.dispose();
34658		}
34659
34660	}
34661
34662	class ShapePath {
34663		constructor() {
34664			this.type = 'ShapePath';
34665			this.color = new Color();
34666			this.subPaths = [];
34667			this.currentPath = null;
34668		}
34669
34670		moveTo(x, y) {
34671			this.currentPath = new Path();
34672			this.subPaths.push(this.currentPath);
34673			this.currentPath.moveTo(x, y);
34674			return this;
34675		}
34676
34677		lineTo(x, y) {
34678			this.currentPath.lineTo(x, y);
34679			return this;
34680		}
34681
34682		quadraticCurveTo(aCPx, aCPy, aX, aY) {
34683			this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY);
34684			return this;
34685		}
34686
34687		bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) {
34688			this.currentPath.bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY);
34689			return this;
34690		}
34691
34692		splineThru(pts) {
34693			this.currentPath.splineThru(pts);
34694			return this;
34695		}
34696
34697		toShapes(isCCW, noHoles) {
34698			function toShapesNoHoles(inSubpaths) {
34699				const shapes = [];
34700
34701				for (let i = 0, l = inSubpaths.length; i < l; i++) {
34702					const tmpPath = inSubpaths[i];
34703					const tmpShape = new Shape();
34704					tmpShape.curves = tmpPath.curves;
34705					shapes.push(tmpShape);
34706				}
34707
34708				return shapes;
34709			}
34710
34711			function isPointInsidePolygon(inPt, inPolygon) {
34712				const polyLen = inPolygon.length; // inPt on polygon contour => immediate success		or
34713				// toggling of inside/outside at every single! intersection point of an edge
34714				//	with the horizontal line through inPt, left of inPt
34715				//	not counting lowerY endpoints of edges and whole edges on that line
34716
34717				let inside = false;
vendor: 5,023 bytes, lines 34718-34891
34718
34719				for (let p = polyLen - 1, q = 0; q < polyLen; p = q++) {
34720					let edgeLowPt = inPolygon[p];
34721					let edgeHighPt = inPolygon[q];
34722					let edgeDx = edgeHighPt.x - edgeLowPt.x;
34723					let edgeDy = edgeHighPt.y - edgeLowPt.y;
34724
34725					if (Math.abs(edgeDy) > Number.EPSILON) {
34726						// not parallel
34727						if (edgeDy < 0) {
34728							edgeLowPt = inPolygon[q];
34729							edgeDx = -edgeDx;
34730							edgeHighPt = inPolygon[p];
34731							edgeDy = -edgeDy;
34732						}
34733
34734						if (inPt.y < edgeLowPt.y || inPt.y > edgeHighPt.y) continue;
34735
34736						if (inPt.y === edgeLowPt.y) {
34737							if (inPt.x === edgeLowPt.x) return true; // inPt is on contour ?
34738							// continue;				// no intersection or edgeLowPt => doesn't count !!!
34739						} else {
34740							const perpEdge = edgeDy * (inPt.x - edgeLowPt.x) - edgeDx * (inPt.y - edgeLowPt.y);
34741							if (perpEdge === 0) return true; // inPt is on contour ?
34742
34743							if (perpEdge < 0) continue;
34744							inside = !inside; // true intersection left of inPt
34745						}
34746					} else {
34747						// parallel or collinear
34748						if (inPt.y !== edgeLowPt.y) continue; // parallel
34749						// edge lies on the same horizontal line as inPt
34750
34751						if (edgeHighPt.x <= inPt.x && inPt.x <= edgeLowPt.x || edgeLowPt.x <= inPt.x && inPt.x <= edgeHighPt.x) return true; // inPt: Point on contour !
34752						// continue;
34753					}
34754				}
34755
34756				return inside;
34757			}
34758
34759			const isClockWise = ShapeUtils.isClockWise;
34760			const subPaths = this.subPaths;
34761			if (subPaths.length === 0) return [];
34762			if (noHoles === true) return toShapesNoHoles(subPaths);
34763			let solid, tmpPath, tmpShape;
34764			const shapes = [];
34765
34766			if (subPaths.length === 1) {
34767				tmpPath = subPaths[0];
34768				tmpShape = new Shape();
34769				tmpShape.curves = tmpPath.curves;
34770				shapes.push(tmpShape);
34771				return shapes;
34772			}
34773
34774			let holesFirst = !isClockWise(subPaths[0].getPoints());
34775			holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst);
34776
34777			const betterShapeHoles = [];
34778			const newShapes = [];
34779			let newShapeHoles = [];
34780			let mainIdx = 0;
34781			let tmpPoints;
34782			newShapes[mainIdx] = undefined;
34783			newShapeHoles[mainIdx] = [];
34784
34785			for (let i = 0, l = subPaths.length; i < l; i++) {
34786				tmpPath = subPaths[i];
34787				tmpPoints = tmpPath.getPoints();
34788				solid = isClockWise(tmpPoints);
34789				solid = isCCW ? !solid : solid;
34790
34791				if (solid) {
34792					if (!holesFirst && newShapes[mainIdx]) mainIdx++;
34793					newShapes[mainIdx] = {
34794						s: new Shape(),
34795						p: tmpPoints
34796					};
34797					newShapes[mainIdx].s.curves = tmpPath.curves;
34798					if (holesFirst) mainIdx++;
34799					newShapeHoles[mainIdx] = []; //console.log('cw', i);
34800				} else {
34801					newShapeHoles[mainIdx].push({
34802						h: tmpPath,
34803						p: tmpPoints[0]
34804					}); //console.log('ccw', i);
34805				}
34806			} // only Holes? -> probably all Shapes with wrong orientation
34807
34808
34809			if (!newShapes[0]) return toShapesNoHoles(subPaths);
34810
34811			if (newShapes.length > 1) {
34812				let ambiguous = false;
34813				const toChange = [];
34814
34815				for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) {
34816					betterShapeHoles[sIdx] = [];
34817				}
34818
34819				for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) {
34820					const sho = newShapeHoles[sIdx];
34821
34822					for (let hIdx = 0; hIdx < sho.length; hIdx++) {
34823						const ho = sho[hIdx];
34824						let hole_unassigned = true;
34825
34826						for (let s2Idx = 0; s2Idx < newShapes.length; s2Idx++) {
34827							if (isPointInsidePolygon(ho.p, newShapes[s2Idx].p)) {
34828								if (sIdx !== s2Idx) toChange.push({
34829									froms: sIdx,
34830									tos: s2Idx,
34831									hole: hIdx
34832								});
34833
34834								if (hole_unassigned) {
34835									hole_unassigned = false;
34836									betterShapeHoles[s2Idx].push(ho);
34837								} else {
34838									ambiguous = true;
34839								}
34840							}
34841						}
34842
34843						if (hole_unassigned) {
34844							betterShapeHoles[sIdx].push(ho);
34845						}
34846					}
34847				} // console.log("ambiguous: ", ambiguous);
34848
34849
34850				if (toChange.length > 0) {
34851					// console.log("to change: ", toChange);
34852					if (!ambiguous) newShapeHoles = betterShapeHoles;
34853				}
34854			}
34855
34856			let tmpHoles;
34857
34858			for (let i = 0, il = newShapes.length; i < il; i++) {
34859				tmpShape = newShapes[i].s;
34860				shapes.push(tmpShape);
34861				tmpHoles = newShapeHoles[i];
34862
34863				for (let j = 0, jl = tmpHoles.length; j < jl; j++) {
34864					tmpShape.holes.push(tmpHoles[j].h);
34865				}
34866			} //console.log("shape", shapes);
34867
34868
34869			return shapes;
34870		}
34871
34872	}
34873
34874	const _floatView = new Float32Array(1);
34875
34876	const _int32View = new Int32Array(_floatView.buffer);
34877
34878	class DataUtils {
34879		// Converts float32 to float16 (stored as uint16 value).
34880		static toHalfFloat(val) {
34881			if (val > 65504) {
34882				console.warn('THREE.DataUtils.toHalfFloat(): value exceeds 65504.');
34883				val = 65504; // maximum representable value in float16
34884			} // Source: http://gamedev.stackexchange.com/questions/17326/conversion-of-a-number-from-single-precision-floating-point-representation-to-a/17410#17410
34885
34886			/* This method is faster than the OpenEXR implementation (very often
34887			* used, eg. in Ogre), with the additional benefit of rounding, inspired
34888			* by James Tursa?s half-precision code. */
34889
34890
34891			_floatView[0] = val;
34892			const x = _int32View[0];
34893			let bits = x >> 16 & 0x8000;
34894			/* Get the sign */
34895
34896			let m = x >> 12 & 0x07ff;
34897			/* Keep one extra bit for rounding */
34898
34899			const e = x >> 23 & 0xff;
34900			/* Using int is faster here */
34901
34902			/* If zero, or denormal, or exponent underflows too much for a denormal
34903				* half, return signed zero. */
34904
34905			if (e < 103) return bits;
34906			/* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
34907
34908			if (e > 142) {
34909				bits |= 0x7c00;
34910				/* If exponent was 0xff and one mantissa bit was set, it means NaN,
34911							* not Inf, so make sure we set one mantissa bit too. */
34912
34913				bits |= (e == 255 ? 0 : 1) && x & 0x007fffff;
34914				return bits;
34915			}
34916			/* If exponent underflows but not too much, return a denormal */
34917
34918
34919			if (e < 113) {
34920				m |= 0x0800;
34921				/* Extra rounding may overflow and set mantissa to 0 and exponent
34922					* to 1, which is OK. */
34923
34924				bits |= (m >> 114 - e) + (m >> 113 - e & 1);
34925				return bits;
34926			}
34927
34928			bits |= e - 112 << 10 | m >> 1;
34929			/* Extra rounding. An overflow will set mantissa to 0 and increment
34930				* the exponent, which is OK. */
34931
34932			bits += m & 1;
34933			return bits;
34934		}
34935
34936	}
34937
34938	const LineStrip = 0;
34939	const LinePieces = 1;
34940	const NoColors = 0;
34941	const FaceColors = 1;
34942	const VertexColors = 2;
34943	function MeshFaceMaterial(materials) {
34944		console.warn('THREE.MeshFaceMaterial has been removed. Use an Array instead.');
34945		return materials;
34946	}
34947	function MultiMaterial(materials = []) {
34948		console.warn('THREE.MultiMaterial has been removed. Use an Array instead.');
34949		materials.isMultiMaterial = true;
34950		materials.materials = materials;
34951
34952		materials.clone = function () {
34953			return materials.slice();
34954		};
34955
34956		return materials;
34957	}
34958	function PointCloud(geometry, material) {
34959		console.warn('THREE.PointCloud has been renamed to THREE.Points.');
34960		return new Points(geometry, material);
34961	}
34962	function Particle(material) {
34963		console.warn('THREE.Particle has been renamed to THREE.Sprite.');
34964		return new Sprite(material);
34965	}
34966	function ParticleSystem(geometry, material) {
34967		console.warn('THREE.ParticleSystem has been renamed to THREE.Points.');
34968		return new Points(geometry, material);
34969	}
34970	function PointCloudMaterial(parameters) {
34971		console.warn('THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.');
34972		return new PointsMaterial(parameters);
34973	}
34974	function ParticleBasicMaterial(parameters) {
34975		console.warn('THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.');
34976		return new PointsMaterial(parameters);
34977	}
34978	function ParticleSystemMaterial(parameters) {
34979		console.warn('THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.');
34980		return new PointsMaterial(parameters);
34981	}
34982	function Vertex(x, y, z) {
34983		console.warn('THREE.Vertex has been removed. Use THREE.Vector3 instead.');
34984		return new Vector3(x, y, z);
34985	} //
34986
34987	function DynamicBufferAttribute(array, itemSize) {
34988		console.warn('THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.');
34989		return new BufferAttribute(array, itemSize).setUsage(DynamicDrawUsage);
34990	}
34991	function Int8Attribute(array, itemSize) {
34992		console.warn('THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.');
34993		return new Int8BufferAttribute(array, itemSize);
34994	}
34995	function Uint8Attribute(array, itemSize) {
34996		console.warn('THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.');
34997		return new Uint8BufferAttribute(array, itemSize);
34998	}
34999	function Uint8ClampedAttribute(array, itemSize) {
35000		console.warn('THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.');
35001		return new Uint8ClampedBufferAttribute(array, itemSize);
35002	}
35003	function Int16Attribute(array, itemSize) {
35004		console.warn('THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.');
35005		return new Int16BufferAttribute(array, itemSize);
35006	}
35007	function Uint16Attribute(array, itemSize) {
35008		console.warn('THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.');
35009		return new Uint16BufferAttribute(array, itemSize);
35010	}
35011	function Int32Attribute(array, itemSize) {
35012		console.warn('THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.');
35013		return new Int32BufferAttribute(array, itemSize);
35014	}
35015	function Uint32Attribute(array, itemSize) {
35016		console.warn('THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.');
35017		return new Uint32BufferAttribute(array, itemSize);
35018	}
35019	function Float32Attribute(array, itemSize) {
35020		console.warn('THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.');
35021		return new Float32BufferAttribute(array, itemSize);
35022	}
35023	function Float64Attribute(array, itemSize) {
35024		console.warn('THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.');
35025		return new Float64BufferAttribute(array, itemSize);
35026	} //
35027
35028	Curve.create = function (construct, getPoint) {
35029		console.log('THREE.Curve.create() has been deprecated');
35030		construct.prototype = Object.create(Curve.prototype);
35031		construct.prototype.constructor = construct;
35032		construct.prototype.getPoint = getPoint;
35033		return construct;
35034	}; //
35035
35036
35037	Path.prototype.fromPoints = function (points) {
35038		console.warn('THREE.Path: .fromPoints() has been renamed to .setFromPoints().');
35039		return this.setFromPoints(points);
35040	}; //
35041
35042
35043	function AxisHelper(size) {
35044		console.warn('THREE.AxisHelper has been renamed to THREE.AxesHelper.');
35045		return new AxesHelper(size);
35046	}
35047	function BoundingBoxHelper(object, color) {
35048		console.warn('THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.');
35049		return new BoxHelper(object, color);
35050	}
35051	function EdgesHelper(object, hex) {
35052		console.warn('THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.');
35053		return new LineSegments(new EdgesGeometry(object.geometry), new LineBasicMaterial({
35054			color: hex !== undefined ? hex : 0xffffff
35055		}));
35056	}
35057
35058	GridHelper.prototype.setColors = function () {
35059		console.error('THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.');
35060	};
35061
35062	SkeletonHelper.prototype.update = function () {
35063		console.error('THREE.SkeletonHelper: update() no longer needs to be called.');
35064	};
35065
35066	function WireframeHelper(object, hex) {
35067		console.warn('THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.');
35068		return new LineSegments(new WireframeGeometry(object.geometry), new LineBasicMaterial({
35069			color: hex !== undefined ? hex : 0xffffff
35070		}));
35071	} //
35072
35073	Loader.prototype.extractUrlBase = function (url) {
35074		console.warn('THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.');
35075		return LoaderUtils.extractUrlBase(url);
35076	};
35077
35078	Loader.Handlers = {
35079		add: function () {
35080			console.error('THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.');
35081		},
35082		get: function () {
35083			console.error('THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.');
35084		}
35085	};
35086	function XHRLoader(manager) {
35087		console.warn('THREE.XHRLoader has been renamed to THREE.FileLoader.');
35088		return new FileLoader(manager);
35089	}
35090	function BinaryTextureLoader(manager) {
35091		console.warn('THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.');
35092		return new DataTextureLoader(manager);
35093	} //
35094
35095	Box2.prototype.center = function (optionalTarget) {
35096		console.warn('THREE.Box2: .center() has been renamed to .getCenter().');
35097		return this.getCenter(optionalTarget);
35098	};
35099
35100	Box2.prototype.empty = function () {
35101		console.warn('THREE.Box2: .empty() has been renamed to .isEmpty().');
35102		return this.isEmpty();
35103	};
35104
35105	Box2.prototype.isIntersectionBox = function (box) {
35106		console.warn('THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().');
35107		return this.intersectsBox(box);
35108	};
35109
35110	Box2.prototype.size = function (optionalTarget) {
35111		console.warn('THREE.Box2: .size() has been renamed to .getSize().');
35112		return this.getSize(optionalTarget);
35113	}; //
35114
35115
35116	Box3.prototype.center = function (optionalTarget) {
35117		console.warn('THREE.Box3: .center() has been renamed to .getCenter().');
35118		return this.getCenter(optionalTarget);
35119	};
35120
35121	Box3.prototype.empty = function () {
35122		console.warn('THREE.Box3: .empty() has been renamed to .isEmpty().');
35123		return this.isEmpty();
35124	};
35125
35126	Box3.prototype.isIntersectionBox = function (box) {
35127		console.warn('THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().');
35128		return this.intersectsBox(box);
35129	};
35130
35131	Box3.prototype.isIntersectionSphere = function (sphere) {
35132		console.warn('THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().');
35133		return this.intersectsSphere(sphere);
35134	};
35135
35136	Box3.prototype.size = function (optionalTarget) {
35137		console.warn('THREE.Box3: .size() has been renamed to .getSize().');
35138		return this.getSize(optionalTarget);
35139	}; //
35140
35141
35142	Sphere.prototype.empty = function () {
35143		console.warn('THREE.Sphere: .empty() has been renamed to .isEmpty().');
35144		return this.isEmpty();
35145	}; //
35146
35147
35148	Frustum.prototype.setFromMatrix = function (m) {
35149		console.warn('THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().');
35150		return this.setFromProjectionMatrix(m);
35151	}; //
35152
35153
35154	Line3.prototype.center = function (optionalTarget) {
35155		console.warn('THREE.Line3: .center() has been renamed to .getCenter().');
35156		return this.getCenter(optionalTarget);
35157	}; //
35158
35159
35160	Matrix3.prototype.flattenToArrayOffset = function (array, offset) {
35161		console.warn('THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.');
35162		return this.toArray(array, offset);
35163	};
35164
35165	Matrix3.prototype.multiplyVector3 = function (vector) {
35166		console.warn('THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.');
35167		return vector.applyMatrix3(this);
35168	};
35169
35170	Matrix3.prototype.multiplyVector3Array = function () {
35171		console.error('THREE.Matrix3: .multiplyVector3Array() has been removed.');
35172	};
35173
35174	Matrix3.prototype.applyToBufferAttribute = function (attribute) {
35175		console.warn('THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.');
35176		return attribute.applyMatrix3(this);
35177	};
35178
35179	Matrix3.prototype.applyToVector3Array = function () {
35180		console.error('THREE.Matrix3: .applyToVector3Array() has been removed.');
35181	};
35182
35183	Matrix3.prototype.getInverse = function (matrix) {
35184		console.warn('THREE.Matrix3: .getInverse() has been removed. Use matrixInv.copy( matrix ).invert(); instead.');
35185		return this.copy(matrix).invert();
35186	}; //
35187
35188
35189	Matrix4.prototype.extractPosition = function (m) {
35190		console.warn('THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().');
35191		return this.copyPosition(m);
35192	};
35193
35194	Matrix4.prototype.flattenToArrayOffset = function (array, offset) {
35195		console.warn('THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.');
35196		return this.toArray(array, offset);
35197	};
35198
35199	Matrix4.prototype.getPosition = function () {
35200		console.warn('THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.');
35201		return new Vector3().setFromMatrixColumn(this, 3);
35202	};
35203
35204	Matrix4.prototype.setRotationFromQuaternion = function (q) {
35205		console.warn('THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().');
35206		return this.makeRotationFromQuaternion(q);
35207	};
35208
35209	Matrix4.prototype.multiplyToArray = function () {
35210		console.warn('THREE.Matrix4: .multiplyToArray() has been removed.');
35211	};
35212
35213	Matrix4.prototype.multiplyVector3 = function (vector) {
35214		console.warn('THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.');
35215		return vector.applyMatrix4(this);
35216	};
35217
35218	Matrix4.prototype.multiplyVector4 = function (vector) {
35219		console.warn('THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.');
35220		return vector.applyMatrix4(this);
35221	};
35222
35223	Matrix4.prototype.multiplyVector3Array = function () {
35224		console.error('THREE.Matrix4: .multiplyVector3Array() has been removed.');
35225	};
35226
35227	Matrix4.prototype.rotateAxis = function (v) {
35228		console.warn('THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.');
35229		v.transformDirection(this);
35230	};
35231
35232	Matrix4.prototype.crossVector = function (vector) {
35233		console.warn('THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.');
35234		return vector.applyMatrix4(this);
35235	};
35236
35237	Matrix4.prototype.translate = function () {
35238		console.error('THREE.Matrix4: .translate() has been removed.');
35239	};
35240
35241	Matrix4.prototype.rotateX = function () {
35242		console.error('THREE.Matrix4: .rotateX() has been removed.');
35243	};
35244
35245	Matrix4.prototype.rotateY = function () {
35246		console.error('THREE.Matrix4: .rotateY() has been removed.');
35247	};
35248
35249	Matrix4.prototype.rotateZ = function () {
35250		console.error('THREE.Matrix4: .rotateZ() has been removed.');
35251	};
35252
35253	Matrix4.prototype.rotateByAxis = function () {
35254		console.error('THREE.Matrix4: .rotateByAxis() has been removed.');
35255	};
35256
35257	Matrix4.prototype.applyToBufferAttribute = function (attribute) {
35258		console.warn('THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.');
35259		return attribute.applyMatrix4(this);
35260	};
35261
35262	Matrix4.prototype.applyToVector3Array = function () {
35263		console.error('THREE.Matrix4: .applyToVector3Array() has been removed.');
35264	};
35265
35266	Matrix4.prototype.makeFrustum = function (left, right, bottom, top, near, far) {
35267		console.warn('THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.');
35268		return this.makePerspective(left, right, top, bottom, near, far);
35269	};
35270
35271	Matrix4.prototype.getInverse = function (matrix) {
35272		console.warn('THREE.Matrix4: .getInverse() has been removed. Use matrixInv.copy( matrix ).invert(); instead.');
35273		return this.copy(matrix).invert();
35274	}; //
35275
35276
35277	Plane.prototype.isIntersectionLine = function (line) {
35278		console.warn('THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().');
35279		return this.intersectsLine(line);
35280	}; //
35281
35282
35283	Quaternion.prototype.multiplyVector3 = function (vector) {
35284		console.warn('THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.');
35285		return vector.applyQuaternion(this);
35286	};
35287
35288	Quaternion.prototype.inverse = function () {
35289		console.warn('THREE.Quaternion: .inverse() has been renamed to invert().');
35290		return this.invert();
35291	}; //
35292
35293
35294	Ray.prototype.isIntersectionBox = function (box) {
35295		console.warn('THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().');
35296		return this.intersectsBox(box);
35297	};
35298
35299	Ray.prototype.isIntersectionPlane = function (plane) {
35300		console.warn('THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().');
35301		return this.intersectsPlane(plane);
35302	};
35303
35304	Ray.prototype.isIntersectionSphere = function (sphere) {
35305		console.warn('THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().');
35306		return this.intersectsSphere(sphere);
35307	}; //
35308
35309
35310	Triangle.prototype.area = function () {
35311		console.warn('THREE.Triangle: .area() has been renamed to .getArea().');
35312		return this.getArea();
35313	};
35314
35315	Triangle.prototype.barycoordFromPoint = function (point, target) {
35316		console.warn('THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().');
35317		return this.getBarycoord(point, target);
35318	};
35319
35320	Triangle.prototype.midpoint = function (target) {
35321		console.warn('THREE.Triangle: .midpoint() has been renamed to .getMidpoint().');
35322		return this.getMidpoint(target);
35323	};
35324
35325	Triangle.prototypenormal = function (target) {
35326		console.warn('THREE.Triangle: .normal() has been renamed to .getNormal().');
35327		return this.getNormal(target);
35328	};
35329
35330	Triangle.prototype.plane = function (target) {
35331		console.warn('THREE.Triangle: .plane() has been renamed to .getPlane().');
35332		return this.getPlane(target);
35333	};
35334
35335	Triangle.barycoordFromPoint = function (point, a, b, c, target) {
35336		console.warn('THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().');
35337		return Triangle.getBarycoord(point, a, b, c, target);
35338	};
35339
35340	Triangle.normal = function (a, b, c, target) {
35341		console.warn('THREE.Triangle: .normal() has been renamed to .getNormal().');
35342		return Triangle.getNormal(a, b, c, target);
35343	}; //
35344
35345
35346	Shape.prototype.extractAllPoints = function (divisions) {
35347		console.warn('THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.');
35348		return this.extractPoints(divisions);
35349	};
35350
35351	Shape.prototype.extrude = function (options) {
35352		console.warn('THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.');
35353		return new ExtrudeGeometry(this, options);
35354	};
35355
35356	Shape.prototype.makeGeometry = function (options) {
35357		console.warn('THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.');
35358		return new ShapeGeometry(this, options);
35359	}; //
35360
35361
35362	Vector2.prototype.fromAttribute = function (attribute, index, offset) {
35363		console.warn('THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().');
35364		return this.fromBufferAttribute(attribute, index, offset);
35365	};
35366
35367	Vector2.prototype.distanceToManhattan = function (v) {
35368		console.warn('THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().');
35369		return this.manhattanDistanceTo(v);
35370	};
35371
35372	Vector2.prototype.lengthManhattan = function () {
35373		console.warn('THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().');
35374		return this.manhattanLength();
35375	}; //
35376
35377
35378	Vector3.prototype.setEulerFromRotationMatrix = function () {
35379		console.error('THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.');
35380	};
35381
35382	Vector3.prototype.setEulerFromQuaternion = function () {
35383		console.error('THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.');
35384	};
35385
35386	Vector3.prototype.getPositionFromMatrix = function (m) {
35387		console.warn('THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().');
35388		return this.setFromMatrixPosition(m);
35389	};
35390
35391	Vector3.prototype.getScaleFromMatrix = function (m) {
35392		console.warn('THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().');
35393		return this.setFromMatrixScale(m);
35394	};
35395
vendor: 9,256 bytes, lines 35396-35658
35396	Vector3.prototype.getColumnFromMatrix = function (index, matrix) {
35397		console.warn('THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().');
35398		return this.setFromMatrixColumn(matrix, index);
35399	};
35400
35401	Vector3.prototype.applyProjection = function (m) {
35402		console.warn('THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.');
35403		return this.applyMatrix4(m);
35404	};
35405
35406	Vector3.prototype.fromAttribute = function (attribute, index, offset) {
35407		console.warn('THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().');
35408		return this.fromBufferAttribute(attribute, index, offset);
35409	};
35410
35411	Vector3.prototype.distanceToManhattan = function (v) {
35412		console.warn('THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().');
35413		return this.manhattanDistanceTo(v);
35414	};
35415
35416	Vector3.prototype.lengthManhattan = function () {
35417		console.warn('THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().');
35418		return this.manhattanLength();
35419	}; //
35420
35421
35422	Vector4.prototype.fromAttribute = function (attribute, index, offset) {
35423		console.warn('THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().');
35424		return this.fromBufferAttribute(attribute, index, offset);
35425	};
35426
35427	Vector4.prototype.lengthManhattan = function () {
35428		console.warn('THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().');
35429		return this.manhattanLength();
35430	}; //
35431
35432
35433	Object3D.prototype.getChildByName = function (name) {
35434		console.warn('THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().');
35435		return this.getObjectByName(name);
35436	};
35437
35438	Object3D.prototype.renderDepth = function () {
35439		console.warn('THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.');
35440	};
35441
35442	Object3D.prototype.translate = function (distance, axis) {
35443		console.warn('THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.');
35444		return this.translateOnAxis(axis, distance);
35445	};
35446
35447	Object3D.prototype.getWorldRotation = function () {
35448		console.error('THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.');
35449	};
35450
35451	Object3D.prototype.applyMatrix = function (matrix) {
35452		console.warn('THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().');
35453		return this.applyMatrix4(matrix);
35454	};
35455
35456	Object.defineProperties(Object3D.prototype, {
35457		eulerOrder: {
35458			get: function () {
35459				console.warn('THREE.Object3D: .eulerOrder is now .rotation.order.');
35460				return this.rotation.order;
35461			},
35462			set: function (value) {
35463				console.warn('THREE.Object3D: .eulerOrder is now .rotation.order.');
35464				this.rotation.order = value;
35465			}
35466		},
35467		useQuaternion: {
35468			get: function () {
35469				console.warn('THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.');
35470			},
35471			set: function () {
35472				console.warn('THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.');
35473			}
35474		}
35475	});
35476
35477	Mesh.prototype.setDrawMode = function () {
35478		console.error('THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.');
35479	};
35480
35481	Object.defineProperties(Mesh.prototype, {
35482		drawMode: {
35483			get: function () {
35484				console.error('THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.');
35485				return TrianglesDrawMode;
35486			},
35487			set: function () {
35488				console.error('THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.');
35489			}
35490		}
35491	});
35492
35493	SkinnedMesh.prototype.initBones = function () {
35494		console.error('THREE.SkinnedMesh: initBones() has been removed.');
35495	}; //
35496
35497
35498	PerspectiveCamera.prototype.setLens = function (focalLength, filmGauge) {
35499		console.warn('THREE.PerspectiveCamera.setLens is deprecated. ' + 'Use .setFocalLength and .filmGauge for a photographic setup.');
35500		if (filmGauge !== undefined) this.filmGauge = filmGauge;
35501		this.setFocalLength(focalLength);
35502	}; //
35503
35504
35505	Object.defineProperties(Light.prototype, {
35506		onlyShadow: {
35507			set: function () {
35508				console.warn('THREE.Light: .onlyShadow has been removed.');
35509			}
35510		},
35511		shadowCameraFov: {
35512			set: function (value) {
35513				console.warn('THREE.Light: .shadowCameraFov is now .shadow.camera.fov.');
35514				this.shadow.camera.fov = value;
35515			}
35516		},
35517		shadowCameraLeft: {
35518			set: function (value) {
35519				console.warn('THREE.Light: .shadowCameraLeft is now .shadow.camera.left.');
35520				this.shadow.camera.left = value;
35521			}
35522		},
35523		shadowCameraRight: {
35524			set: function (value) {
35525				console.warn('THREE.Light: .shadowCameraRight is now .shadow.camera.right.');
35526				this.shadow.camera.right = value;
35527			}
35528		},
35529		shadowCameraTop: {
35530			set: function (value) {
35531				console.warn('THREE.Light: .shadowCameraTop is now .shadow.camera.top.');
35532				this.shadow.camera.top = value;
35533			}
35534		},
35535		shadowCameraBottom: {
35536			set: function (value) {
35537				console.warn('THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.');
35538				this.shadow.camera.bottom = value;
35539			}
35540		},
35541		shadowCameraNear: {
35542			set: function (value) {
35543				console.warn('THREE.Light: .shadowCameraNear is now .shadow.camera.near.');
35544				this.shadow.camera.near = value;
35545			}
35546		},
35547		shadowCameraFar: {
35548			set: function (value) {
35549				console.warn('THREE.Light: .shadowCameraFar is now .shadow.camera.far.');
35550				this.shadow.camera.far = value;
35551			}
35552		},
35553		shadowCameraVisible: {
35554			set: function () {
35555				console.warn('THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.');
35556			}
35557		},
35558		shadowBias: {
35559			set: function (value) {
35560				console.warn('THREE.Light: .shadowBias is now .shadow.bias.');
35561				this.shadow.bias = value;
35562			}
35563		},
35564		shadowDarkness: {
35565			set: function () {
35566				console.warn('THREE.Light: .shadowDarkness has been removed.');
35567			}
35568		},
35569		shadowMapWidth: {
35570			set: function (value) {
35571				console.warn('THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.');
35572				this.shadow.mapSize.width = value;
35573			}
35574		},
35575		shadowMapHeight: {
35576			set: function (value) {
35577				console.warn('THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.');
35578				this.shadow.mapSize.height = value;
35579			}
35580		}
35581	}); //
35582
35583	Object.defineProperties(BufferAttribute.prototype, {
35584		length: {
35585			get: function () {
35586				console.warn('THREE.BufferAttribute: .length has been deprecated. Use .count instead.');
35587				return this.array.length;
35588			}
35589		},
35590		dynamic: {
35591			get: function () {
35592				console.warn('THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.');
35593				return this.usage === DynamicDrawUsage;
35594			},
35595			set: function () {
35596				console.warn('THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.');
35597				this.setUsage(DynamicDrawUsage);
35598			}
35599		}
35600	});
35601
35602	BufferAttribute.prototype.setDynamic = function (value) {
35603		console.warn('THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.');
35604		this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage);
35605		return this;
35606	};
35607
35608	BufferAttribute.prototype.copyIndicesArray = function () {
35609		console.error('THREE.BufferAttribute: .copyIndicesArray() has been removed.');
35610	}, BufferAttribute.prototype.setArray = function () {
35611		console.error('THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers');
35612	}; //
35613
35614	BufferGeometry.prototype.addIndex = function (index) {
35615		console.warn('THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().');
35616		this.setIndex(index);
35617	};
35618
35619	BufferGeometry.prototype.addAttribute = function (name, attribute) {
35620		console.warn('THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().');
35621
35622		if (!(attribute && attribute.isBufferAttribute) && !(attribute && attribute.isInterleavedBufferAttribute)) {
35623			console.warn('THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).');
35624			return this.setAttribute(name, new BufferAttribute(arguments[1], arguments[2]));
35625		}
35626
35627		if (name === 'index') {
35628			console.warn('THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.');
35629			this.setIndex(attribute);
35630			return this;
35631		}
35632
35633		return this.setAttribute(name, attribute);
35634	};
35635
35636	BufferGeometry.prototype.addDrawCall = function (start, count, indexOffset) {
35637		if (indexOffset !== undefined) {
35638			console.warn('THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.');
35639		}
35640
35641		console.warn('THREE.BufferGeometry: .addDrawCall() is now .addGroup().');
35642		this.addGroup(start, count);
35643	};
35644
35645	BufferGeometry.prototype.clearDrawCalls = function () {
35646		console.warn('THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().');
35647		this.clearGroups();
35648	};
35649
35650	BufferGeometry.prototype.computeOffsets = function () {
35651		console.warn('THREE.BufferGeometry: .computeOffsets() has been removed.');
35652	};
35653
35654	BufferGeometry.prototype.removeAttribute = function (name) {
35655		console.warn('THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().');
35656		return this.deleteAttribute(name);
35657	};
35658
35659	BufferGeometry.prototype.applyMatrix = function (matrix) {
35660		console.warn('THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().');
35661		return this.applyMatrix4(matrix);
35662	};
35663
35664	Object.defineProperties(BufferGeometry.prototype, {
35665		drawcalls: {
35666			get: function () {
35667				console.error('THREE.BufferGeometry: .drawcalls has been renamed to .groups.');
35668				return this.groups;
35669			}
35670		},
35671		offsets: {
35672			get: function () {
35673				console.warn('THREE.BufferGeometry: .offsets has been renamed to .groups.');
35674				return this.groups;
35675			}
35676		}
35677	});
35678
35679	InterleavedBuffer.prototype.setDynamic = function (value) {
35680		console.warn('THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.');
35681		this.setUsage(value === true ? DynamicDrawUsage : StaticDrawUsage);
35682		return this;
35683	};
35684
35685	InterleavedBuffer.prototype.setArray = function () {
35686		console.error('THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers');
35687	}; //
35688
35689
35690	ExtrudeGeometry.prototype.getArrays = function () {
35691		console.error('THREE.ExtrudeGeometry: .getArrays() has been removed.');
35692	};
35693
35694	ExtrudeGeometry.prototype.addShapeList = function () {
35695		console.error('THREE.ExtrudeGeometry: .addShapeList() has been removed.');
35696	};
35697
35698	ExtrudeGeometry.prototype.addShape = function () {
35699		console.error('THREE.ExtrudeGeometry: .addShape() has been removed.');
35700	}; //
35701
35702
35703	Scene.prototype.dispose = function () {
35704		console.error('THREE.Scene: .dispose() has been removed.');
35705	}; //
35706
35707
35708	Uniform.prototype.onUpdate = function () {
35709		console.warn('THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.');
35710		return this;
35711	}; //
35712
35713
35714	Object.defineProperties(Material.prototype, {
35715		wrapAround: {
35716			get: function () {
35717				console.warn('THREE.Material: .wrapAround has been removed.');
35718			},
35719			set: function () {
35720				console.warn('THREE.Material: .wrapAround has been removed.');
35721			}
35722		},
35723		overdraw: {
35724			get: function () {
35725				console.warn('THREE.Material: .overdraw has been removed.');
35726			},
35727			set: function () {
35728				console.warn('THREE.Material: .overdraw has been removed.');
35729			}
35730		},
35731		wrapRGB: {
35732			get: function () {
35733				console.warn('THREE.Material: .wrapRGB has been removed.');
35734				return new Color();
35735			}
35736		},
35737		shading: {
35738			get: function () {
35739				console.error('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.');
35740			},
35741			set: function (value) {
35742				console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.');
35743				this.flatShading = value === FlatShading;
35744			}
35745		},
35746		stencilMask: {
35747			get: function () {
35748				console.warn('THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.');
35749				return this.stencilFuncMask;
35750			},
35751			set: function (value) {
35752				console.warn('THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.');
35753				this.stencilFuncMask = value;
35754			}
35755		},
35756		vertexTangents: {
35757			get: function () {
35758				console.warn('THREE.' + this.type + ': .vertexTangents has been removed.');
35759			},
35760			set: function () {
35761				console.warn('THREE.' + this.type + ': .vertexTangents has been removed.');
35762			}
35763		}
35764	});
35765	Object.defineProperties(ShaderMaterial.prototype, {
35766		derivatives: {
35767			get: function () {
35768				console.warn('THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.');
35769				return this.extensions.derivatives;
35770			},
35771			set: function (value) {
35772				console.warn('THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.');
35773				this.extensions.derivatives = value;
35774			}
35775		}
35776	}); //
35777
35778	WebGLRenderer.prototype.clearTarget = function (renderTarget, color, depth, stencil) {
35779		console.warn('THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead.');
35780		this.setRenderTarget(renderTarget);
35781		this.clear(color, depth, stencil);
35782	};
35783
35784	WebGLRenderer.prototype.animate = function (callback) {
35785		console.warn('THREE.WebGLRenderer: .animate() is now .setAnimationLoop().');
35786		this.setAnimationLoop(callback);
35787	};
35788
35789	WebGLRenderer.prototype.getCurrentRenderTarget = function () {
35790		console.warn('THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().');
35791		return this.getRenderTarget();
35792	};
35793
35794	WebGLRenderer.prototype.getMaxAnisotropy = function () {
35795		console.warn('THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().');
35796		return this.capabilities.getMaxAnisotropy();
35797	};
35798
35799	WebGLRenderer.prototype.getPrecision = function () {
35800		console.warn('THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.');
35801		return this.capabilities.precision;
35802	};
35803
35804	WebGLRenderer.prototype.resetGLState = function () {
35805		console.warn('THREE.WebGLRenderer: .resetGLState() is now .state.reset().');
35806		return this.state.reset();
35807	};
35808
35809	WebGLRenderer.prototype.supportsFloatTextures = function () {
35810		console.warn('THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).');
35811		return this.extensions.get('OES_texture_float');
35812	};
35813
35814	WebGLRenderer.prototype.supportsHalfFloatTextures = function () {
35815		console.warn('THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).');
35816		return this.extensions.get('OES_texture_half_float');
35817	};
35818
35819	WebGLRenderer.prototype.supportsStandardDerivatives = function () {
35820		console.warn('THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).');
35821		return this.extensions.get('OES_standard_derivatives');
35822	};
35823
35824	WebGLRenderer.prototype.supportsCompressedTextureS3TC = function () {
35825		console.warn('THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).');
35826		return this.extensions.get('WEBGL_compressed_texture_s3tc');
35827	};
35828
35829	WebGLRenderer.prototype.supportsCompressedTexturePVRTC = function () {
35830		console.warn('THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).');
35831		return this.extensions.get('WEBGL_compressed_texture_pvrtc');
35832	};
35833
35834	WebGLRenderer.prototype.supportsBlendMinMax = function () {
35835		console.warn('THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).');
35836		return this.extensions.get('EXT_blend_minmax');
35837	};
35838
35839	WebGLRenderer.prototype.supportsVertexTextures = function () {
35840		console.warn('THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.');
35841		return this.capabilities.vertexTextures;
35842	};
35843
35844	WebGLRenderer.prototype.supportsInstancedArrays = function () {
35845		console.warn('THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_
vendor: 4,353 bytes, lines 35845-35978
35845instanced_arrays\' ).');
35846		return this.extensions.get('ANGLE_instanced_arrays');
35847	};
35848
35849	WebGLRenderer.prototype.enableScissorTest = function (boolean) {
35850		console.warn('THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().');
35851		this.setScissorTest(boolean);
35852	};
35853
35854	WebGLRenderer.prototype.initMaterial = function () {
35855		console.warn('THREE.WebGLRenderer: .initMaterial() has been removed.');
35856	};
35857
35858	WebGLRenderer.prototype.addPrePlugin = function () {
35859		console.warn('THREE.WebGLRenderer: .addPrePlugin() has been removed.');
35860	};
35861
35862	WebGLRenderer.prototype.addPostPlugin = function () {
35863		console.warn('THREE.WebGLRenderer: .addPostPlugin() has been removed.');
35864	};
35865
35866	WebGLRenderer.prototype.updateShadowMap = function () {
35867		console.warn('THREE.WebGLRenderer: .updateShadowMap() has been removed.');
35868	};
35869
35870	WebGLRenderer.prototype.setFaceCulling = function () {
35871		console.warn('THREE.WebGLRenderer: .setFaceCulling() has been removed.');
35872	};
35873
35874	WebGLRenderer.prototype.allocTextureUnit = function () {
35875		console.warn('THREE.WebGLRenderer: .allocTextureUnit() has been removed.');
35876	};
35877
35878	WebGLRenderer.prototype.setTexture = function () {
35879		console.warn('THREE.WebGLRenderer: .setTexture() has been removed.');
35880	};
35881
35882	WebGLRenderer.prototype.setTexture2D = function () {
35883		console.warn('THREE.WebGLRenderer: .setTexture2D() has been removed.');
35884	};
35885
35886	WebGLRenderer.prototype.setTextureCube = function () {
35887		console.warn('THREE.WebGLRenderer: .setTextureCube() has been removed.');
35888	};
35889
35890	WebGLRenderer.prototype.getActiveMipMapLevel = function () {
35891		console.warn('THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel().');
35892		return this.getActiveMipmapLevel();
35893	};
35894
35895	Object.defineProperties(WebGLRenderer.prototype, {
35896		shadowMapEnabled: {
35897			get: function () {
35898				return this.shadowMap.enabled;
35899			},
35900			set: function (value) {
35901				console.warn('THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.');
35902				this.shadowMap.enabled = value;
35903			}
35904		},
35905		shadowMapType: {
35906			get: function () {
35907				return this.shadowMap.type;
35908			},
35909			set: function (value) {
35910				console.warn('THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.');
35911				this.shadowMap.type = value;
35912			}
35913		},
35914		shadowMapCullFace: {
35915			get: function () {
35916				console.warn('THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.');
35917				return undefined;
35918			},
35919			set: function () {
35920				console.warn('THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.');
35921			}
35922		},
35923		context: {
35924			get: function () {
35925				console.warn('THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.');
35926				return this.getContext();
35927			}
35928		},
35929		vr: {
35930			get: function () {
35931				console.warn('THREE.WebGLRenderer: .vr has been renamed to .xr');
35932				return this.xr;
35933			}
35934		},
35935		gammaInput: {
35936			get: function () {
35937				console.warn('THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.');
35938				return false;
35939			},
35940			set: function () {
35941				console.warn('THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.');
35942			}
35943		},
35944		gammaOutput: {
35945			get: function () {
35946				console.warn('THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.');
35947				return false;
35948			},
35949			set: function (value) {
35950				console.warn('THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.');
35951				this.outputEncoding = value === true ? sRGBEncoding : LinearEncoding;
35952			}
35953		},
35954		toneMappingWhitePoint: {
35955			get: function () {
35956				console.warn('THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.');
35957				return 1.0;
35958			},
35959			set: function () {
35960				console.warn('THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.');
35961			}
35962		},
35963		gammaFactor: {
35964			get: function () {
35965				console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.');
35966				return 2;
35967			},
35968			set: function () {
35969				console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.');
35970			}
35971		}
35972	});
35973	Object.defineProperties(WebGLShadowMap.prototype, {
35974		cullFace: {
35975			get: function () {
35976				console.warn('THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.');
35977				return undefined;
35978			},
35979			set: function () {
35980				console.warn('THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.');
35981			}
35982		},
35983		renderReverseSided: {
35984			get: function () {
35985				console.warn('THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.');
35986				return undefined;
35987			},
35988			set: function () {
35989				console.warn('THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.');
35990			}
35991		},
35992		renderSingleSided: {
35993			get: function () {
35994				console.warn('THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.');
35995				return undefined;
35996			},
35997			set: function () {
35998				console.warn('THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.');
35999			}
36000		}
36001	});
36002	function WebGLRenderTargetCube(width, height, options) {
36003		console.warn('THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).');
36004		return new WebGLCubeRenderTarget(width, options);
36005	} //
36006
36007	Object.defineProperties(WebGLRenderTarget.prototype, {
36008		wrapS: {
36009			get: function () {
36010				console.warn('THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.');
36011				return this.texture.wrapS;
36012			},
36013			set: function (value) {
36014				console.warn('THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.');
36015				this.texture.wrapS = value;
36016			}
36017		},
36018		wrapT: {
36019			get: function () {
36020				console.warn('THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.');
36021				return this.texture.wrapT;
36022			},
36023			set: function (value) {
36024				console.warn('THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.');
36025				this.texture.wrapT = value;
36026			}
36027		},
36028		magFilter: {
36029			get: function () {
36030				console.warn('THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.');
36031				return this.texture.magFilter;
36032			},
36033			set: function (value) {
36034				console.warn('THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.');
36035				this.texture.magFilter = value;
36036			}
36037		},
36038		minFilter: {
36039			get: function () {
36040				console.warn('THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.');
36041				return this.texture.minFilter;
36042			},
36043			set: function (value) {
36044				console.warn('THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.');
36045				this.texture.minFilter = value;
36046			}
36047		},
36048		anisotropy: {
36049			get: function () {
36050				console.warn('THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.');
36051				return this.texture.anisotropy;
36052			},
36053			set: function (value) {
36054				console.warn('THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.');
36055				this.texture.anisotropy = value;
36056			}
36057		},
36058		offset: {
36059			get: function () {
36060				console.warn('THREE.WebGLRenderTarget: .offset is now .texture.offset.');
36061				return this.texture.offset;
36062			},
36063			set: function (value) {
36064				console.warn('THREE.WebGLRenderTarget: .offset is now .texture.offset.');
36065				this.texture.offset = value;
36066			}
36067		},
36068		repeat: {
36069			get: function () {
36070				console.warn('THREE.WebGLRenderTarget: .repeat is now .texture.repeat.');
36071				return this.texture.repeat;
36072			},
36073			set: function (value) {
36074				console.warn('THREE.WebGLRenderTarget: .repeat is now .texture.repeat.');
36075				this.texture.repeat = value;
36076			}
36077		},
36078		format: {
36079			get: function () {
36080				console.warn('THREE.WebGLRenderTarget: .format is now .texture.format.');
36081				return this.texture.format;
36082			},
36083			set: function (value) {
36084				console.warn('THREE.WebGLRenderTarget: .format is now .texture.format.');
36085				this.texture.format = value;
36086			}
36087		},
36088		type: {
36089			get: function () {
36090				console.warn('THREE.WebGLRenderTarget: .type is now .texture.type.');
36091				return this.texture.type;
36092			},
36093			set: function (value) {
36094				console.warn('THREE.WebGLRenderTarget: .type is now .texture.type.');
36095				this.texture.type = value;
36096			}
36097		},
36098		generateMipmaps: {
36099			get: function () {
36100				console.warn('THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.');
36101				return this.texture.generateMipmaps;
36102			},
36103			set: function (value) {
36104				console.warn('THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.');
36105				this.texture.generateMipmaps = value;
36106			}
36107		}
36108	}); //
36109
36110	Audio.prototype.load = function (file) {
36111		console.warn('THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.');
36112		const scope = this;
36113		const audioLoader = new AudioLoader();
36114		audioLoader.load(file, function (buffer) {
36115			scope.setBuffer(buffer);
36116		});
36117		return this;
36118	};
36119
36120	AudioAnalyser.prototype.getData = function () {
36121		console.warn('THREE.AudioAnalyser: .getData() is now .getFrequencyData().');
36122		return this.getFrequencyData();
36123	}; //
36124
36125
36126	CubeCamera.prototype.updateCubeMap = function (renderer, scene) {
36127		console.warn('THREE.CubeCamera: .updateCubeMap() is now .update(
36127).');
36128		return this.update(renderer, scene);
36129	};
36130
36131	CubeCamera.prototype.clear = function (renderer, color, depth, stencil) {
36132		console.warn('THREE.CubeCamera: .clear() is now .renderTarget.clear().');
36133		return this.renderTarget.clear(renderer, color, depth, stencil);
36134	};
36135
36136	ImageUtils.crossOrigin = undefined;
36137
36138	ImageUtils.loadTexture = function (url, mapping, onLoad, onError) {
36139		console.warn('THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.');
36140		const loader = new TextureLoader();
36141		loader.setCrossOrigin(this.crossOrigin);
36142		const texture = loader.load(url, onLoad, undefined, onError);
36143		if (mapping) texture.mapping = mapping;
36144		return texture;
36145	};
36146
36147	ImageUtils.loadTextureCube = function (urls, mapping, onLoad, onError) {
36148		console.warn('THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.');
36149		const loader = new CubeTextureLoader();
36150		loader.setCrossOrigin(this.crossOrigin);
36151		const texture = loader.load(urls, onLoad, undefined, onError);
36152		if (mapping) texture.mapping = mapping;
36153		return texture;
36154	};
36155
36156	ImageUtils.loadCompressedTexture = function () {
36157		console.error('THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.');
36158	};
36159
36160	ImageUtils.loadCompressedTextureCube = function () {
36161		console.error('THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.');
36162	}; //
36163
36164
36165	function CanvasRenderer() {
36166		console.error('THREE.CanvasRenderer has been removed');
36167	} //
36168
36169	function JSONLoader() {
36170		console.error('THREE.JSONLoader has been removed.');
36171	} //
36172
36173	const SceneUtils = {
36174		createMultiMaterialObject: function () {
36175			console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js');
36176		},
36177		detach: function () {
36178			console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js');
36179		},
36180		attach: function () {
36181			console.error('THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js');
36182		}
36183	}; //
36184
36185	function LensFlare() {
36186		console.error('THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js');
36187	} //
36188
36189	function ParametricGeometry() {
36190		console.error('THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js');
36191		return new BufferGeometry();
36192	}
36193	function TextGeometry() {
36194		console.error('THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js');
36195		return new BufferGeometry();
36196	}
36197	function FontLoader() {
36198		console.error('THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js');
36199	}
36200	function Font() {
36201		console.error('THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js');
36202	}
36203	function ImmediateRenderObject() {
36204		console.error('THREE.ImmediateRenderObject has been removed.');
36205	}
36206
36207	if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
36208		__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('register', {
36209			detail: {
36210				revision: REVISION
36211			}
36212		}));
36213	}
36214
36215	if (typeof window !== 'undefined') {
36216		if (window.__THREE__) {
36217			console.warn('WARNING: Multiple instances of Three.js being imported.');
36218		} else {
36219			window.__THREE__ = REVISION;
36220		}
36221	}
36222
36223	exports.ACESFilmicToneMapping = ACESFilmicToneMapping;
36224	exports.AddEquation = AddEquation;
36225	exports.AddOperation = AddOperation;
36226	exports.AdditiveAnimationBlendMode = AdditiveAnimationBlendMode;
36227	exports.AdditiveBlending = AdditiveBlending;
36228	exports.AlphaFormat = AlphaFormat;
36229	exports.AlwaysDepth = AlwaysDepth;
36230	exports.AlwaysStencilFunc = AlwaysStencilFunc;
36231	exports.AmbientLight = AmbientLight;
36232	exports.AmbientLightProbe = AmbientLightProbe;
36233	exports.AnimationClip = AnimationClip;
36234	exports.AnimationLoader = AnimationLoader;
36235	exports.AnimationMixer = AnimationMixer;
36236	exports.AnimationObjectGroup = AnimationObjectGroup;
36237	exports.AnimationUtils = AnimationUtils;
36238	exports.ArcCurve = ArcCurve;
36239	exports.ArrayCamera = ArrayCamera;
36240	exports.ArrowHelper = ArrowHelper;
36241	exports.Audio = Audio;
36242	exports.AudioAnalyser = AudioAnalyser;
36243	exports.AudioContext = AudioContext;
36244	exports.AudioListener = AudioListener;
36245	exports.AudioLoader = AudioLoader;
36246	exports.AxesHelper = AxesHelper;
36247	exports.AxisHelper = AxisHelper;
36248	exports.BackSide = BackSide;
36249	exports.BasicDepthPacking = BasicDepthPacking;
36250	exports.BasicShadowMap = BasicShadowMap;
36251	exports.BinaryTextureLoader = BinaryTextureLoader;
36252	exports.Bone = Bone;
36253	exports.BooleanKeyframeTrack = BooleanKeyframeTrack;
36254	exports.BoundingBoxHelper = BoundingBoxHelper;
36255	exports.Box2 = Box2;
36256	exports.Box3 = Box3;
36257	exports.Box3Helper = Box3Helper;
36258	exports.BoxBufferGeometry = BoxGeometry;
36259	exports.BoxGeometry = BoxGeometry;
36260	exports.BoxHelper = BoxHelper;
36261	exports.BufferAttribute = BufferAttribute;
36262	exports.BufferGeometry = BufferGeometry;
36263	exports.BufferGeometryLoader = BufferGeometryLoader;
36264	exports.ByteType = ByteType;
36265	exports.Cache = Cache;
36266	exports.Camera = Camera;
36267	exports.CameraHelper = CameraHelper;
36268	exports.CanvasRenderer = CanvasRenderer;
36269	exports.CanvasTexture = CanvasTexture;
36270	exports.CatmullRomCurve3 = CatmullRomCurve3;
36271	exports.CineonToneMapping = CineonToneMapping;
36272	exports.CircleBufferGeometry = CircleGeometry;
36273	exports.CircleGeometry = CircleGeometry;
36274	exports.ClampToEdgeWrapping = ClampToEdgeWrapping;
36275	exports.Clock = Clock;
36276	exports.Color = Color;
36277	exports.ColorKeyframeTrack = ColorKeyframeTrack;
36278	exports.CompressedTexture = CompressedTexture;
36279	exports.CompressedTextureLoader = CompressedTextureLoader;
36280	exports.ConeBufferGeometry = ConeGeometry;
36281	exports.ConeGeometry = ConeGeometry;
36282	exports.CubeCamera = CubeCamera;
36283	exports.CubeReflectionMapping = CubeReflectionMapping;
36284	exports.CubeRefractionMapping = CubeRefractionMapping;
36285	exports.CubeTexture = CubeTexture;
36286	exports.CubeTextureLoader = CubeTextureLoader;
36287	exports.CubeUVReflectionMapping = CubeUVReflectionMapping;
36288	exports.CubeUVRefractionMapping = CubeUVRefractionMapping;
36289	exports.CubicBezierCurve = CubicBezierCurve;
36290	exports.CubicBezierCurve3 = CubicBezierCurve3;
36291	exports.CubicInterpolant = CubicInterpolant;
36292	exports.CullFaceBack = CullFaceBack;
36293	exports.CullFaceFront = CullFaceFront;
36294	exports.CullFaceFrontBack = CullFaceFrontBack;
36295	exports.CullFaceNone = CullFaceNone;
36296	exports.Curve = Curve;
36297	exports.CurvePath = CurvePath;
36298	exports.CustomBlending = CustomBlending;
36299	exports.CustomToneMapping = CustomToneMapping;
36300	exports.CylinderBufferGeometry = CylinderGeometry;
36301	exports.CylinderGeometry = CylinderGeometry;
36302	exports.Cylindrical = Cylindrical;
36303	exports.DataTexture = DataTexture;
36304	exports.DataTexture2DArray = DataTexture2DArray;
36305	exports.DataTexture3D = DataTexture3D;
36306	exports.DataTextureLoader = DataTextureLoader;
36307	exports.DataUtils = DataUtils;
36308	exports.DecrementStencilOp = DecrementStencilOp;
36309	exports.DecrementWrapStencilOp = DecrementWrapStencilOp;
36310	exports.DefaultLoadingManager = DefaultLoadingManager;
36311	exports.DepthFormat = DepthFormat;
36312	exports.DepthStencilFormat = DepthStencilFormat;
36313	exports.DepthTexture = DepthTexture;
36314	exports.DirectionalLight = DirectionalLight;
36315	exports.DirectionalLightHelper = DirectionalLightHelper;
36316	exports.DiscreteInterpolant = DiscreteInterpolant;
36317	exports.DodecahedronBufferGeometry = DodecahedronGeometry;
36318	exports.DodecahedronGeometry = DodecahedronGeometry;
36319	exports.DoubleSide = DoubleSide;
36320	exports.DstAlphaFactor = DstAlphaFactor;
36321	exports.DstColorFactor = DstColorFactor;
36322	exports.DynamicBufferAttribute = DynamicBufferAttribute;
36323	exports.DynamicCopyUsage = DynamicCopyUsage;
36324	exports.DynamicDrawUsage = DynamicDrawUsage;
36325	exports.DynamicReadUsage = DynamicReadUsage;
36326	exports.EdgesGeometry = EdgesGeometry;
36327	exports.EdgesHelper = EdgesHelper;
36328	exports.EllipseCurve = EllipseCurve;
36329	exports.EqualDepth = EqualDepth;
36330	exports.EqualStencilFunc = EqualStencilFunc;
36331	exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;
36332	exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;
36333	exports.Euler = Euler;
36334	exports.EventDispatcher = EventDispatcher;
36335	exports.ExtrudeBufferGeometry = ExtrudeGeometry;
36336	exports.ExtrudeGeometry = ExtrudeGeometry;
36337	exports.FaceColors = FaceColors;
36338	exports.FileLoader = FileLoader;
36339	exports.FlatShading = FlatShading;
36340	exports.Float16BufferAttribute = Float16BufferAttribute;
36341	exports.Float32Attribute = Float32Attribute;
36342	exports.Float32BufferAttribute = Float32BufferAttribute;
36343	exports.Float64Attribute = Float64Attribute;
36344	exports.Float64BufferAttribute = Float64BufferAttribute;
36345	exports.FloatType = FloatType;
36346	exports.Fog = Fog;
36347	exports.FogExp2 = FogExp2;
36348	exports.Font = Font;
36349	exports.FontLoader = FontLoader;
36350	exports.FramebufferTexture = FramebufferTexture;
36351	exports.FrontSide = FrontSide;
36352	exports.Frustum = Frustum;
36353	exports.GLBufferAttribute = GLBufferAttribute;
36354	exports.GLSL1 = GLSL1;
36355	exports.GLSL3 = GLSL3;
36356	exports.GreaterDepth = GreaterDepth;
36357	exports.GreaterEqualDepth = GreaterEqualDepth;
36358	exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc;
36359	exports.GreaterStencilFunc = GreaterStencilFunc;
36360	exports.GridHelper = GridHelper;
36361	exports.Group = Group;
36362	exports.HalfFloatType = HalfFloatType;
36363	exports.HemisphereLight = HemisphereLight;
36364	exports.HemisphereLightHelper = HemisphereLightHelper;
36365	exports.HemisphereLightProbe = HemisphereLightProbe;
36366	exports.IcosahedronBufferGeometry = IcosahedronGeometry;
36367	exports.IcosahedronGeometry = IcosahedronGeometry;
36368	exports.ImageBitmapLoader = ImageBitmapLoader;
36369	exports.ImageLoader = ImageLoader;
36370	exports.ImageUtils = ImageUtils;
36371	exports.ImmediateRenderObject = ImmediateRenderObject;
36372	exports.IncrementStencilOp = IncrementStencilOp;
36373	exports.IncrementWrapStencilOp = IncrementWrapStencilOp;
36374	exports.InstancedBufferAttribute = InstancedBufferAttribute;
36375	exports.InstancedBufferGeometry = InstancedBufferGeometry;
36376	exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;
36377	exports.InstancedMesh = InstancedMesh;
36378	exports.Int16Attribute = Int16Attribute;
36379	exports.Int16BufferAttribute = Int16BufferAttribute;
36380	exports.Int32Attribute = Int32Attribute;
36381	exports.Int32BufferAttribute = Int32BufferAttribute;
36382	exports.Int8Attribute = Int8Attribute;
36383	exports.Int8BufferAttribute = Int8BufferAttribute;
36384	exports.IntType = IntType;
36385	exports.InterleavedBuffer = InterleavedBuffer;
36386	exports.InterleavedBufferAttribute = InterleavedBufferAttribute;
36387	exports.Interpolant = Interpolant;
36388	exports.InterpolateDiscrete = InterpolateDiscrete;
36389	exports.InterpolateLinear = InterpolateLinear;
36390	exports.InterpolateSmooth = InterpolateSmooth;
36391	exports.InvertStencilOp = InvertStencilOp;
36392	exports.JSONLoader = JSONLoader;
36393	exports.KeepStencilOp = KeepStencilOp;
36394	exports.KeyframeTrack = KeyframeTrack;
36395	exports.LOD = LOD;
36396	exports.LatheBufferGeometry = LatheGeometry;
36397	exports.LatheGeometry = LatheGeometry;
36398	exports.Layers = Layers;
36399	exports.LensFlare = LensFlare;
36400	exports.LessDepth = LessDepth;
36401	exports.LessEqualDepth = LessEqualDepth;
36402	exports.LessEqualStencilFunc = LessEqualStencilFunc;
36403	exports.LessStencilFunc = LessStencilFunc;
36404	exports.Light = Light;
36405	exports.LightProbe = LightProbe;
36406	exports.Line = Line;
36407	exports.Line3 = Line3;
36408	exports.LineBasicMaterial = LineBasicMaterial;
36409	exports.LineCurve = LineCurve;
36410	exports.LineCurve3 = LineCurve3;
36411	exports.LineDashedMaterial = LineDashedMaterial;
36412	exports.LineLoop = LineLoop;
36413	exports.LinePieces = LinePieces;
36414	exports.LineSegments = LineSegments;
36415	exports.LineStrip = LineStrip;
36416	exports.LinearEncoding = LinearEncoding;
36417	exports.LinearFilter = LinearFilter;
36418	exports.LinearInterpolant = LinearInterpolant;
36419	exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;
36420	exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;
36421	exports.LinearMipmapLinearFilter = LinearMipmapLinearFilter;
36422	exports.LinearMipmapNearestFilter = LinearMipmapNearestFilter;
36423	exports.LinearToneMapping = LinearToneMapping;
36424	exports.Loader = Loader;
36425	exports.LoaderUtils = LoaderUtils;
36426	exports.LoadingManager = LoadingManager;
36427	exports.LoopOnce = LoopOnce;
36428	exports.LoopPingPong = LoopPingPong;
36429	exports.LoopRepeat = LoopRepeat;
36430	exports.LuminanceAlphaFormat = LuminanceAlphaFormat;
36431	exports.LuminanceFormat = LuminanceFormat;
36432	exports.MOUSE = MOUSE;
36433	exports.Material = Material;
36434	exports.MaterialLoader = MaterialLoader;
36435	exports.Math = MathUtils;
36436	exports.MathUtils = MathUtils;
36437	exports.Matrix3 = Matrix3;
36438	exports.Matrix4 = Matrix4;
36439	exports.MaxEquation = MaxEquation;
36440	exports.Mesh = Mesh;
36441	exports.MeshBasicMaterial = MeshBasicMaterial;
36442	exports.MeshDepthMaterial = MeshDepthMaterial;
36443	exports.MeshDistanceMaterial = MeshDistanceMaterial;
36444	exports.MeshFaceMaterial = MeshFaceMaterial;
36445	exports.MeshLambertMaterial = MeshLambertMaterial;
36446	exports.MeshMatcapMaterial = MeshMatcapMaterial;
36447	exports.MeshNormalMaterial = MeshNormalMaterial;
36448	exports.MeshPhongMaterial = MeshPhongMaterial;
36449	exports.MeshPhysicalMaterial = MeshPhysicalMaterial;
36450	exports.MeshStandardMaterial = MeshStandardMaterial;
36451	exports.MeshToonMaterial = MeshToonMaterial;
36452	exports.MinEquation = MinEquation;
36453	exports.MirroredRepeatWrapping = MirroredRepeatWrapping;
36454	exports.MixOperation = MixOperation;
36455	exports.MultiMaterial = MultiMaterial;
36456	exports.MultiplyBlending = MultiplyBlending;
36457	exports.MultiplyOperation = MultiplyOperation;
36458	exports.NearestFilter = NearestFilter;
36459	exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;
36460	exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;
36461	exports.NearestMipmapLinearFilter = NearestMipmapLinearFilter;
36462	exports.NearestMipmapNearestFilter = NearestMipmapNearestFilter;
36463	exports.NeverDepth = NeverDepth;
36464	exports.NeverStencilFunc = NeverStencilFunc;
36465	exports.NoBlending = NoBlending;
36466	exports.NoColors = NoColors;
36467	exports.NoToneMapping = NoToneMapping;
36468	exports.NormalAnimationBlendMode = NormalAnimationBlendMode;
36469	exports.NormalBlending = NormalBlending;
36470	exports.NotEqualDepth = NotEqualDepth;
36471	exports.NotEqualStencilFunc = NotEqualStencilFunc;
36472	exports.NumberKeyframeTrack = NumberKeyframeTrack;
36473	exports.Object3D = Object3D;
36474	exports.ObjectLoader = ObjectLoader;
36475	exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap;
36476	exports.OctahedronBufferGeometry = OctahedronGeometry;
36477	exports.OctahedronGeometry = OctahedronGeometry;
36478	exports.OneFactor = OneFactor;
36479	exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;
36480	exports.OneMinusDstColorFactor = OneMinusDstColorFactor;
36481	exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;
36482	exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;
36483	exports.OrthographicCamera = OrthographicCamera;
36484	exports.PCFShadowMap = PCFShadowMap;
36485	exports.PCFSoftShadowMap = PCFSoftShadowMap;
36486	exports.PMREMGenerator = PMREMGenerator;
36487	exports.ParametricGeometry = ParametricGeometry;
36488	exports.Particle = Particle;
36489	exports.ParticleBasicMaterial = ParticleBasicMaterial;
36490	exports.ParticleSystem = ParticleSystem;
36491	exports.ParticleSystemMaterial = ParticleSystemMaterial;
36492	exports.Path = Path;
36493	exports.PerspectiveCamera = PerspectiveCamera;
36494	exports.Plane = Plane;
36495	exports.PlaneBufferGeometry = PlaneGeometry;
36496	exports.PlaneGeometry = PlaneGeometry;
36497	exports.PlaneHelper = PlaneHelper;
36498	exports.PointCloud = PointCloud;
36499	exports.PointCloudMaterial = PointCloudMaterial;
36500	exports.PointLight = PointLight;
36501	exports.PointLightHelper = PointLightHelper;
36502	exports.Points = Points;
36503	exports.PointsMaterial = PointsMaterial;
36504	exports.PolarGridHelper = PolarGridHelper;
36505	exports.PolyhedronBufferGeometry = PolyhedronGeometry;
36506	exports.PolyhedronGeometry = PolyhedronGeometry;
36507	exports.PositionalAudio = PositionalAudio;
36508	exports.PropertyBinding = PropertyBinding;
36509	exports.PropertyMixer = PropertyMixer;
36510	exports.QuadraticBezierCurve = QuadraticBezierCurve;
36511	exports.QuadraticBezierCurve3 = QuadraticBezierCurve3;
36512	exports.Quaternion = Quaternion;
36513	exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;
36514	exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;
36515	exports.REVISION = REVISION;
36516	exports.RGBADepthPacking = RGBADepthPacking;
36517	exports.RGBAFormat = RGBAFormat;
36518	exports.RGBAIntegerFormat = RGBAIntegerFormat;
36519	exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format;
36520	exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format;
36521	exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format;
36522	exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format;
36523	exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format;
36524	exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format;
36525	exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format;
36526	exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format;
36527	exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format;
36528	exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format;
36529	exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format;
36530	exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format;
36531	exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format;
36532	exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format;
36533	exports.RGBA_BPTC_Format = RGBA_BPTC_Format;
36534	exports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format;
36535	exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;
36536	exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;
36537	exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;
36538	exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;
36539	exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;
36540	exports.RGBFormat = RGBFormat;
36541	exports.RGBIntegerFormat = RGBIntegerFormat;
36542	exports.RGB_ETC1_Format = RGB_ETC1_Format;
36543	exports.RGB_ETC2_Format = RGB_ETC2_Format;
36544	exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;
36545	exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;
36546	exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;
36547	exports.RGFormat = RGFormat;
36548	exports.RGIntegerFormat = RGIntegerFormat;
36549	exports.RawShaderMaterial = RawShaderMaterial;
36550	exports.Ray = Ray;
36551	exports.Raycaster = Raycaster;
36552	exports.RectAreaLight = RectAreaLight;
36553	exports.RedFormat = RedFormat;
36554	exports.RedIntegerFormat = RedIntegerFormat;
36555	exports.ReinhardToneMapping = ReinhardToneMapping;
36556	exports.RepeatWrapping = RepeatWrapping;
36557	exports.ReplaceStencilOp = ReplaceStencilOp;
36558	exports.ReverseSubtractEquation = ReverseSubtractEquation;
36559	exports.RingBufferGeometry = RingGeometry;
36560	exports.RingGeometry = RingGeometry;
36561	exports.SRGB8_ALPHA8_ASTC_10x10_Format = SRGB8_ALPHA8_ASTC_10x10_Format;
36562	exports.SRGB8_ALPHA8_ASTC_10x5_Format = SRGB8_ALPHA8_ASTC_10x5_Format;
36563	exports.SRGB8_ALPHA8_ASTC_10x6_Format = SRGB8_ALPHA8_ASTC_10x6_Format;
36564	exports.SRGB8_ALPHA8_ASTC_10x8_Format = SRGB8_ALPHA8_ASTC_10x8_Format;
36565	exports.SRGB8_ALPHA8_ASTC_12x10_Format = SRGB8_ALPHA8_ASTC_12x10_Format;
36566	exports.SRGB8_ALPHA8_ASTC_12x12_Format = SRGB8_ALPHA8_ASTC_12x12_Format;
36567	exports.SRGB8_ALPHA8_ASTC_4x4_Format = SRGB8_ALPHA8_ASTC_4x4_Format;
36568	exports.SRGB8_ALPHA8_ASTC_5x4_Format = SRGB8_ALPHA8_ASTC_5x4_Format;
36569	exports.SRGB8_ALPHA8_ASTC_5x5_Format = SRGB8_ALPHA8_ASTC_5x5_Format;
36570	exports.SRGB8_ALPHA8_ASTC_6x5_Format = SRGB8_ALPHA8_ASTC_6x5_Format;
36571	exports.SRGB8_ALPHA8_ASTC_6x6_Format = SRGB8_ALPHA8_ASTC_6x6_Format;
36572	exports.SRGB8_ALPHA8_ASTC_8x5_Format = SRGB8_ALPHA8_ASTC_8x5_Format;
36573	exports.SRGB8_ALPHA8_ASTC_8x6_Format = SRGB8_ALPHA8_ASTC_8x6_Format;
36574	exports.SRGB8_ALPHA8_ASTC_8x8_Format = SRGB8_ALPHA8_ASTC_8x8_Format;
36575	exports.Scene = Scene;
36576	exports.SceneUtils = SceneUtils;
36577	exports.ShaderChunk = ShaderChunk;
36578	exports.ShaderLib = ShaderLib;
36579	exports.ShaderMaterial = ShaderMaterial;
36580	exports.ShadowMaterial = ShadowMaterial;
36581	exports.Shape = Shape;
36582	exports.ShapeBufferGeometry = ShapeGeometry;
36583	exports.ShapeGeometry = ShapeGeometry;
36584	exports.ShapePath = ShapePath;
36585	exports.ShapeUtils = ShapeUtils;
36586	exports.ShortType = ShortType;
36587	exports.Skeleton = Skeleton;
36588	exports.SkeletonHelper = SkeletonHelper;
36589	exports.SkinnedMesh = SkinnedMesh;
36590	exports.SmoothShading = SmoothShading;
36591	exports.Sphere = Sphere;
36592	exports.SphereBufferGeometry = SphereGeometry;
36593	exports.SphereGeometry = SphereGeometry;
36594	exports.Spherical = Spherical;
36595	exports.SphericalHarmonics3 = SphericalHarmonics3;
36596	exports.SplineCurve = SplineCurve;
36597	exports.SpotLight = SpotLight;
36598	exports.SpotLightHelper = SpotLightHelper;
36599	exports.Sprite = Sprite;
36600	exports.SpriteMaterial = SpriteMaterial;
36601	exports.SrcAlphaFactor = SrcAlphaFactor;
36602	exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;
36603	exports.SrcColorFactor = SrcColorFactor;
36604	exports.StaticCopyUsage = StaticCopyUsage;
36605	exports.StaticDrawUsage = StaticDrawUsage;
36606	exports.StaticReadUsage = StaticReadUsage;
36607	exports.StereoCamera = StereoCamera;
36608	exports.StreamCopyUsage = StreamCopyUsage;
36609	exports.StreamDrawUsage = StreamDrawUsage;
36610	exports.StreamReadUsage = StreamReadUsage;
36611	exports.StringKeyframeTrack = StringKeyframeTrack;
36612	exports.SubtractEquation = SubtractEquation;
36613	exports.SubtractiveBlending = SubtractiveBlending;
36614	exports.TOUCH = TOUCH;
36615	exports.TangentSpaceNormalMap = TangentSpaceNormalMap;
36616	exports.TetrahedronBufferGeometry = TetrahedronGeometry;
36617	exports.TetrahedronGeometry = TetrahedronGeometry;
36618	exports.TextGeometry = TextGeometry;
36619	exports.Texture = Texture;
36620	exports.TextureLoader = TextureLoader;
36621	exports.TorusBufferGeometry = TorusGeometry;
36622	exports.TorusGeometry = TorusGeometry;
36623	exports.TorusKnotBufferGeometry = TorusKnotGeometry;
36624	exports.TorusKnotGeometry = TorusKnotGeometry;
36625	exports.Triangle = Triangle;
36626	exports.TriangleFanDrawMode = TriangleFanDrawMode;
36627	exports.TriangleStripDrawMode = TriangleStripDrawMode;
36628	exports.TrianglesDrawMode = TrianglesDrawMode;
36629	exports.TubeBufferGeometry = TubeGeometry;
36630	exports.TubeGeometry = TubeGeometry;
36631	exports.UVMapping = UVMapping;
36632	exports.Uint16Attribute = Uint16Attribute;
36633	exports.Uint16BufferAttribute = Uint16BufferAttribute;
36634	exports.Uint32Attribute = Uint32Attribute;
36635	exports.Uint32BufferAttribute = Uint32BufferAttribute;
36636	exports.Uint8Attribute = Uint8Attribute;
36637	exports.Uint8BufferAttribute = Uint8BufferAttribute;
36638	exports.Uint8ClampedAttribute = Uint8ClampedAttribute;
36639	exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;
36640	exports.Uniform = Uniform;
36641	exports.UniformsLib = UniformsLib;
36642	exports.UniformsUtils = UniformsUtils;
36643	exports.UnsignedByteType = UnsignedByteType;
36644	exports.UnsignedInt248Type = UnsignedInt248Type;
36645	exports.UnsignedIntType = UnsignedIntType;
36646	exports.UnsignedShort4444Type = UnsignedShort4444Type;
36647	exports.UnsignedShort5551Type = UnsignedShort5551Type;
36648	exports.UnsignedShort565Type = UnsignedShort565Type;
36649	exports.UnsignedShortType = UnsignedShortType;
36650	exports.VSMShadowMap = VSMShadowMap;
36651	exports.Vector2 = Vector2;
36652	exports.Vector3 = Vector3;
36653	exports.Vector4 = Vector4;
36654	exports.VectorKeyframeTrack = VectorKeyframeTrack;
36655	exports.Vertex = Vertex;
36656	exports.VertexColors = VertexColors;
36657	exports.VideoTexture = VideoTexture;
36658	exports.WebGL1Renderer = WebGL1Renderer;
36659	exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget;
36660	exports.WebGLMultipleRenderTargets = WebGLMultipleRenderTargets;
36661	exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget;
36662	exports.WebGLRenderTarget = WebGLRenderTarget;
36663	exports.WebGLRenderTargetCube = WebGLRenderTargetCube;
36664	exports.WebGLRenderer = WebGLRenderer;
36665	exports.WebGLUtils = WebGLUtils;
36666	exports.WireframeGeometry = WireframeGeometry;
36667	exports.WireframeHelper = WireframeHelper;
36668	exports.WrapAroundEnding = WrapAroundEnding;
36669	exports.XHRLoader = XHRLoader;
36670	exports.ZeroCurvatureEnding = ZeroCurvatureEnding;
36671	exports.ZeroFactor = ZeroFactor;
36672	exports.ZeroSlopeEnding = ZeroSlopeEnding;
36673	exports.ZeroStencilOp = ZeroStencilOp;
36674	exports.sRGBEncoding = sRGBEncoding;
36675
36676	Object.defineProperty(exports, '__esModule', { value: true });
36677
36678}));

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.