UNPKG

1.24 MBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = global || self, factory(global.THREE = {}));
5}(this, (function (exports) { 'use strict';
6
7 // Polyfills
8
9 if ( Number.EPSILON === undefined ) {
10
11 Number.EPSILON = Math.pow( 2, - 52 );
12
13 }
14
15 if ( Number.isInteger === undefined ) {
16
17 // Missing in IE
18 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
19
20 Number.isInteger = function ( value ) {
21
22 return typeof value === 'number' && isFinite( value ) && Math.floor( value ) === value;
23
24 };
25
26 }
27
28 //
29
30 if ( Math.sign === undefined ) {
31
32 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
33
34 Math.sign = function ( x ) {
35
36 return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x;
37
38 };
39
40 }
41
42 if ( 'name' in Function.prototype === false ) {
43
44 // Missing in IE
45 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
46
47 Object.defineProperty( Function.prototype, 'name', {
48
49 get: function () {
50
51 return this.toString().match( /^\s*function\s*([^\(\s]*)/ )[ 1 ];
52
53 }
54
55 } );
56
57 }
58
59 if ( Object.assign === undefined ) {
60
61 // Missing in IE
62 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
63
64 Object.assign = function ( target ) {
65
66 if ( target === undefined || target === null ) {
67
68 throw new TypeError( 'Cannot convert undefined or null to object' );
69
70 }
71
72 var output = Object( target );
73
74 for ( var index = 1; index < arguments.length; index ++ ) {
75
76 var source = arguments[ index ];
77
78 if ( source !== undefined && source !== null ) {
79
80 for ( var nextKey in source ) {
81
82 if ( Object.prototype.hasOwnProperty.call( source, nextKey ) ) {
83
84 output[ nextKey ] = source[ nextKey ];
85
86 }
87
88 }
89
90 }
91
92 }
93
94 return output;
95
96 };
97
98 }
99
100 var REVISION = '119';
101 var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
102 var TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
103 var CullFaceNone = 0;
104 var CullFaceBack = 1;
105 var CullFaceFront = 2;
106 var CullFaceFrontBack = 3;
107 var BasicShadowMap = 0;
108 var PCFShadowMap = 1;
109 var PCFSoftShadowMap = 2;
110 var VSMShadowMap = 3;
111 var FrontSide = 0;
112 var BackSide = 1;
113 var DoubleSide = 2;
114 var FlatShading = 1;
115 var SmoothShading = 2;
116 var NoBlending = 0;
117 var NormalBlending = 1;
118 var AdditiveBlending = 2;
119 var SubtractiveBlending = 3;
120 var MultiplyBlending = 4;
121 var CustomBlending = 5;
122 var AddEquation = 100;
123 var SubtractEquation = 101;
124 var ReverseSubtractEquation = 102;
125 var MinEquation = 103;
126 var MaxEquation = 104;
127 var ZeroFactor = 200;
128 var OneFactor = 201;
129 var SrcColorFactor = 202;
130 var OneMinusSrcColorFactor = 203;
131 var SrcAlphaFactor = 204;
132 var OneMinusSrcAlphaFactor = 205;
133 var DstAlphaFactor = 206;
134 var OneMinusDstAlphaFactor = 207;
135 var DstColorFactor = 208;
136 var OneMinusDstColorFactor = 209;
137 var SrcAlphaSaturateFactor = 210;
138 var NeverDepth = 0;
139 var AlwaysDepth = 1;
140 var LessDepth = 2;
141 var LessEqualDepth = 3;
142 var EqualDepth = 4;
143 var GreaterEqualDepth = 5;
144 var GreaterDepth = 6;
145 var NotEqualDepth = 7;
146 var MultiplyOperation = 0;
147 var MixOperation = 1;
148 var AddOperation = 2;
149 var NoToneMapping = 0;
150 var LinearToneMapping = 1;
151 var ReinhardToneMapping = 2;
152 var CineonToneMapping = 3;
153 var ACESFilmicToneMapping = 4;
154 var CustomToneMapping = 5;
155
156 var UVMapping = 300;
157 var CubeReflectionMapping = 301;
158 var CubeRefractionMapping = 302;
159 var EquirectangularReflectionMapping = 303;
160 var EquirectangularRefractionMapping = 304;
161 var CubeUVReflectionMapping = 306;
162 var CubeUVRefractionMapping = 307;
163 var RepeatWrapping = 1000;
164 var ClampToEdgeWrapping = 1001;
165 var MirroredRepeatWrapping = 1002;
166 var NearestFilter = 1003;
167 var NearestMipmapNearestFilter = 1004;
168 var NearestMipMapNearestFilter = 1004;
169 var NearestMipmapLinearFilter = 1005;
170 var NearestMipMapLinearFilter = 1005;
171 var LinearFilter = 1006;
172 var LinearMipmapNearestFilter = 1007;
173 var LinearMipMapNearestFilter = 1007;
174 var LinearMipmapLinearFilter = 1008;
175 var LinearMipMapLinearFilter = 1008;
176 var UnsignedByteType = 1009;
177 var ByteType = 1010;
178 var ShortType = 1011;
179 var UnsignedShortType = 1012;
180 var IntType = 1013;
181 var UnsignedIntType = 1014;
182 var FloatType = 1015;
183 var HalfFloatType = 1016;
184 var UnsignedShort4444Type = 1017;
185 var UnsignedShort5551Type = 1018;
186 var UnsignedShort565Type = 1019;
187 var UnsignedInt248Type = 1020;
188 var AlphaFormat = 1021;
189 var RGBFormat = 1022;
190 var RGBAFormat = 1023;
191 var LuminanceFormat = 1024;
192 var LuminanceAlphaFormat = 1025;
193 var RGBEFormat = RGBAFormat;
194 var DepthFormat = 1026;
195 var DepthStencilFormat = 1027;
196 var RedFormat = 1028;
197 var RedIntegerFormat = 1029;
198 var RGFormat = 1030;
199 var RGIntegerFormat = 1031;
200 var RGBIntegerFormat = 1032;
201 var RGBAIntegerFormat = 1033;
202
203 var RGB_S3TC_DXT1_Format = 33776;
204 var RGBA_S3TC_DXT1_Format = 33777;
205 var RGBA_S3TC_DXT3_Format = 33778;
206 var RGBA_S3TC_DXT5_Format = 33779;
207 var RGB_PVRTC_4BPPV1_Format = 35840;
208 var RGB_PVRTC_2BPPV1_Format = 35841;
209 var RGBA_PVRTC_4BPPV1_Format = 35842;
210 var RGBA_PVRTC_2BPPV1_Format = 35843;
211 var RGB_ETC1_Format = 36196;
212 var RGB_ETC2_Format = 37492;
213 var RGBA_ETC2_EAC_Format = 37496;
214 var RGBA_ASTC_4x4_Format = 37808;
215 var RGBA_ASTC_5x4_Format = 37809;
216 var RGBA_ASTC_5x5_Format = 37810;
217 var RGBA_ASTC_6x5_Format = 37811;
218 var RGBA_ASTC_6x6_Format = 37812;
219 var RGBA_ASTC_8x5_Format = 37813;
220 var RGBA_ASTC_8x6_Format = 37814;
221 var RGBA_ASTC_8x8_Format = 37815;
222 var RGBA_ASTC_10x5_Format = 37816;
223 var RGBA_ASTC_10x6_Format = 37817;
224 var RGBA_ASTC_10x8_Format = 37818;
225 var RGBA_ASTC_10x10_Format = 37819;
226 var RGBA_ASTC_12x10_Format = 37820;
227 var RGBA_ASTC_12x12_Format = 37821;
228 var RGBA_BPTC_Format = 36492;
229 var SRGB8_ALPHA8_ASTC_4x4_Format = 37840;
230 var SRGB8_ALPHA8_ASTC_5x4_Format = 37841;
231 var SRGB8_ALPHA8_ASTC_5x5_Format = 37842;
232 var SRGB8_ALPHA8_ASTC_6x5_Format = 37843;
233 var SRGB8_ALPHA8_ASTC_6x6_Format = 37844;
234 var SRGB8_ALPHA8_ASTC_8x5_Format = 37845;
235 var SRGB8_ALPHA8_ASTC_8x6_Format = 37846;
236 var SRGB8_ALPHA8_ASTC_8x8_Format = 37847;
237 var SRGB8_ALPHA8_ASTC_10x5_Format = 37848;
238 var SRGB8_ALPHA8_ASTC_10x6_Format = 37849;
239 var SRGB8_ALPHA8_ASTC_10x8_Format = 37850;
240 var SRGB8_ALPHA8_ASTC_10x10_Format = 37851;
241 var SRGB8_ALPHA8_ASTC_12x10_Format = 37852;
242 var SRGB8_ALPHA8_ASTC_12x12_Format = 37853;
243 var LoopOnce = 2200;
244 var LoopRepeat = 2201;
245 var LoopPingPong = 2202;
246 var InterpolateDiscrete = 2300;
247 var InterpolateLinear = 2301;
248 var InterpolateSmooth = 2302;
249 var ZeroCurvatureEnding = 2400;
250 var ZeroSlopeEnding = 2401;
251 var WrapAroundEnding = 2402;
252 var NormalAnimationBlendMode = 2500;
253 var AdditiveAnimationBlendMode = 2501;
254 var TrianglesDrawMode = 0;
255 var TriangleStripDrawMode = 1;
256 var TriangleFanDrawMode = 2;
257 var LinearEncoding = 3000;
258 var sRGBEncoding = 3001;
259 var GammaEncoding = 3007;
260 var RGBEEncoding = 3002;
261 var LogLuvEncoding = 3003;
262 var RGBM7Encoding = 3004;
263 var RGBM16Encoding = 3005;
264 var RGBDEncoding = 3006;
265 var BasicDepthPacking = 3200;
266 var RGBADepthPacking = 3201;
267 var TangentSpaceNormalMap = 0;
268 var ObjectSpaceNormalMap = 1;
269
270 var ZeroStencilOp = 0;
271 var KeepStencilOp = 7680;
272 var ReplaceStencilOp = 7681;
273 var IncrementStencilOp = 7682;
274 var DecrementStencilOp = 7683;
275 var IncrementWrapStencilOp = 34055;
276 var DecrementWrapStencilOp = 34056;
277 var InvertStencilOp = 5386;
278
279 var NeverStencilFunc = 512;
280 var LessStencilFunc = 513;
281 var EqualStencilFunc = 514;
282 var LessEqualStencilFunc = 515;
283 var GreaterStencilFunc = 516;
284 var NotEqualStencilFunc = 517;
285 var GreaterEqualStencilFunc = 518;
286 var AlwaysStencilFunc = 519;
287
288 var StaticDrawUsage = 35044;
289 var DynamicDrawUsage = 35048;
290 var StreamDrawUsage = 35040;
291 var StaticReadUsage = 35045;
292 var DynamicReadUsage = 35049;
293 var StreamReadUsage = 35041;
294 var StaticCopyUsage = 35046;
295 var DynamicCopyUsage = 35050;
296 var StreamCopyUsage = 35042;
297
298 /**
299 * https://github.com/mrdoob/eventdispatcher.js/
300 */
301
302 function EventDispatcher() {}
303
304 Object.assign( EventDispatcher.prototype, {
305
306 addEventListener: function ( type, listener ) {
307
308 if ( this._listeners === undefined ) { this._listeners = {}; }
309
310 var listeners = this._listeners;
311
312 if ( listeners[ type ] === undefined ) {
313
314 listeners[ type ] = [];
315
316 }
317
318 if ( listeners[ type ].indexOf( listener ) === - 1 ) {
319
320 listeners[ type ].push( listener );
321
322 }
323
324 },
325
326 hasEventListener: function ( type, listener ) {
327
328 if ( this._listeners === undefined ) { return false; }
329
330 var listeners = this._listeners;
331
332 return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
333
334 },
335
336 removeEventListener: function ( type, listener ) {
337
338 if ( this._listeners === undefined ) { return; }
339
340 var listeners = this._listeners;
341 var listenerArray = listeners[ type ];
342
343 if ( listenerArray !== undefined ) {
344
345 var index = listenerArray.indexOf( listener );
346
347 if ( index !== - 1 ) {
348
349 listenerArray.splice( index, 1 );
350
351 }
352
353 }
354
355 },
356
357 dispatchEvent: function ( event ) {
358
359 if ( this._listeners === undefined ) { return; }
360
361 var listeners = this._listeners;
362 var listenerArray = listeners[ event.type ];
363
364 if ( listenerArray !== undefined ) {
365
366 event.target = this;
367
368 // Make a copy, in case listeners are removed while iterating.
369 var array = listenerArray.slice( 0 );
370
371 for ( var i = 0, l = array.length; i < l; i ++ ) {
372
373 array[ i ].call( this, event );
374
375 }
376
377 }
378
379 }
380
381 } );
382
383 var _lut = [];
384
385 for ( var i = 0; i < 256; i ++ ) {
386
387 _lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 );
388
389 }
390
391 var _seed = 1234567;
392
393 var MathUtils = {
394
395 DEG2RAD: Math.PI / 180,
396 RAD2DEG: 180 / Math.PI,
397
398 generateUUID: function () {
399
400 // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136
401
402 var d0 = Math.random() * 0xffffffff | 0;
403 var d1 = Math.random() * 0xffffffff | 0;
404 var d2 = Math.random() * 0xffffffff | 0;
405 var d3 = Math.random() * 0xffffffff | 0;
406 var uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' +
407 _lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' +
408 _lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] +
409 _lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ];
410
411 // .toUpperCase() here flattens concatenated strings to save heap memory space.
412 return uuid.toUpperCase();
413
414 },
415
416 clamp: function ( value, min, max ) {
417
418 return Math.max( min, Math.min( max, value ) );
419
420 },
421
422 // compute euclidian modulo of m % n
423 // https://en.wikipedia.org/wiki/Modulo_operation
424
425 euclideanModulo: function ( n, m ) {
426
427 return ( ( n % m ) + m ) % m;
428
429 },
430
431 // Linear mapping from range <a1, a2> to range <b1, b2>
432
433 mapLinear: function ( x, a1, a2, b1, b2 ) {
434
435 return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
436
437 },
438
439 // https://en.wikipedia.org/wiki/Linear_interpolation
440
441 lerp: function ( x, y, t ) {
442
443 return ( 1 - t ) * x + t * y;
444
445 },
446
447 // http://en.wikipedia.org/wiki/Smoothstep
448
449 smoothstep: function ( x, min, max ) {
450
451 if ( x <= min ) { return 0; }
452 if ( x >= max ) { return 1; }
453
454 x = ( x - min ) / ( max - min );
455
456 return x * x * ( 3 - 2 * x );
457
458 },
459
460 smootherstep: function ( x, min, max ) {
461
462 if ( x <= min ) { return 0; }
463 if ( x >= max ) { return 1; }
464
465 x = ( x - min ) / ( max - min );
466
467 return x * x * x * ( x * ( x * 6 - 15 ) + 10 );
468
469 },
470
471 // Random integer from <low, high> interval
472
473 randInt: function ( low, high ) {
474
475 return low + Math.floor( Math.random() * ( high - low + 1 ) );
476
477 },
478
479 // Random float from <low, high> interval
480
481 randFloat: function ( low, high ) {
482
483 return low + Math.random() * ( high - low );
484
485 },
486
487 // Random float from <-range/2, range/2> interval
488
489 randFloatSpread: function ( range ) {
490
491 return range * ( 0.5 - Math.random() );
492
493 },
494
495 // Deterministic pseudo-random float in the interval [ 0, 1 ]
496
497 seededRandom: function ( s ) {
498
499 if ( s !== undefined ) { _seed = s % 2147483647; }
500
501 // Park-Miller algorithm
502
503 _seed = _seed * 16807 % 2147483647;
504
505 return ( _seed - 1 ) / 2147483646;
506
507 },
508
509 degToRad: function ( degrees ) {
510
511 return degrees * MathUtils.DEG2RAD;
512
513 },
514
515 radToDeg: function ( radians ) {
516
517 return radians * MathUtils.RAD2DEG;
518
519 },
520
521 isPowerOfTwo: function ( value ) {
522
523 return ( value & ( value - 1 ) ) === 0 && value !== 0;
524
525 },
526
527 ceilPowerOfTwo: function ( value ) {
528
529 return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) );
530
531 },
532
533 floorPowerOfTwo: function ( value ) {
534
535 return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) );
536
537 },
538
539 setQuaternionFromProperEuler: function ( q, a, b, c, order ) {
540
541 // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles
542
543 // rotations are applied to the axes in the order specified by 'order'
544 // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c'
545 // angles are in radians
546
547 var cos = Math.cos;
548 var sin = Math.sin;
549
550 var c2 = cos( b / 2 );
551 var s2 = sin( b / 2 );
552
553 var c13 = cos( ( a + c ) / 2 );
554 var s13 = sin( ( a + c ) / 2 );
555
556 var c1_3 = cos( ( a - c ) / 2 );
557 var s1_3 = sin( ( a - c ) / 2 );
558
559 var c3_1 = cos( ( c - a ) / 2 );
560 var s3_1 = sin( ( c - a ) / 2 );
561
562 switch ( order ) {
563
564 case 'XYX':
565 q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 );
566 break;
567
568 case 'YZY':
569 q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 );
570 break;
571
572 case 'ZXZ':
573 q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 );
574 break;
575
576 case 'XZX':
577 q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 );
578 break;
579
580 case 'YXY':
581 q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 );
582 break;
583
584 case 'ZYZ':
585 q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 );
586 break;
587
588 default:
589 console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order );
590
591 }
592
593 }
594
595 };
596
597 function Vector2( x, y ) {
598 if ( x === void 0 ) x = 0;
599 if ( y === void 0 ) y = 0;
600
601
602 this.x = x;
603 this.y = y;
604
605 }
606
607 Object.defineProperties( Vector2.prototype, {
608
609 "width": {
610
611 get: function () {
612
613 return this.x;
614
615 },
616
617 set: function ( value ) {
618
619 this.x = value;
620
621 }
622
623 },
624
625 "height": {
626
627 get: function () {
628
629 return this.y;
630
631 },
632
633 set: function ( value ) {
634
635 this.y = value;
636
637 }
638
639 }
640
641 } );
642
643 Object.assign( Vector2.prototype, {
644
645 isVector2: true,
646
647 set: function ( x, y ) {
648
649 this.x = x;
650 this.y = y;
651
652 return this;
653
654 },
655
656 setScalar: function ( scalar ) {
657
658 this.x = scalar;
659 this.y = scalar;
660
661 return this;
662
663 },
664
665 setX: function ( x ) {
666
667 this.x = x;
668
669 return this;
670
671 },
672
673 setY: function ( y ) {
674
675 this.y = y;
676
677 return this;
678
679 },
680
681 setComponent: function ( index, value ) {
682
683 switch ( index ) {
684
685 case 0: this.x = value; break;
686 case 1: this.y = value; break;
687 default: throw new Error( 'index is out of range: ' + index );
688
689 }
690
691 return this;
692
693 },
694
695 getComponent: function ( index ) {
696
697 switch ( index ) {
698
699 case 0: return this.x;
700 case 1: return this.y;
701 default: throw new Error( 'index is out of range: ' + index );
702
703 }
704
705 },
706
707 clone: function () {
708
709 return new this.constructor( this.x, this.y );
710
711 },
712
713 copy: function ( v ) {
714
715 this.x = v.x;
716 this.y = v.y;
717
718 return this;
719
720 },
721
722 add: function ( v, w ) {
723
724 if ( w !== undefined ) {
725
726 console.warn( 'THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
727 return this.addVectors( v, w );
728
729 }
730
731 this.x += v.x;
732 this.y += v.y;
733
734 return this;
735
736 },
737
738 addScalar: function ( s ) {
739
740 this.x += s;
741 this.y += s;
742
743 return this;
744
745 },
746
747 addVectors: function ( a, b ) {
748
749 this.x = a.x + b.x;
750 this.y = a.y + b.y;
751
752 return this;
753
754 },
755
756 addScaledVector: function ( v, s ) {
757
758 this.x += v.x * s;
759 this.y += v.y * s;
760
761 return this;
762
763 },
764
765 sub: function ( v, w ) {
766
767 if ( w !== undefined ) {
768
769 console.warn( 'THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
770 return this.subVectors( v, w );
771
772 }
773
774 this.x -= v.x;
775 this.y -= v.y;
776
777 return this;
778
779 },
780
781 subScalar: function ( s ) {
782
783 this.x -= s;
784 this.y -= s;
785
786 return this;
787
788 },
789
790 subVectors: function ( a, b ) {
791
792 this.x = a.x - b.x;
793 this.y = a.y - b.y;
794
795 return this;
796
797 },
798
799 multiply: function ( v ) {
800
801 this.x *= v.x;
802 this.y *= v.y;
803
804 return this;
805
806 },
807
808 multiplyScalar: function ( scalar ) {
809
810 this.x *= scalar;
811 this.y *= scalar;
812
813 return this;
814
815 },
816
817 divide: function ( v ) {
818
819 this.x /= v.x;
820 this.y /= v.y;
821
822 return this;
823
824 },
825
826 divideScalar: function ( scalar ) {
827
828 return this.multiplyScalar( 1 / scalar );
829
830 },
831
832 applyMatrix3: function ( m ) {
833
834 var x = this.x, y = this.y;
835 var e = m.elements;
836
837 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ];
838 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ];
839
840 return this;
841
842 },
843
844 min: function ( v ) {
845
846 this.x = Math.min( this.x, v.x );
847 this.y = Math.min( this.y, v.y );
848
849 return this;
850
851 },
852
853 max: function ( v ) {
854
855 this.x = Math.max( this.x, v.x );
856 this.y = Math.max( this.y, v.y );
857
858 return this;
859
860 },
861
862 clamp: function ( min, max ) {
863
864 // assumes min < max, componentwise
865
866 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
867 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
868
869 return this;
870
871 },
872
873 clampScalar: function ( minVal, maxVal ) {
874
875 this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
876 this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
877
878 return this;
879
880 },
881
882 clampLength: function ( min, max ) {
883
884 var length = this.length();
885
886 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
887
888 },
889
890 floor: function () {
891
892 this.x = Math.floor( this.x );
893 this.y = Math.floor( this.y );
894
895 return this;
896
897 },
898
899 ceil: function () {
900
901 this.x = Math.ceil( this.x );
902 this.y = Math.ceil( this.y );
903
904 return this;
905
906 },
907
908 round: function () {
909
910 this.x = Math.round( this.x );
911 this.y = Math.round( this.y );
912
913 return this;
914
915 },
916
917 roundToZero: function () {
918
919 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
920 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
921
922 return this;
923
924 },
925
926 negate: function () {
927
928 this.x = - this.x;
929 this.y = - this.y;
930
931 return this;
932
933 },
934
935 dot: function ( v ) {
936
937 return this.x * v.x + this.y * v.y;
938
939 },
940
941 cross: function ( v ) {
942
943 return this.x * v.y - this.y * v.x;
944
945 },
946
947 lengthSq: function () {
948
949 return this.x * this.x + this.y * this.y;
950
951 },
952
953 length: function () {
954
955 return Math.sqrt( this.x * this.x + this.y * this.y );
956
957 },
958
959 manhattanLength: function () {
960
961 return Math.abs( this.x ) + Math.abs( this.y );
962
963 },
964
965 normalize: function () {
966
967 return this.divideScalar( this.length() || 1 );
968
969 },
970
971 angle: function () {
972
973 // computes the angle in radians with respect to the positive x-axis
974
975 var angle = Math.atan2( - this.y, - this.x ) + Math.PI;
976
977 return angle;
978
979 },
980
981 distanceTo: function ( v ) {
982
983 return Math.sqrt( this.distanceToSquared( v ) );
984
985 },
986
987 distanceToSquared: function ( v ) {
988
989 var dx = this.x - v.x, dy = this.y - v.y;
990 return dx * dx + dy * dy;
991
992 },
993
994 manhattanDistanceTo: function ( v ) {
995
996 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y );
997
998 },
999
1000 setLength: function ( length ) {
1001
1002 return this.normalize().multiplyScalar( length );
1003
1004 },
1005
1006 lerp: function ( v, alpha ) {
1007
1008 this.x += ( v.x - this.x ) * alpha;
1009 this.y += ( v.y - this.y ) * alpha;
1010
1011 return this;
1012
1013 },
1014
1015 lerpVectors: function ( v1, v2, alpha ) {
1016
1017 this.x = v1.x + ( v2.x - v1.x ) * alpha;
1018 this.y = v1.y + ( v2.y - v1.y ) * alpha;
1019
1020 return this;
1021
1022 },
1023
1024 equals: function ( v ) {
1025
1026 return ( ( v.x === this.x ) && ( v.y === this.y ) );
1027
1028 },
1029
1030 fromArray: function ( array, offset ) {
1031
1032 if ( offset === undefined ) { offset = 0; }
1033
1034 this.x = array[ offset ];
1035 this.y = array[ offset + 1 ];
1036
1037 return this;
1038
1039 },
1040
1041 toArray: function ( array, offset ) {
1042
1043 if ( array === undefined ) { array = []; }
1044 if ( offset === undefined ) { offset = 0; }
1045
1046 array[ offset ] = this.x;
1047 array[ offset + 1 ] = this.y;
1048
1049 return array;
1050
1051 },
1052
1053 fromBufferAttribute: function ( attribute, index, offset ) {
1054
1055 if ( offset !== undefined ) {
1056
1057 console.warn( 'THREE.Vector2: offset has been removed from .fromBufferAttribute().' );
1058
1059 }
1060
1061 this.x = attribute.getX( index );
1062 this.y = attribute.getY( index );
1063
1064 return this;
1065
1066 },
1067
1068 rotateAround: function ( center, angle ) {
1069
1070 var c = Math.cos( angle ), s = Math.sin( angle );
1071
1072 var x = this.x - center.x;
1073 var y = this.y - center.y;
1074
1075 this.x = x * c - y * s + center.x;
1076 this.y = x * s + y * c + center.y;
1077
1078 return this;
1079
1080 },
1081
1082 random: function () {
1083
1084 this.x = Math.random();
1085 this.y = Math.random();
1086
1087 return this;
1088
1089 }
1090
1091 } );
1092
1093 function Matrix3() {
1094
1095 this.elements = [
1096
1097 1, 0, 0,
1098 0, 1, 0,
1099 0, 0, 1
1100
1101 ];
1102
1103 if ( arguments.length > 0 ) {
1104
1105 console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' );
1106
1107 }
1108
1109 }
1110
1111 Object.assign( Matrix3.prototype, {
1112
1113 isMatrix3: true,
1114
1115 set: function ( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) {
1116
1117 var te = this.elements;
1118
1119 te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31;
1120 te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32;
1121 te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33;
1122
1123 return this;
1124
1125 },
1126
1127 identity: function () {
1128
1129 this.set(
1130
1131 1, 0, 0,
1132 0, 1, 0,
1133 0, 0, 1
1134
1135 );
1136
1137 return this;
1138
1139 },
1140
1141 clone: function () {
1142
1143 return new this.constructor().fromArray( this.elements );
1144
1145 },
1146
1147 copy: function ( m ) {
1148
1149 var te = this.elements;
1150 var me = m.elements;
1151
1152 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ];
1153 te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ];
1154 te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ];
1155
1156 return this;
1157
1158 },
1159
1160 extractBasis: function ( xAxis, yAxis, zAxis ) {
1161
1162 xAxis.setFromMatrix3Column( this, 0 );
1163 yAxis.setFromMatrix3Column( this, 1 );
1164 zAxis.setFromMatrix3Column( this, 2 );
1165
1166 return this;
1167
1168 },
1169
1170 setFromMatrix4: function ( m ) {
1171
1172 var me = m.elements;
1173
1174 this.set(
1175
1176 me[ 0 ], me[ 4 ], me[ 8 ],
1177 me[ 1 ], me[ 5 ], me[ 9 ],
1178 me[ 2 ], me[ 6 ], me[ 10 ]
1179
1180 );
1181
1182 return this;
1183
1184 },
1185
1186 multiply: function ( m ) {
1187
1188 return this.multiplyMatrices( this, m );
1189
1190 },
1191
1192 premultiply: function ( m ) {
1193
1194 return this.multiplyMatrices( m, this );
1195
1196 },
1197
1198 multiplyMatrices: function ( a, b ) {
1199
1200 var ae = a.elements;
1201 var be = b.elements;
1202 var te = this.elements;
1203
1204 var a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ];
1205 var a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ];
1206 var a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ];
1207
1208 var b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ];
1209 var b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ];
1210 var b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ];
1211
1212 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31;
1213 te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32;
1214 te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33;
1215
1216 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31;
1217 te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32;
1218 te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33;
1219
1220 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31;
1221 te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32;
1222 te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33;
1223
1224 return this;
1225
1226 },
1227
1228 multiplyScalar: function ( s ) {
1229
1230 var te = this.elements;
1231
1232 te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s;
1233 te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s;
1234 te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s;
1235
1236 return this;
1237
1238 },
1239
1240 determinant: function () {
1241
1242 var te = this.elements;
1243
1244 var a = te[ 0 ], b = te[ 1 ], c = te[ 2 ],
1245 d = te[ 3 ], e = te[ 4 ], f = te[ 5 ],
1246 g = te[ 6 ], h = te[ 7 ], i = te[ 8 ];
1247
1248 return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
1249
1250 },
1251
1252 getInverse: function ( matrix, throwOnDegenerate ) {
1253
1254 if ( throwOnDegenerate !== undefined ) {
1255
1256 console.warn( "THREE.Matrix3: .getInverse() can no longer be configured to throw on degenerate." );
1257
1258 }
1259
1260 var me = matrix.elements,
1261 te = this.elements,
1262
1263 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ],
1264 n12 = me[ 3 ], n22 = me[ 4 ], n32 = me[ 5 ],
1265 n13 = me[ 6 ], n23 = me[ 7 ], n33 = me[ 8 ],
1266
1267 t11 = n33 * n22 - n32 * n23,
1268 t12 = n32 * n13 - n33 * n12,
1269 t13 = n23 * n12 - n22 * n13,
1270
1271 det = n11 * t11 + n21 * t12 + n31 * t13;
1272
1273 if ( det === 0 ) { return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); }
1274
1275 var detInv = 1 / det;
1276
1277 te[ 0 ] = t11 * detInv;
1278 te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv;
1279 te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv;
1280
1281 te[ 3 ] = t12 * detInv;
1282 te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv;
1283 te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv;
1284
1285 te[ 6 ] = t13 * detInv;
1286 te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv;
1287 te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv;
1288
1289 return this;
1290
1291 },
1292
1293 transpose: function () {
1294
1295 var tmp;
1296 var m = this.elements;
1297
1298 tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp;
1299 tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp;
1300 tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp;
1301
1302 return this;
1303
1304 },
1305
1306 getNormalMatrix: function ( matrix4 ) {
1307
1308 return this.setFromMatrix4( matrix4 ).getInverse( this ).transpose();
1309
1310 },
1311
1312 transposeIntoArray: function ( r ) {
1313
1314 var m = this.elements;
1315
1316 r[ 0 ] = m[ 0 ];
1317 r[ 1 ] = m[ 3 ];
1318 r[ 2 ] = m[ 6 ];
1319 r[ 3 ] = m[ 1 ];
1320 r[ 4 ] = m[ 4 ];
1321 r[ 5 ] = m[ 7 ];
1322 r[ 6 ] = m[ 2 ];
1323 r[ 7 ] = m[ 5 ];
1324 r[ 8 ] = m[ 8 ];
1325
1326 return this;
1327
1328 },
1329
1330 setUvTransform: function ( tx, ty, sx, sy, rotation, cx, cy ) {
1331
1332 var c = Math.cos( rotation );
1333 var s = Math.sin( rotation );
1334
1335 this.set(
1336 sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx,
1337 - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty,
1338 0, 0, 1
1339 );
1340
1341 },
1342
1343 scale: function ( sx, sy ) {
1344
1345 var te = this.elements;
1346
1347 te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx;
1348 te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy;
1349
1350 return this;
1351
1352 },
1353
1354 rotate: function ( theta ) {
1355
1356 var c = Math.cos( theta );
1357 var s = Math.sin( theta );
1358
1359 var te = this.elements;
1360
1361 var a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ];
1362 var a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ];
1363
1364 te[ 0 ] = c * a11 + s * a21;
1365 te[ 3 ] = c * a12 + s * a22;
1366 te[ 6 ] = c * a13 + s * a23;
1367
1368 te[ 1 ] = - s * a11 + c * a21;
1369 te[ 4 ] = - s * a12 + c * a22;
1370 te[ 7 ] = - s * a13 + c * a23;
1371
1372 return this;
1373
1374 },
1375
1376 translate: function ( tx, ty ) {
1377
1378 var te = this.elements;
1379
1380 te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ];
1381 te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ];
1382
1383 return this;
1384
1385 },
1386
1387 equals: function ( matrix ) {
1388
1389 var te = this.elements;
1390 var me = matrix.elements;
1391
1392 for ( var i = 0; i < 9; i ++ ) {
1393
1394 if ( te[ i ] !== me[ i ] ) { return false; }
1395
1396 }
1397
1398 return true;
1399
1400 },
1401
1402 fromArray: function ( array, offset ) {
1403
1404 if ( offset === undefined ) { offset = 0; }
1405
1406 for ( var i = 0; i < 9; i ++ ) {
1407
1408 this.elements[ i ] = array[ i + offset ];
1409
1410 }
1411
1412 return this;
1413
1414 },
1415
1416 toArray: function ( array, offset ) {
1417
1418 if ( array === undefined ) { array = []; }
1419 if ( offset === undefined ) { offset = 0; }
1420
1421 var te = this.elements;
1422
1423 array[ offset ] = te[ 0 ];
1424 array[ offset + 1 ] = te[ 1 ];
1425 array[ offset + 2 ] = te[ 2 ];
1426
1427 array[ offset + 3 ] = te[ 3 ];
1428 array[ offset + 4 ] = te[ 4 ];
1429 array[ offset + 5 ] = te[ 5 ];
1430
1431 array[ offset + 6 ] = te[ 6 ];
1432 array[ offset + 7 ] = te[ 7 ];
1433 array[ offset + 8 ] = te[ 8 ];
1434
1435 return array;
1436
1437 }
1438
1439 } );
1440
1441 var _canvas;
1442
1443 var ImageUtils = {
1444
1445 getDataURL: function ( image ) {
1446
1447 if ( /^data:/i.test( image.src ) ) {
1448
1449 return image.src;
1450
1451 }
1452
1453 if ( typeof HTMLCanvasElement == 'undefined' ) {
1454
1455 return image.src;
1456
1457 }
1458
1459 var canvas;
1460
1461 if ( image instanceof HTMLCanvasElement ) {
1462
1463 canvas = image;
1464
1465 } else {
1466
1467 if ( _canvas === undefined ) { _canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ); }
1468
1469 _canvas.width = image.width;
1470 _canvas.height = image.height;
1471
1472 var context = _canvas.getContext( '2d' );
1473
1474 if ( image instanceof ImageData ) {
1475
1476 context.putImageData( image, 0, 0 );
1477
1478 } else {
1479
1480 context.drawImage( image, 0, 0, image.width, image.height );
1481
1482 }
1483
1484 canvas = _canvas;
1485
1486 }
1487
1488 if ( canvas.width > 2048 || canvas.height > 2048 ) {
1489
1490 return canvas.toDataURL( 'image/jpeg', 0.6 );
1491
1492 } else {
1493
1494 return canvas.toDataURL( 'image/png' );
1495
1496 }
1497
1498 }
1499
1500 };
1501
1502 var textureId = 0;
1503
1504 function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
1505
1506 Object.defineProperty( this, 'id', { value: textureId ++ } );
1507
1508 this.uuid = MathUtils.generateUUID();
1509
1510 this.name = '';
1511
1512 this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
1513 this.mipmaps = [];
1514
1515 this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;
1516
1517 this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
1518 this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;
1519
1520 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
1521 this.minFilter = minFilter !== undefined ? minFilter : LinearMipmapLinearFilter;
1522
1523 this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
1524
1525 this.format = format !== undefined ? format : RGBAFormat;
1526 this.internalFormat = null;
1527 this.type = type !== undefined ? type : UnsignedByteType;
1528
1529 this.offset = new Vector2( 0, 0 );
1530 this.repeat = new Vector2( 1, 1 );
1531 this.center = new Vector2( 0, 0 );
1532 this.rotation = 0;
1533
1534 this.matrixAutoUpdate = true;
1535 this.matrix = new Matrix3();
1536
1537 this.generateMipmaps = true;
1538 this.premultiplyAlpha = false;
1539 this.flipY = true;
1540 this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
1541
1542 // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
1543 //
1544 // Also changing the encoding after already used by a Material will not automatically make the Material
1545 // update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
1546 this.encoding = encoding !== undefined ? encoding : LinearEncoding;
1547
1548 this.version = 0;
1549 this.onUpdate = null;
1550
1551 }
1552
1553 Texture.DEFAULT_IMAGE = undefined;
1554 Texture.DEFAULT_MAPPING = UVMapping;
1555
1556 Texture.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
1557
1558 constructor: Texture,
1559
1560 isTexture: true,
1561
1562 updateMatrix: function () {
1563
1564 this.matrix.setUvTransform( this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y );
1565
1566 },
1567
1568 clone: function () {
1569
1570 return new this.constructor().copy( this );
1571
1572 },
1573
1574 copy: function ( source ) {
1575
1576 this.name = source.name;
1577
1578 this.image = source.image;
1579 this.mipmaps = source.mipmaps.slice( 0 );
1580
1581 this.mapping = source.mapping;
1582
1583 this.wrapS = source.wrapS;
1584 this.wrapT = source.wrapT;
1585
1586 this.magFilter = source.magFilter;
1587 this.minFilter = source.minFilter;
1588
1589 this.anisotropy = source.anisotropy;
1590
1591 this.format = source.format;
1592 this.internalFormat = source.internalFormat;
1593 this.type = source.type;
1594
1595 this.offset.copy( source.offset );
1596 this.repeat.copy( source.repeat );
1597 this.center.copy( source.center );
1598 this.rotation = source.rotation;
1599
1600 this.matrixAutoUpdate = source.matrixAutoUpdate;
1601 this.matrix.copy( source.matrix );
1602
1603 this.generateMipmaps = source.generateMipmaps;
1604 this.premultiplyAlpha = source.premultiplyAlpha;
1605 this.flipY = source.flipY;
1606 this.unpackAlignment = source.unpackAlignment;
1607 this.encoding = source.encoding;
1608
1609 return this;
1610
1611 },
1612
1613 toJSON: function ( meta ) {
1614
1615 var isRootObject = ( meta === undefined || typeof meta === 'string' );
1616
1617 if ( ! isRootObject && meta.textures[ this.uuid ] !== undefined ) {
1618
1619 return meta.textures[ this.uuid ];
1620
1621 }
1622
1623 var output = {
1624
1625 metadata: {
1626 version: 4.5,
1627 type: 'Texture',
1628 generator: 'Texture.toJSON'
1629 },
1630
1631 uuid: this.uuid,
1632 name: this.name,
1633
1634 mapping: this.mapping,
1635
1636 repeat: [ this.repeat.x, this.repeat.y ],
1637 offset: [ this.offset.x, this.offset.y ],
1638 center: [ this.center.x, this.center.y ],
1639 rotation: this.rotation,
1640
1641 wrap: [ this.wrapS, this.wrapT ],
1642
1643 format: this.format,
1644 type: this.type,
1645 encoding: this.encoding,
1646
1647 minFilter: this.minFilter,
1648 magFilter: this.magFilter,
1649 anisotropy: this.anisotropy,
1650
1651 flipY: this.flipY,
1652
1653 premultiplyAlpha: this.premultiplyAlpha,
1654 unpackAlignment: this.unpackAlignment
1655
1656 };
1657
1658 if ( this.image !== undefined ) {
1659
1660 // TODO: Move to THREE.Image
1661
1662 var image = this.image;
1663
1664 if ( image.uuid === undefined ) {
1665
1666 image.uuid = MathUtils.generateUUID(); // UGH
1667
1668 }
1669
1670 if ( ! isRootObject && meta.images[ image.uuid ] === undefined ) {
1671
1672 var url;
1673
1674 if ( Array.isArray( image ) ) {
1675
1676 // process array of images e.g. CubeTexture
1677
1678 url = [];
1679
1680 for ( var i = 0, l = image.length; i < l; i ++ ) {
1681
1682 url.push( ImageUtils.getDataURL( image[ i ] ) );
1683
1684 }
1685
1686 } else {
1687
1688 // process single image
1689
1690 url = ImageUtils.getDataURL( image );
1691
1692 }
1693
1694 meta.images[ image.uuid ] = {
1695 uuid: image.uuid,
1696 url: url
1697 };
1698
1699 }
1700
1701 output.image = image.uuid;
1702
1703 }
1704
1705 if ( ! isRootObject ) {
1706
1707 meta.textures[ this.uuid ] = output;
1708
1709 }
1710
1711 return output;
1712
1713 },
1714
1715 dispose: function () {
1716
1717 this.dispatchEvent( { type: 'dispose' } );
1718
1719 },
1720
1721 transformUv: function ( uv ) {
1722
1723 if ( this.mapping !== UVMapping ) { return uv; }
1724
1725 uv.applyMatrix3( this.matrix );
1726
1727 if ( uv.x < 0 || uv.x > 1 ) {
1728
1729 switch ( this.wrapS ) {
1730
1731 case RepeatWrapping:
1732
1733 uv.x = uv.x - Math.floor( uv.x );
1734 break;
1735
1736 case ClampToEdgeWrapping:
1737
1738 uv.x = uv.x < 0 ? 0 : 1;
1739 break;
1740
1741 case MirroredRepeatWrapping:
1742
1743 if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {
1744
1745 uv.x = Math.ceil( uv.x ) - uv.x;
1746
1747 } else {
1748
1749 uv.x = uv.x - Math.floor( uv.x );
1750
1751 }
1752
1753 break;
1754
1755 }
1756
1757 }
1758
1759 if ( uv.y < 0 || uv.y > 1 ) {
1760
1761 switch ( this.wrapT ) {
1762
1763 case RepeatWrapping:
1764
1765 uv.y = uv.y - Math.floor( uv.y );
1766 break;
1767
1768 case ClampToEdgeWrapping:
1769
1770 uv.y = uv.y < 0 ? 0 : 1;
1771 break;
1772
1773 case MirroredRepeatWrapping:
1774
1775 if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {
1776
1777 uv.y = Math.ceil( uv.y ) - uv.y;
1778
1779 } else {
1780
1781 uv.y = uv.y - Math.floor( uv.y );
1782
1783 }
1784
1785 break;
1786
1787 }
1788
1789 }
1790
1791 if ( this.flipY ) {
1792
1793 uv.y = 1 - uv.y;
1794
1795 }
1796
1797 return uv;
1798
1799 }
1800
1801 } );
1802
1803 Object.defineProperty( Texture.prototype, "needsUpdate", {
1804
1805 set: function ( value ) {
1806
1807 if ( value === true ) { this.version ++; }
1808
1809 }
1810
1811 } );
1812
1813 function Vector4( x, y, z, w ) {
1814 if ( x === void 0 ) x = 0;
1815 if ( y === void 0 ) y = 0;
1816 if ( z === void 0 ) z = 0;
1817 if ( w === void 0 ) w = 1;
1818
1819
1820 this.x = x;
1821 this.y = y;
1822 this.z = z;
1823 this.w = w;
1824
1825 }
1826
1827 Object.defineProperties( Vector4.prototype, {
1828
1829 "width": {
1830
1831 get: function () {
1832
1833 return this.z;
1834
1835 },
1836
1837 set: function ( value ) {
1838
1839 this.z = value;
1840
1841 }
1842
1843 },
1844
1845 "height": {
1846
1847 get: function () {
1848
1849 return this.w;
1850
1851 },
1852
1853 set: function ( value ) {
1854
1855 this.w = value;
1856
1857 }
1858
1859 }
1860
1861 } );
1862
1863 Object.assign( Vector4.prototype, {
1864
1865 isVector4: true,
1866
1867 set: function ( x, y, z, w ) {
1868
1869 this.x = x;
1870 this.y = y;
1871 this.z = z;
1872 this.w = w;
1873
1874 return this;
1875
1876 },
1877
1878 setScalar: function ( scalar ) {
1879
1880 this.x = scalar;
1881 this.y = scalar;
1882 this.z = scalar;
1883 this.w = scalar;
1884
1885 return this;
1886
1887 },
1888
1889 setX: function ( x ) {
1890
1891 this.x = x;
1892
1893 return this;
1894
1895 },
1896
1897 setY: function ( y ) {
1898
1899 this.y = y;
1900
1901 return this;
1902
1903 },
1904
1905 setZ: function ( z ) {
1906
1907 this.z = z;
1908
1909 return this;
1910
1911 },
1912
1913 setW: function ( w ) {
1914
1915 this.w = w;
1916
1917 return this;
1918
1919 },
1920
1921 setComponent: function ( index, value ) {
1922
1923 switch ( index ) {
1924
1925 case 0: this.x = value; break;
1926 case 1: this.y = value; break;
1927 case 2: this.z = value; break;
1928 case 3: this.w = value; break;
1929 default: throw new Error( 'index is out of range: ' + index );
1930
1931 }
1932
1933 return this;
1934
1935 },
1936
1937 getComponent: function ( index ) {
1938
1939 switch ( index ) {
1940
1941 case 0: return this.x;
1942 case 1: return this.y;
1943 case 2: return this.z;
1944 case 3: return this.w;
1945 default: throw new Error( 'index is out of range: ' + index );
1946
1947 }
1948
1949 },
1950
1951 clone: function () {
1952
1953 return new this.constructor( this.x, this.y, this.z, this.w );
1954
1955 },
1956
1957 copy: function ( v ) {
1958
1959 this.x = v.x;
1960 this.y = v.y;
1961 this.z = v.z;
1962 this.w = ( v.w !== undefined ) ? v.w : 1;
1963
1964 return this;
1965
1966 },
1967
1968 add: function ( v, w ) {
1969
1970 if ( w !== undefined ) {
1971
1972 console.warn( 'THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
1973 return this.addVectors( v, w );
1974
1975 }
1976
1977 this.x += v.x;
1978 this.y += v.y;
1979 this.z += v.z;
1980 this.w += v.w;
1981
1982 return this;
1983
1984 },
1985
1986 addScalar: function ( s ) {
1987
1988 this.x += s;
1989 this.y += s;
1990 this.z += s;
1991 this.w += s;
1992
1993 return this;
1994
1995 },
1996
1997 addVectors: function ( a, b ) {
1998
1999 this.x = a.x + b.x;
2000 this.y = a.y + b.y;
2001 this.z = a.z + b.z;
2002 this.w = a.w + b.w;
2003
2004 return this;
2005
2006 },
2007
2008 addScaledVector: function ( v, s ) {
2009
2010 this.x += v.x * s;
2011 this.y += v.y * s;
2012 this.z += v.z * s;
2013 this.w += v.w * s;
2014
2015 return this;
2016
2017 },
2018
2019 sub: function ( v, w ) {
2020
2021 if ( w !== undefined ) {
2022
2023 console.warn( 'THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
2024 return this.subVectors( v, w );
2025
2026 }
2027
2028 this.x -= v.x;
2029 this.y -= v.y;
2030 this.z -= v.z;
2031 this.w -= v.w;
2032
2033 return this;
2034
2035 },
2036
2037 subScalar: function ( s ) {
2038
2039 this.x -= s;
2040 this.y -= s;
2041 this.z -= s;
2042 this.w -= s;
2043
2044 return this;
2045
2046 },
2047
2048 subVectors: function ( a, b ) {
2049
2050 this.x = a.x - b.x;
2051 this.y = a.y - b.y;
2052 this.z = a.z - b.z;
2053 this.w = a.w - b.w;
2054
2055 return this;
2056
2057 },
2058
2059 multiplyScalar: function ( scalar ) {
2060
2061 this.x *= scalar;
2062 this.y *= scalar;
2063 this.z *= scalar;
2064 this.w *= scalar;
2065
2066 return this;
2067
2068 },
2069
2070 applyMatrix4: function ( m ) {
2071
2072 var x = this.x, y = this.y, z = this.z, w = this.w;
2073 var e = m.elements;
2074
2075 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] * w;
2076 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] * w;
2077 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] * w;
2078 this.w = e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] * w;
2079
2080 return this;
2081
2082 },
2083
2084 divideScalar: function ( scalar ) {
2085
2086 return this.multiplyScalar( 1 / scalar );
2087
2088 },
2089
2090 setAxisAngleFromQuaternion: function ( q ) {
2091
2092 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
2093
2094 // q is assumed to be normalized
2095
2096 this.w = 2 * Math.acos( q.w );
2097
2098 var s = Math.sqrt( 1 - q.w * q.w );
2099
2100 if ( s < 0.0001 ) {
2101
2102 this.x = 1;
2103 this.y = 0;
2104 this.z = 0;
2105
2106 } else {
2107
2108 this.x = q.x / s;
2109 this.y = q.y / s;
2110 this.z = q.z / s;
2111
2112 }
2113
2114 return this;
2115
2116 },
2117
2118 setAxisAngleFromRotationMatrix: function ( m ) {
2119
2120 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
2121
2122 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
2123
2124 var angle, x, y, z; // variables for result
2125 var epsilon = 0.01, // margin to allow for rounding errors
2126 epsilon2 = 0.1, // margin to distinguish between 0 and 180 degrees
2127
2128 te = m.elements,
2129
2130 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
2131 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
2132 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
2133
2134 if ( ( Math.abs( m12 - m21 ) < epsilon ) &&
2135 ( Math.abs( m13 - m31 ) < epsilon ) &&
2136 ( Math.abs( m23 - m32 ) < epsilon ) ) {
2137
2138 // singularity found
2139 // first check for identity matrix which must have +1 for all terms
2140 // in leading diagonal and zero in other terms
2141
2142 if ( ( Math.abs( m12 + m21 ) < epsilon2 ) &&
2143 ( Math.abs( m13 + m31 ) < epsilon2 ) &&
2144 ( Math.abs( m23 + m32 ) < epsilon2 ) &&
2145 ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
2146
2147 // this singularity is identity matrix so angle = 0
2148
2149 this.set( 1, 0, 0, 0 );
2150
2151 return this; // zero angle, arbitrary axis
2152
2153 }
2154
2155 // otherwise this singularity is angle = 180
2156
2157 angle = Math.PI;
2158
2159 var xx = ( m11 + 1 ) / 2;
2160 var yy = ( m22 + 1 ) / 2;
2161 var zz = ( m33 + 1 ) / 2;
2162 var xy = ( m12 + m21 ) / 4;
2163 var xz = ( m13 + m31 ) / 4;
2164 var yz = ( m23 + m32 ) / 4;
2165
2166 if ( ( xx > yy ) && ( xx > zz ) ) {
2167
2168 // m11 is the largest diagonal term
2169
2170 if ( xx < epsilon ) {
2171
2172 x = 0;
2173 y = 0.707106781;
2174 z = 0.707106781;
2175
2176 } else {
2177
2178 x = Math.sqrt( xx );
2179 y = xy / x;
2180 z = xz / x;
2181
2182 }
2183
2184 } else if ( yy > zz ) {
2185
2186 // m22 is the largest diagonal term
2187
2188 if ( yy < epsilon ) {
2189
2190 x = 0.707106781;
2191 y = 0;
2192 z = 0.707106781;
2193
2194 } else {
2195
2196 y = Math.sqrt( yy );
2197 x = xy / y;
2198 z = yz / y;
2199
2200 }
2201
2202 } else {
2203
2204 // m33 is the largest diagonal term so base result on this
2205
2206 if ( zz < epsilon ) {
2207
2208 x = 0.707106781;
2209 y = 0.707106781;
2210 z = 0;
2211
2212 } else {
2213
2214 z = Math.sqrt( zz );
2215 x = xz / z;
2216 y = yz / z;
2217
2218 }
2219
2220 }
2221
2222 this.set( x, y, z, angle );
2223
2224 return this; // return 180 deg rotation
2225
2226 }
2227
2228 // as we have reached here there are no singularities so we can handle normally
2229
2230 var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 ) +
2231 ( m13 - m31 ) * ( m13 - m31 ) +
2232 ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
2233
2234 if ( Math.abs( s ) < 0.001 ) { s = 1; }
2235
2236 // prevent divide by zero, should not happen if matrix is orthogonal and should be
2237 // caught by singularity test above, but I've left it in just in case
2238
2239 this.x = ( m32 - m23 ) / s;
2240 this.y = ( m13 - m31 ) / s;
2241 this.z = ( m21 - m12 ) / s;
2242 this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
2243
2244 return this;
2245
2246 },
2247
2248 min: function ( v ) {
2249
2250 this.x = Math.min( this.x, v.x );
2251 this.y = Math.min( this.y, v.y );
2252 this.z = Math.min( this.z, v.z );
2253 this.w = Math.min( this.w, v.w );
2254
2255 return this;
2256
2257 },
2258
2259 max: function ( v ) {
2260
2261 this.x = Math.max( this.x, v.x );
2262 this.y = Math.max( this.y, v.y );
2263 this.z = Math.max( this.z, v.z );
2264 this.w = Math.max( this.w, v.w );
2265
2266 return this;
2267
2268 },
2269
2270 clamp: function ( min, max ) {
2271
2272 // assumes min < max, componentwise
2273
2274 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
2275 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
2276 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
2277 this.w = Math.max( min.w, Math.min( max.w, this.w ) );
2278
2279 return this;
2280
2281 },
2282
2283 clampScalar: function ( minVal, maxVal ) {
2284
2285 this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
2286 this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
2287 this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
2288 this.w = Math.max( minVal, Math.min( maxVal, this.w ) );
2289
2290 return this;
2291
2292 },
2293
2294 clampLength: function ( min, max ) {
2295
2296 var length = this.length();
2297
2298 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
2299
2300 },
2301
2302 floor: function () {
2303
2304 this.x = Math.floor( this.x );
2305 this.y = Math.floor( this.y );
2306 this.z = Math.floor( this.z );
2307 this.w = Math.floor( this.w );
2308
2309 return this;
2310
2311 },
2312
2313 ceil: function () {
2314
2315 this.x = Math.ceil( this.x );
2316 this.y = Math.ceil( this.y );
2317 this.z = Math.ceil( this.z );
2318 this.w = Math.ceil( this.w );
2319
2320 return this;
2321
2322 },
2323
2324 round: function () {
2325
2326 this.x = Math.round( this.x );
2327 this.y = Math.round( this.y );
2328 this.z = Math.round( this.z );
2329 this.w = Math.round( this.w );
2330
2331 return this;
2332
2333 },
2334
2335 roundToZero: function () {
2336
2337 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
2338 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
2339 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
2340 this.w = ( this.w < 0 ) ? Math.ceil( this.w ) : Math.floor( this.w );
2341
2342 return this;
2343
2344 },
2345
2346 negate: function () {
2347
2348 this.x = - this.x;
2349 this.y = - this.y;
2350 this.z = - this.z;
2351 this.w = - this.w;
2352
2353 return this;
2354
2355 },
2356
2357 dot: function ( v ) {
2358
2359 return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
2360
2361 },
2362
2363 lengthSq: function () {
2364
2365 return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
2366
2367 },
2368
2369 length: function () {
2370
2371 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
2372
2373 },
2374
2375 manhattanLength: function () {
2376
2377 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
2378
2379 },
2380
2381 normalize: function () {
2382
2383 return this.divideScalar( this.length() || 1 );
2384
2385 },
2386
2387 setLength: function ( length ) {
2388
2389 return this.normalize().multiplyScalar( length );
2390
2391 },
2392
2393 lerp: function ( v, alpha ) {
2394
2395 this.x += ( v.x - this.x ) * alpha;
2396 this.y += ( v.y - this.y ) * alpha;
2397 this.z += ( v.z - this.z ) * alpha;
2398 this.w += ( v.w - this.w ) * alpha;
2399
2400 return this;
2401
2402 },
2403
2404 lerpVectors: function ( v1, v2, alpha ) {
2405
2406 this.x = v1.x + ( v2.x - v1.x ) * alpha;
2407 this.y = v1.y + ( v2.y - v1.y ) * alpha;
2408 this.z = v1.z + ( v2.z - v1.z ) * alpha;
2409 this.w = v1.w + ( v2.w - v1.w ) * alpha;
2410
2411 return this;
2412
2413 },
2414
2415 equals: function ( v ) {
2416
2417 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) && ( v.w === this.w ) );
2418
2419 },
2420
2421 fromArray: function ( array, offset ) {
2422
2423 if ( offset === undefined ) { offset = 0; }
2424
2425 this.x = array[ offset ];
2426 this.y = array[ offset + 1 ];
2427 this.z = array[ offset + 2 ];
2428 this.w = array[ offset + 3 ];
2429
2430 return this;
2431
2432 },
2433
2434 toArray: function ( array, offset ) {
2435
2436 if ( array === undefined ) { array = []; }
2437 if ( offset === undefined ) { offset = 0; }
2438
2439 array[ offset ] = this.x;
2440 array[ offset + 1 ] = this.y;
2441 array[ offset + 2 ] = this.z;
2442 array[ offset + 3 ] = this.w;
2443
2444 return array;
2445
2446 },
2447
2448 fromBufferAttribute: function ( attribute, index, offset ) {
2449
2450 if ( offset !== undefined ) {
2451
2452 console.warn( 'THREE.Vector4: offset has been removed from .fromBufferAttribute().' );
2453
2454 }
2455
2456 this.x = attribute.getX( index );
2457 this.y = attribute.getY( index );
2458 this.z = attribute.getZ( index );
2459 this.w = attribute.getW( index );
2460
2461 return this;
2462
2463 },
2464
2465 random: function () {
2466
2467 this.x = Math.random();
2468 this.y = Math.random();
2469 this.z = Math.random();
2470 this.w = Math.random();
2471
2472 return this;
2473
2474 }
2475
2476 } );
2477
2478 /*
2479 In options, we can specify:
2480 * Texture parameters for an auto-generated target texture
2481 * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
2482 */
2483 function WebGLRenderTarget( width, height, options ) {
2484
2485 this.width = width;
2486 this.height = height;
2487
2488 this.scissor = new Vector4( 0, 0, width, height );
2489 this.scissorTest = false;
2490
2491 this.viewport = new Vector4( 0, 0, width, height );
2492
2493 options = options || {};
2494
2495 this.texture = new Texture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
2496
2497 this.texture.image = {};
2498 this.texture.image.width = width;
2499 this.texture.image.height = height;
2500
2501 this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
2502 this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
2503
2504 this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
2505 this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
2506 this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
2507
2508 }
2509
2510 WebGLRenderTarget.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
2511
2512 constructor: WebGLRenderTarget,
2513
2514 isWebGLRenderTarget: true,
2515
2516 setSize: function ( width, height ) {
2517
2518 if ( this.width !== width || this.height !== height ) {
2519
2520 this.width = width;
2521 this.height = height;
2522
2523 this.texture.image.width = width;
2524 this.texture.image.height = height;
2525
2526 this.dispose();
2527
2528 }
2529
2530 this.viewport.set( 0, 0, width, height );
2531 this.scissor.set( 0, 0, width, height );
2532
2533 },
2534
2535 clone: function () {
2536
2537 return new this.constructor().copy( this );
2538
2539 },
2540
2541 copy: function ( source ) {
2542
2543 this.width = source.width;
2544 this.height = source.height;
2545
2546 this.viewport.copy( source.viewport );
2547
2548 this.texture = source.texture.clone();
2549
2550 this.depthBuffer = source.depthBuffer;
2551 this.stencilBuffer = source.stencilBuffer;
2552 this.depthTexture = source.depthTexture;
2553
2554 return this;
2555
2556 },
2557
2558 dispose: function () {
2559
2560 this.dispatchEvent( { type: 'dispose' } );
2561
2562 }
2563
2564 } );
2565
2566 function WebGLMultisampleRenderTarget( width, height, options ) {
2567
2568 WebGLRenderTarget.call( this, width, height, options );
2569
2570 this.samples = 4;
2571
2572 }
2573
2574 WebGLMultisampleRenderTarget.prototype = Object.assign( Object.create( WebGLRenderTarget.prototype ), {
2575
2576 constructor: WebGLMultisampleRenderTarget,
2577
2578 isWebGLMultisampleRenderTarget: true,
2579
2580 copy: function ( source ) {
2581
2582 WebGLRenderTarget.prototype.copy.call( this, source );
2583
2584 this.samples = source.samples;
2585
2586 return this;
2587
2588 }
2589
2590 } );
2591
2592 function Quaternion( x, y, z, w ) {
2593 if ( x === void 0 ) x = 0;
2594 if ( y === void 0 ) y = 0;
2595 if ( z === void 0 ) z = 0;
2596 if ( w === void 0 ) w = 1;
2597
2598
2599 this._x = x;
2600 this._y = y;
2601 this._z = z;
2602 this._w = w;
2603
2604 }
2605
2606 Object.assign( Quaternion, {
2607
2608 slerp: function ( qa, qb, qm, t ) {
2609
2610 return qm.copy( qa ).slerp( qb, t );
2611
2612 },
2613
2614 slerpFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) {
2615
2616 // fuzz-free, array-based Quaternion SLERP operation
2617
2618 var x0 = src0[ srcOffset0 + 0 ],
2619 y0 = src0[ srcOffset0 + 1 ],
2620 z0 = src0[ srcOffset0 + 2 ],
2621 w0 = src0[ srcOffset0 + 3 ];
2622
2623 var x1 = src1[ srcOffset1 + 0 ],
2624 y1 = src1[ srcOffset1 + 1 ],
2625 z1 = src1[ srcOffset1 + 2 ],
2626 w1 = src1[ srcOffset1 + 3 ];
2627
2628 if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) {
2629
2630 var s = 1 - t,
2631
2632 cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
2633
2634 dir = ( cos >= 0 ? 1 : - 1 ),
2635 sqrSin = 1 - cos * cos;
2636
2637 // Skip the Slerp for tiny steps to avoid numeric problems:
2638 if ( sqrSin > Number.EPSILON ) {
2639
2640 var sin = Math.sqrt( sqrSin ),
2641 len = Math.atan2( sin, cos * dir );
2642
2643 s = Math.sin( s * len ) / sin;
2644 t = Math.sin( t * len ) / sin;
2645
2646 }
2647
2648 var tDir = t * dir;
2649
2650 x0 = x0 * s + x1 * tDir;
2651 y0 = y0 * s + y1 * tDir;
2652 z0 = z0 * s + z1 * tDir;
2653 w0 = w0 * s + w1 * tDir;
2654
2655 // Normalize in case we just did a lerp:
2656 if ( s === 1 - t ) {
2657
2658 var f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 );
2659
2660 x0 *= f;
2661 y0 *= f;
2662 z0 *= f;
2663 w0 *= f;
2664
2665 }
2666
2667 }
2668
2669 dst[ dstOffset ] = x0;
2670 dst[ dstOffset + 1 ] = y0;
2671 dst[ dstOffset + 2 ] = z0;
2672 dst[ dstOffset + 3 ] = w0;
2673
2674 },
2675
2676 multiplyQuaternionsFlat: function ( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) {
2677
2678 var x0 = src0[ srcOffset0 ];
2679 var y0 = src0[ srcOffset0 + 1 ];
2680 var z0 = src0[ srcOffset0 + 2 ];
2681 var w0 = src0[ srcOffset0 + 3 ];
2682
2683 var x1 = src1[ srcOffset1 ];
2684 var y1 = src1[ srcOffset1 + 1 ];
2685 var z1 = src1[ srcOffset1 + 2 ];
2686 var w1 = src1[ srcOffset1 + 3 ];
2687
2688 dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
2689 dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
2690 dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
2691 dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
2692
2693 return dst;
2694
2695 }
2696
2697 } );
2698
2699 Object.defineProperties( Quaternion.prototype, {
2700
2701 x: {
2702
2703 get: function () {
2704
2705 return this._x;
2706
2707 },
2708
2709 set: function ( value ) {
2710
2711 this._x = value;
2712 this._onChangeCallback();
2713
2714 }
2715
2716 },
2717
2718 y: {
2719
2720 get: function () {
2721
2722 return this._y;
2723
2724 },
2725
2726 set: function ( value ) {
2727
2728 this._y = value;
2729 this._onChangeCallback();
2730
2731 }
2732
2733 },
2734
2735 z: {
2736
2737 get: function () {
2738
2739 return this._z;
2740
2741 },
2742
2743 set: function ( value ) {
2744
2745 this._z = value;
2746 this._onChangeCallback();
2747
2748 }
2749
2750 },
2751
2752 w: {
2753
2754 get: function () {
2755
2756 return this._w;
2757
2758 },
2759
2760 set: function ( value ) {
2761
2762 this._w = value;
2763 this._onChangeCallback();
2764
2765 }
2766
2767 }
2768
2769 } );
2770
2771 Object.assign( Quaternion.prototype, {
2772
2773 isQuaternion: true,
2774
2775 set: function ( x, y, z, w ) {
2776
2777 this._x = x;
2778 this._y = y;
2779 this._z = z;
2780 this._w = w;
2781
2782 this._onChangeCallback();
2783
2784 return this;
2785
2786 },
2787
2788 clone: function () {
2789
2790 return new this.constructor( this._x, this._y, this._z, this._w );
2791
2792 },
2793
2794 copy: function ( quaternion ) {
2795
2796 this._x = quaternion.x;
2797 this._y = quaternion.y;
2798 this._z = quaternion.z;
2799 this._w = quaternion.w;
2800
2801 this._onChangeCallback();
2802
2803 return this;
2804
2805 },
2806
2807 setFromEuler: function ( euler, update ) {
2808
2809 if ( ! ( euler && euler.isEuler ) ) {
2810
2811 throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' );
2812
2813 }
2814
2815 var x = euler._x, y = euler._y, z = euler._z, order = euler.order;
2816
2817 // http://www.mathworks.com/matlabcentral/fileexchange/
2818 // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
2819 // content/SpinCalc.m
2820
2821 var cos = Math.cos;
2822 var sin = Math.sin;
2823
2824 var c1 = cos( x / 2 );
2825 var c2 = cos( y / 2 );
2826 var c3 = cos( z / 2 );
2827
2828 var s1 = sin( x / 2 );
2829 var s2 = sin( y / 2 );
2830 var s3 = sin( z / 2 );
2831
2832 switch ( order ) {
2833
2834 case 'XYZ':
2835 this._x = s1 * c2 * c3 + c1 * s2 * s3;
2836 this._y = c1 * s2 * c3 - s1 * c2 * s3;
2837 this._z = c1 * c2 * s3 + s1 * s2 * c3;
2838 this._w = c1 * c2 * c3 - s1 * s2 * s3;
2839 break;
2840
2841 case 'YXZ':
2842 this._x = s1 * c2 * c3 + c1 * s2 * s3;
2843 this._y = c1 * s2 * c3 - s1 * c2 * s3;
2844 this._z = c1 * c2 * s3 - s1 * s2 * c3;
2845 this._w = c1 * c2 * c3 + s1 * s2 * s3;
2846 break;
2847
2848 case 'ZXY':
2849 this._x = s1 * c2 * c3 - c1 * s2 * s3;
2850 this._y = c1 * s2 * c3 + s1 * c2 * s3;
2851 this._z = c1 * c2 * s3 + s1 * s2 * c3;
2852 this._w = c1 * c2 * c3 - s1 * s2 * s3;
2853 break;
2854
2855 case 'ZYX':
2856 this._x = s1 * c2 * c3 - c1 * s2 * s3;
2857 this._y = c1 * s2 * c3 + s1 * c2 * s3;
2858 this._z = c1 * c2 * s3 - s1 * s2 * c3;
2859 this._w = c1 * c2 * c3 + s1 * s2 * s3;
2860 break;
2861
2862 case 'YZX':
2863 this._x = s1 * c2 * c3 + c1 * s2 * s3;
2864 this._y = c1 * s2 * c3 + s1 * c2 * s3;
2865 this._z = c1 * c2 * s3 - s1 * s2 * c3;
2866 this._w = c1 * c2 * c3 - s1 * s2 * s3;
2867 break;
2868
2869 case 'XZY':
2870 this._x = s1 * c2 * c3 - c1 * s2 * s3;
2871 this._y = c1 * s2 * c3 - s1 * c2 * s3;
2872 this._z = c1 * c2 * s3 + s1 * s2 * c3;
2873 this._w = c1 * c2 * c3 + s1 * s2 * s3;
2874 break;
2875
2876 default:
2877 console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order );
2878
2879 }
2880
2881 if ( update !== false ) { this._onChangeCallback(); }
2882
2883 return this;
2884
2885 },
2886
2887 setFromAxisAngle: function ( axis, angle ) {
2888
2889 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
2890
2891 // assumes axis is normalized
2892
2893 var halfAngle = angle / 2, s = Math.sin( halfAngle );
2894
2895 this._x = axis.x * s;
2896 this._y = axis.y * s;
2897 this._z = axis.z * s;
2898 this._w = Math.cos( halfAngle );
2899
2900 this._onChangeCallback();
2901
2902 return this;
2903
2904 },
2905
2906 setFromRotationMatrix: function ( m ) {
2907
2908 // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
2909
2910 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
2911
2912 var te = m.elements,
2913
2914 m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ],
2915 m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ],
2916 m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ],
2917
2918 trace = m11 + m22 + m33;
2919
2920 if ( trace > 0 ) {
2921
2922 var s = 0.5 / Math.sqrt( trace + 1.0 );
2923
2924 this._w = 0.25 / s;
2925 this._x = ( m32 - m23 ) * s;
2926 this._y = ( m13 - m31 ) * s;
2927 this._z = ( m21 - m12 ) * s;
2928
2929 } else if ( m11 > m22 && m11 > m33 ) {
2930
2931 var s$1 = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
2932
2933 this._w = ( m32 - m23 ) / s$1;
2934 this._x = 0.25 * s$1;
2935 this._y = ( m12 + m21 ) / s$1;
2936 this._z = ( m13 + m31 ) / s$1;
2937
2938 } else if ( m22 > m33 ) {
2939
2940 var s$2 = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
2941
2942 this._w = ( m13 - m31 ) / s$2;
2943 this._x = ( m12 + m21 ) / s$2;
2944 this._y = 0.25 * s$2;
2945 this._z = ( m23 + m32 ) / s$2;
2946
2947 } else {
2948
2949 var s$3 = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
2950
2951 this._w = ( m21 - m12 ) / s$3;
2952 this._x = ( m13 + m31 ) / s$3;
2953 this._y = ( m23 + m32 ) / s$3;
2954 this._z = 0.25 * s$3;
2955
2956 }
2957
2958 this._onChangeCallback();
2959
2960 return this;
2961
2962 },
2963
2964 setFromUnitVectors: function ( vFrom, vTo ) {
2965
2966 // assumes direction vectors vFrom and vTo are normalized
2967
2968 var EPS = 0.000001;
2969
2970 var r = vFrom.dot( vTo ) + 1;
2971
2972 if ( r < EPS ) {
2973
2974 r = 0;
2975
2976 if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
2977
2978 this._x = - vFrom.y;
2979 this._y = vFrom.x;
2980 this._z = 0;
2981 this._w = r;
2982
2983 } else {
2984
2985 this._x = 0;
2986 this._y = - vFrom.z;
2987 this._z = vFrom.y;
2988 this._w = r;
2989
2990 }
2991
2992 } else {
2993
2994 // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3
2995
2996 this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
2997 this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
2998 this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
2999 this._w = r;
3000
3001 }
3002
3003 return this.normalize();
3004
3005 },
3006
3007 angleTo: function ( q ) {
3008
3009 return 2 * Math.acos( Math.abs( MathUtils.clamp( this.dot( q ), - 1, 1 ) ) );
3010
3011 },
3012
3013 rotateTowards: function ( q, step ) {
3014
3015 var angle = this.angleTo( q );
3016
3017 if ( angle === 0 ) { return this; }
3018
3019 var t = Math.min( 1, step / angle );
3020
3021 this.slerp( q, t );
3022
3023 return this;
3024
3025 },
3026
3027 identity: function () {
3028
3029 return this.set( 0, 0, 0, 1 );
3030
3031 },
3032
3033 inverse: function () {
3034
3035 // quaternion is assumed to have unit length
3036
3037 return this.conjugate();
3038
3039 },
3040
3041 conjugate: function () {
3042
3043 this._x *= - 1;
3044 this._y *= - 1;
3045 this._z *= - 1;
3046
3047 this._onChangeCallback();
3048
3049 return this;
3050
3051 },
3052
3053 dot: function ( v ) {
3054
3055 return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
3056
3057 },
3058
3059 lengthSq: function () {
3060
3061 return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
3062
3063 },
3064
3065 length: function () {
3066
3067 return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w );
3068
3069 },
3070
3071 normalize: function () {
3072
3073 var l = this.length();
3074
3075 if ( l === 0 ) {
3076
3077 this._x = 0;
3078 this._y = 0;
3079 this._z = 0;
3080 this._w = 1;
3081
3082 } else {
3083
3084 l = 1 / l;
3085
3086 this._x = this._x * l;
3087 this._y = this._y * l;
3088 this._z = this._z * l;
3089 this._w = this._w * l;
3090
3091 }
3092
3093 this._onChangeCallback();
3094
3095 return this;
3096
3097 },
3098
3099 multiply: function ( q, p ) {
3100
3101 if ( p !== undefined ) {
3102
3103 console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' );
3104 return this.multiplyQuaternions( q, p );
3105
3106 }
3107
3108 return this.multiplyQuaternions( this, q );
3109
3110 },
3111
3112 premultiply: function ( q ) {
3113
3114 return this.multiplyQuaternions( q, this );
3115
3116 },
3117
3118 multiplyQuaternions: function ( a, b ) {
3119
3120 // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
3121
3122 var qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
3123 var qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
3124
3125 this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
3126 this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
3127 this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
3128 this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
3129
3130 this._onChangeCallback();
3131
3132 return this;
3133
3134 },
3135
3136 slerp: function ( qb, t ) {
3137
3138 if ( t === 0 ) { return this; }
3139 if ( t === 1 ) { return this.copy( qb ); }
3140
3141 var x = this._x, y = this._y, z = this._z, w = this._w;
3142
3143 // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
3144
3145 var cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
3146
3147 if ( cosHalfTheta < 0 ) {
3148
3149 this._w = - qb._w;
3150 this._x = - qb._x;
3151 this._y = - qb._y;
3152 this._z = - qb._z;
3153
3154 cosHalfTheta = - cosHalfTheta;
3155
3156 } else {
3157
3158 this.copy( qb );
3159
3160 }
3161
3162 if ( cosHalfTheta >= 1.0 ) {
3163
3164 this._w = w;
3165 this._x = x;
3166 this._y = y;
3167 this._z = z;
3168
3169 return this;
3170
3171 }
3172
3173 var sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
3174
3175 if ( sqrSinHalfTheta <= Number.EPSILON ) {
3176
3177 var s = 1 - t;
3178 this._w = s * w + t * this._w;
3179 this._x = s * x + t * this._x;
3180 this._y = s * y + t * this._y;
3181 this._z = s * z + t * this._z;
3182
3183 this.normalize();
3184 this._onChangeCallback();
3185
3186 return this;
3187
3188 }
3189
3190 var sinHalfTheta = Math.sqrt( sqrSinHalfTheta );
3191 var halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta );
3192 var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
3193 ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
3194
3195 this._w = ( w * ratioA + this._w * ratioB );
3196 this._x = ( x * ratioA + this._x * ratioB );
3197 this._y = ( y * ratioA + this._y * ratioB );
3198 this._z = ( z * ratioA + this._z * ratioB );
3199
3200 this._onChangeCallback();
3201
3202 return this;
3203
3204 },
3205
3206 equals: function ( quaternion ) {
3207
3208 return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w );
3209
3210 },
3211
3212 fromArray: function ( array, offset ) {
3213
3214 if ( offset === undefined ) { offset = 0; }
3215
3216 this._x = array[ offset ];
3217 this._y = array[ offset + 1 ];
3218 this._z = array[ offset + 2 ];
3219 this._w = array[ offset + 3 ];
3220
3221 this._onChangeCallback();
3222
3223 return this;
3224
3225 },
3226
3227 toArray: function ( array, offset ) {
3228
3229 if ( array === undefined ) { array = []; }
3230 if ( offset === undefined ) { offset = 0; }
3231
3232 array[ offset ] = this._x;
3233 array[ offset + 1 ] = this._y;
3234 array[ offset + 2 ] = this._z;
3235 array[ offset + 3 ] = this._w;
3236
3237 return array;
3238
3239 },
3240
3241 fromBufferAttribute: function ( attribute, index ) {
3242
3243 this._x = attribute.getX( index );
3244 this._y = attribute.getY( index );
3245 this._z = attribute.getZ( index );
3246 this._w = attribute.getW( index );
3247
3248 return this;
3249
3250 },
3251
3252 _onChange: function ( callback ) {
3253
3254 this._onChangeCallback = callback;
3255
3256 return this;
3257
3258 },
3259
3260 _onChangeCallback: function () {}
3261
3262 } );
3263
3264 var _vector = new Vector3();
3265 var _quaternion = new Quaternion();
3266
3267 function Vector3( x, y, z ) {
3268 if ( x === void 0 ) x = 0;
3269 if ( y === void 0 ) y = 0;
3270 if ( z === void 0 ) z = 0;
3271
3272
3273 this.x = x;
3274 this.y = y;
3275 this.z = z;
3276
3277 }
3278
3279 Object.assign( Vector3.prototype, {
3280
3281 isVector3: true,
3282
3283 set: function ( x, y, z ) {
3284
3285 if ( z === undefined ) { z = this.z; } // sprite.scale.set(x,y)
3286
3287 this.x = x;
3288 this.y = y;
3289 this.z = z;
3290
3291 return this;
3292
3293 },
3294
3295 setScalar: function ( scalar ) {
3296
3297 this.x = scalar;
3298 this.y = scalar;
3299 this.z = scalar;
3300
3301 return this;
3302
3303 },
3304
3305 setX: function ( x ) {
3306
3307 this.x = x;
3308
3309 return this;
3310
3311 },
3312
3313 setY: function ( y ) {
3314
3315 this.y = y;
3316
3317 return this;
3318
3319 },
3320
3321 setZ: function ( z ) {
3322
3323 this.z = z;
3324
3325 return this;
3326
3327 },
3328
3329 setComponent: function ( index, value ) {
3330
3331 switch ( index ) {
3332
3333 case 0: this.x = value; break;
3334 case 1: this.y = value; break;
3335 case 2: this.z = value; break;
3336 default: throw new Error( 'index is out of range: ' + index );
3337
3338 }
3339
3340 return this;
3341
3342 },
3343
3344 getComponent: function ( index ) {
3345
3346 switch ( index ) {
3347
3348 case 0: return this.x;
3349 case 1: return this.y;
3350 case 2: return this.z;
3351 default: throw new Error( 'index is out of range: ' + index );
3352
3353 }
3354
3355 },
3356
3357 clone: function () {
3358
3359 return new this.constructor( this.x, this.y, this.z );
3360
3361 },
3362
3363 copy: function ( v ) {
3364
3365 this.x = v.x;
3366 this.y = v.y;
3367 this.z = v.z;
3368
3369 return this;
3370
3371 },
3372
3373 add: function ( v, w ) {
3374
3375 if ( w !== undefined ) {
3376
3377 console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' );
3378 return this.addVectors( v, w );
3379
3380 }
3381
3382 this.x += v.x;
3383 this.y += v.y;
3384 this.z += v.z;
3385
3386 return this;
3387
3388 },
3389
3390 addScalar: function ( s ) {
3391
3392 this.x += s;
3393 this.y += s;
3394 this.z += s;
3395
3396 return this;
3397
3398 },
3399
3400 addVectors: function ( a, b ) {
3401
3402 this.x = a.x + b.x;
3403 this.y = a.y + b.y;
3404 this.z = a.z + b.z;
3405
3406 return this;
3407
3408 },
3409
3410 addScaledVector: function ( v, s ) {
3411
3412 this.x += v.x * s;
3413 this.y += v.y * s;
3414 this.z += v.z * s;
3415
3416 return this;
3417
3418 },
3419
3420 sub: function ( v, w ) {
3421
3422 if ( w !== undefined ) {
3423
3424 console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' );
3425 return this.subVectors( v, w );
3426
3427 }
3428
3429 this.x -= v.x;
3430 this.y -= v.y;
3431 this.z -= v.z;
3432
3433 return this;
3434
3435 },
3436
3437 subScalar: function ( s ) {
3438
3439 this.x -= s;
3440 this.y -= s;
3441 this.z -= s;
3442
3443 return this;
3444
3445 },
3446
3447 subVectors: function ( a, b ) {
3448
3449 this.x = a.x - b.x;
3450 this.y = a.y - b.y;
3451 this.z = a.z - b.z;
3452
3453 return this;
3454
3455 },
3456
3457 multiply: function ( v, w ) {
3458
3459 if ( w !== undefined ) {
3460
3461 console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' );
3462 return this.multiplyVectors( v, w );
3463
3464 }
3465
3466 this.x *= v.x;
3467 this.y *= v.y;
3468 this.z *= v.z;
3469
3470 return this;
3471
3472 },
3473
3474 multiplyScalar: function ( scalar ) {
3475
3476 this.x *= scalar;
3477 this.y *= scalar;
3478 this.z *= scalar;
3479
3480 return this;
3481
3482 },
3483
3484 multiplyVectors: function ( a, b ) {
3485
3486 this.x = a.x * b.x;
3487 this.y = a.y * b.y;
3488 this.z = a.z * b.z;
3489
3490 return this;
3491
3492 },
3493
3494 applyEuler: function ( euler ) {
3495
3496 if ( ! ( euler && euler.isEuler ) ) {
3497
3498 console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' );
3499
3500 }
3501
3502 return this.applyQuaternion( _quaternion.setFromEuler( euler ) );
3503
3504 },
3505
3506 applyAxisAngle: function ( axis, angle ) {
3507
3508 return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) );
3509
3510 },
3511
3512 applyMatrix3: function ( m ) {
3513
3514 var x = this.x, y = this.y, z = this.z;
3515 var e = m.elements;
3516
3517 this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z;
3518 this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z;
3519 this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z;
3520
3521 return this;
3522
3523 },
3524
3525 applyNormalMatrix: function ( m ) {
3526
3527 return this.applyMatrix3( m ).normalize();
3528
3529 },
3530
3531 applyMatrix4: function ( m ) {
3532
3533 var x = this.x, y = this.y, z = this.z;
3534 var e = m.elements;
3535
3536 var w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] );
3537
3538 this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w;
3539 this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w;
3540 this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w;
3541
3542 return this;
3543
3544 },
3545
3546 applyQuaternion: function ( q ) {
3547
3548 var x = this.x, y = this.y, z = this.z;
3549 var qx = q.x, qy = q.y, qz = q.z, qw = q.w;
3550
3551 // calculate quat * vector
3552
3553 var ix = qw * x + qy * z - qz * y;
3554 var iy = qw * y + qz * x - qx * z;
3555 var iz = qw * z + qx * y - qy * x;
3556 var iw = - qx * x - qy * y - qz * z;
3557
3558 // calculate result * inverse quat
3559
3560 this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
3561 this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
3562 this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
3563
3564 return this;
3565
3566 },
3567
3568 project: function ( camera ) {
3569
3570 return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );
3571
3572 },
3573
3574 unproject: function ( camera ) {
3575
3576 return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld );
3577
3578 },
3579
3580 transformDirection: function ( m ) {
3581
3582 // input: THREE.Matrix4 affine matrix
3583 // vector interpreted as a direction
3584
3585 var x = this.x, y = this.y, z = this.z;
3586 var e = m.elements;
3587
3588 this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z;
3589 this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z;
3590 this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z;
3591
3592 return this.normalize();
3593
3594 },
3595
3596 divide: function ( v ) {
3597
3598 this.x /= v.x;
3599 this.y /= v.y;
3600 this.z /= v.z;
3601
3602 return this;
3603
3604 },
3605
3606 divideScalar: function ( scalar ) {
3607
3608 return this.multiplyScalar( 1 / scalar );
3609
3610 },
3611
3612 min: function ( v ) {
3613
3614 this.x = Math.min( this.x, v.x );
3615 this.y = Math.min( this.y, v.y );
3616 this.z = Math.min( this.z, v.z );
3617
3618 return this;
3619
3620 },
3621
3622 max: function ( v ) {
3623
3624 this.x = Math.max( this.x, v.x );
3625 this.y = Math.max( this.y, v.y );
3626 this.z = Math.max( this.z, v.z );
3627
3628 return this;
3629
3630 },
3631
3632 clamp: function ( min, max ) {
3633
3634 // assumes min < max, componentwise
3635
3636 this.x = Math.max( min.x, Math.min( max.x, this.x ) );
3637 this.y = Math.max( min.y, Math.min( max.y, this.y ) );
3638 this.z = Math.max( min.z, Math.min( max.z, this.z ) );
3639
3640 return this;
3641
3642 },
3643
3644 clampScalar: function ( minVal, maxVal ) {
3645
3646 this.x = Math.max( minVal, Math.min( maxVal, this.x ) );
3647 this.y = Math.max( minVal, Math.min( maxVal, this.y ) );
3648 this.z = Math.max( minVal, Math.min( maxVal, this.z ) );
3649
3650 return this;
3651
3652 },
3653
3654 clampLength: function ( min, max ) {
3655
3656 var length = this.length();
3657
3658 return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) );
3659
3660 },
3661
3662 floor: function () {
3663
3664 this.x = Math.floor( this.x );
3665 this.y = Math.floor( this.y );
3666 this.z = Math.floor( this.z );
3667
3668 return this;
3669
3670 },
3671
3672 ceil: function () {
3673
3674 this.x = Math.ceil( this.x );
3675 this.y = Math.ceil( this.y );
3676 this.z = Math.ceil( this.z );
3677
3678 return this;
3679
3680 },
3681
3682 round: function () {
3683
3684 this.x = Math.round( this.x );
3685 this.y = Math.round( this.y );
3686 this.z = Math.round( this.z );
3687
3688 return this;
3689
3690 },
3691
3692 roundToZero: function () {
3693
3694 this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x );
3695 this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y );
3696 this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z );
3697
3698 return this;
3699
3700 },
3701
3702 negate: function () {
3703
3704 this.x = - this.x;
3705 this.y = - this.y;
3706 this.z = - this.z;
3707
3708 return this;
3709
3710 },
3711
3712 dot: function ( v ) {
3713
3714 return this.x * v.x + this.y * v.y + this.z * v.z;
3715
3716 },
3717
3718 // TODO lengthSquared?
3719
3720 lengthSq: function () {
3721
3722 return this.x * this.x + this.y * this.y + this.z * this.z;
3723
3724 },
3725
3726 length: function () {
3727
3728 return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
3729
3730 },
3731
3732 manhattanLength: function () {
3733
3734 return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
3735
3736 },
3737
3738 normalize: function () {
3739
3740 return this.divideScalar( this.length() || 1 );
3741
3742 },
3743
3744 setLength: function ( length ) {
3745
3746 return this.normalize().multiplyScalar( length );
3747
3748 },
3749
3750 lerp: function ( v, alpha ) {
3751
3752 this.x += ( v.x - this.x ) * alpha;
3753 this.y += ( v.y - this.y ) * alpha;
3754 this.z += ( v.z - this.z ) * alpha;
3755
3756 return this;
3757
3758 },
3759
3760 lerpVectors: function ( v1, v2, alpha ) {
3761
3762 this.x = v1.x + ( v2.x - v1.x ) * alpha;
3763 this.y = v1.y + ( v2.y - v1.y ) * alpha;
3764 this.z = v1.z + ( v2.z - v1.z ) * alpha;
3765
3766 return this;
3767
3768 },
3769
3770 cross: function ( v, w ) {
3771
3772 if ( w !== undefined ) {
3773
3774 console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' );
3775 return this.crossVectors( v, w );
3776
3777 }
3778
3779 return this.crossVectors( this, v );
3780
3781 },
3782
3783 crossVectors: function ( a, b ) {
3784
3785 var ax = a.x, ay = a.y, az = a.z;
3786 var bx = b.x, by = b.y, bz = b.z;
3787
3788 this.x = ay * bz - az * by;
3789 this.y = az * bx - ax * bz;
3790 this.z = ax * by - ay * bx;
3791
3792 return this;
3793
3794 },
3795
3796 projectOnVector: function ( v ) {
3797
3798 var denominator = v.lengthSq();
3799
3800 if ( denominator === 0 ) { return this.set( 0, 0, 0 ); }
3801
3802 var scalar = v.dot( this ) / denominator;
3803
3804 return this.copy( v ).multiplyScalar( scalar );
3805
3806 },
3807
3808 projectOnPlane: function ( planeNormal ) {
3809
3810 _vector.copy( this ).projectOnVector( planeNormal );
3811
3812 return this.sub( _vector );
3813
3814 },
3815
3816 reflect: function ( normal ) {
3817
3818 // reflect incident vector off plane orthogonal to normal
3819 // normal is assumed to have unit length
3820
3821 return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) );
3822
3823 },
3824
3825 angleTo: function ( v ) {
3826
3827 var denominator = Math.sqrt( this.lengthSq() * v.lengthSq() );
3828
3829 if ( denominator === 0 ) { return Math.PI / 2; }
3830
3831 var theta = this.dot( v ) / denominator;
3832
3833 // clamp, to handle numerical problems
3834
3835 return Math.acos( MathUtils.clamp( theta, - 1, 1 ) );
3836
3837 },
3838
3839 distanceTo: function ( v ) {
3840
3841 return Math.sqrt( this.distanceToSquared( v ) );
3842
3843 },
3844
3845 distanceToSquared: function ( v ) {
3846
3847 var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
3848
3849 return dx * dx + dy * dy + dz * dz;
3850
3851 },
3852
3853 manhattanDistanceTo: function ( v ) {
3854
3855 return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z );
3856
3857 },
3858
3859 setFromSpherical: function ( s ) {
3860
3861 return this.setFromSphericalCoords( s.radius, s.phi, s.theta );
3862
3863 },
3864
3865 setFromSphericalCoords: function ( radius, phi, theta ) {
3866
3867 var sinPhiRadius = Math.sin( phi ) * radius;
3868
3869 this.x = sinPhiRadius * Math.sin( theta );
3870 this.y = Math.cos( phi ) * radius;
3871 this.z = sinPhiRadius * Math.cos( theta );
3872
3873 return this;
3874
3875 },
3876
3877 setFromCylindrical: function ( c ) {
3878
3879 return this.setFromCylindricalCoords( c.radius, c.theta, c.y );
3880
3881 },
3882
3883 setFromCylindricalCoords: function ( radius, theta, y ) {
3884
3885 this.x = radius * Math.sin( theta );
3886 this.y = y;
3887 this.z = radius * Math.cos( theta );
3888
3889 return this;
3890
3891 },
3892
3893 setFromMatrixPosition: function ( m ) {
3894
3895 var e = m.elements;
3896
3897 this.x = e[ 12 ];
3898 this.y = e[ 13 ];
3899 this.z = e[ 14 ];
3900
3901 return this;
3902
3903 },
3904
3905 setFromMatrixScale: function ( m ) {
3906
3907 var sx = this.setFromMatrixColumn( m, 0 ).length();
3908 var sy = this.setFromMatrixColumn( m, 1 ).length();
3909 var sz = this.setFromMatrixColumn( m, 2 ).length();
3910
3911 this.x = sx;
3912 this.y = sy;
3913 this.z = sz;
3914
3915 return this;
3916
3917 },
3918
3919 setFromMatrixColumn: function ( m, index ) {
3920
3921 return this.fromArray( m.elements, index * 4 );
3922
3923 },
3924
3925 setFromMatrix3Column: function ( m, index ) {
3926
3927 return this.fromArray( m.elements, index * 3 );
3928
3929 },
3930
3931 equals: function ( v ) {
3932
3933 return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
3934
3935 },
3936
3937 fromArray: function ( array, offset ) {
3938
3939 if ( offset === undefined ) { offset = 0; }
3940
3941 this.x = array[ offset ];
3942 this.y = array[ offset + 1 ];
3943 this.z = array[ offset + 2 ];
3944
3945 return this;
3946
3947 },
3948
3949 toArray: function ( array, offset ) {
3950
3951 if ( array === undefined ) { array = []; }
3952 if ( offset === undefined ) { offset = 0; }
3953
3954 array[ offset ] = this.x;
3955 array[ offset + 1 ] = this.y;
3956 array[ offset + 2 ] = this.z;
3957
3958 return array;
3959
3960 },
3961
3962 fromBufferAttribute: function ( attribute, index, offset ) {
3963
3964 if ( offset !== undefined ) {
3965
3966 console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' );
3967
3968 }
3969
3970 this.x = attribute.getX( index );
3971 this.y = attribute.getY( index );
3972 this.z = attribute.getZ( index );
3973
3974 return this;
3975
3976 },
3977
3978 random: function () {
3979
3980 this.x = Math.random();
3981 this.y = Math.random();
3982 this.z = Math.random();
3983
3984 return this;
3985
3986 }
3987
3988 } );
3989
3990 var _v1 = new Vector3();
3991 var _m1 = new Matrix4();
3992 var _zero = new Vector3( 0, 0, 0 );
3993 var _one = new Vector3( 1, 1, 1 );
3994 var _x = new Vector3();
3995 var _y = new Vector3();
3996 var _z = new Vector3();
3997
3998 function Matrix4() {
3999
4000 this.elements = [
4001
4002 1, 0, 0, 0,
4003 0, 1, 0, 0,
4004 0, 0, 1, 0,
4005 0, 0, 0, 1
4006
4007 ];
4008
4009 if ( arguments.length > 0 ) {
4010
4011 console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' );
4012
4013 }
4014
4015 }
4016
4017 Object.assign( Matrix4.prototype, {
4018
4019 isMatrix4: true,
4020
4021 set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
4022
4023 var te = this.elements;
4024
4025 te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14;
4026 te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24;
4027 te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34;
4028 te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44;
4029
4030 return this;
4031
4032 },
4033
4034 identity: function () {
4035
4036 this.set(
4037
4038 1, 0, 0, 0,
4039 0, 1, 0, 0,
4040 0, 0, 1, 0,
4041 0, 0, 0, 1
4042
4043 );
4044
4045 return this;
4046
4047 },
4048
4049 clone: function () {
4050
4051 return new Matrix4().fromArray( this.elements );
4052
4053 },
4054
4055 copy: function ( m ) {
4056
4057 var te = this.elements;
4058 var me = m.elements;
4059
4060 te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ];
4061 te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ];
4062 te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ];
4063 te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ];
4064
4065 return this;
4066
4067 },
4068
4069 copyPosition: function ( m ) {
4070
4071 var te = this.elements, me = m.elements;
4072
4073 te[ 12 ] = me[ 12 ];
4074 te[ 13 ] = me[ 13 ];
4075 te[ 14 ] = me[ 14 ];
4076
4077 return this;
4078
4079 },
4080
4081 extractBasis: function ( xAxis, yAxis, zAxis ) {
4082
4083 xAxis.setFromMatrixColumn( this, 0 );
4084 yAxis.setFromMatrixColumn( this, 1 );
4085 zAxis.setFromMatrixColumn( this, 2 );
4086
4087 return this;
4088
4089 },
4090
4091 makeBasis: function ( xAxis, yAxis, zAxis ) {
4092
4093 this.set(
4094 xAxis.x, yAxis.x, zAxis.x, 0,
4095 xAxis.y, yAxis.y, zAxis.y, 0,
4096 xAxis.z, yAxis.z, zAxis.z, 0,
4097 0, 0, 0, 1
4098 );
4099
4100 return this;
4101
4102 },
4103
4104 extractRotation: function ( m ) {
4105
4106 // this method does not support reflection matrices
4107
4108 var te = this.elements;
4109 var me = m.elements;
4110
4111 var scaleX = 1 / _v1.setFromMatrixColumn( m, 0 ).length();
4112 var scaleY = 1 / _v1.setFromMatrixColumn( m, 1 ).length();
4113 var scaleZ = 1 / _v1.setFromMatrixColumn( m, 2 ).length();
4114
4115 te[ 0 ] = me[ 0 ] * scaleX;
4116 te[ 1 ] = me[ 1 ] * scaleX;
4117 te[ 2 ] = me[ 2 ] * scaleX;
4118 te[ 3 ] = 0;
4119
4120 te[ 4 ] = me[ 4 ] * scaleY;
4121 te[ 5 ] = me[ 5 ] * scaleY;
4122 te[ 6 ] = me[ 6 ] * scaleY;
4123 te[ 7 ] = 0;
4124
4125 te[ 8 ] = me[ 8 ] * scaleZ;
4126 te[ 9 ] = me[ 9 ] * scaleZ;
4127 te[ 10 ] = me[ 10 ] * scaleZ;
4128 te[ 11 ] = 0;
4129
4130 te[ 12 ] = 0;
4131 te[ 13 ] = 0;
4132 te[ 14 ] = 0;
4133 te[ 15 ] = 1;
4134
4135 return this;
4136
4137 },
4138
4139 makeRotationFromEuler: function ( euler ) {
4140
4141 if ( ! ( euler && euler.isEuler ) ) {
4142
4143 console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' );
4144
4145 }
4146
4147 var te = this.elements;
4148
4149 var x = euler.x, y = euler.y, z = euler.z;
4150 var a = Math.cos( x ), b = Math.sin( x );
4151 var c = Math.cos( y ), d = Math.sin( y );
4152 var e = Math.cos( z ), f = Math.sin( z );
4153
4154 if ( euler.order === 'XYZ' ) {
4155
4156 var ae = a * e, af = a * f, be = b * e, bf = b * f;
4157
4158 te[ 0 ] = c * e;
4159 te[ 4 ] = - c * f;
4160 te[ 8 ] = d;
4161
4162 te[ 1 ] = af + be * d;
4163 te[ 5 ] = ae - bf * d;
4164 te[ 9 ] = - b * c;
4165
4166 te[ 2 ] = bf - ae * d;
4167 te[ 6 ] = be + af * d;
4168 te[ 10 ] = a * c;
4169
4170 } else if ( euler.order === 'YXZ' ) {
4171
4172 var ce = c * e, cf = c * f, de = d * e, df = d * f;
4173
4174 te[ 0 ] = ce + df * b;
4175 te[ 4 ] = de * b - cf;
4176 te[ 8 ] = a * d;
4177
4178 te[ 1 ] = a * f;
4179 te[ 5 ] = a * e;
4180 te[ 9 ] = - b;
4181
4182 te[ 2 ] = cf * b - de;
4183 te[ 6 ] = df + ce * b;
4184 te[ 10 ] = a * c;
4185
4186 } else if ( euler.order === 'ZXY' ) {
4187
4188 var ce$1 = c * e, cf$1 = c * f, de$1 = d * e, df$1 = d * f;
4189
4190 te[ 0 ] = ce$1 - df$1 * b;
4191 te[ 4 ] = - a * f;
4192 te[ 8 ] = de$1 + cf$1 * b;
4193
4194 te[ 1 ] = cf$1 + de$1 * b;
4195 te[ 5 ] = a * e;
4196 te[ 9 ] = df$1 - ce$1 * b;
4197
4198 te[ 2 ] = - a * d;
4199 te[ 6 ] = b;
4200 te[ 10 ] = a * c;
4201
4202 } else if ( euler.order === 'ZYX' ) {
4203
4204 var ae$1 = a * e, af$1 = a * f, be$1 = b * e, bf$1 = b * f;
4205
4206 te[ 0 ] = c * e;
4207 te[ 4 ] = be$1 * d - af$1;
4208 te[ 8 ] = ae$1 * d + bf$1;
4209
4210 te[ 1 ] = c * f;
4211 te[ 5 ] = bf$1 * d + ae$1;
4212 te[ 9 ] = af$1 * d - be$1;
4213
4214 te[ 2 ] = - d;
4215 te[ 6 ] = b * c;
4216 te[ 10 ] = a * c;
4217
4218 } else if ( euler.order === 'YZX' ) {
4219
4220 var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
4221
4222 te[ 0 ] = c * e;
4223 te[ 4 ] = bd - ac * f;
4224 te[ 8 ] = bc * f + ad;
4225
4226 te[ 1 ] = f;
4227 te[ 5 ] = a * e;
4228 te[ 9 ] = - b * e;
4229
4230 te[ 2 ] = - d * e;
4231 te[ 6 ] = ad * f + bc;
4232 te[ 10 ] = ac - bd * f;
4233
4234 } else if ( euler.order === 'XZY' ) {
4235
4236 var ac$1 = a * c, ad$1 = a * d, bc$1 = b * c, bd$1 = b * d;
4237
4238 te[ 0 ] = c * e;
4239 te[ 4 ] = - f;
4240 te[ 8 ] = d * e;
4241
4242 te[ 1 ] = ac$1 * f + bd$1;
4243 te[ 5 ] = a * e;
4244 te[ 9 ] = ad$1 * f - bc$1;
4245
4246 te[ 2 ] = bc$1 * f - ad$1;
4247 te[ 6 ] = b * e;
4248 te[ 10 ] = bd$1 * f + ac$1;
4249
4250 }
4251
4252 // bottom row
4253 te[ 3 ] = 0;
4254 te[ 7 ] = 0;
4255 te[ 11 ] = 0;
4256
4257 // last column
4258 te[ 12 ] = 0;
4259 te[ 13 ] = 0;
4260 te[ 14 ] = 0;
4261 te[ 15 ] = 1;
4262
4263 return this;
4264
4265 },
4266
4267 makeRotationFromQuaternion: function ( q ) {
4268
4269 return this.compose( _zero, q, _one );
4270
4271 },
4272
4273 lookAt: function ( eye, target, up ) {
4274
4275 var te = this.elements;
4276
4277 _z.subVectors( eye, target );
4278
4279 if ( _z.lengthSq() === 0 ) {
4280
4281 // eye and target are in the same position
4282
4283 _z.z = 1;
4284
4285 }
4286
4287 _z.normalize();
4288 _x.crossVectors( up, _z );
4289
4290 if ( _x.lengthSq() === 0 ) {
4291
4292 // up and z are parallel
4293
4294 if ( Math.abs( up.z ) === 1 ) {
4295
4296 _z.x += 0.0001;
4297
4298 } else {
4299
4300 _z.z += 0.0001;
4301
4302 }
4303
4304 _z.normalize();
4305 _x.crossVectors( up, _z );
4306
4307 }
4308
4309 _x.normalize();
4310 _y.crossVectors( _z, _x );
4311
4312 te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x;
4313 te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y;
4314 te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z;
4315
4316 return this;
4317
4318 },
4319
4320 multiply: function ( m, n ) {
4321
4322 if ( n !== undefined ) {
4323
4324 console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' );
4325 return this.multiplyMatrices( m, n );
4326
4327 }
4328
4329 return this.multiplyMatrices( this, m );
4330
4331 },
4332
4333 premultiply: function ( m ) {
4334
4335 return this.multiplyMatrices( m, this );
4336
4337 },
4338
4339 multiplyMatrices: function ( a, b ) {
4340
4341 var ae = a.elements;
4342 var be = b.elements;
4343 var te = this.elements;
4344
4345 var a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ];
4346 var a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ];
4347 var a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ];
4348 var a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ];
4349
4350 var b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ];
4351 var b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ];
4352 var b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ];
4353 var b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ];
4354
4355 te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
4356 te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
4357 te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
4358 te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
4359
4360 te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
4361 te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
4362 te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
4363 te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
4364
4365 te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
4366 te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
4367 te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
4368 te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
4369
4370 te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
4371 te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
4372 te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
4373 te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
4374
4375 return this;
4376
4377 },
4378
4379 multiplyScalar: function ( s ) {
4380
4381 var te = this.elements;
4382
4383 te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s;
4384 te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s;
4385 te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s;
4386 te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s;
4387
4388 return this;
4389
4390 },
4391
4392 determinant: function () {
4393
4394 var te = this.elements;
4395
4396 var n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ];
4397 var n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ];
4398 var n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ];
4399 var n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ];
4400
4401 //TODO: make this more efficient
4402 //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
4403
4404 return (
4405 n41 * (
4406 + n14 * n23 * n32
4407 - n13 * n24 * n32
4408 - n14 * n22 * n33
4409 + n12 * n24 * n33
4410 + n13 * n22 * n34
4411 - n12 * n23 * n34
4412 ) +
4413 n42 * (
4414 + n11 * n23 * n34
4415 - n11 * n24 * n33
4416 + n14 * n21 * n33
4417 - n13 * n21 * n34
4418 + n13 * n24 * n31
4419 - n14 * n23 * n31
4420 ) +
4421 n43 * (
4422 + n11 * n24 * n32
4423 - n11 * n22 * n34
4424 - n14 * n21 * n32
4425 + n12 * n21 * n34
4426 + n14 * n22 * n31
4427 - n12 * n24 * n31
4428 ) +
4429 n44 * (
4430 - n13 * n22 * n31
4431 - n11 * n23 * n32
4432 + n11 * n22 * n33
4433 + n13 * n21 * n32
4434 - n12 * n21 * n33
4435 + n12 * n23 * n31
4436 )
4437
4438 );
4439
4440 },
4441
4442 transpose: function () {
4443
4444 var te = this.elements;
4445 var tmp;
4446
4447 tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp;
4448 tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp;
4449 tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp;
4450
4451 tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp;
4452 tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp;
4453 tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp;
4454
4455 return this;
4456
4457 },
4458
4459 setPosition: function ( x, y, z ) {
4460
4461 var te = this.elements;
4462
4463 if ( x.isVector3 ) {
4464
4465 te[ 12 ] = x.x;
4466 te[ 13 ] = x.y;
4467 te[ 14 ] = x.z;
4468
4469 } else {
4470
4471 te[ 12 ] = x;
4472 te[ 13 ] = y;
4473 te[ 14 ] = z;
4474
4475 }
4476
4477 return this;
4478
4479 },
4480
4481 getInverse: function ( m, throwOnDegenerate ) {
4482
4483 if ( throwOnDegenerate !== undefined ) {
4484
4485 console.warn( "THREE.Matrix4: .getInverse() can no longer be configured to throw on degenerate." );
4486
4487 }
4488
4489 // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
4490 var te = this.elements,
4491 me = m.elements,
4492
4493 n11 = me[ 0 ], n21 = me[ 1 ], n31 = me[ 2 ], n41 = me[ 3 ],
4494 n12 = me[ 4 ], n22 = me[ 5 ], n32 = me[ 6 ], n42 = me[ 7 ],
4495 n13 = me[ 8 ], n23 = me[ 9 ], n33 = me[ 10 ], n43 = me[ 11 ],
4496 n14 = me[ 12 ], n24 = me[ 13 ], n34 = me[ 14 ], n44 = me[ 15 ],
4497
4498 t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
4499 t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
4500 t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
4501 t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
4502
4503 var det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
4504
4505 if ( det === 0 ) { return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); }
4506
4507 var detInv = 1 / det;
4508
4509 te[ 0 ] = t11 * detInv;
4510 te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv;
4511 te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv;
4512 te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv;
4513
4514 te[ 4 ] = t12 * detInv;
4515 te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv;
4516 te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv;
4517 te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv;
4518
4519 te[ 8 ] = t13 * detInv;
4520 te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv;
4521 te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv;
4522 te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv;
4523
4524 te[ 12 ] = t14 * detInv;
4525 te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv;
4526 te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv;
4527 te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv;
4528
4529 return this;
4530
4531 },
4532
4533 scale: function ( v ) {
4534
4535 var te = this.elements;
4536 var x = v.x, y = v.y, z = v.z;
4537
4538 te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z;
4539 te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z;
4540 te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z;
4541 te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z;
4542
4543 return this;
4544
4545 },
4546
4547 getMaxScaleOnAxis: function () {
4548
4549 var te = this.elements;
4550
4551 var scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ];
4552 var scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ];
4553 var scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ];
4554
4555 return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) );
4556
4557 },
4558
4559 makeTranslation: function ( x, y, z ) {
4560
4561 this.set(
4562
4563 1, 0, 0, x,
4564 0, 1, 0, y,
4565 0, 0, 1, z,
4566 0, 0, 0, 1
4567
4568 );
4569
4570 return this;
4571
4572 },
4573
4574 makeRotationX: function ( theta ) {
4575
4576 var c = Math.cos( theta ), s = Math.sin( theta );
4577
4578 this.set(
4579
4580 1, 0, 0, 0,
4581 0, c, - s, 0,
4582 0, s, c, 0,
4583 0, 0, 0, 1
4584
4585 );
4586
4587 return this;
4588
4589 },
4590
4591 makeRotationY: function ( theta ) {
4592
4593 var c = Math.cos( theta ), s = Math.sin( theta );
4594
4595 this.set(
4596
4597 c, 0, s, 0,
4598 0, 1, 0, 0,
4599 - s, 0, c, 0,
4600 0, 0, 0, 1
4601
4602 );
4603
4604 return this;
4605
4606 },
4607
4608 makeRotationZ: function ( theta ) {
4609
4610 var c = Math.cos( theta ), s = Math.sin( theta );
4611
4612 this.set(
4613
4614 c, - s, 0, 0,
4615 s, c, 0, 0,
4616 0, 0, 1, 0,
4617 0, 0, 0, 1
4618
4619 );
4620
4621 return this;
4622
4623 },
4624
4625 makeRotationAxis: function ( axis, angle ) {
4626
4627 // Based on http://www.gamedev.net/reference/articles/article1199.asp
4628
4629 var c = Math.cos( angle );
4630 var s = Math.sin( angle );
4631 var t = 1 - c;
4632 var x = axis.x, y = axis.y, z = axis.z;
4633 var tx = t * x, ty = t * y;
4634
4635 this.set(
4636
4637 tx * x + c, tx * y - s * z, tx * z + s * y, 0,
4638 tx * y + s * z, ty * y + c, ty * z - s * x, 0,
4639 tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
4640 0, 0, 0, 1
4641
4642 );
4643
4644 return this;
4645
4646 },
4647
4648 makeScale: function ( x, y, z ) {
4649
4650 this.set(
4651
4652 x, 0, 0, 0,
4653 0, y, 0, 0,
4654 0, 0, z, 0,
4655 0, 0, 0, 1
4656
4657 );
4658
4659 return this;
4660
4661 },
4662
4663 makeShear: function ( x, y, z ) {
4664
4665 this.set(
4666
4667 1, y, z, 0,
4668 x, 1, z, 0,
4669 x, y, 1, 0,
4670 0, 0, 0, 1
4671
4672 );
4673
4674 return this;
4675
4676 },
4677
4678 compose: function ( position, quaternion, scale ) {
4679
4680 var te = this.elements;
4681
4682 var x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
4683 var x2 = x + x, y2 = y + y, z2 = z + z;
4684 var xx = x * x2, xy = x * y2, xz = x * z2;
4685 var yy = y * y2, yz = y * z2, zz = z * z2;
4686 var wx = w * x2, wy = w * y2, wz = w * z2;
4687
4688 var sx = scale.x, sy = scale.y, sz = scale.z;
4689
4690 te[ 0 ] = ( 1 - ( yy + zz ) ) * sx;
4691 te[ 1 ] = ( xy + wz ) * sx;
4692 te[ 2 ] = ( xz - wy ) * sx;
4693 te[ 3 ] = 0;
4694
4695 te[ 4 ] = ( xy - wz ) * sy;
4696 te[ 5 ] = ( 1 - ( xx + zz ) ) * sy;
4697 te[ 6 ] = ( yz + wx ) * sy;
4698 te[ 7 ] = 0;
4699
4700 te[ 8 ] = ( xz + wy ) * sz;
4701 te[ 9 ] = ( yz - wx ) * sz;
4702 te[ 10 ] = ( 1 - ( xx + yy ) ) * sz;
4703 te[ 11 ] = 0;
4704
4705 te[ 12 ] = position.x;
4706 te[ 13 ] = position.y;
4707 te[ 14 ] = position.z;
4708 te[ 15 ] = 1;
4709
4710 return this;
4711
4712 },
4713
4714 decompose: function ( position, quaternion, scale ) {
4715
4716 var te = this.elements;
4717
4718 var sx = _v1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length();
4719 var sy = _v1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length();
4720 var sz = _v1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length();
4721
4722 // if determine is negative, we need to invert one scale
4723 var det = this.determinant();
4724 if ( det < 0 ) { sx = - sx; }
4725
4726 position.x = te[ 12 ];
4727 position.y = te[ 13 ];
4728 position.z = te[ 14 ];
4729
4730 // scale the rotation part
4731 _m1.copy( this );
4732
4733 var invSX = 1 / sx;
4734 var invSY = 1 / sy;
4735 var invSZ = 1 / sz;
4736
4737 _m1.elements[ 0 ] *= invSX;
4738 _m1.elements[ 1 ] *= invSX;
4739 _m1.elements[ 2 ] *= invSX;
4740
4741 _m1.elements[ 4 ] *= invSY;
4742 _m1.elements[ 5 ] *= invSY;
4743 _m1.elements[ 6 ] *= invSY;
4744
4745 _m1.elements[ 8 ] *= invSZ;
4746 _m1.elements[ 9 ] *= invSZ;
4747 _m1.elements[ 10 ] *= invSZ;
4748
4749 quaternion.setFromRotationMatrix( _m1 );
4750
4751 scale.x = sx;
4752 scale.y = sy;
4753 scale.z = sz;
4754
4755 return this;
4756
4757 },
4758
4759 makePerspective: function ( left, right, top, bottom, near, far ) {
4760
4761 if ( far === undefined ) {
4762
4763 console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' );
4764
4765 }
4766
4767 var te = this.elements;
4768 var x = 2 * near / ( right - left );
4769 var y = 2 * near / ( top - bottom );
4770
4771 var a = ( right + left ) / ( right - left );
4772 var b = ( top + bottom ) / ( top - bottom );
4773 var c = - ( far + near ) / ( far - near );
4774 var d = - 2 * far * near / ( far - near );
4775
4776 te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0;
4777 te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0;
4778 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d;
4779 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0;
4780
4781 return this;
4782
4783 },
4784
4785 makeOrthographic: function ( left, right, top, bottom, near, far ) {
4786
4787 var te = this.elements;
4788 var w = 1.0 / ( right - left );
4789 var h = 1.0 / ( top - bottom );
4790 var p = 1.0 / ( far - near );
4791
4792 var x = ( right + left ) * w;
4793 var y = ( top + bottom ) * h;
4794 var z = ( far + near ) * p;
4795
4796 te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x;
4797 te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y;
4798 te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z;
4799 te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1;
4800
4801 return this;
4802
4803 },
4804
4805 equals: function ( matrix ) {
4806
4807 var te = this.elements;
4808 var me = matrix.elements;
4809
4810 for ( var i = 0; i < 16; i ++ ) {
4811
4812 if ( te[ i ] !== me[ i ] ) { return false; }
4813
4814 }
4815
4816 return true;
4817
4818 },
4819
4820 fromArray: function ( array, offset ) {
4821
4822 if ( offset === undefined ) { offset = 0; }
4823
4824 for ( var i = 0; i < 16; i ++ ) {
4825
4826 this.elements[ i ] = array[ i + offset ];
4827
4828 }
4829
4830 return this;
4831
4832 },
4833
4834 toArray: function ( array, offset ) {
4835
4836 if ( array === undefined ) { array = []; }
4837 if ( offset === undefined ) { offset = 0; }
4838
4839 var te = this.elements;
4840
4841 array[ offset ] = te[ 0 ];
4842 array[ offset + 1 ] = te[ 1 ];
4843 array[ offset + 2 ] = te[ 2 ];
4844 array[ offset + 3 ] = te[ 3 ];
4845
4846 array[ offset + 4 ] = te[ 4 ];
4847 array[ offset + 5 ] = te[ 5 ];
4848 array[ offset + 6 ] = te[ 6 ];
4849 array[ offset + 7 ] = te[ 7 ];
4850
4851 array[ offset + 8 ] = te[ 8 ];
4852 array[ offset + 9 ] = te[ 9 ];
4853 array[ offset + 10 ] = te[ 10 ];
4854 array[ offset + 11 ] = te[ 11 ];
4855
4856 array[ offset + 12 ] = te[ 12 ];
4857 array[ offset + 13 ] = te[ 13 ];
4858 array[ offset + 14 ] = te[ 14 ];
4859 array[ offset + 15 ] = te[ 15 ];
4860
4861 return array;
4862
4863 }
4864
4865 } );
4866
4867 var _matrix = new Matrix4();
4868 var _quaternion$1 = new Quaternion();
4869
4870 function Euler( x, y, z, order ) {
4871 if ( x === void 0 ) x = 0;
4872 if ( y === void 0 ) y = 0;
4873 if ( z === void 0 ) z = 0;
4874 if ( order === void 0 ) order = Euler.DefaultOrder;
4875
4876
4877 this._x = x;
4878 this._y = y;
4879 this._z = z;
4880 this._order = order;
4881
4882 }
4883
4884 Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ];
4885
4886 Euler.DefaultOrder = 'XYZ';
4887
4888 Object.defineProperties( Euler.prototype, {
4889
4890 x: {
4891
4892 get: function () {
4893
4894 return this._x;
4895
4896 },
4897
4898 set: function ( value ) {
4899
4900 this._x = value;
4901 this._onChangeCallback();
4902
4903 }
4904
4905 },
4906
4907 y: {
4908
4909 get: function () {
4910
4911 return this._y;
4912
4913 },
4914
4915 set: function ( value ) {
4916
4917 this._y = value;
4918 this._onChangeCallback();
4919
4920 }
4921
4922 },
4923
4924 z: {
4925
4926 get: function () {
4927
4928 return this._z;
4929
4930 },
4931
4932 set: function ( value ) {
4933
4934 this._z = value;
4935 this._onChangeCallback();
4936
4937 }
4938
4939 },
4940
4941 order: {
4942
4943 get: function () {
4944
4945 return this._order;
4946
4947 },
4948
4949 set: function ( value ) {
4950
4951 this._order = value;
4952 this._onChangeCallback();
4953
4954 }
4955
4956 }
4957
4958 } );
4959
4960 Object.assign( Euler.prototype, {
4961
4962 isEuler: true,
4963
4964 set: function ( x, y, z, order ) {
4965
4966 this._x = x;
4967 this._y = y;
4968 this._z = z;
4969 this._order = order || this._order;
4970
4971 this._onChangeCallback();
4972
4973 return this;
4974
4975 },
4976
4977 clone: function () {
4978
4979 return new this.constructor( this._x, this._y, this._z, this._order );
4980
4981 },
4982
4983 copy: function ( euler ) {
4984
4985 this._x = euler._x;
4986 this._y = euler._y;
4987 this._z = euler._z;
4988 this._order = euler._order;
4989
4990 this._onChangeCallback();
4991
4992 return this;
4993
4994 },
4995
4996 setFromRotationMatrix: function ( m, order, update ) {
4997
4998 var clamp = MathUtils.clamp;
4999
5000 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
5001
5002 var te = m.elements;
5003 var m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ];
5004 var m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ];
5005 var m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ];
5006
5007 order = order || this._order;
5008
5009 switch ( order ) {
5010
5011 case 'XYZ':
5012
5013 this._y = Math.asin( clamp( m13, - 1, 1 ) );
5014
5015 if ( Math.abs( m13 ) < 0.9999999 ) {
5016
5017 this._x = Math.atan2( - m23, m33 );
5018 this._z = Math.atan2( - m12, m11 );
5019
5020 } else {
5021
5022 this._x = Math.atan2( m32, m22 );
5023 this._z = 0;
5024
5025 }
5026
5027 break;
5028
5029 case 'YXZ':
5030
5031 this._x = Math.asin( - clamp( m23, - 1, 1 ) );
5032
5033 if ( Math.abs( m23 ) < 0.9999999 ) {
5034
5035 this._y = Math.atan2( m13, m33 );
5036 this._z = Math.atan2( m21, m22 );
5037
5038 } else {
5039
5040 this._y = Math.atan2( - m31, m11 );
5041 this._z = 0;
5042
5043 }
5044
5045 break;
5046
5047 case 'ZXY':
5048
5049 this._x = Math.asin( clamp( m32, - 1, 1 ) );
5050
5051 if ( Math.abs( m32 ) < 0.9999999 ) {
5052
5053 this._y = Math.atan2( - m31, m33 );
5054 this._z = Math.atan2( - m12, m22 );
5055
5056 } else {
5057
5058 this._y = 0;
5059 this._z = Math.atan2( m21, m11 );
5060
5061 }
5062
5063 break;
5064
5065 case 'ZYX':
5066
5067 this._y = Math.asin( - clamp( m31, - 1, 1 ) );
5068
5069 if ( Math.abs( m31 ) < 0.9999999 ) {
5070
5071 this._x = Math.atan2( m32, m33 );
5072 this._z = Math.atan2( m21, m11 );
5073
5074 } else {
5075
5076 this._x = 0;
5077 this._z = Math.atan2( - m12, m22 );
5078
5079 }
5080
5081 break;
5082
5083 case 'YZX':
5084
5085 this._z = Math.asin( clamp( m21, - 1, 1 ) );
5086
5087 if ( Math.abs( m21 ) < 0.9999999 ) {
5088
5089 this._x = Math.atan2( - m23, m22 );
5090 this._y = Math.atan2( - m31, m11 );
5091
5092 } else {
5093
5094 this._x = 0;
5095 this._y = Math.atan2( m13, m33 );
5096
5097 }
5098
5099 break;
5100
5101 case 'XZY':
5102
5103 this._z = Math.asin( - clamp( m12, - 1, 1 ) );
5104
5105 if ( Math.abs( m12 ) < 0.9999999 ) {
5106
5107 this._x = Math.atan2( m32, m22 );
5108 this._y = Math.atan2( m13, m11 );
5109
5110 } else {
5111
5112 this._x = Math.atan2( - m23, m33 );
5113 this._y = 0;
5114
5115 }
5116
5117 break;
5118
5119 default:
5120
5121 console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order );
5122
5123 }
5124
5125 this._order = order;
5126
5127 if ( update !== false ) { this._onChangeCallback(); }
5128
5129 return this;
5130
5131 },
5132
5133 setFromQuaternion: function ( q, order, update ) {
5134
5135 _matrix.makeRotationFromQuaternion( q );
5136
5137 return this.setFromRotationMatrix( _matrix, order, update );
5138
5139 },
5140
5141 setFromVector3: function ( v, order ) {
5142
5143 return this.set( v.x, v.y, v.z, order || this._order );
5144
5145 },
5146
5147 reorder: function ( newOrder ) {
5148
5149 // WARNING: this discards revolution information -bhouston
5150
5151 _quaternion$1.setFromEuler( this );
5152
5153 return this.setFromQuaternion( _quaternion$1, newOrder );
5154
5155 },
5156
5157 equals: function ( euler ) {
5158
5159 return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order );
5160
5161 },
5162
5163 fromArray: function ( array ) {
5164
5165 this._x = array[ 0 ];
5166 this._y = array[ 1 ];
5167 this._z = array[ 2 ];
5168 if ( array[ 3 ] !== undefined ) { this._order = array[ 3 ]; }
5169
5170 this._onChangeCallback();
5171
5172 return this;
5173
5174 },
5175
5176 toArray: function ( array, offset ) {
5177
5178 if ( array === undefined ) { array = []; }
5179 if ( offset === undefined ) { offset = 0; }
5180
5181 array[ offset ] = this._x;
5182 array[ offset + 1 ] = this._y;
5183 array[ offset + 2 ] = this._z;
5184 array[ offset + 3 ] = this._order;
5185
5186 return array;
5187
5188 },
5189
5190 toVector3: function ( optionalResult ) {
5191
5192 if ( optionalResult ) {
5193
5194 return optionalResult.set( this._x, this._y, this._z );
5195
5196 } else {
5197
5198 return new Vector3( this._x, this._y, this._z );
5199
5200 }
5201
5202 },
5203
5204 _onChange: function ( callback ) {
5205
5206 this._onChangeCallback = callback;
5207
5208 return this;
5209
5210 },
5211
5212 _onChangeCallback: function () {}
5213
5214 } );
5215
5216 function Layers() {
5217
5218 this.mask = 1 | 0;
5219
5220 }
5221
5222 Object.assign( Layers.prototype, {
5223
5224 set: function ( channel ) {
5225
5226 this.mask = 1 << channel | 0;
5227
5228 },
5229
5230 enable: function ( channel ) {
5231
5232 this.mask |= 1 << channel | 0;
5233
5234 },
5235
5236 enableAll: function () {
5237
5238 this.mask = 0xffffffff | 0;
5239
5240 },
5241
5242 toggle: function ( channel ) {
5243
5244 this.mask ^= 1 << channel | 0;
5245
5246 },
5247
5248 disable: function ( channel ) {
5249
5250 this.mask &= ~ ( 1 << channel | 0 );
5251
5252 },
5253
5254 disableAll: function () {
5255
5256 this.mask = 0;
5257
5258 },
5259
5260 test: function ( layers ) {
5261
5262 return ( this.mask & layers.mask ) !== 0;
5263
5264 }
5265
5266 } );
5267
5268 var _object3DId = 0;
5269
5270 var _v1$1 = new Vector3();
5271 var _q1 = new Quaternion();
5272 var _m1$1 = new Matrix4();
5273 var _target = new Vector3();
5274
5275 var _position = new Vector3();
5276 var _scale = new Vector3();
5277 var _quaternion$2 = new Quaternion();
5278
5279 var _xAxis = new Vector3( 1, 0, 0 );
5280 var _yAxis = new Vector3( 0, 1, 0 );
5281 var _zAxis = new Vector3( 0, 0, 1 );
5282
5283 var _addedEvent = { type: 'added' };
5284 var _removedEvent = { type: 'removed' };
5285
5286 function Object3D() {
5287
5288 Object.defineProperty( this, 'id', { value: _object3DId ++ } );
5289
5290 this.uuid = MathUtils.generateUUID();
5291
5292 this.name = '';
5293 this.type = 'Object3D';
5294
5295 this.parent = null;
5296 this.children = [];
5297
5298 this.up = Object3D.DefaultUp.clone();
5299
5300 var position = new Vector3();
5301 var rotation = new Euler();
5302 var quaternion = new Quaternion();
5303 var scale = new Vector3( 1, 1, 1 );
5304
5305 function onRotationChange() {
5306
5307 quaternion.setFromEuler( rotation, false );
5308
5309 }
5310
5311 function onQuaternionChange() {
5312
5313 rotation.setFromQuaternion( quaternion, undefined, false );
5314
5315 }
5316
5317 rotation._onChange( onRotationChange );
5318 quaternion._onChange( onQuaternionChange );
5319
5320 Object.defineProperties( this, {
5321 position: {
5322 configurable: true,
5323 enumerable: true,
5324 value: position
5325 },
5326 rotation: {
5327 configurable: true,
5328 enumerable: true,
5329 value: rotation
5330 },
5331 quaternion: {
5332 configurable: true,
5333 enumerable: true,
5334 value: quaternion
5335 },
5336 scale: {
5337 configurable: true,
5338 enumerable: true,
5339 value: scale
5340 },
5341 modelViewMatrix: {
5342 value: new Matrix4()
5343 },
5344 normalMatrix: {
5345 value: new Matrix3()
5346 }
5347 } );
5348
5349 this.matrix = new Matrix4();
5350 this.matrixWorld = new Matrix4();
5351
5352 this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
5353 this.matrixWorldNeedsUpdate = false;
5354
5355 this.layers = new Layers();
5356 this.visible = true;
5357
5358 this.castShadow = false;
5359 this.receiveShadow = false;
5360
5361 this.frustumCulled = true;
5362 this.renderOrder = 0;
5363
5364 this.userData = {};
5365
5366 }
5367
5368 Object3D.DefaultUp = new Vector3( 0, 1, 0 );
5369 Object3D.DefaultMatrixAutoUpdate = true;
5370
5371 Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
5372
5373 constructor: Object3D,
5374
5375 isObject3D: true,
5376
5377 onBeforeRender: function () {},
5378 onAfterRender: function () {},
5379
5380 applyMatrix4: function ( matrix ) {
5381
5382 if ( this.matrixAutoUpdate ) { this.updateMatrix(); }
5383
5384 this.matrix.premultiply( matrix );
5385
5386 this.matrix.decompose( this.position, this.quaternion, this.scale );
5387
5388 },
5389
5390 applyQuaternion: function ( q ) {
5391
5392 this.quaternion.premultiply( q );
5393
5394 return this;
5395
5396 },
5397
5398 setRotationFromAxisAngle: function ( axis, angle ) {
5399
5400 // assumes axis is normalized
5401
5402 this.quaternion.setFromAxisAngle( axis, angle );
5403
5404 },
5405
5406 setRotationFromEuler: function ( euler ) {
5407
5408 this.quaternion.setFromEuler( euler, true );
5409
5410 },
5411
5412 setRotationFromMatrix: function ( m ) {
5413
5414 // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
5415
5416 this.quaternion.setFromRotationMatrix( m );
5417
5418 },
5419
5420 setRotationFromQuaternion: function ( q ) {
5421
5422 // assumes q is normalized
5423
5424 this.quaternion.copy( q );
5425
5426 },
5427
5428 rotateOnAxis: function ( axis, angle ) {
5429
5430 // rotate object on axis in object space
5431 // axis is assumed to be normalized
5432
5433 _q1.setFromAxisAngle( axis, angle );
5434
5435 this.quaternion.multiply( _q1 );
5436
5437 return this;
5438
5439 },
5440
5441 rotateOnWorldAxis: function ( axis, angle ) {
5442
5443 // rotate object on axis in world space
5444 // axis is assumed to be normalized
5445 // method assumes no rotated parent
5446
5447 _q1.setFromAxisAngle( axis, angle );
5448
5449 this.quaternion.premultiply( _q1 );
5450
5451 return this;
5452
5453 },
5454
5455 rotateX: function ( angle ) {
5456
5457 return this.rotateOnAxis( _xAxis, angle );
5458
5459 },
5460
5461 rotateY: function ( angle ) {
5462
5463 return this.rotateOnAxis( _yAxis, angle );
5464
5465 },
5466
5467 rotateZ: function ( angle ) {
5468
5469 return this.rotateOnAxis( _zAxis, angle );
5470
5471 },
5472
5473 translateOnAxis: function ( axis, distance ) {
5474
5475 // translate object by distance along axis in object space
5476 // axis is assumed to be normalized
5477
5478 _v1$1.copy( axis ).applyQuaternion( this.quaternion );
5479
5480 this.position.add( _v1$1.multiplyScalar( distance ) );
5481
5482 return this;
5483
5484 },
5485
5486 translateX: function ( distance ) {
5487
5488 return this.translateOnAxis( _xAxis, distance );
5489
5490 },
5491
5492 translateY: function ( distance ) {
5493
5494 return this.translateOnAxis( _yAxis, distance );
5495
5496 },
5497
5498 translateZ: function ( distance ) {
5499
5500 return this.translateOnAxis( _zAxis, distance );
5501
5502 },
5503
5504 localToWorld: function ( vector ) {
5505
5506 return vector.applyMatrix4( this.matrixWorld );
5507
5508 },
5509
5510 worldToLocal: function ( vector ) {
5511
5512 return vector.applyMatrix4( _m1$1.getInverse( this.matrixWorld ) );
5513
5514 },
5515
5516 lookAt: function ( x, y, z ) {
5517
5518 // This method does not support objects having non-uniformly-scaled parent(s)
5519
5520 if ( x.isVector3 ) {
5521
5522 _target.copy( x );
5523
5524 } else {
5525
5526 _target.set( x, y, z );
5527
5528 }
5529
5530 var parent = this.parent;
5531
5532 this.updateWorldMatrix( true, false );
5533
5534 _position.setFromMatrixPosition( this.matrixWorld );
5535
5536 if ( this.isCamera || this.isLight ) {
5537
5538 _m1$1.lookAt( _position, _target, this.up );
5539
5540 } else {
5541
5542 _m1$1.lookAt( _target, _position, this.up );
5543
5544 }
5545
5546 this.quaternion.setFromRotationMatrix( _m1$1 );
5547
5548 if ( parent ) {
5549
5550 _m1$1.extractRotation( parent.matrixWorld );
5551 _q1.setFromRotationMatrix( _m1$1 );
5552 this.quaternion.premultiply( _q1.inverse() );
5553
5554 }
5555
5556 },
5557
5558 add: function ( object ) {
5559
5560 if ( arguments.length > 1 ) {
5561
5562 for ( var i = 0; i < arguments.length; i ++ ) {
5563
5564 this.add( arguments[ i ] );
5565
5566 }
5567
5568 return this;
5569
5570 }
5571
5572 if ( object === this ) {
5573
5574 console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
5575 return this;
5576
5577 }
5578
5579 if ( ( object && object.isObject3D ) ) {
5580
5581 if ( object.parent !== null ) {
5582
5583 object.parent.remove( object );
5584
5585 }
5586
5587 object.parent = this;
5588 this.children.push( object );
5589
5590 object.dispatchEvent( _addedEvent );
5591
5592 } else {
5593
5594 console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
5595
5596 }
5597
5598 return this;
5599
5600 },
5601
5602 remove: function ( object ) {
5603
5604 if ( arguments.length > 1 ) {
5605
5606 for ( var i = 0; i < arguments.length; i ++ ) {
5607
5608 this.remove( arguments[ i ] );
5609
5610 }
5611
5612 return this;
5613
5614 }
5615
5616 var index = this.children.indexOf( object );
5617
5618 if ( index !== - 1 ) {
5619
5620 object.parent = null;
5621 this.children.splice( index, 1 );
5622
5623 object.dispatchEvent( _removedEvent );
5624
5625 }
5626
5627 return this;
5628
5629 },
5630
5631 attach: function ( object ) {
5632
5633 // adds object as a child of this, while maintaining the object's world transform
5634
5635 this.updateWorldMatrix( true, false );
5636
5637 _m1$1.getInverse( this.matrixWorld );
5638
5639 if ( object.parent !== null ) {
5640
5641 object.parent.updateWorldMatrix( true, false );
5642
5643 _m1$1.multiply( object.parent.matrixWorld );
5644
5645 }
5646
5647 object.applyMatrix4( _m1$1 );
5648
5649 object.updateWorldMatrix( false, false );
5650
5651 this.add( object );
5652
5653 return this;
5654
5655 },
5656
5657 getObjectById: function ( id ) {
5658
5659 return this.getObjectByProperty( 'id', id );
5660
5661 },
5662
5663 getObjectByName: function ( name ) {
5664
5665 return this.getObjectByProperty( 'name', name );
5666
5667 },
5668
5669 getObjectByProperty: function ( name, value ) {
5670
5671 if ( this[ name ] === value ) { return this; }
5672
5673 for ( var i = 0, l = this.children.length; i < l; i ++ ) {
5674
5675 var child = this.children[ i ];
5676 var object = child.getObjectByProperty( name, value );
5677
5678 if ( object !== undefined ) {
5679
5680 return object;
5681
5682 }
5683
5684 }
5685
5686 return undefined;
5687
5688 },
5689
5690 getWorldPosition: function ( target ) {
5691
5692 if ( target === undefined ) {
5693
5694 console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' );
5695 target = new Vector3();
5696
5697 }
5698
5699 this.updateMatrixWorld( true );
5700
5701 return target.setFromMatrixPosition( this.matrixWorld );
5702
5703 },
5704
5705 getWorldQuaternion: function ( target ) {
5706
5707 if ( target === undefined ) {
5708
5709 console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
5710 target = new Quaternion();
5711
5712 }
5713
5714 this.updateMatrixWorld( true );
5715
5716 this.matrixWorld.decompose( _position, target, _scale );
5717
5718 return target;
5719
5720 },
5721
5722 getWorldScale: function ( target ) {
5723
5724 if ( target === undefined ) {
5725
5726 console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
5727 target = new Vector3();
5728
5729 }
5730
5731 this.updateMatrixWorld( true );
5732
5733 this.matrixWorld.decompose( _position, _quaternion$2, target );
5734
5735 return target;
5736
5737 },
5738
5739 getWorldDirection: function ( target ) {
5740
5741 if ( target === undefined ) {
5742
5743 console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' );
5744 target = new Vector3();
5745
5746 }
5747
5748 this.updateMatrixWorld( true );
5749
5750 var e = this.matrixWorld.elements;
5751
5752 return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
5753
5754 },
5755
5756 raycast: function () {},
5757
5758 traverse: function ( callback ) {
5759
5760 callback( this );
5761
5762 var children = this.children;
5763
5764 for ( var i = 0, l = children.length; i < l; i ++ ) {
5765
5766 children[ i ].traverse( callback );
5767
5768 }
5769
5770 },
5771
5772 traverseVisible: function ( callback ) {
5773
5774 if ( this.visible === false ) { return; }
5775
5776 callback( this );
5777
5778 var children = this.children;
5779
5780 for ( var i = 0, l = children.length; i < l; i ++ ) {
5781
5782 children[ i ].traverseVisible( callback );
5783
5784 }
5785
5786 },
5787
5788 traverseAncestors: function ( callback ) {
5789
5790 var parent = this.parent;
5791
5792 if ( parent !== null ) {
5793
5794 callback( parent );
5795
5796 parent.traverseAncestors( callback );
5797
5798 }
5799
5800 },
5801
5802 updateMatrix: function () {
5803
5804 this.matrix.compose( this.position, this.quaternion, this.scale );
5805
5806 this.matrixWorldNeedsUpdate = true;
5807
5808 },
5809
5810 updateMatrixWorld: function ( force ) {
5811
5812 if ( this.matrixAutoUpdate ) { this.updateMatrix(); }
5813
5814 if ( this.matrixWorldNeedsUpdate || force ) {
5815
5816 if ( this.parent === null ) {
5817
5818 this.matrixWorld.copy( this.matrix );
5819
5820 } else {
5821
5822 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
5823
5824 }
5825
5826 this.matrixWorldNeedsUpdate = false;
5827
5828 force = true;
5829
5830 }
5831
5832 // update children
5833
5834 var children = this.children;
5835
5836 for ( var i = 0, l = children.length; i < l; i ++ ) {
5837
5838 children[ i ].updateMatrixWorld( force );
5839
5840 }
5841
5842 },
5843
5844 updateWorldMatrix: function ( updateParents, updateChildren ) {
5845
5846 var parent = this.parent;
5847
5848 if ( updateParents === true && parent !== null ) {
5849
5850 parent.updateWorldMatrix( true, false );
5851
5852 }
5853
5854 if ( this.matrixAutoUpdate ) { this.updateMatrix(); }
5855
5856 if ( this.parent === null ) {
5857
5858 this.matrixWorld.copy( this.matrix );
5859
5860 } else {
5861
5862 this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
5863
5864 }
5865
5866 // update children
5867
5868 if ( updateChildren === true ) {
5869
5870 var children = this.children;
5871
5872 for ( var i = 0, l = children.length; i < l; i ++ ) {
5873
5874 children[ i ].updateWorldMatrix( false, true );
5875
5876 }
5877
5878 }
5879
5880 },
5881
5882 toJSON: function ( meta ) {
5883
5884 // meta is a string when called from JSON.stringify
5885 var isRootObject = ( meta === undefined || typeof meta === 'string' );
5886
5887 var output = {};
5888
5889 // meta is a hash used to collect geometries, materials.
5890 // not providing it implies that this is the root object
5891 // being serialized.
5892 if ( isRootObject ) {
5893
5894 // initialize meta obj
5895 meta = {
5896 geometries: {},
5897 materials: {},
5898 textures: {},
5899 images: {},
5900 shapes: {}
5901 };
5902
5903 output.metadata = {
5904 version: 4.5,
5905 type: 'Object',
5906 generator: 'Object3D.toJSON'
5907 };
5908
5909 }
5910
5911 // standard Object3D serialization
5912
5913 var object = {};
5914
5915 object.uuid = this.uuid;
5916 object.type = this.type;
5917
5918 if ( this.name !== '' ) { object.name = this.name; }
5919 if ( this.castShadow === true ) { object.castShadow = true; }
5920 if ( this.receiveShadow === true ) { object.receiveShadow = true; }
5921 if ( this.visible === false ) { object.visible = false; }
5922 if ( this.frustumCulled === false ) { object.frustumCulled = false; }
5923 if ( this.renderOrder !== 0 ) { object.renderOrder = this.renderOrder; }
5924 if ( JSON.stringify( this.userData ) !== '{}' ) { object.userData = this.userData; }
5925
5926 object.layers = this.layers.mask;
5927 object.matrix = this.matrix.toArray();
5928
5929 if ( this.matrixAutoUpdate === false ) { object.matrixAutoUpdate = false; }
5930
5931 // object specific properties
5932
5933 if ( this.isInstancedMesh ) {
5934
5935 object.type = 'InstancedMesh';
5936 object.count = this.count;
5937 object.instanceMatrix = this.instanceMatrix.toJSON();
5938
5939 }
5940
5941 //
5942
5943 function serialize( library, element ) {
5944
5945 if ( library[ element.uuid ] === undefined ) {
5946
5947 library[ element.uuid ] = element.toJSON( meta );
5948
5949 }
5950
5951 return element.uuid;
5952
5953 }
5954
5955 if ( this.isMesh || this.isLine || this.isPoints ) {
5956
5957 object.geometry = serialize( meta.geometries, this.geometry );
5958
5959 var parameters = this.geometry.parameters;
5960
5961 if ( parameters !== undefined && parameters.shapes !== undefined ) {
5962
5963 var shapes = parameters.shapes;
5964
5965 if ( Array.isArray( shapes ) ) {
5966
5967 for ( var i = 0, l = shapes.length; i < l; i ++ ) {
5968
5969 var shape = shapes[ i ];
5970
5971 serialize( meta.shapes, shape );
5972
5973 }
5974
5975 } else {
5976
5977 serialize( meta.shapes, shapes );
5978
5979 }
5980
5981 }
5982
5983 }
5984
5985 if ( this.material !== undefined ) {
5986
5987 if ( Array.isArray( this.material ) ) {
5988
5989 var uuids = [];
5990
5991 for ( var i$1 = 0, l$1 = this.material.length; i$1 < l$1; i$1 ++ ) {
5992
5993 uuids.push( serialize( meta.materials, this.material[ i$1 ] ) );
5994
5995 }
5996
5997 object.material = uuids;
5998
5999 } else {
6000
6001 object.material = serialize( meta.materials, this.material );
6002
6003 }
6004
6005 }
6006
6007 //
6008
6009 if ( this.children.length > 0 ) {
6010
6011 object.children = [];
6012
6013 for ( var i$2 = 0; i$2 < this.children.length; i$2 ++ ) {
6014
6015 object.children.push( this.children[ i$2 ].toJSON( meta ).object );
6016
6017 }
6018
6019 }
6020
6021 if ( isRootObject ) {
6022
6023 var geometries = extractFromCache( meta.geometries );
6024 var materials = extractFromCache( meta.materials );
6025 var textures = extractFromCache( meta.textures );
6026 var images = extractFromCache( meta.images );
6027 var shapes$1 = extractFromCache( meta.shapes );
6028
6029 if ( geometries.length > 0 ) { output.geometries = geometries; }
6030 if ( materials.length > 0 ) { output.materials = materials; }
6031 if ( textures.length > 0 ) { output.textures = textures; }
6032 if ( images.length > 0 ) { output.images = images; }
6033 if ( shapes$1.length > 0 ) { output.shapes = shapes$1; }
6034
6035 }
6036
6037 output.object = object;
6038
6039 return output;
6040
6041 // extract data from the cache hash
6042 // remove metadata on each item
6043 // and return as array
6044 function extractFromCache( cache ) {
6045
6046 var values = [];
6047 for ( var key in cache ) {
6048
6049 var data = cache[ key ];
6050 delete data.metadata;
6051 values.push( data );
6052
6053 }
6054
6055 return values;
6056
6057 }
6058
6059 },
6060
6061 clone: function ( recursive ) {
6062
6063 return new this.constructor().copy( this, recursive );
6064
6065 },
6066
6067 copy: function ( source, recursive ) {
6068
6069 if ( recursive === undefined ) { recursive = true; }
6070
6071 this.name = source.name;
6072
6073 this.up.copy( source.up );
6074
6075 this.position.copy( source.position );
6076 this.rotation.order = source.rotation.order;
6077 this.quaternion.copy( source.quaternion );
6078 this.scale.copy( source.scale );
6079
6080 this.matrix.copy( source.matrix );
6081 this.matrixWorld.copy( source.matrixWorld );
6082
6083 this.matrixAutoUpdate = source.matrixAutoUpdate;
6084 this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
6085
6086 this.layers.mask = source.layers.mask;
6087 this.visible = source.visible;
6088
6089 this.castShadow = source.castShadow;
6090 this.receiveShadow = source.receiveShadow;
6091
6092 this.frustumCulled = source.frustumCulled;
6093 this.renderOrder = source.renderOrder;
6094
6095 this.userData = JSON.parse( JSON.stringify( source.userData ) );
6096
6097 if ( recursive === true ) {
6098
6099 for ( var i = 0; i < source.children.length; i ++ ) {
6100
6101 var child = source.children[ i ];
6102 this.add( child.clone() );
6103
6104 }
6105
6106 }
6107
6108 return this;
6109
6110 }
6111
6112 } );
6113
6114 function Scene() {
6115
6116 Object3D.call( this );
6117
6118 this.type = 'Scene';
6119
6120 this.background = null;
6121 this.environment = null;
6122 this.fog = null;
6123
6124 this.overrideMaterial = null;
6125
6126 this.autoUpdate = true; // checked by the renderer
6127
6128 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
6129
6130 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef
6131
6132 }
6133
6134 }
6135
6136 Scene.prototype = Object.assign( Object.create( Object3D.prototype ), {
6137
6138 constructor: Scene,
6139
6140 isScene: true,
6141
6142 copy: function ( source, recursive ) {
6143
6144 Object3D.prototype.copy.call( this, source, recursive );
6145
6146 if ( source.background !== null ) { this.background = source.background.clone(); }
6147 if ( source.environment !== null ) { this.environment = source.environment.clone(); }
6148 if ( source.fog !== null ) { this.fog = source.fog.clone(); }
6149
6150 if ( source.overrideMaterial !== null ) { this.overrideMaterial = source.overrideMaterial.clone(); }
6151
6152 this.autoUpdate = source.autoUpdate;
6153 this.matrixAutoUpdate = source.matrixAutoUpdate;
6154
6155 return this;
6156
6157 },
6158
6159 toJSON: function ( meta ) {
6160
6161 var data = Object3D.prototype.toJSON.call( this, meta );
6162
6163 if ( this.background !== null ) { data.object.background = this.background.toJSON( meta ); }
6164 if ( this.environment !== null ) { data.object.environment = this.environment.toJSON( meta ); }
6165 if ( this.fog !== null ) { data.object.fog = this.fog.toJSON(); }
6166
6167 return data;
6168
6169 },
6170
6171 dispose: function () {
6172
6173 this.dispatchEvent( { type: 'dispose' } );
6174
6175 }
6176
6177 } );
6178
6179 var _points = [
6180 new Vector3(),
6181 new Vector3(),
6182 new Vector3(),
6183 new Vector3(),
6184 new Vector3(),
6185 new Vector3(),
6186 new Vector3(),
6187 new Vector3()
6188 ];
6189
6190 var _vector$1 = new Vector3();
6191
6192 var _box = new Box3();
6193
6194 // triangle centered vertices
6195
6196 var _v0 = new Vector3();
6197 var _v1$2 = new Vector3();
6198 var _v2 = new Vector3();
6199
6200 // triangle edge vectors
6201
6202 var _f0 = new Vector3();
6203 var _f1 = new Vector3();
6204 var _f2 = new Vector3();
6205
6206 var _center = new Vector3();
6207 var _extents = new Vector3();
6208 var _triangleNormal = new Vector3();
6209 var _testAxis = new Vector3();
6210
6211 function Box3( min, max ) {
6212
6213 this.min = ( min !== undefined ) ? min : new Vector3( + Infinity, + Infinity, + Infinity );
6214 this.max = ( max !== undefined ) ? max : new Vector3( - Infinity, - Infinity, - Infinity );
6215
6216 }
6217
6218
6219 Object.assign( Box3.prototype, {
6220
6221 isBox3: true,
6222
6223 set: function ( min, max ) {
6224
6225 this.min.copy( min );
6226 this.max.copy( max );
6227
6228 return this;
6229
6230 },
6231
6232 setFromArray: function ( array ) {
6233
6234 var minX = + Infinity;
6235 var minY = + Infinity;
6236 var minZ = + Infinity;
6237
6238 var maxX = - Infinity;
6239 var maxY = - Infinity;
6240 var maxZ = - Infinity;
6241
6242 for ( var i = 0, l = array.length; i < l; i += 3 ) {
6243
6244 var x = array[ i ];
6245 var y = array[ i + 1 ];
6246 var z = array[ i + 2 ];
6247
6248 if ( x < minX ) { minX = x; }
6249 if ( y < minY ) { minY = y; }
6250 if ( z < minZ ) { minZ = z; }
6251
6252 if ( x > maxX ) { maxX = x; }
6253 if ( y > maxY ) { maxY = y; }
6254 if ( z > maxZ ) { maxZ = z; }
6255
6256 }
6257
6258 this.min.set( minX, minY, minZ );
6259 this.max.set( maxX, maxY, maxZ );
6260
6261 return this;
6262
6263 },
6264
6265 setFromBufferAttribute: function ( attribute ) {
6266
6267 var minX = + Infinity;
6268 var minY = + Infinity;
6269 var minZ = + Infinity;
6270
6271 var maxX = - Infinity;
6272 var maxY = - Infinity;
6273 var maxZ = - Infinity;
6274
6275 for ( var i = 0, l = attribute.count; i < l; i ++ ) {
6276
6277 var x = attribute.getX( i );
6278 var y = attribute.getY( i );
6279 var z = attribute.getZ( i );
6280
6281 if ( x < minX ) { minX = x; }
6282 if ( y < minY ) { minY = y; }
6283 if ( z < minZ ) { minZ = z; }
6284
6285 if ( x > maxX ) { maxX = x; }
6286 if ( y > maxY ) { maxY = y; }
6287 if ( z > maxZ ) { maxZ = z; }
6288
6289 }
6290
6291 this.min.set( minX, minY, minZ );
6292 this.max.set( maxX, maxY, maxZ );
6293
6294 return this;
6295
6296 },
6297
6298 setFromPoints: function ( points ) {
6299
6300 this.makeEmpty();
6301
6302 for ( var i = 0, il = points.length; i < il; i ++ ) {
6303
6304 this.expandByPoint( points[ i ] );
6305
6306 }
6307
6308 return this;
6309
6310 },
6311
6312 setFromCenterAndSize: function ( center, size ) {
6313
6314 var halfSize = _vector$1.copy( size ).multiplyScalar( 0.5 );
6315
6316 this.min.copy( center ).sub( halfSize );
6317 this.max.copy( center ).add( halfSize );
6318
6319 return this;
6320
6321 },
6322
6323 setFromObject: function ( object ) {
6324
6325 this.makeEmpty();
6326
6327 return this.expandByObject( object );
6328
6329 },
6330
6331 clone: function () {
6332
6333 return new this.constructor().copy( this );
6334
6335 },
6336
6337 copy: function ( box ) {
6338
6339 this.min.copy( box.min );
6340 this.max.copy( box.max );
6341
6342 return this;
6343
6344 },
6345
6346 makeEmpty: function () {
6347
6348 this.min.x = this.min.y = this.min.z = + Infinity;
6349 this.max.x = this.max.y = this.max.z = - Infinity;
6350
6351 return this;
6352
6353 },
6354
6355 isEmpty: function () {
6356
6357 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
6358
6359 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z );
6360
6361 },
6362
6363 getCenter: function ( target ) {
6364
6365 if ( target === undefined ) {
6366
6367 console.warn( 'THREE.Box3: .getCenter() target is now required' );
6368 target = new Vector3();
6369
6370 }
6371
6372 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
6373
6374 },
6375
6376 getSize: function ( target ) {
6377
6378 if ( target === undefined ) {
6379
6380 console.warn( 'THREE.Box3: .getSize() target is now required' );
6381 target = new Vector3();
6382
6383 }
6384
6385 return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min );
6386
6387 },
6388
6389 expandByPoint: function ( point ) {
6390
6391 this.min.min( point );
6392 this.max.max( point );
6393
6394 return this;
6395
6396 },
6397
6398 expandByVector: function ( vector ) {
6399
6400 this.min.sub( vector );
6401 this.max.add( vector );
6402
6403 return this;
6404
6405 },
6406
6407 expandByScalar: function ( scalar ) {
6408
6409 this.min.addScalar( - scalar );
6410 this.max.addScalar( scalar );
6411
6412 return this;
6413
6414 },
6415
6416 expandByObject: function ( object ) {
6417
6418 // Computes the world-axis-aligned bounding box of an object (including its children),
6419 // accounting for both the object's, and children's, world transforms
6420
6421 object.updateWorldMatrix( false, false );
6422
6423 var geometry = object.geometry;
6424
6425 if ( geometry !== undefined ) {
6426
6427 if ( geometry.boundingBox === null ) {
6428
6429 geometry.computeBoundingBox();
6430
6431 }
6432
6433 _box.copy( geometry.boundingBox );
6434 _box.applyMatrix4( object.matrixWorld );
6435
6436 this.union( _box );
6437
6438 }
6439
6440 var children = object.children;
6441
6442 for ( var i = 0, l = children.length; i < l; i ++ ) {
6443
6444 this.expandByObject( children[ i ] );
6445
6446 }
6447
6448 return this;
6449
6450 },
6451
6452 containsPoint: function ( point ) {
6453
6454 return point.x < this.min.x || point.x > this.max.x ||
6455 point.y < this.min.y || point.y > this.max.y ||
6456 point.z < this.min.z || point.z > this.max.z ? false : true;
6457
6458 },
6459
6460 containsBox: function ( box ) {
6461
6462 return this.min.x <= box.min.x && box.max.x <= this.max.x &&
6463 this.min.y <= box.min.y && box.max.y <= this.max.y &&
6464 this.min.z <= box.min.z && box.max.z <= this.max.z;
6465
6466 },
6467
6468 getParameter: function ( point, target ) {
6469
6470 // This can potentially have a divide by zero if the box
6471 // has a size dimension of 0.
6472
6473 if ( target === undefined ) {
6474
6475 console.warn( 'THREE.Box3: .getParameter() target is now required' );
6476 target = new Vector3();
6477
6478 }
6479
6480 return target.set(
6481 ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
6482 ( point.y - this.min.y ) / ( this.max.y - this.min.y ),
6483 ( point.z - this.min.z ) / ( this.max.z - this.min.z )
6484 );
6485
6486 },
6487
6488 intersectsBox: function ( box ) {
6489
6490 // using 6 splitting planes to rule out intersections.
6491 return box.max.x < this.min.x || box.min.x > this.max.x ||
6492 box.max.y < this.min.y || box.min.y > this.max.y ||
6493 box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
6494
6495 },
6496
6497 intersectsSphere: function ( sphere ) {
6498
6499 // Find the point on the AABB closest to the sphere center.
6500 this.clampPoint( sphere.center, _vector$1 );
6501
6502 // If that point is inside the sphere, the AABB and sphere intersect.
6503 return _vector$1.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius );
6504
6505 },
6506
6507 intersectsPlane: function ( plane ) {
6508
6509 // We compute the minimum and maximum dot product values. If those values
6510 // are on the same side (back or front) of the plane, then there is no intersection.
6511
6512 var min, max;
6513
6514 if ( plane.normal.x > 0 ) {
6515
6516 min = plane.normal.x * this.min.x;
6517 max = plane.normal.x * this.max.x;
6518
6519 } else {
6520
6521 min = plane.normal.x * this.max.x;
6522 max = plane.normal.x * this.min.x;
6523
6524 }
6525
6526 if ( plane.normal.y > 0 ) {
6527
6528 min += plane.normal.y * this.min.y;
6529 max += plane.normal.y * this.max.y;
6530
6531 } else {
6532
6533 min += plane.normal.y * this.max.y;
6534 max += plane.normal.y * this.min.y;
6535
6536 }
6537
6538 if ( plane.normal.z > 0 ) {
6539
6540 min += plane.normal.z * this.min.z;
6541 max += plane.normal.z * this.max.z;
6542
6543 } else {
6544
6545 min += plane.normal.z * this.max.z;
6546 max += plane.normal.z * this.min.z;
6547
6548 }
6549
6550 return ( min <= - plane.constant && max >= - plane.constant );
6551
6552 },
6553
6554 intersectsTriangle: function ( triangle ) {
6555
6556 if ( this.isEmpty() ) {
6557
6558 return false;
6559
6560 }
6561
6562 // compute box center and extents
6563 this.getCenter( _center );
6564 _extents.subVectors( this.max, _center );
6565
6566 // translate triangle to aabb origin
6567 _v0.subVectors( triangle.a, _center );
6568 _v1$2.subVectors( triangle.b, _center );
6569 _v2.subVectors( triangle.c, _center );
6570
6571 // compute edge vectors for triangle
6572 _f0.subVectors( _v1$2, _v0 );
6573 _f1.subVectors( _v2, _v1$2 );
6574 _f2.subVectors( _v0, _v2 );
6575
6576 // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb
6577 // 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
6578 // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned)
6579 var axes = [
6580 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y,
6581 _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x,
6582 - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0
6583 ];
6584 if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) {
6585
6586 return false;
6587
6588 }
6589
6590 // test 3 face normals from the aabb
6591 axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ];
6592 if ( ! satForAxes( axes, _v0, _v1$2, _v2, _extents ) ) {
6593
6594 return false;
6595
6596 }
6597
6598 // finally testing the face normal of the triangle
6599 // use already existing triangle edge vectors here
6600 _triangleNormal.crossVectors( _f0, _f1 );
6601 axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ];
6602
6603 return satForAxes( axes, _v0, _v1$2, _v2, _extents );
6604
6605 },
6606
6607 clampPoint: function ( point, target ) {
6608
6609 if ( target === undefined ) {
6610
6611 console.warn( 'THREE.Box3: .clampPoint() target is now required' );
6612 target = new Vector3();
6613
6614 }
6615
6616 return target.copy( point ).clamp( this.min, this.max );
6617
6618 },
6619
6620 distanceToPoint: function ( point ) {
6621
6622 var clampedPoint = _vector$1.copy( point ).clamp( this.min, this.max );
6623
6624 return clampedPoint.sub( point ).length();
6625
6626 },
6627
6628 getBoundingSphere: function ( target ) {
6629
6630 if ( target === undefined ) {
6631
6632 console.error( 'THREE.Box3: .getBoundingSphere() target is now required' );
6633 //target = new Sphere(); // removed to avoid cyclic dependency
6634
6635 }
6636
6637 this.getCenter( target.center );
6638
6639 target.radius = this.getSize( _vector$1 ).length() * 0.5;
6640
6641 return target;
6642
6643 },
6644
6645 intersect: function ( box ) {
6646
6647 this.min.max( box.min );
6648 this.max.min( box.max );
6649
6650 // 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.
6651 if ( this.isEmpty() ) { this.makeEmpty(); }
6652
6653 return this;
6654
6655 },
6656
6657 union: function ( box ) {
6658
6659 this.min.min( box.min );
6660 this.max.max( box.max );
6661
6662 return this;
6663
6664 },
6665
6666 applyMatrix4: function ( matrix ) {
6667
6668 // transform of empty box is an empty box.
6669 if ( this.isEmpty() ) { return this; }
6670
6671 // NOTE: I am using a binary pattern to specify all 2^3 combinations below
6672 _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000
6673 _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001
6674 _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010
6675 _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011
6676 _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100
6677 _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101
6678 _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110
6679 _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111
6680
6681 this.setFromPoints( _points );
6682
6683 return this;
6684
6685 },
6686
6687 translate: function ( offset ) {
6688
6689 this.min.add( offset );
6690 this.max.add( offset );
6691
6692 return this;
6693
6694 },
6695
6696 equals: function ( box ) {
6697
6698 return box.min.equals( this.min ) && box.max.equals( this.max );
6699
6700 }
6701
6702 } );
6703
6704 function satForAxes( axes, v0, v1, v2, extents ) {
6705
6706 for ( var i = 0, j = axes.length - 3; i <= j; i += 3 ) {
6707
6708 _testAxis.fromArray( axes, i );
6709 // project the aabb onto the seperating axis
6710 var r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z );
6711 // project all 3 vertices of the triangle onto the seperating axis
6712 var p0 = v0.dot( _testAxis );
6713 var p1 = v1.dot( _testAxis );
6714 var p2 = v2.dot( _testAxis );
6715 // actual test, basically see if either of the most extreme of the triangle points intersects r
6716 if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) {
6717
6718 // points of the projected triangle are outside the projected half-length of the aabb
6719 // the axis is seperating and we can exit
6720 return false;
6721
6722 }
6723
6724 }
6725
6726 return true;
6727
6728 }
6729
6730 var _box$1 = new Box3();
6731
6732 function Sphere( center, radius ) {
6733
6734 this.center = ( center !== undefined ) ? center : new Vector3();
6735 this.radius = ( radius !== undefined ) ? radius : - 1;
6736
6737 }
6738
6739 Object.assign( Sphere.prototype, {
6740
6741 set: function ( center, radius ) {
6742
6743 this.center.copy( center );
6744 this.radius = radius;
6745
6746 return this;
6747
6748 },
6749
6750 setFromPoints: function ( points, optionalCenter ) {
6751
6752 var center = this.center;
6753
6754 if ( optionalCenter !== undefined ) {
6755
6756 center.copy( optionalCenter );
6757
6758 } else {
6759
6760 _box$1.setFromPoints( points ).getCenter( center );
6761
6762 }
6763
6764 var maxRadiusSq = 0;
6765
6766 for ( var i = 0, il = points.length; i < il; i ++ ) {
6767
6768 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) );
6769
6770 }
6771
6772 this.radius = Math.sqrt( maxRadiusSq );
6773
6774 return this;
6775
6776 },
6777
6778 clone: function () {
6779
6780 return new this.constructor().copy( this );
6781
6782 },
6783
6784 copy: function ( sphere ) {
6785
6786 this.center.copy( sphere.center );
6787 this.radius = sphere.radius;
6788
6789 return this;
6790
6791 },
6792
6793 isEmpty: function () {
6794
6795 return ( this.radius < 0 );
6796
6797 },
6798
6799 makeEmpty: function () {
6800
6801 this.center.set( 0, 0, 0 );
6802 this.radius = - 1;
6803
6804 return this;
6805
6806 },
6807
6808 containsPoint: function ( point ) {
6809
6810 return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) );
6811
6812 },
6813
6814 distanceToPoint: function ( point ) {
6815
6816 return ( point.distanceTo( this.center ) - this.radius );
6817
6818 },
6819
6820 intersectsSphere: function ( sphere ) {
6821
6822 var radiusSum = this.radius + sphere.radius;
6823
6824 return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum );
6825
6826 },
6827
6828 intersectsBox: function ( box ) {
6829
6830 return box.intersectsSphere( this );
6831
6832 },
6833
6834 intersectsPlane: function ( plane ) {
6835
6836 return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;
6837
6838 },
6839
6840 clampPoint: function ( point, target ) {
6841
6842 var deltaLengthSq = this.center.distanceToSquared( point );
6843
6844 if ( target === undefined ) {
6845
6846 console.warn( 'THREE.Sphere: .clampPoint() target is now required' );
6847 target = new Vector3();
6848
6849 }
6850
6851 target.copy( point );
6852
6853 if ( deltaLengthSq > ( this.radius * this.radius ) ) {
6854
6855 target.sub( this.center ).normalize();
6856 target.multiplyScalar( this.radius ).add( this.center );
6857
6858 }
6859
6860 return target;
6861
6862 },
6863
6864 getBoundingBox: function ( target ) {
6865
6866 if ( target === undefined ) {
6867
6868 console.warn( 'THREE.Sphere: .getBoundingBox() target is now required' );
6869 target = new Box3();
6870
6871 }
6872
6873 if ( this.isEmpty() ) {
6874
6875 // Empty sphere produces empty bounding box
6876 target.makeEmpty();
6877 return target;
6878
6879 }
6880
6881 target.set( this.center, this.center );
6882 target.expandByScalar( this.radius );
6883
6884 return target;
6885
6886 },
6887
6888 applyMatrix4: function ( matrix ) {
6889
6890 this.center.applyMatrix4( matrix );
6891 this.radius = this.radius * matrix.getMaxScaleOnAxis();
6892
6893 return this;
6894
6895 },
6896
6897 translate: function ( offset ) {
6898
6899 this.center.add( offset );
6900
6901 return this;
6902
6903 },
6904
6905 equals: function ( sphere ) {
6906
6907 return sphere.center.equals( this.center ) && ( sphere.radius === this.radius );
6908
6909 }
6910
6911 } );
6912
6913 var _vector$2 = new Vector3();
6914 var _segCenter = new Vector3();
6915 var _segDir = new Vector3();
6916 var _diff = new Vector3();
6917
6918 var _edge1 = new Vector3();
6919 var _edge2 = new Vector3();
6920 var _normal = new Vector3();
6921
6922 function Ray( origin, direction ) {
6923
6924 this.origin = ( origin !== undefined ) ? origin : new Vector3();
6925 this.direction = ( direction !== undefined ) ? direction : new Vector3( 0, 0, - 1 );
6926
6927 }
6928
6929 Object.assign( Ray.prototype, {
6930
6931 set: function ( origin, direction ) {
6932
6933 this.origin.copy( origin );
6934 this.direction.copy( direction );
6935
6936 return this;
6937
6938 },
6939
6940 clone: function () {
6941
6942 return new this.constructor().copy( this );
6943
6944 },
6945
6946 copy: function ( ray ) {
6947
6948 this.origin.copy( ray.origin );
6949 this.direction.copy( ray.direction );
6950
6951 return this;
6952
6953 },
6954
6955 at: function ( t, target ) {
6956
6957 if ( target === undefined ) {
6958
6959 console.warn( 'THREE.Ray: .at() target is now required' );
6960 target = new Vector3();
6961
6962 }
6963
6964 return target.copy( this.direction ).multiplyScalar( t ).add( this.origin );
6965
6966 },
6967
6968 lookAt: function ( v ) {
6969
6970 this.direction.copy( v ).sub( this.origin ).normalize();
6971
6972 return this;
6973
6974 },
6975
6976 recast: function ( t ) {
6977
6978 this.origin.copy( this.at( t, _vector$2 ) );
6979
6980 return this;
6981
6982 },
6983
6984 closestPointToPoint: function ( point, target ) {
6985
6986 if ( target === undefined ) {
6987
6988 console.warn( 'THREE.Ray: .closestPointToPoint() target is now required' );
6989 target = new Vector3();
6990
6991 }
6992
6993 target.subVectors( point, this.origin );
6994
6995 var directionDistance = target.dot( this.direction );
6996
6997 if ( directionDistance < 0 ) {
6998
6999 return target.copy( this.origin );
7000
7001 }
7002
7003 return target.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
7004
7005 },
7006
7007 distanceToPoint: function ( point ) {
7008
7009 return Math.sqrt( this.distanceSqToPoint( point ) );
7010
7011 },
7012
7013 distanceSqToPoint: function ( point ) {
7014
7015 var directionDistance = _vector$2.subVectors( point, this.origin ).dot( this.direction );
7016
7017 // point behind the ray
7018
7019 if ( directionDistance < 0 ) {
7020
7021 return this.origin.distanceToSquared( point );
7022
7023 }
7024
7025 _vector$2.copy( this.direction ).multiplyScalar( directionDistance ).add( this.origin );
7026
7027 return _vector$2.distanceToSquared( point );
7028
7029 },
7030
7031 distanceSqToSegment: function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
7032
7033 // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteDistRaySegment.h
7034 // It returns the min distance between the ray and the segment
7035 // defined by v0 and v1
7036 // It can also set two optional targets :
7037 // - The closest point on the ray
7038 // - The closest point on the segment
7039
7040 _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
7041 _segDir.copy( v1 ).sub( v0 ).normalize();
7042 _diff.copy( this.origin ).sub( _segCenter );
7043
7044 var segExtent = v0.distanceTo( v1 ) * 0.5;
7045 var a01 = - this.direction.dot( _segDir );
7046 var b0 = _diff.dot( this.direction );
7047 var b1 = - _diff.dot( _segDir );
7048 var c = _diff.lengthSq();
7049 var det = Math.abs( 1 - a01 * a01 );
7050 var s0, s1, sqrDist, extDet;
7051
7052 if ( det > 0 ) {
7053
7054 // The ray and segment are not parallel.
7055
7056 s0 = a01 * b1 - b0;
7057 s1 = a01 * b0 - b1;
7058 extDet = segExtent * det;
7059
7060 if ( s0 >= 0 ) {
7061
7062 if ( s1 >= - extDet ) {
7063
7064 if ( s1 <= extDet ) {
7065
7066 // region 0
7067 // Minimum at interior points of ray and segment.
7068
7069 var invDet = 1 / det;
7070 s0 *= invDet;
7071 s1 *= invDet;
7072 sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
7073
7074 } else {
7075
7076 // region 1
7077
7078 s1 = segExtent;
7079 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
7080 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7081
7082 }
7083
7084 } else {
7085
7086 // region 5
7087
7088 s1 = - segExtent;
7089 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
7090 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7091
7092 }
7093
7094 } else {
7095
7096 if ( s1 <= - extDet ) {
7097
7098 // region 4
7099
7100 s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
7101 s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
7102 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7103
7104 } else if ( s1 <= extDet ) {
7105
7106 // region 3
7107
7108 s0 = 0;
7109 s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
7110 sqrDist = s1 * ( s1 + 2 * b1 ) + c;
7111
7112 } else {
7113
7114 // region 2
7115
7116 s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
7117 s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
7118 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7119
7120 }
7121
7122 }
7123
7124 } else {
7125
7126 // Ray and segment are parallel.
7127
7128 s1 = ( a01 > 0 ) ? - segExtent : segExtent;
7129 s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
7130 sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
7131
7132 }
7133
7134 if ( optionalPointOnRay ) {
7135
7136 optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
7137
7138 }
7139
7140 if ( optionalPointOnSegment ) {
7141
7142 optionalPointOnSegment.copy( _segDir ).multiplyScalar( s1 ).add( _segCenter );
7143
7144 }
7145
7146 return sqrDist;
7147
7148 },
7149
7150 intersectSphere: function ( sphere, target ) {
7151
7152 _vector$2.subVectors( sphere.center, this.origin );
7153 var tca = _vector$2.dot( this.direction );
7154 var d2 = _vector$2.dot( _vector$2 ) - tca * tca;
7155 var radius2 = sphere.radius * sphere.radius;
7156
7157 if ( d2 > radius2 ) { return null; }
7158
7159 var thc = Math.sqrt( radius2 - d2 );
7160
7161 // t0 = first intersect point - entrance on front of sphere
7162 var t0 = tca - thc;
7163
7164 // t1 = second intersect point - exit point on back of sphere
7165 var t1 = tca + thc;
7166
7167 // test to see if both t0 and t1 are behind the ray - if so, return null
7168 if ( t0 < 0 && t1 < 0 ) { return null; }
7169
7170 // test to see if t0 is behind the ray:
7171 // if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
7172 // in order to always return an intersect point that is in front of the ray.
7173 if ( t0 < 0 ) { return this.at( t1, target ); }
7174
7175 // else t0 is in front of the ray, so return the first collision point scaled by t0
7176 return this.at( t0, target );
7177
7178 },
7179
7180 intersectsSphere: function ( sphere ) {
7181
7182 return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius );
7183
7184 },
7185
7186 distanceToPlane: function ( plane ) {
7187
7188 var denominator = plane.normal.dot( this.direction );
7189
7190 if ( denominator === 0 ) {
7191
7192 // line is coplanar, return origin
7193 if ( plane.distanceToPoint( this.origin ) === 0 ) {
7194
7195 return 0;
7196
7197 }
7198
7199 // Null is preferable to undefined since undefined means.... it is undefined
7200
7201 return null;
7202
7203 }
7204
7205 var t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator;
7206
7207 // Return if the ray never intersects the plane
7208
7209 return t >= 0 ? t : null;
7210
7211 },
7212
7213 intersectPlane: function ( plane, target ) {
7214
7215 var t = this.distanceToPlane( plane );
7216
7217 if ( t === null ) {
7218
7219 return null;
7220
7221 }
7222
7223 return this.at( t, target );
7224
7225 },
7226
7227 intersectsPlane: function ( plane ) {
7228
7229 // check if the ray lies on the plane first
7230
7231 var distToPoint = plane.distanceToPoint( this.origin );
7232
7233 if ( distToPoint === 0 ) {
7234
7235 return true;
7236
7237 }
7238
7239 var denominator = plane.normal.dot( this.direction );
7240
7241 if ( denominator * distToPoint < 0 ) {
7242
7243 return true;
7244
7245 }
7246
7247 // ray origin is behind the plane (and is pointing behind it)
7248
7249 return false;
7250
7251 },
7252
7253 intersectBox: function ( box, target ) {
7254
7255 var tmin, tmax, tymin, tymax, tzmin, tzmax;
7256
7257 var invdirx = 1 / this.direction.x,
7258 invdiry = 1 / this.direction.y,
7259 invdirz = 1 / this.direction.z;
7260
7261 var origin = this.origin;
7262
7263 if ( invdirx >= 0 ) {
7264
7265 tmin = ( box.min.x - origin.x ) * invdirx;
7266 tmax = ( box.max.x - origin.x ) * invdirx;
7267
7268 } else {
7269
7270 tmin = ( box.max.x - origin.x ) * invdirx;
7271 tmax = ( box.min.x - origin.x ) * invdirx;
7272
7273 }
7274
7275 if ( invdiry >= 0 ) {
7276
7277 tymin = ( box.min.y - origin.y ) * invdiry;
7278 tymax = ( box.max.y - origin.y ) * invdiry;
7279
7280 } else {
7281
7282 tymin = ( box.max.y - origin.y ) * invdiry;
7283 tymax = ( box.min.y - origin.y ) * invdiry;
7284
7285 }
7286
7287 if ( ( tmin > tymax ) || ( tymin > tmax ) ) { return null; }
7288
7289 // These lines also handle the case where tmin or tmax is NaN
7290 // (result of 0 * Infinity). x !== x returns true if x is NaN
7291
7292 if ( tymin > tmin || tmin !== tmin ) { tmin = tymin; }
7293
7294 if ( tymax < tmax || tmax !== tmax ) { tmax = tymax; }
7295
7296 if ( invdirz >= 0 ) {
7297
7298 tzmin = ( box.min.z - origin.z ) * invdirz;
7299 tzmax = ( box.max.z - origin.z ) * invdirz;
7300
7301 } else {
7302
7303 tzmin = ( box.max.z - origin.z ) * invdirz;
7304 tzmax = ( box.min.z - origin.z ) * invdirz;
7305
7306 }
7307
7308 if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) { return null; }
7309
7310 if ( tzmin > tmin || tmin !== tmin ) { tmin = tzmin; }
7311
7312 if ( tzmax < tmax || tmax !== tmax ) { tmax = tzmax; }
7313
7314 //return point closest to the ray (positive side)
7315
7316 if ( tmax < 0 ) { return null; }
7317
7318 return this.at( tmin >= 0 ? tmin : tmax, target );
7319
7320 },
7321
7322 intersectsBox: function ( box ) {
7323
7324 return this.intersectBox( box, _vector$2 ) !== null;
7325
7326 },
7327
7328 intersectTriangle: function ( a, b, c, backfaceCulling, target ) {
7329
7330 // Compute the offset origin, edges, and normal.
7331
7332 // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
7333
7334 _edge1.subVectors( b, a );
7335 _edge2.subVectors( c, a );
7336 _normal.crossVectors( _edge1, _edge2 );
7337
7338 // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
7339 // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
7340 // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
7341 // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
7342 // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
7343 var DdN = this.direction.dot( _normal );
7344 var sign;
7345
7346 if ( DdN > 0 ) {
7347
7348 if ( backfaceCulling ) { return null; }
7349 sign = 1;
7350
7351 } else if ( DdN < 0 ) {
7352
7353 sign = - 1;
7354 DdN = - DdN;
7355
7356 } else {
7357
7358 return null;
7359
7360 }
7361
7362 _diff.subVectors( this.origin, a );
7363 var DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) );
7364
7365 // b1 < 0, no intersection
7366 if ( DdQxE2 < 0 ) {
7367
7368 return null;
7369
7370 }
7371
7372 var DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) );
7373
7374 // b2 < 0, no intersection
7375 if ( DdE1xQ < 0 ) {
7376
7377 return null;
7378
7379 }
7380
7381 // b1+b2 > 1, no intersection
7382 if ( DdQxE2 + DdE1xQ > DdN ) {
7383
7384 return null;
7385
7386 }
7387
7388 // Line intersects triangle, check if ray does.
7389 var QdN = - sign * _diff.dot( _normal );
7390
7391 // t < 0, no intersection
7392 if ( QdN < 0 ) {
7393
7394 return null;
7395
7396 }
7397
7398 // Ray intersects triangle.
7399 return this.at( QdN / DdN, target );
7400
7401 },
7402
7403 applyMatrix4: function ( matrix4 ) {
7404
7405 this.origin.applyMatrix4( matrix4 );
7406 this.direction.transformDirection( matrix4 );
7407
7408 return this;
7409
7410 },
7411
7412 equals: function ( ray ) {
7413
7414 return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction );
7415
7416 }
7417
7418 } );
7419
7420 var _vector1 = new Vector3();
7421 var _vector2 = new Vector3();
7422 var _normalMatrix = new Matrix3();
7423
7424 function Plane( normal, constant ) {
7425
7426 // normal is assumed to be normalized
7427
7428 this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
7429 this.constant = ( constant !== undefined ) ? constant : 0;
7430
7431 }
7432
7433 Object.assign( Plane.prototype, {
7434
7435 isPlane: true,
7436
7437 set: function ( normal, constant ) {
7438
7439 this.normal.copy( normal );
7440 this.constant = constant;
7441
7442 return this;
7443
7444 },
7445
7446 setComponents: function ( x, y, z, w ) {
7447
7448 this.normal.set( x, y, z );
7449 this.constant = w;
7450
7451 return this;
7452
7453 },
7454
7455 setFromNormalAndCoplanarPoint: function ( normal, point ) {
7456
7457 this.normal.copy( normal );
7458 this.constant = - point.dot( this.normal );
7459
7460 return this;
7461
7462 },
7463
7464 setFromCoplanarPoints: function ( a, b, c ) {
7465
7466 var normal = _vector1.subVectors( c, b ).cross( _vector2.subVectors( a, b ) ).normalize();
7467
7468 // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
7469
7470 this.setFromNormalAndCoplanarPoint( normal, a );
7471
7472 return this;
7473
7474 },
7475
7476 clone: function () {
7477
7478 return new this.constructor().copy( this );
7479
7480 },
7481
7482 copy: function ( plane ) {
7483
7484 this.normal.copy( plane.normal );
7485 this.constant = plane.constant;
7486
7487 return this;
7488
7489 },
7490
7491 normalize: function () {
7492
7493 // Note: will lead to a divide by zero if the plane is invalid.
7494
7495 var inverseNormalLength = 1.0 / this.normal.length();
7496 this.normal.multiplyScalar( inverseNormalLength );
7497 this.constant *= inverseNormalLength;
7498
7499 return this;
7500
7501 },
7502
7503 negate: function () {
7504
7505 this.constant *= - 1;
7506 this.normal.negate();
7507
7508 return this;
7509
7510 },
7511
7512 distanceToPoint: function ( point ) {
7513
7514 return this.normal.dot( point ) + this.constant;
7515
7516 },
7517
7518 distanceToSphere: function ( sphere ) {
7519
7520 return this.distanceToPoint( sphere.center ) - sphere.radius;
7521
7522 },
7523
7524 projectPoint: function ( point, target ) {
7525
7526 if ( target === undefined ) {
7527
7528 console.warn( 'THREE.Plane: .projectPoint() target is now required' );
7529 target = new Vector3();
7530
7531 }
7532
7533 return target.copy( this.normal ).multiplyScalar( - this.distanceToPoint( point ) ).add( point );
7534
7535 },
7536
7537 intersectLine: function ( line, target ) {
7538
7539 if ( target === undefined ) {
7540
7541 console.warn( 'THREE.Plane: .intersectLine() target is now required' );
7542 target = new Vector3();
7543
7544 }
7545
7546 var direction = line.delta( _vector1 );
7547
7548 var denominator = this.normal.dot( direction );
7549
7550 if ( denominator === 0 ) {
7551
7552 // line is coplanar, return origin
7553 if ( this.distanceToPoint( line.start ) === 0 ) {
7554
7555 return target.copy( line.start );
7556
7557 }
7558
7559 // Unsure if this is the correct method to handle this case.
7560 return undefined;
7561
7562 }
7563
7564 var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
7565
7566 if ( t < 0 || t > 1 ) {
7567
7568 return undefined;
7569
7570 }
7571
7572 return target.copy( direction ).multiplyScalar( t ).add( line.start );
7573
7574 },
7575
7576 intersectsLine: function ( line ) {
7577
7578 // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
7579
7580 var startSign = this.distanceToPoint( line.start );
7581 var endSign = this.distanceToPoint( line.end );
7582
7583 return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
7584
7585 },
7586
7587 intersectsBox: function ( box ) {
7588
7589 return box.intersectsPlane( this );
7590
7591 },
7592
7593 intersectsSphere: function ( sphere ) {
7594
7595 return sphere.intersectsPlane( this );
7596
7597 },
7598
7599 coplanarPoint: function ( target ) {
7600
7601 if ( target === undefined ) {
7602
7603 console.warn( 'THREE.Plane: .coplanarPoint() target is now required' );
7604 target = new Vector3();
7605
7606 }
7607
7608 return target.copy( this.normal ).multiplyScalar( - this.constant );
7609
7610 },
7611
7612 applyMatrix4: function ( matrix, optionalNormalMatrix ) {
7613
7614 var normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix( matrix );
7615
7616 var referencePoint = this.coplanarPoint( _vector1 ).applyMatrix4( matrix );
7617
7618 var normal = this.normal.applyMatrix3( normalMatrix ).normalize();
7619
7620 this.constant = - referencePoint.dot( normal );
7621
7622 return this;
7623
7624 },
7625
7626 translate: function ( offset ) {
7627
7628 this.constant -= offset.dot( this.normal );
7629
7630 return this;
7631
7632 },
7633
7634 equals: function ( plane ) {
7635
7636 return plane.normal.equals( this.normal ) && ( plane.constant === this.constant );
7637
7638 }
7639
7640 } );
7641
7642 var _v0$1 = new Vector3();
7643 var _v1$3 = new Vector3();
7644 var _v2$1 = new Vector3();
7645 var _v3 = new Vector3();
7646
7647 var _vab = new Vector3();
7648 var _vac = new Vector3();
7649 var _vbc = new Vector3();
7650 var _vap = new Vector3();
7651 var _vbp = new Vector3();
7652 var _vcp = new Vector3();
7653
7654 function Triangle( a, b, c ) {
7655
7656 this.a = ( a !== undefined ) ? a : new Vector3();
7657 this.b = ( b !== undefined ) ? b : new Vector3();
7658 this.c = ( c !== undefined ) ? c : new Vector3();
7659
7660 }
7661
7662 Object.assign( Triangle, {
7663
7664 getNormal: function ( a, b, c, target ) {
7665
7666 if ( target === undefined ) {
7667
7668 console.warn( 'THREE.Triangle: .getNormal() target is now required' );
7669 target = new Vector3();
7670
7671 }
7672
7673 target.subVectors( c, b );
7674 _v0$1.subVectors( a, b );
7675 target.cross( _v0$1 );
7676
7677 var targetLengthSq = target.lengthSq();
7678 if ( targetLengthSq > 0 ) {
7679
7680 return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) );
7681
7682 }
7683
7684 return target.set( 0, 0, 0 );
7685
7686 },
7687
7688 // static/instance method to calculate barycentric coordinates
7689 // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
7690 getBarycoord: function ( point, a, b, c, target ) {
7691
7692 _v0$1.subVectors( c, a );
7693 _v1$3.subVectors( b, a );
7694 _v2$1.subVectors( point, a );
7695
7696 var dot00 = _v0$1.dot( _v0$1 );
7697 var dot01 = _v0$1.dot( _v1$3 );
7698 var dot02 = _v0$1.dot( _v2$1 );
7699 var dot11 = _v1$3.dot( _v1$3 );
7700 var dot12 = _v1$3.dot( _v2$1 );
7701
7702 var denom = ( dot00 * dot11 - dot01 * dot01 );
7703
7704 if ( target === undefined ) {
7705
7706 console.warn( 'THREE.Triangle: .getBarycoord() target is now required' );
7707 target = new Vector3();
7708
7709 }
7710
7711 // collinear or singular triangle
7712 if ( denom === 0 ) {
7713
7714 // arbitrary location outside of triangle?
7715 // not sure if this is the best idea, maybe should be returning undefined
7716 return target.set( - 2, - 1, - 1 );
7717
7718 }
7719
7720 var invDenom = 1 / denom;
7721 var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
7722 var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
7723
7724 // barycentric coordinates must always sum to 1
7725 return target.set( 1 - u - v, v, u );
7726
7727 },
7728
7729 containsPoint: function ( point, a, b, c ) {
7730
7731 Triangle.getBarycoord( point, a, b, c, _v3 );
7732
7733 return ( _v3.x >= 0 ) && ( _v3.y >= 0 ) && ( ( _v3.x + _v3.y ) <= 1 );
7734
7735 },
7736
7737 getUV: function ( point, p1, p2, p3, uv1, uv2, uv3, target ) {
7738
7739 this.getBarycoord( point, p1, p2, p3, _v3 );
7740
7741 target.set( 0, 0 );
7742 target.addScaledVector( uv1, _v3.x );
7743 target.addScaledVector( uv2, _v3.y );
7744 target.addScaledVector( uv3, _v3.z );
7745
7746 return target;
7747
7748 },
7749
7750 isFrontFacing: function ( a, b, c, direction ) {
7751
7752 _v0$1.subVectors( c, b );
7753 _v1$3.subVectors( a, b );
7754
7755 // strictly front facing
7756 return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false;
7757
7758 }
7759
7760 } );
7761
7762 Object.assign( Triangle.prototype, {
7763
7764 set: function ( a, b, c ) {
7765
7766 this.a.copy( a );
7767 this.b.copy( b );
7768 this.c.copy( c );
7769
7770 return this;
7771
7772 },
7773
7774 setFromPointsAndIndices: function ( points, i0, i1, i2 ) {
7775
7776 this.a.copy( points[ i0 ] );
7777 this.b.copy( points[ i1 ] );
7778 this.c.copy( points[ i2 ] );
7779
7780 return this;
7781
7782 },
7783
7784 clone: function () {
7785
7786 return new this.constructor().copy( this );
7787
7788 },
7789
7790 copy: function ( triangle ) {
7791
7792 this.a.copy( triangle.a );
7793 this.b.copy( triangle.b );
7794 this.c.copy( triangle.c );
7795
7796 return this;
7797
7798 },
7799
7800 getArea: function () {
7801
7802 _v0$1.subVectors( this.c, this.b );
7803 _v1$3.subVectors( this.a, this.b );
7804
7805 return _v0$1.cross( _v1$3 ).length() * 0.5;
7806
7807 },
7808
7809 getMidpoint: function ( target ) {
7810
7811 if ( target === undefined ) {
7812
7813 console.warn( 'THREE.Triangle: .getMidpoint() target is now required' );
7814 target = new Vector3();
7815
7816 }
7817
7818 return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 );
7819
7820 },
7821
7822 getNormal: function ( target ) {
7823
7824 return Triangle.getNormal( this.a, this.b, this.c, target );
7825
7826 },
7827
7828 getPlane: function ( target ) {
7829
7830 if ( target === undefined ) {
7831
7832 console.warn( 'THREE.Triangle: .getPlane() target is now required' );
7833 target = new Plane();
7834
7835 }
7836
7837 return target.setFromCoplanarPoints( this.a, this.b, this.c );
7838
7839 },
7840
7841 getBarycoord: function ( point, target ) {
7842
7843 return Triangle.getBarycoord( point, this.a, this.b, this.c, target );
7844
7845 },
7846
7847 getUV: function ( point, uv1, uv2, uv3, target ) {
7848
7849 return Triangle.getUV( point, this.a, this.b, this.c, uv1, uv2, uv3, target );
7850
7851 },
7852
7853 containsPoint: function ( point ) {
7854
7855 return Triangle.containsPoint( point, this.a, this.b, this.c );
7856
7857 },
7858
7859 isFrontFacing: function ( direction ) {
7860
7861 return Triangle.isFrontFacing( this.a, this.b, this.c, direction );
7862
7863 },
7864
7865 intersectsBox: function ( box ) {
7866
7867 return box.intersectsTriangle( this );
7868
7869 },
7870
7871 closestPointToPoint: function ( p, target ) {
7872
7873 if ( target === undefined ) {
7874
7875 console.warn( 'THREE.Triangle: .closestPointToPoint() target is now required' );
7876 target = new Vector3();
7877
7878 }
7879
7880 var a = this.a, b = this.b, c = this.c;
7881 var v, w;
7882
7883 // algorithm thanks to Real-Time Collision Detection by Christer Ericson,
7884 // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,
7885 // under the accompanying license; see chapter 5.1.5 for detailed explanation.
7886 // basically, we're distinguishing which of the voronoi regions of the triangle
7887 // the point lies in with the minimum amount of redundant computation.
7888
7889 _vab.subVectors( b, a );
7890 _vac.subVectors( c, a );
7891 _vap.subVectors( p, a );
7892 var d1 = _vab.dot( _vap );
7893 var d2 = _vac.dot( _vap );
7894 if ( d1 <= 0 && d2 <= 0 ) {
7895
7896 // vertex region of A; barycentric coords (1, 0, 0)
7897 return target.copy( a );
7898
7899 }
7900
7901 _vbp.subVectors( p, b );
7902 var d3 = _vab.dot( _vbp );
7903 var d4 = _vac.dot( _vbp );
7904 if ( d3 >= 0 && d4 <= d3 ) {
7905
7906 // vertex region of B; barycentric coords (0, 1, 0)
7907 return target.copy( b );
7908
7909 }
7910
7911 var vc = d1 * d4 - d3 * d2;
7912 if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) {
7913
7914 v = d1 / ( d1 - d3 );
7915 // edge region of AB; barycentric coords (1-v, v, 0)
7916 return target.copy( a ).addScaledVector( _vab, v );
7917
7918 }
7919
7920 _vcp.subVectors( p, c );
7921 var d5 = _vab.dot( _vcp );
7922 var d6 = _vac.dot( _vcp );
7923 if ( d6 >= 0 && d5 <= d6 ) {
7924
7925 // vertex region of C; barycentric coords (0, 0, 1)
7926 return target.copy( c );
7927
7928 }
7929
7930 var vb = d5 * d2 - d1 * d6;
7931 if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) {
7932
7933 w = d2 / ( d2 - d6 );
7934 // edge region of AC; barycentric coords (1-w, 0, w)
7935 return target.copy( a ).addScaledVector( _vac, w );
7936
7937 }
7938
7939 var va = d3 * d6 - d5 * d4;
7940 if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) {
7941
7942 _vbc.subVectors( c, b );
7943 w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) );
7944 // edge region of BC; barycentric coords (0, 1-w, w)
7945 return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC
7946
7947 }
7948
7949 // face region
7950 var denom = 1 / ( va + vb + vc );
7951 // u = va * denom
7952 v = vb * denom;
7953 w = vc * denom;
7954
7955 return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w );
7956
7957 },
7958
7959 equals: function ( triangle ) {
7960
7961 return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
7962
7963 }
7964
7965 } );
7966
7967 var _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF,
7968 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2,
7969 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50,
7970 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B,
7971 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B,
7972 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F,
7973 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3,
7974 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222,
7975 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700,
7976 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4,
7977 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00,
7978 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3,
7979 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA,
7980 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32,
7981 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3,
7982 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC,
7983 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD,
7984 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6,
7985 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9,
7986 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F,
7987 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE,
7988 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA,
7989 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0,
7990 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 };
7991
7992 var _hslA = { h: 0, s: 0, l: 0 };
7993 var _hslB = { h: 0, s: 0, l: 0 };
7994
7995 function Color( r, g, b ) {
7996
7997 if ( g === undefined && b === undefined ) {
7998
7999 // r is THREE.Color, hex or string
8000 return this.set( r );
8001
8002 }
8003
8004 return this.setRGB( r, g, b );
8005
8006 }
8007
8008 function hue2rgb( p, q, t ) {
8009
8010 if ( t < 0 ) { t += 1; }
8011 if ( t > 1 ) { t -= 1; }
8012 if ( t < 1 / 6 ) { return p + ( q - p ) * 6 * t; }
8013 if ( t < 1 / 2 ) { return q; }
8014 if ( t < 2 / 3 ) { return p + ( q - p ) * 6 * ( 2 / 3 - t ); }
8015 return p;
8016
8017 }
8018
8019 function SRGBToLinear( c ) {
8020
8021 return ( c < 0.04045 ) ? c * 0.0773993808 : Math.pow( c * 0.9478672986 + 0.0521327014, 2.4 );
8022
8023 }
8024
8025 function LinearToSRGB( c ) {
8026
8027 return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
8028
8029 }
8030
8031 Object.assign( Color.prototype, {
8032
8033 isColor: true,
8034
8035 r: 1, g: 1, b: 1,
8036
8037 set: function ( value ) {
8038
8039 if ( value && value.isColor ) {
8040
8041 this.copy( value );
8042
8043 } else if ( typeof value === 'number' ) {
8044
8045 this.setHex( value );
8046
8047 } else if ( typeof value === 'string' ) {
8048
8049 this.setStyle( value );
8050
8051 }
8052
8053 return this;
8054
8055 },
8056
8057 setScalar: function ( scalar ) {
8058
8059 this.r = scalar;
8060 this.g = scalar;
8061 this.b = scalar;
8062
8063 return this;
8064
8065 },
8066
8067 setHex: function ( hex ) {
8068
8069 hex = Math.floor( hex );
8070
8071 this.r = ( hex >> 16 & 255 ) / 255;
8072 this.g = ( hex >> 8 & 255 ) / 255;
8073 this.b = ( hex & 255 ) / 255;
8074
8075 return this;
8076
8077 },
8078
8079 setRGB: function ( r, g, b ) {
8080
8081 this.r = r;
8082 this.g = g;
8083 this.b = b;
8084
8085 return this;
8086
8087 },
8088
8089 setHSL: function ( h, s, l ) {
8090
8091 // h,s,l ranges are in 0.0 - 1.0
8092 h = MathUtils.euclideanModulo( h, 1 );
8093 s = MathUtils.clamp( s, 0, 1 );
8094 l = MathUtils.clamp( l, 0, 1 );
8095
8096 if ( s === 0 ) {
8097
8098 this.r = this.g = this.b = l;
8099
8100 } else {
8101
8102 var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s );
8103 var q = ( 2 * l ) - p;
8104
8105 this.r = hue2rgb( q, p, h + 1 / 3 );
8106 this.g = hue2rgb( q, p, h );
8107 this.b = hue2rgb( q, p, h - 1 / 3 );
8108
8109 }
8110
8111 return this;
8112
8113 },
8114
8115 setStyle: function ( style ) {
8116
8117 function handleAlpha( string ) {
8118
8119 if ( string === undefined ) { return; }
8120
8121 if ( parseFloat( string ) < 1 ) {
8122
8123 console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' );
8124
8125 }
8126
8127 }
8128
8129
8130 var m;
8131
8132 if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) {
8133
8134 // rgb / hsl
8135
8136 var color;
8137 var name = m[ 1 ];
8138 var components = m[ 2 ];
8139
8140 switch ( name ) {
8141
8142 case 'rgb':
8143 case 'rgba':
8144
8145 if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
8146
8147 // rgb(255,0,0) rgba(255,0,0,0.5)
8148 this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255;
8149 this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255;
8150 this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255;
8151
8152 handleAlpha( color[ 5 ] );
8153
8154 return this;
8155
8156 }
8157
8158 if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
8159
8160 // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
8161 this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100;
8162 this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100;
8163 this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100;
8164
8165 handleAlpha( color[ 5 ] );
8166
8167 return this;
8168
8169 }
8170
8171 break;
8172
8173 case 'hsl':
8174 case 'hsla':
8175
8176 if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) {
8177
8178 // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
8179 var h = parseFloat( color[ 1 ] ) / 360;
8180 var s = parseInt( color[ 2 ], 10 ) / 100;
8181 var l = parseInt( color[ 3 ], 10 ) / 100;
8182
8183 handleAlpha( color[ 5 ] );
8184
8185 return this.setHSL( h, s, l );
8186
8187 }
8188
8189 break;
8190
8191 }
8192
8193 } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) {
8194
8195 // hex color
8196
8197 var hex = m[ 1 ];
8198 var size = hex.length;
8199
8200 if ( size === 3 ) {
8201
8202 // #ff0
8203 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255;
8204 this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255;
8205 this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255;
8206
8207 return this;
8208
8209 } else if ( size === 6 ) {
8210
8211 // #ff0000
8212 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255;
8213 this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255;
8214 this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255;
8215
8216 return this;
8217
8218 }
8219
8220 }
8221
8222 if ( style && style.length > 0 ) {
8223
8224 return this.setColorName( style );
8225
8226 }
8227
8228 return this;
8229
8230 },
8231
8232 setColorName: function ( style ) {
8233
8234 // color keywords
8235 var hex = _colorKeywords[ style ];
8236
8237 if ( hex !== undefined ) {
8238
8239 // red
8240 this.setHex( hex );
8241
8242 } else {
8243
8244 // unknown color
8245 console.warn( 'THREE.Color: Unknown color ' + style );
8246
8247 }
8248
8249 return this;
8250
8251 },
8252
8253 clone: function () {
8254
8255 return new this.constructor( this.r, this.g, this.b );
8256
8257 },
8258
8259 copy: function ( color ) {
8260
8261 this.r = color.r;
8262 this.g = color.g;
8263 this.b = color.b;
8264
8265 return this;
8266
8267 },
8268
8269 copyGammaToLinear: function ( color, gammaFactor ) {
8270
8271 if ( gammaFactor === undefined ) { gammaFactor = 2.0; }
8272
8273 this.r = Math.pow( color.r, gammaFactor );
8274 this.g = Math.pow( color.g, gammaFactor );
8275 this.b = Math.pow( color.b, gammaFactor );
8276
8277 return this;
8278
8279 },
8280
8281 copyLinearToGamma: function ( color, gammaFactor ) {
8282
8283 if ( gammaFactor === undefined ) { gammaFactor = 2.0; }
8284
8285 var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0;
8286
8287 this.r = Math.pow( color.r, safeInverse );
8288 this.g = Math.pow( color.g, safeInverse );
8289 this.b = Math.pow( color.b, safeInverse );
8290
8291 return this;
8292
8293 },
8294
8295 convertGammaToLinear: function ( gammaFactor ) {
8296
8297 this.copyGammaToLinear( this, gammaFactor );
8298
8299 return this;
8300
8301 },
8302
8303 convertLinearToGamma: function ( gammaFactor ) {
8304
8305 this.copyLinearToGamma( this, gammaFactor );
8306
8307 return this;
8308
8309 },
8310
8311 copySRGBToLinear: function ( color ) {
8312
8313 this.r = SRGBToLinear( color.r );
8314 this.g = SRGBToLinear( color.g );
8315 this.b = SRGBToLinear( color.b );
8316
8317 return this;
8318
8319 },
8320
8321 copyLinearToSRGB: function ( color ) {
8322
8323 this.r = LinearToSRGB( color.r );
8324 this.g = LinearToSRGB( color.g );
8325 this.b = LinearToSRGB( color.b );
8326
8327 return this;
8328
8329 },
8330
8331 convertSRGBToLinear: function () {
8332
8333 this.copySRGBToLinear( this );
8334
8335 return this;
8336
8337 },
8338
8339 convertLinearToSRGB: function () {
8340
8341 this.copyLinearToSRGB( this );
8342
8343 return this;
8344
8345 },
8346
8347 getHex: function () {
8348
8349 return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
8350
8351 },
8352
8353 getHexString: function () {
8354
8355 return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 );
8356
8357 },
8358
8359 getHSL: function ( target ) {
8360
8361 // h,s,l ranges are in 0.0 - 1.0
8362
8363 if ( target === undefined ) {
8364
8365 console.warn( 'THREE.Color: .getHSL() target is now required' );
8366 target = { h: 0, s: 0, l: 0 };
8367
8368 }
8369
8370 var r = this.r, g = this.g, b = this.b;
8371
8372 var max = Math.max( r, g, b );
8373 var min = Math.min( r, g, b );
8374
8375 var hue, saturation;
8376 var lightness = ( min + max ) / 2.0;
8377
8378 if ( min === max ) {
8379
8380 hue = 0;
8381 saturation = 0;
8382
8383 } else {
8384
8385 var delta = max - min;
8386
8387 saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min );
8388
8389 switch ( max ) {
8390
8391 case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break;
8392 case g: hue = ( b - r ) / delta + 2; break;
8393 case b: hue = ( r - g ) / delta + 4; break;
8394
8395 }
8396
8397 hue /= 6;
8398
8399 }
8400
8401 target.h = hue;
8402 target.s = saturation;
8403 target.l = lightness;
8404
8405 return target;
8406
8407 },
8408
8409 getStyle: function () {
8410
8411 return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
8412
8413 },
8414
8415 offsetHSL: function ( h, s, l ) {
8416
8417 this.getHSL( _hslA );
8418
8419 _hslA.h += h; _hslA.s += s; _hslA.l += l;
8420
8421 this.setHSL( _hslA.h, _hslA.s, _hslA.l );
8422
8423 return this;
8424
8425 },
8426
8427 add: function ( color ) {
8428
8429 this.r += color.r;
8430 this.g += color.g;
8431 this.b += color.b;
8432
8433 return this;
8434
8435 },
8436
8437 addColors: function ( color1, color2 ) {
8438
8439 this.r = color1.r + color2.r;
8440 this.g = color1.g + color2.g;
8441 this.b = color1.b + color2.b;
8442
8443 return this;
8444
8445 },
8446
8447 addScalar: function ( s ) {
8448
8449 this.r += s;
8450 this.g += s;
8451 this.b += s;
8452
8453 return this;
8454
8455 },
8456
8457 sub: function ( color ) {
8458
8459 this.r = Math.max( 0, this.r - color.r );
8460 this.g = Math.max( 0, this.g - color.g );
8461 this.b = Math.max( 0, this.b - color.b );
8462
8463 return this;
8464
8465 },
8466
8467 multiply: function ( color ) {
8468
8469 this.r *= color.r;
8470 this.g *= color.g;
8471 this.b *= color.b;
8472
8473 return this;
8474
8475 },
8476
8477 multiplyScalar: function ( s ) {
8478
8479 this.r *= s;
8480 this.g *= s;
8481 this.b *= s;
8482
8483 return this;
8484
8485 },
8486
8487 lerp: function ( color, alpha ) {
8488
8489 this.r += ( color.r - this.r ) * alpha;
8490 this.g += ( color.g - this.g ) * alpha;
8491 this.b += ( color.b - this.b ) * alpha;
8492
8493 return this;
8494
8495 },
8496
8497 lerpHSL: function ( color, alpha ) {
8498
8499 this.getHSL( _hslA );
8500 color.getHSL( _hslB );
8501
8502 var h = MathUtils.lerp( _hslA.h, _hslB.h, alpha );
8503 var s = MathUtils.lerp( _hslA.s, _hslB.s, alpha );
8504 var l = MathUtils.lerp( _hslA.l, _hslB.l, alpha );
8505
8506 this.setHSL( h, s, l );
8507
8508 return this;
8509
8510 },
8511
8512 equals: function ( c ) {
8513
8514 return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b );
8515
8516 },
8517
8518 fromArray: function ( array, offset ) {
8519
8520 if ( offset === undefined ) { offset = 0; }
8521
8522 this.r = array[ offset ];
8523 this.g = array[ offset + 1 ];
8524 this.b = array[ offset + 2 ];
8525
8526 return this;
8527
8528 },
8529
8530 toArray: function ( array, offset ) {
8531
8532 if ( array === undefined ) { array = []; }
8533 if ( offset === undefined ) { offset = 0; }
8534
8535 array[ offset ] = this.r;
8536 array[ offset + 1 ] = this.g;
8537 array[ offset + 2 ] = this.b;
8538
8539 return array;
8540
8541 },
8542
8543 fromBufferAttribute: function ( attribute, index ) {
8544
8545 this.r = attribute.getX( index );
8546 this.g = attribute.getY( index );
8547 this.b = attribute.getZ( index );
8548
8549 if ( attribute.normalized === true ) {
8550
8551 // assuming Uint8Array
8552
8553 this.r /= 255;
8554 this.g /= 255;
8555 this.b /= 255;
8556
8557 }
8558
8559 return this;
8560
8561 },
8562
8563 toJSON: function () {
8564
8565 return this.getHex();
8566
8567 }
8568
8569 } );
8570
8571 Color.NAMES = _colorKeywords;
8572
8573 function Face3( a, b, c, normal, color, materialIndex ) {
8574
8575 this.a = a;
8576 this.b = b;
8577 this.c = c;
8578
8579 this.normal = ( normal && normal.isVector3 ) ? normal : new Vector3();
8580 this.vertexNormals = Array.isArray( normal ) ? normal : [];
8581
8582 this.color = ( color && color.isColor ) ? color : new Color();
8583 this.vertexColors = Array.isArray( color ) ? color : [];
8584
8585 this.materialIndex = materialIndex !== undefined ? materialIndex : 0;
8586
8587 }
8588
8589 Object.assign( Face3.prototype, {
8590
8591 clone: function () {
8592
8593 return new this.constructor().copy( this );
8594
8595 },
8596
8597 copy: function ( source ) {
8598
8599 this.a = source.a;
8600 this.b = source.b;
8601 this.c = source.c;
8602
8603 this.normal.copy( source.normal );
8604 this.color.copy( source.color );
8605
8606 this.materialIndex = source.materialIndex;
8607
8608 for ( var i = 0, il = source.vertexNormals.length; i < il; i ++ ) {
8609
8610 this.vertexNormals[ i ] = source.vertexNormals[ i ].clone();
8611
8612 }
8613
8614 for ( var i$1 = 0, il$1 = source.vertexColors.length; i$1 < il$1; i$1 ++ ) {
8615
8616 this.vertexColors[ i$1 ] = source.vertexColors[ i$1 ].clone();
8617
8618 }
8619
8620 return this;
8621
8622 }
8623
8624 } );
8625
8626 var materialId = 0;
8627
8628 function Material() {
8629
8630 Object.defineProperty( this, 'id', { value: materialId ++ } );
8631
8632 this.uuid = MathUtils.generateUUID();
8633
8634 this.name = '';
8635 this.type = 'Material';
8636
8637 this.fog = true;
8638
8639 this.blending = NormalBlending;
8640 this.side = FrontSide;
8641 this.flatShading = false;
8642 this.vertexColors = false;
8643
8644 this.opacity = 1;
8645 this.transparent = false;
8646
8647 this.blendSrc = SrcAlphaFactor;
8648 this.blendDst = OneMinusSrcAlphaFactor;
8649 this.blendEquation = AddEquation;
8650 this.blendSrcAlpha = null;
8651 this.blendDstAlpha = null;
8652 this.blendEquationAlpha = null;
8653
8654 this.depthFunc = LessEqualDepth;
8655 this.depthTest = true;
8656 this.depthWrite = true;
8657
8658 this.stencilWriteMask = 0xff;
8659 this.stencilFunc = AlwaysStencilFunc;
8660 this.stencilRef = 0;
8661 this.stencilFuncMask = 0xff;
8662 this.stencilFail = KeepStencilOp;
8663 this.stencilZFail = KeepStencilOp;
8664 this.stencilZPass = KeepStencilOp;
8665 this.stencilWrite = false;
8666
8667 this.clippingPlanes = null;
8668 this.clipIntersection = false;
8669 this.clipShadows = false;
8670
8671 this.shadowSide = null;
8672
8673 this.colorWrite = true;
8674
8675 this.precision = null; // override the renderer's default precision for this material
8676
8677 this.polygonOffset = false;
8678 this.polygonOffsetFactor = 0;
8679 this.polygonOffsetUnits = 0;
8680
8681 this.dithering = false;
8682
8683 this.alphaTest = 0;
8684 this.premultipliedAlpha = false;
8685
8686 this.visible = true;
8687
8688 this.toneMapped = true;
8689
8690 this.userData = {};
8691
8692 this.version = 0;
8693
8694 }
8695
8696 Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
8697
8698 constructor: Material,
8699
8700 isMaterial: true,
8701
8702 onBeforeCompile: function ( /* shaderobject, renderer */ ) {},
8703
8704 customProgramCacheKey: function () {
8705
8706 return this.onBeforeCompile.toString();
8707
8708 },
8709
8710 setValues: function ( values ) {
8711
8712 if ( values === undefined ) { return; }
8713
8714 for ( var key in values ) {
8715
8716 var newValue = values[ key ];
8717
8718 if ( newValue === undefined ) {
8719
8720 console.warn( "THREE.Material: '" + key + "' parameter is undefined." );
8721 continue;
8722
8723 }
8724
8725 // for backward compatability if shading is set in the constructor
8726 if ( key === 'shading' ) {
8727
8728 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
8729 this.flatShading = ( newValue === FlatShading ) ? true : false;
8730 continue;
8731
8732 }
8733
8734 var currentValue = this[ key ];
8735
8736 if ( currentValue === undefined ) {
8737
8738 console.warn( "THREE." + this.type + ": '" + key + "' is not a property of this material." );
8739 continue;
8740
8741 }
8742
8743 if ( currentValue && currentValue.isColor ) {
8744
8745 currentValue.set( newValue );
8746
8747 } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) {
8748
8749 currentValue.copy( newValue );
8750
8751 } else {
8752
8753 this[ key ] = newValue;
8754
8755 }
8756
8757 }
8758
8759 },
8760
8761 toJSON: function ( meta ) {
8762
8763 var isRoot = ( meta === undefined || typeof meta === 'string' );
8764
8765 if ( isRoot ) {
8766
8767 meta = {
8768 textures: {},
8769 images: {}
8770 };
8771
8772 }
8773
8774 var data = {
8775 metadata: {
8776 version: 4.5,
8777 type: 'Material',
8778 generator: 'Material.toJSON'
8779 }
8780 };
8781
8782 // standard Material serialization
8783 data.uuid = this.uuid;
8784 data.type = this.type;
8785
8786 if ( this.name !== '' ) { data.name = this.name; }
8787
8788 if ( this.color && this.color.isColor ) { data.color = this.color.getHex(); }
8789
8790 if ( this.roughness !== undefined ) { data.roughness = this.roughness; }
8791 if ( this.metalness !== undefined ) { data.metalness = this.metalness; }
8792
8793 if ( this.sheen && this.sheen.isColor ) { data.sheen = this.sheen.getHex(); }
8794 if ( this.emissive && this.emissive.isColor ) { data.emissive = this.emissive.getHex(); }
8795 if ( this.emissiveIntensity && this.emissiveIntensity !== 1 ) { data.emissiveIntensity = this.emissiveIntensity; }
8796
8797 if ( this.specular && this.specular.isColor ) { data.specular = this.specular.getHex(); }
8798 if ( this.shininess !== undefined ) { data.shininess = this.shininess; }
8799 if ( this.clearcoat !== undefined ) { data.clearcoat = this.clearcoat; }
8800 if ( this.clearcoatRoughness !== undefined ) { data.clearcoatRoughness = this.clearcoatRoughness; }
8801
8802 if ( this.clearcoatMap && this.clearcoatMap.isTexture ) {
8803
8804 data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid;
8805
8806 }
8807
8808 if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) {
8809
8810 data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid;
8811
8812 }
8813
8814 if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) {
8815
8816 data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid;
8817 data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
8818
8819 }
8820
8821 if ( this.map && this.map.isTexture ) { data.map = this.map.toJSON( meta ).uuid; }
8822 if ( this.matcap && this.matcap.isTexture ) { data.matcap = this.matcap.toJSON( meta ).uuid; }
8823 if ( this.alphaMap && this.alphaMap.isTexture ) { data.alphaMap = this.alphaMap.toJSON( meta ).uuid; }
8824 if ( this.lightMap && this.lightMap.isTexture ) { data.lightMap = this.lightMap.toJSON( meta ).uuid; }
8825
8826 if ( this.aoMap && this.aoMap.isTexture ) {
8827
8828 data.aoMap = this.aoMap.toJSON( meta ).uuid;
8829 data.aoMapIntensity = this.aoMapIntensity;
8830
8831 }
8832
8833 if ( this.bumpMap && this.bumpMap.isTexture ) {
8834
8835 data.bumpMap = this.bumpMap.toJSON( meta ).uuid;
8836 data.bumpScale = this.bumpScale;
8837
8838 }
8839
8840 if ( this.normalMap && this.normalMap.isTexture ) {
8841
8842 data.normalMap = this.normalMap.toJSON( meta ).uuid;
8843 data.normalMapType = this.normalMapType;
8844 data.normalScale = this.normalScale.toArray();
8845
8846 }
8847
8848 if ( this.displacementMap && this.displacementMap.isTexture ) {
8849
8850 data.displacementMap = this.displacementMap.toJSON( meta ).uuid;
8851 data.displacementScale = this.displacementScale;
8852 data.displacementBias = this.displacementBias;
8853
8854 }
8855
8856 if ( this.roughnessMap && this.roughnessMap.isTexture ) { data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; }
8857 if ( this.metalnessMap && this.metalnessMap.isTexture ) { data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; }
8858
8859 if ( this.emissiveMap && this.emissiveMap.isTexture ) { data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; }
8860 if ( this.specularMap && this.specularMap.isTexture ) { data.specularMap = this.specularMap.toJSON( meta ).uuid; }
8861
8862 if ( this.envMap && this.envMap.isTexture ) {
8863
8864 data.envMap = this.envMap.toJSON( meta ).uuid;
8865 data.reflectivity = this.reflectivity; // Scale behind envMap
8866 data.refractionRatio = this.refractionRatio;
8867
8868 if ( this.combine !== undefined ) { data.combine = this.combine; }
8869 if ( this.envMapIntensity !== undefined ) { data.envMapIntensity = this.envMapIntensity; }
8870
8871 }
8872
8873 if ( this.gradientMap && this.gradientMap.isTexture ) {
8874
8875 data.gradientMap = this.gradientMap.toJSON( meta ).uuid;
8876
8877 }
8878
8879 if ( this.size !== undefined ) { data.size = this.size; }
8880 if ( this.sizeAttenuation !== undefined ) { data.sizeAttenuation = this.sizeAttenuation; }
8881
8882 if ( this.blending !== NormalBlending ) { data.blending = this.blending; }
8883 if ( this.flatShading === true ) { data.flatShading = this.flatShading; }
8884 if ( this.side !== FrontSide ) { data.side = this.side; }
8885 if ( this.vertexColors ) { data.vertexColors = true; }
8886
8887 if ( this.opacity < 1 ) { data.opacity = this.opacity; }
8888 if ( this.transparent === true ) { data.transparent = this.transparent; }
8889
8890 data.depthFunc = this.depthFunc;
8891 data.depthTest = this.depthTest;
8892 data.depthWrite = this.depthWrite;
8893
8894 data.stencilWrite = this.stencilWrite;
8895 data.stencilWriteMask = this.stencilWriteMask;
8896 data.stencilFunc = this.stencilFunc;
8897 data.stencilRef = this.stencilRef;
8898 data.stencilFuncMask = this.stencilFuncMask;
8899 data.stencilFail = this.stencilFail;
8900 data.stencilZFail = this.stencilZFail;
8901 data.stencilZPass = this.stencilZPass;
8902
8903 // rotation (SpriteMaterial)
8904 if ( this.rotation && this.rotation !== 0 ) { data.rotation = this.rotation; }
8905
8906 if ( this.polygonOffset === true ) { data.polygonOffset = true; }
8907 if ( this.polygonOffsetFactor !== 0 ) { data.polygonOffsetFactor = this.polygonOffsetFactor; }
8908 if ( this.polygonOffsetUnits !== 0 ) { data.polygonOffsetUnits = this.polygonOffsetUnits; }
8909
8910 if ( this.linewidth && this.linewidth !== 1 ) { data.linewidth = this.linewidth; }
8911 if ( this.dashSize !== undefined ) { data.dashSize = this.dashSize; }
8912 if ( this.gapSize !== undefined ) { data.gapSize = this.gapSize; }
8913 if ( this.scale !== undefined ) { data.scale = this.scale; }
8914
8915 if ( this.dithering === true ) { data.dithering = true; }
8916
8917 if ( this.alphaTest > 0 ) { data.alphaTest = this.alphaTest; }
8918 if ( this.premultipliedAlpha === true ) { data.premultipliedAlpha = this.premultipliedAlpha; }
8919
8920 if ( this.wireframe === true ) { data.wireframe = this.wireframe; }
8921 if ( this.wireframeLinewidth > 1 ) { data.wireframeLinewidth = this.wireframeLinewidth; }
8922 if ( this.wireframeLinecap !== 'round' ) { data.wireframeLinecap = this.wireframeLinecap; }
8923 if ( this.wireframeLinejoin !== 'round' ) { data.wireframeLinejoin = this.wireframeLinejoin; }
8924
8925 if ( this.morphTargets === true ) { data.morphTargets = true; }
8926 if ( this.morphNormals === true ) { data.morphNormals = true; }
8927 if ( this.skinning === true ) { data.skinning = true; }
8928
8929 if ( this.visible === false ) { data.visible = false; }
8930
8931 if ( this.toneMapped === false ) { data.toneMapped = false; }
8932
8933 if ( JSON.stringify( this.userData ) !== '{}' ) { data.userData = this.userData; }
8934
8935 // TODO: Copied from Object3D.toJSON
8936
8937 function extractFromCache( cache ) {
8938
8939 var values = [];
8940
8941 for ( var key in cache ) {
8942
8943 var data = cache[ key ];
8944 delete data.metadata;
8945 values.push( data );
8946
8947 }
8948
8949 return values;
8950
8951 }
8952
8953 if ( isRoot ) {
8954
8955 var textures = extractFromCache( meta.textures );
8956 var images = extractFromCache( meta.images );
8957
8958 if ( textures.length > 0 ) { data.textures = textures; }
8959 if ( images.length > 0 ) { data.images = images; }
8960
8961 }
8962
8963 return data;
8964
8965 },
8966
8967 clone: function () {
8968
8969 return new this.constructor().copy( this );
8970
8971 },
8972
8973 copy: function ( source ) {
8974
8975 this.name = source.name;
8976
8977 this.fog = source.fog;
8978
8979 this.blending = source.blending;
8980 this.side = source.side;
8981 this.flatShading = source.flatShading;
8982 this.vertexColors = source.vertexColors;
8983
8984 this.opacity = source.opacity;
8985 this.transparent = source.transparent;
8986
8987 this.blendSrc = source.blendSrc;
8988 this.blendDst = source.blendDst;
8989 this.blendEquation = source.blendEquation;
8990 this.blendSrcAlpha = source.blendSrcAlpha;
8991 this.blendDstAlpha = source.blendDstAlpha;
8992 this.blendEquationAlpha = source.blendEquationAlpha;
8993
8994 this.depthFunc = source.depthFunc;
8995 this.depthTest = source.depthTest;
8996 this.depthWrite = source.depthWrite;
8997
8998 this.stencilWriteMask = source.stencilWriteMask;
8999 this.stencilFunc = source.stencilFunc;
9000 this.stencilRef = source.stencilRef;
9001 this.stencilFuncMask = source.stencilFuncMask;
9002 this.stencilFail = source.stencilFail;
9003 this.stencilZFail = source.stencilZFail;
9004 this.stencilZPass = source.stencilZPass;
9005 this.stencilWrite = source.stencilWrite;
9006
9007 var srcPlanes = source.clippingPlanes;
9008 var dstPlanes = null;
9009
9010 if ( srcPlanes !== null ) {
9011
9012 var n = srcPlanes.length;
9013 dstPlanes = new Array( n );
9014
9015 for ( var i = 0; i !== n; ++ i ) {
9016
9017 dstPlanes[ i ] = srcPlanes[ i ].clone();
9018
9019 }
9020
9021 }
9022
9023 this.clippingPlanes = dstPlanes;
9024 this.clipIntersection = source.clipIntersection;
9025 this.clipShadows = source.clipShadows;
9026
9027 this.shadowSide = source.shadowSide;
9028
9029 this.colorWrite = source.colorWrite;
9030
9031 this.precision = source.precision;
9032
9033 this.polygonOffset = source.polygonOffset;
9034 this.polygonOffsetFactor = source.polygonOffsetFactor;
9035 this.polygonOffsetUnits = source.polygonOffsetUnits;
9036
9037 this.dithering = source.dithering;
9038
9039 this.alphaTest = source.alphaTest;
9040 this.premultipliedAlpha = source.premultipliedAlpha;
9041
9042 this.visible = source.visible;
9043
9044 this.toneMapped = source.toneMapped;
9045
9046 this.userData = JSON.parse( JSON.stringify( source.userData ) );
9047
9048 return this;
9049
9050 },
9051
9052 dispose: function () {
9053
9054 this.dispatchEvent( { type: 'dispose' } );
9055
9056 }
9057
9058 } );
9059
9060 Object.defineProperty( Material.prototype, 'needsUpdate', {
9061
9062 set: function ( value ) {
9063
9064 if ( value === true ) { this.version ++; }
9065
9066 }
9067
9068 } );
9069
9070 /**
9071 * parameters = {
9072 * color: <hex>,
9073 * opacity: <float>,
9074 * map: new THREE.Texture( <Image> ),
9075 *
9076 * lightMap: new THREE.Texture( <Image> ),
9077 * lightMapIntensity: <float>
9078 *
9079 * aoMap: new THREE.Texture( <Image> ),
9080 * aoMapIntensity: <float>
9081 *
9082 * specularMap: new THREE.Texture( <Image> ),
9083 *
9084 * alphaMap: new THREE.Texture( <Image> ),
9085 *
9086 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
9087 * combine: THREE.Multiply,
9088 * reflectivity: <float>,
9089 * refractionRatio: <float>,
9090 *
9091 * depthTest: <bool>,
9092 * depthWrite: <bool>,
9093 *
9094 * wireframe: <boolean>,
9095 * wireframeLinewidth: <float>,
9096 *
9097 * skinning: <bool>,
9098 * morphTargets: <bool>
9099 * }
9100 */
9101
9102 function MeshBasicMaterial( parameters ) {
9103
9104 Material.call( this );
9105
9106 this.type = 'MeshBasicMaterial';
9107
9108 this.color = new Color( 0xffffff ); // emissive
9109
9110 this.map = null;
9111
9112 this.lightMap = null;
9113 this.lightMapIntensity = 1.0;
9114
9115 this.aoMap = null;
9116 this.aoMapIntensity = 1.0;
9117
9118 this.specularMap = null;
9119
9120 this.alphaMap = null;
9121
9122 this.envMap = null;
9123 this.combine = MultiplyOperation;
9124 this.reflectivity = 1;
9125 this.refractionRatio = 0.98;
9126
9127 this.wireframe = false;
9128 this.wireframeLinewidth = 1;
9129 this.wireframeLinecap = 'round';
9130 this.wireframeLinejoin = 'round';
9131
9132 this.skinning = false;
9133 this.morphTargets = false;
9134
9135 this.setValues( parameters );
9136
9137 }
9138
9139 MeshBasicMaterial.prototype = Object.create( Material.prototype );
9140 MeshBasicMaterial.prototype.constructor = MeshBasicMaterial;
9141
9142 MeshBasicMaterial.prototype.isMeshBasicMaterial = true;
9143
9144 MeshBasicMaterial.prototype.copy = function ( source ) {
9145
9146 Material.prototype.copy.call( this, source );
9147
9148 this.color.copy( source.color );
9149
9150 this.map = source.map;
9151
9152 this.lightMap = source.lightMap;
9153 this.lightMapIntensity = source.lightMapIntensity;
9154
9155 this.aoMap = source.aoMap;
9156 this.aoMapIntensity = source.aoMapIntensity;
9157
9158 this.specularMap = source.specularMap;
9159
9160 this.alphaMap = source.alphaMap;
9161
9162 this.envMap = source.envMap;
9163 this.combine = source.combine;
9164 this.reflectivity = source.reflectivity;
9165 this.refractionRatio = source.refractionRatio;
9166
9167 this.wireframe = source.wireframe;
9168 this.wireframeLinewidth = source.wireframeLinewidth;
9169 this.wireframeLinecap = source.wireframeLinecap;
9170 this.wireframeLinejoin = source.wireframeLinejoin;
9171
9172 this.skinning = source.skinning;
9173 this.morphTargets = source.morphTargets;
9174
9175 return this;
9176
9177 };
9178
9179 var _vector$3 = new Vector3();
9180 var _vector2$1 = new Vector2();
9181
9182 function BufferAttribute( array, itemSize, normalized ) {
9183
9184 if ( Array.isArray( array ) ) {
9185
9186 throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
9187
9188 }
9189
9190 this.name = '';
9191
9192 this.array = array;
9193 this.itemSize = itemSize;
9194 this.count = array !== undefined ? array.length / itemSize : 0;
9195 this.normalized = normalized === true;
9196
9197 this.usage = StaticDrawUsage;
9198 this.updateRange = { offset: 0, count: - 1 };
9199
9200 this.version = 0;
9201
9202 }
9203
9204 Object.defineProperty( BufferAttribute.prototype, 'needsUpdate', {
9205
9206 set: function ( value ) {
9207
9208 if ( value === true ) { this.version ++; }
9209
9210 }
9211
9212 } );
9213
9214 Object.assign( BufferAttribute.prototype, {
9215
9216 isBufferAttribute: true,
9217
9218 onUploadCallback: function () {},
9219
9220 setUsage: function ( value ) {
9221
9222 this.usage = value;
9223
9224 return this;
9225
9226 },
9227
9228 copy: function ( source ) {
9229
9230 this.name = source.name;
9231 this.array = new source.array.constructor( source.array );
9232 this.itemSize = source.itemSize;
9233 this.count = source.count;
9234 this.normalized = source.normalized;
9235
9236 this.usage = source.usage;
9237
9238 return this;
9239
9240 },
9241
9242 copyAt: function ( index1, attribute, index2 ) {
9243
9244 index1 *= this.itemSize;
9245 index2 *= attribute.itemSize;
9246
9247 for ( var i = 0, l = this.itemSize; i < l; i ++ ) {
9248
9249 this.array[ index1 + i ] = attribute.array[ index2 + i ];
9250
9251 }
9252
9253 return this;
9254
9255 },
9256
9257 copyArray: function ( array ) {
9258
9259 this.array.set( array );
9260
9261 return this;
9262
9263 },
9264
9265 copyColorsArray: function ( colors ) {
9266
9267 var array = this.array;
9268 var offset = 0;
9269
9270 for ( var i = 0, l = colors.length; i < l; i ++ ) {
9271
9272 var color = colors[ i ];
9273
9274 if ( color === undefined ) {
9275
9276 console.warn( 'THREE.BufferAttribute.copyColorsArray(): color is undefined', i );
9277 color = new Color();
9278
9279 }
9280
9281 array[ offset ++ ] = color.r;
9282 array[ offset ++ ] = color.g;
9283 array[ offset ++ ] = color.b;
9284
9285 }
9286
9287 return this;
9288
9289 },
9290
9291 copyVector2sArray: function ( vectors ) {
9292
9293 var array = this.array;
9294 var offset = 0;
9295
9296 for ( var i = 0, l = vectors.length; i < l; i ++ ) {
9297
9298 var vector = vectors[ i ];
9299
9300 if ( vector === undefined ) {
9301
9302 console.warn( 'THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i );
9303 vector = new Vector2();
9304
9305 }
9306
9307 array[ offset ++ ] = vector.x;
9308 array[ offset ++ ] = vector.y;
9309
9310 }
9311
9312 return this;
9313
9314 },
9315
9316 copyVector3sArray: function ( vectors ) {
9317
9318 var array = this.array;
9319 var offset = 0;
9320
9321 for ( var i = 0, l = vectors.length; i < l; i ++ ) {
9322
9323 var vector = vectors[ i ];
9324
9325 if ( vector === undefined ) {
9326
9327 console.warn( 'THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i );
9328 vector = new Vector3();
9329
9330 }
9331
9332 array[ offset ++ ] = vector.x;
9333 array[ offset ++ ] = vector.y;
9334 array[ offset ++ ] = vector.z;
9335
9336 }
9337
9338 return this;
9339
9340 },
9341
9342 copyVector4sArray: function ( vectors ) {
9343
9344 var array = this.array;
9345 var offset = 0;
9346
9347 for ( var i = 0, l = vectors.length; i < l; i ++ ) {
9348
9349 var vector = vectors[ i ];
9350
9351 if ( vector === undefined ) {
9352
9353 console.warn( 'THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i );
9354 vector = new Vector4();
9355
9356 }
9357
9358 array[ offset ++ ] = vector.x;
9359 array[ offset ++ ] = vector.y;
9360 array[ offset ++ ] = vector.z;
9361 array[ offset ++ ] = vector.w;
9362
9363 }
9364
9365 return this;
9366
9367 },
9368
9369 applyMatrix3: function ( m ) {
9370
9371 if ( this.itemSize === 2 ) {
9372
9373 for ( var i = 0, l = this.count; i < l; i ++ ) {
9374
9375 _vector2$1.fromBufferAttribute( this, i );
9376 _vector2$1.applyMatrix3( m );
9377
9378 this.setXY( i, _vector2$1.x, _vector2$1.y );
9379
9380 }
9381
9382 } else if ( this.itemSize === 3 ) {
9383
9384 for ( var i$1 = 0, l$1 = this.count; i$1 < l$1; i$1 ++ ) {
9385
9386 _vector$3.fromBufferAttribute( this, i$1 );
9387 _vector$3.applyMatrix3( m );
9388
9389 this.setXYZ( i$1, _vector$3.x, _vector$3.y, _vector$3.z );
9390
9391 }
9392
9393 }
9394
9395 return this;
9396
9397 },
9398
9399 applyMatrix4: function ( m ) {
9400
9401 for ( var i = 0, l = this.count; i < l; i ++ ) {
9402
9403 _vector$3.x = this.getX( i );
9404 _vector$3.y = this.getY( i );
9405 _vector$3.z = this.getZ( i );
9406
9407 _vector$3.applyMatrix4( m );
9408
9409 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
9410
9411 }
9412
9413 return this;
9414
9415 },
9416
9417 applyNormalMatrix: function ( m ) {
9418
9419 for ( var i = 0, l = this.count; i < l; i ++ ) {
9420
9421 _vector$3.x = this.getX( i );
9422 _vector$3.y = this.getY( i );
9423 _vector$3.z = this.getZ( i );
9424
9425 _vector$3.applyNormalMatrix( m );
9426
9427 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
9428
9429 }
9430
9431 return this;
9432
9433 },
9434
9435 transformDirection: function ( m ) {
9436
9437 for ( var i = 0, l = this.count; i < l; i ++ ) {
9438
9439 _vector$3.x = this.getX( i );
9440 _vector$3.y = this.getY( i );
9441 _vector$3.z = this.getZ( i );
9442
9443 _vector$3.transformDirection( m );
9444
9445 this.setXYZ( i, _vector$3.x, _vector$3.y, _vector$3.z );
9446
9447 }
9448
9449 return this;
9450
9451 },
9452
9453 set: function ( value, offset ) {
9454
9455 if ( offset === undefined ) { offset = 0; }
9456
9457 this.array.set( value, offset );
9458
9459 return this;
9460
9461 },
9462
9463 getX: function ( index ) {
9464
9465 return this.array[ index * this.itemSize ];
9466
9467 },
9468
9469 setX: function ( index, x ) {
9470
9471 this.array[ index * this.itemSize ] = x;
9472
9473 return this;
9474
9475 },
9476
9477 getY: function ( index ) {
9478
9479 return this.array[ index * this.itemSize + 1 ];
9480
9481 },
9482
9483 setY: function ( index, y ) {
9484
9485 this.array[ index * this.itemSize + 1 ] = y;
9486
9487 return this;
9488
9489 },
9490
9491 getZ: function ( index ) {
9492
9493 return this.array[ index * this.itemSize + 2 ];
9494
9495 },
9496
9497 setZ: function ( index, z ) {
9498
9499 this.array[ index * this.itemSize + 2 ] = z;
9500
9501 return this;
9502
9503 },
9504
9505 getW: function ( index ) {
9506
9507 return this.array[ index * this.itemSize + 3 ];
9508
9509 },
9510
9511 setW: function ( index, w ) {
9512
9513 this.array[ index * this.itemSize + 3 ] = w;
9514
9515 return this;
9516
9517 },
9518
9519 setXY: function ( index, x, y ) {
9520
9521 index *= this.itemSize;
9522
9523 this.array[ index + 0 ] = x;
9524 this.array[ index + 1 ] = y;
9525
9526 return this;
9527
9528 },
9529
9530 setXYZ: function ( index, x, y, z ) {
9531
9532 index *= this.itemSize;
9533
9534 this.array[ index + 0 ] = x;
9535 this.array[ index + 1 ] = y;
9536 this.array[ index + 2 ] = z;
9537
9538 return this;
9539
9540 },
9541
9542 setXYZW: function ( index, x, y, z, w ) {
9543
9544 index *= this.itemSize;
9545
9546 this.array[ index + 0 ] = x;
9547 this.array[ index + 1 ] = y;
9548 this.array[ index + 2 ] = z;
9549 this.array[ index + 3 ] = w;
9550
9551 return this;
9552
9553 },
9554
9555 onUpload: function ( callback ) {
9556
9557 this.onUploadCallback = callback;
9558
9559 return this;
9560
9561 },
9562
9563 clone: function () {
9564
9565 return new this.constructor( this.array, this.itemSize ).copy( this );
9566
9567 },
9568
9569 toJSON: function () {
9570
9571 return {
9572 itemSize: this.itemSize,
9573 type: this.array.constructor.name,
9574 array: Array.prototype.slice.call( this.array ),
9575 normalized: this.normalized
9576 };
9577
9578 }
9579
9580 } );
9581
9582 //
9583
9584 function Int8BufferAttribute( array, itemSize, normalized ) {
9585
9586 BufferAttribute.call( this, new Int8Array( array ), itemSize, normalized );
9587
9588 }
9589
9590 Int8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9591 Int8BufferAttribute.prototype.constructor = Int8BufferAttribute;
9592
9593
9594 function Uint8BufferAttribute( array, itemSize, normalized ) {
9595
9596 BufferAttribute.call( this, new Uint8Array( array ), itemSize, normalized );
9597
9598 }
9599
9600 Uint8BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9601 Uint8BufferAttribute.prototype.constructor = Uint8BufferAttribute;
9602
9603
9604 function Uint8ClampedBufferAttribute( array, itemSize, normalized ) {
9605
9606 BufferAttribute.call( this, new Uint8ClampedArray( array ), itemSize, normalized );
9607
9608 }
9609
9610 Uint8ClampedBufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9611 Uint8ClampedBufferAttribute.prototype.constructor = Uint8ClampedBufferAttribute;
9612
9613
9614 function Int16BufferAttribute( array, itemSize, normalized ) {
9615
9616 BufferAttribute.call( this, new Int16Array( array ), itemSize, normalized );
9617
9618 }
9619
9620 Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9621 Int16BufferAttribute.prototype.constructor = Int16BufferAttribute;
9622
9623
9624 function Uint16BufferAttribute( array, itemSize, normalized ) {
9625
9626 BufferAttribute.call( this, new Uint16Array( array ), itemSize, normalized );
9627
9628 }
9629
9630 Uint16BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9631 Uint16BufferAttribute.prototype.constructor = Uint16BufferAttribute;
9632
9633
9634 function Int32BufferAttribute( array, itemSize, normalized ) {
9635
9636 BufferAttribute.call( this, new Int32Array( array ), itemSize, normalized );
9637
9638 }
9639
9640 Int32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9641 Int32BufferAttribute.prototype.constructor = Int32BufferAttribute;
9642
9643
9644 function Uint32BufferAttribute( array, itemSize, normalized ) {
9645
9646 BufferAttribute.call( this, new Uint32Array( array ), itemSize, normalized );
9647
9648 }
9649
9650 Uint32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9651 Uint32BufferAttribute.prototype.constructor = Uint32BufferAttribute;
9652
9653
9654 function Float32BufferAttribute( array, itemSize, normalized ) {
9655
9656 BufferAttribute.call( this, new Float32Array( array ), itemSize, normalized );
9657
9658 }
9659
9660 Float32BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9661 Float32BufferAttribute.prototype.constructor = Float32BufferAttribute;
9662
9663
9664 function Float64BufferAttribute( array, itemSize, normalized ) {
9665
9666 BufferAttribute.call( this, new Float64Array( array ), itemSize, normalized );
9667
9668 }
9669
9670 Float64BufferAttribute.prototype = Object.create( BufferAttribute.prototype );
9671 Float64BufferAttribute.prototype.constructor = Float64BufferAttribute;
9672
9673 function DirectGeometry() {
9674
9675 this.vertices = [];
9676 this.normals = [];
9677 this.colors = [];
9678 this.uvs = [];
9679 this.uvs2 = [];
9680
9681 this.groups = [];
9682
9683 this.morphTargets = {};
9684
9685 this.skinWeights = [];
9686 this.skinIndices = [];
9687
9688 // this.lineDistances = [];
9689
9690 this.boundingBox = null;
9691 this.boundingSphere = null;
9692
9693 // update flags
9694
9695 this.verticesNeedUpdate = false;
9696 this.normalsNeedUpdate = false;
9697 this.colorsNeedUpdate = false;
9698 this.uvsNeedUpdate = false;
9699 this.groupsNeedUpdate = false;
9700
9701 }
9702
9703 Object.assign( DirectGeometry.prototype, {
9704
9705 computeGroups: function ( geometry ) {
9706
9707 var groups = [];
9708
9709 var group, i;
9710 var materialIndex = undefined;
9711
9712 var faces = geometry.faces;
9713
9714 for ( i = 0; i < faces.length; i ++ ) {
9715
9716 var face = faces[ i ];
9717
9718 // materials
9719
9720 if ( face.materialIndex !== materialIndex ) {
9721
9722 materialIndex = face.materialIndex;
9723
9724 if ( group !== undefined ) {
9725
9726 group.count = ( i * 3 ) - group.start;
9727 groups.push( group );
9728
9729 }
9730
9731 group = {
9732 start: i * 3,
9733 materialIndex: materialIndex
9734 };
9735
9736 }
9737
9738 }
9739
9740 if ( group !== undefined ) {
9741
9742 group.count = ( i * 3 ) - group.start;
9743 groups.push( group );
9744
9745 }
9746
9747 this.groups = groups;
9748
9749 },
9750
9751 fromGeometry: function ( geometry ) {
9752
9753 var faces = geometry.faces;
9754 var vertices = geometry.vertices;
9755 var faceVertexUvs = geometry.faceVertexUvs;
9756
9757 var hasFaceVertexUv = faceVertexUvs[ 0 ] && faceVertexUvs[ 0 ].length > 0;
9758 var hasFaceVertexUv2 = faceVertexUvs[ 1 ] && faceVertexUvs[ 1 ].length > 0;
9759
9760 // morphs
9761
9762 var morphTargets = geometry.morphTargets;
9763 var morphTargetsLength = morphTargets.length;
9764
9765 var morphTargetsPosition;
9766
9767 if ( morphTargetsLength > 0 ) {
9768
9769 morphTargetsPosition = [];
9770
9771 for ( var i = 0; i < morphTargetsLength; i ++ ) {
9772
9773 morphTargetsPosition[ i ] = {
9774 name: morphTargets[ i ].name,
9775 data: []
9776 };
9777
9778 }
9779
9780 this.morphTargets.position = morphTargetsPosition;
9781
9782 }
9783
9784 var morphNormals = geometry.morphNormals;
9785 var morphNormalsLength = morphNormals.length;
9786
9787 var morphTargetsNormal;
9788
9789 if ( morphNormalsLength > 0 ) {
9790
9791 morphTargetsNormal = [];
9792
9793 for ( var i$1 = 0; i$1 < morphNormalsLength; i$1 ++ ) {
9794
9795 morphTargetsNormal[ i$1 ] = {
9796 name: morphNormals[ i$1 ].name,
9797 data: []
9798 };
9799
9800 }
9801
9802 this.morphTargets.normal = morphTargetsNormal;
9803
9804 }
9805
9806 // skins
9807
9808 var skinIndices = geometry.skinIndices;
9809 var skinWeights = geometry.skinWeights;
9810
9811 var hasSkinIndices = skinIndices.length === vertices.length;
9812 var hasSkinWeights = skinWeights.length === vertices.length;
9813
9814 //
9815
9816 if ( vertices.length > 0 && faces.length === 0 ) {
9817
9818 console.error( 'THREE.DirectGeometry: Faceless geometries are not supported.' );
9819
9820 }
9821
9822 for ( var i$2 = 0; i$2 < faces.length; i$2 ++ ) {
9823
9824 var face = faces[ i$2 ];
9825
9826 this.vertices.push( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ] );
9827
9828 var vertexNormals = face.vertexNormals;
9829
9830 if ( vertexNormals.length === 3 ) {
9831
9832 this.normals.push( vertexNormals[ 0 ], vertexNormals[ 1 ], vertexNormals[ 2 ] );
9833
9834 } else {
9835
9836 var normal = face.normal;
9837
9838 this.normals.push( normal, normal, normal );
9839
9840 }
9841
9842 var vertexColors = face.vertexColors;
9843
9844 if ( vertexColors.length === 3 ) {
9845
9846 this.colors.push( vertexColors[ 0 ], vertexColors[ 1 ], vertexColors[ 2 ] );
9847
9848 } else {
9849
9850 var color = face.color;
9851
9852 this.colors.push( color, color, color );
9853
9854 }
9855
9856 if ( hasFaceVertexUv === true ) {
9857
9858 var vertexUvs = faceVertexUvs[ 0 ][ i$2 ];
9859
9860 if ( vertexUvs !== undefined ) {
9861
9862 this.uvs.push( vertexUvs[ 0 ], vertexUvs[ 1 ], vertexUvs[ 2 ] );
9863
9864 } else {
9865
9866 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ', i$2 );
9867
9868 this.uvs.push( new Vector2(), new Vector2(), new Vector2() );
9869
9870 }
9871
9872 }
9873
9874 if ( hasFaceVertexUv2 === true ) {
9875
9876 var vertexUvs$1 = faceVertexUvs[ 1 ][ i$2 ];
9877
9878 if ( vertexUvs$1 !== undefined ) {
9879
9880 this.uvs2.push( vertexUvs$1[ 0 ], vertexUvs$1[ 1 ], vertexUvs$1[ 2 ] );
9881
9882 } else {
9883
9884 console.warn( 'THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ', i$2 );
9885
9886 this.uvs2.push( new Vector2(), new Vector2(), new Vector2() );
9887
9888 }
9889
9890 }
9891
9892 // morphs
9893
9894 for ( var j = 0; j < morphTargetsLength; j ++ ) {
9895
9896 var morphTarget = morphTargets[ j ].vertices;
9897
9898 morphTargetsPosition[ j ].data.push( morphTarget[ face.a ], morphTarget[ face.b ], morphTarget[ face.c ] );
9899
9900 }
9901
9902 for ( var j$1 = 0; j$1 < morphNormalsLength; j$1 ++ ) {
9903
9904 var morphNormal = morphNormals[ j$1 ].vertexNormals[ i$2 ];
9905
9906 morphTargetsNormal[ j$1 ].data.push( morphNormal.a, morphNormal.b, morphNormal.c );
9907
9908 }
9909
9910 // skins
9911
9912 if ( hasSkinIndices ) {
9913
9914 this.skinIndices.push( skinIndices[ face.a ], skinIndices[ face.b ], skinIndices[ face.c ] );
9915
9916 }
9917
9918 if ( hasSkinWeights ) {
9919
9920 this.skinWeights.push( skinWeights[ face.a ], skinWeights[ face.b ], skinWeights[ face.c ] );
9921
9922 }
9923
9924 }
9925
9926 this.computeGroups( geometry );
9927
9928 this.verticesNeedUpdate = geometry.verticesNeedUpdate;
9929 this.normalsNeedUpdate = geometry.normalsNeedUpdate;
9930 this.colorsNeedUpdate = geometry.colorsNeedUpdate;
9931 this.uvsNeedUpdate = geometry.uvsNeedUpdate;
9932 this.groupsNeedUpdate = geometry.groupsNeedUpdate;
9933
9934 if ( geometry.boundingSphere !== null ) {
9935
9936 this.boundingSphere = geometry.boundingSphere.clone();
9937
9938 }
9939
9940 if ( geometry.boundingBox !== null ) {
9941
9942 this.boundingBox = geometry.boundingBox.clone();
9943
9944 }
9945
9946 return this;
9947
9948 }
9949
9950 } );
9951
9952 function arrayMax( array ) {
9953
9954 if ( array.length === 0 ) { return - Infinity; }
9955
9956 var max = array[ 0 ];
9957
9958 for ( var i = 1, l = array.length; i < l; ++ i ) {
9959
9960 if ( array[ i ] > max ) { max = array[ i ]; }
9961
9962 }
9963
9964 return max;
9965
9966 }
9967
9968 var _bufferGeometryId = 1; // BufferGeometry uses odd numbers as Id
9969
9970 var _m1$2 = new Matrix4();
9971 var _obj = new Object3D();
9972 var _offset = new Vector3();
9973 var _box$2 = new Box3();
9974 var _boxMorphTargets = new Box3();
9975 var _vector$4 = new Vector3();
9976
9977 function BufferGeometry() {
9978
9979 Object.defineProperty( this, 'id', { value: _bufferGeometryId += 2 } );
9980
9981 this.uuid = MathUtils.generateUUID();
9982
9983 this.name = '';
9984 this.type = 'BufferGeometry';
9985
9986 this.index = null;
9987 this.attributes = {};
9988
9989 this.morphAttributes = {};
9990 this.morphTargetsRelative = false;
9991
9992 this.groups = [];
9993
9994 this.boundingBox = null;
9995 this.boundingSphere = null;
9996
9997 this.drawRange = { start: 0, count: Infinity };
9998
9999 this.userData = {};
10000
10001 }
10002
10003 BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
10004
10005 constructor: BufferGeometry,
10006
10007 isBufferGeometry: true,
10008
10009 getIndex: function () {
10010
10011 return this.index;
10012
10013 },
10014
10015 setIndex: function ( index ) {
10016
10017 if ( Array.isArray( index ) ) {
10018
10019 this.index = new ( arrayMax( index ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 );
10020
10021 } else {
10022
10023 this.index = index;
10024
10025 }
10026
10027 },
10028
10029 getAttribute: function ( name ) {
10030
10031 return this.attributes[ name ];
10032
10033 },
10034
10035 setAttribute: function ( name, attribute ) {
10036
10037 this.attributes[ name ] = attribute;
10038
10039 return this;
10040
10041 },
10042
10043 deleteAttribute: function ( name ) {
10044
10045 delete this.attributes[ name ];
10046
10047 return this;
10048
10049 },
10050
10051 addGroup: function ( start, count, materialIndex ) {
10052
10053 this.groups.push( {
10054
10055 start: start,
10056 count: count,
10057 materialIndex: materialIndex !== undefined ? materialIndex : 0
10058
10059 } );
10060
10061 },
10062
10063 clearGroups: function () {
10064
10065 this.groups = [];
10066
10067 },
10068
10069 setDrawRange: function ( start, count ) {
10070
10071 this.drawRange.start = start;
10072 this.drawRange.count = count;
10073
10074 },
10075
10076 applyMatrix4: function ( matrix ) {
10077
10078 var position = this.attributes.position;
10079
10080 if ( position !== undefined ) {
10081
10082 position.applyMatrix4( matrix );
10083
10084 position.needsUpdate = true;
10085
10086 }
10087
10088 var normal = this.attributes.normal;
10089
10090 if ( normal !== undefined ) {
10091
10092 var normalMatrix = new Matrix3().getNormalMatrix( matrix );
10093
10094 normal.applyNormalMatrix( normalMatrix );
10095
10096 normal.needsUpdate = true;
10097
10098 }
10099
10100 var tangent = this.attributes.tangent;
10101
10102 if ( tangent !== undefined ) {
10103
10104 tangent.transformDirection( matrix );
10105
10106 tangent.needsUpdate = true;
10107
10108 }
10109
10110 if ( this.boundingBox !== null ) {
10111
10112 this.computeBoundingBox();
10113
10114 }
10115
10116 if ( this.boundingSphere !== null ) {
10117
10118 this.computeBoundingSphere();
10119
10120 }
10121
10122 return this;
10123
10124 },
10125
10126 rotateX: function ( angle ) {
10127
10128 // rotate geometry around world x-axis
10129
10130 _m1$2.makeRotationX( angle );
10131
10132 this.applyMatrix4( _m1$2 );
10133
10134 return this;
10135
10136 },
10137
10138 rotateY: function ( angle ) {
10139
10140 // rotate geometry around world y-axis
10141
10142 _m1$2.makeRotationY( angle );
10143
10144 this.applyMatrix4( _m1$2 );
10145
10146 return this;
10147
10148 },
10149
10150 rotateZ: function ( angle ) {
10151
10152 // rotate geometry around world z-axis
10153
10154 _m1$2.makeRotationZ( angle );
10155
10156 this.applyMatrix4( _m1$2 );
10157
10158 return this;
10159
10160 },
10161
10162 translate: function ( x, y, z ) {
10163
10164 // translate geometry
10165
10166 _m1$2.makeTranslation( x, y, z );
10167
10168 this.applyMatrix4( _m1$2 );
10169
10170 return this;
10171
10172 },
10173
10174 scale: function ( x, y, z ) {
10175
10176 // scale geometry
10177
10178 _m1$2.makeScale( x, y, z );
10179
10180 this.applyMatrix4( _m1$2 );
10181
10182 return this;
10183
10184 },
10185
10186 lookAt: function ( vector ) {
10187
10188 _obj.lookAt( vector );
10189
10190 _obj.updateMatrix();
10191
10192 this.applyMatrix4( _obj.matrix );
10193
10194 return this;
10195
10196 },
10197
10198 center: function () {
10199
10200 this.computeBoundingBox();
10201
10202 this.boundingBox.getCenter( _offset ).negate();
10203
10204 this.translate( _offset.x, _offset.y, _offset.z );
10205
10206 return this;
10207
10208 },
10209
10210 setFromObject: function ( object ) {
10211
10212 // console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
10213
10214 var geometry = object.geometry;
10215
10216 if ( object.isPoints || object.isLine ) {
10217
10218 var positions = new Float32BufferAttribute( geometry.vertices.length * 3, 3 );
10219 var colors = new Float32BufferAttribute( geometry.colors.length * 3, 3 );
10220
10221 this.setAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
10222 this.setAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
10223
10224 if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {
10225
10226 var lineDistances = new Float32BufferAttribute( geometry.lineDistances.length, 1 );
10227
10228 this.setAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
10229
10230 }
10231
10232 if ( geometry.boundingSphere !== null ) {
10233
10234 this.boundingSphere = geometry.boundingSphere.clone();
10235
10236 }
10237
10238 if ( geometry.boundingBox !== null ) {
10239
10240 this.boundingBox = geometry.boundingBox.clone();
10241
10242 }
10243
10244 } else if ( object.isMesh ) {
10245
10246 if ( geometry && geometry.isGeometry ) {
10247
10248 this.fromGeometry( geometry );
10249
10250 }
10251
10252 }
10253
10254 return this;
10255
10256 },
10257
10258 setFromPoints: function ( points ) {
10259
10260 var position = [];
10261
10262 for ( var i = 0, l = points.length; i < l; i ++ ) {
10263
10264 var point = points[ i ];
10265 position.push( point.x, point.y, point.z || 0 );
10266
10267 }
10268
10269 this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) );
10270
10271 return this;
10272
10273 },
10274
10275 updateFromObject: function ( object ) {
10276
10277 var geometry = object.geometry;
10278
10279 if ( object.isMesh ) {
10280
10281 var direct = geometry.__directGeometry;
10282
10283 if ( geometry.elementsNeedUpdate === true ) {
10284
10285 direct = undefined;
10286 geometry.elementsNeedUpdate = false;
10287
10288 }
10289
10290 if ( direct === undefined ) {
10291
10292 return this.fromGeometry( geometry );
10293
10294 }
10295
10296 direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
10297 direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
10298 direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
10299 direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
10300 direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
10301
10302 geometry.verticesNeedUpdate = false;
10303 geometry.normalsNeedUpdate = false;
10304 geometry.colorsNeedUpdate = false;
10305 geometry.uvsNeedUpdate = false;
10306 geometry.groupsNeedUpdate = false;
10307
10308 geometry = direct;
10309
10310 }
10311
10312 if ( geometry.verticesNeedUpdate === true ) {
10313
10314 var attribute = this.attributes.position;
10315
10316 if ( attribute !== undefined ) {
10317
10318 attribute.copyVector3sArray( geometry.vertices );
10319 attribute.needsUpdate = true;
10320
10321 }
10322
10323 geometry.verticesNeedUpdate = false;
10324
10325 }
10326
10327 if ( geometry.normalsNeedUpdate === true ) {
10328
10329 var attribute$1 = this.attributes.normal;
10330
10331 if ( attribute$1 !== undefined ) {
10332
10333 attribute$1.copyVector3sArray( geometry.normals );
10334 attribute$1.needsUpdate = true;
10335
10336 }
10337
10338 geometry.normalsNeedUpdate = false;
10339
10340 }
10341
10342 if ( geometry.colorsNeedUpdate === true ) {
10343
10344 var attribute$2 = this.attributes.color;
10345
10346 if ( attribute$2 !== undefined ) {
10347
10348 attribute$2.copyColorsArray( geometry.colors );
10349 attribute$2.needsUpdate = true;
10350
10351 }
10352
10353 geometry.colorsNeedUpdate = false;
10354
10355 }
10356
10357 if ( geometry.uvsNeedUpdate ) {
10358
10359 var attribute$3 = this.attributes.uv;
10360
10361 if ( attribute$3 !== undefined ) {
10362
10363 attribute$3.copyVector2sArray( geometry.uvs );
10364 attribute$3.needsUpdate = true;
10365
10366 }
10367
10368 geometry.uvsNeedUpdate = false;
10369
10370 }
10371
10372 if ( geometry.lineDistancesNeedUpdate ) {
10373
10374 var attribute$4 = this.attributes.lineDistance;
10375
10376 if ( attribute$4 !== undefined ) {
10377
10378 attribute$4.copyArray( geometry.lineDistances );
10379 attribute$4.needsUpdate = true;
10380
10381 }
10382
10383 geometry.lineDistancesNeedUpdate = false;
10384
10385 }
10386
10387 if ( geometry.groupsNeedUpdate ) {
10388
10389 geometry.computeGroups( object.geometry );
10390 this.groups = geometry.groups;
10391
10392 geometry.groupsNeedUpdate = false;
10393
10394 }
10395
10396 return this;
10397
10398 },
10399
10400 fromGeometry: function ( geometry ) {
10401
10402 geometry.__directGeometry = new DirectGeometry().fromGeometry( geometry );
10403
10404 return this.fromDirectGeometry( geometry.__directGeometry );
10405
10406 },
10407
10408 fromDirectGeometry: function ( geometry ) {
10409
10410 var positions = new Float32Array( geometry.vertices.length * 3 );
10411 this.setAttribute( 'position', new BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
10412
10413 if ( geometry.normals.length > 0 ) {
10414
10415 var normals = new Float32Array( geometry.normals.length * 3 );
10416 this.setAttribute( 'normal', new BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );
10417
10418 }
10419
10420 if ( geometry.colors.length > 0 ) {
10421
10422 var colors = new Float32Array( geometry.colors.length * 3 );
10423 this.setAttribute( 'color', new BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
10424
10425 }
10426
10427 if ( geometry.uvs.length > 0 ) {
10428
10429 var uvs = new Float32Array( geometry.uvs.length * 2 );
10430 this.setAttribute( 'uv', new BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );
10431
10432 }
10433
10434 if ( geometry.uvs2.length > 0 ) {
10435
10436 var uvs2 = new Float32Array( geometry.uvs2.length * 2 );
10437 this.setAttribute( 'uv2', new BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );
10438
10439 }
10440
10441 // groups
10442
10443 this.groups = geometry.groups;
10444
10445 // morphs
10446
10447 for ( var name in geometry.morphTargets ) {
10448
10449 var array = [];
10450 var morphTargets = geometry.morphTargets[ name ];
10451
10452 for ( var i = 0, l = morphTargets.length; i < l; i ++ ) {
10453
10454 var morphTarget = morphTargets[ i ];
10455
10456 var attribute = new Float32BufferAttribute( morphTarget.data.length * 3, 3 );
10457 attribute.name = morphTarget.name;
10458
10459 array.push( attribute.copyVector3sArray( morphTarget.data ) );
10460
10461 }
10462
10463 this.morphAttributes[ name ] = array;
10464
10465 }
10466
10467 // skinning
10468
10469 if ( geometry.skinIndices.length > 0 ) {
10470
10471 var skinIndices = new Float32BufferAttribute( geometry.skinIndices.length * 4, 4 );
10472 this.setAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );
10473
10474 }
10475
10476 if ( geometry.skinWeights.length > 0 ) {
10477
10478 var skinWeights = new Float32BufferAttribute( geometry.skinWeights.length * 4, 4 );
10479 this.setAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );
10480
10481 }
10482
10483 //
10484
10485 if ( geometry.boundingSphere !== null ) {
10486
10487 this.boundingSphere = geometry.boundingSphere.clone();
10488
10489 }
10490
10491 if ( geometry.boundingBox !== null ) {
10492
10493 this.boundingBox = geometry.boundingBox.clone();
10494
10495 }
10496
10497 return this;
10498
10499 },
10500
10501 computeBoundingBox: function () {
10502
10503 if ( this.boundingBox === null ) {
10504
10505 this.boundingBox = new Box3();
10506
10507 }
10508
10509 var position = this.attributes.position;
10510 var morphAttributesPosition = this.morphAttributes.position;
10511
10512 if ( position !== undefined ) {
10513
10514 this.boundingBox.setFromBufferAttribute( position );
10515
10516 // process morph attributes if present
10517
10518 if ( morphAttributesPosition ) {
10519
10520 for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
10521
10522 var morphAttribute = morphAttributesPosition[ i ];
10523 _box$2.setFromBufferAttribute( morphAttribute );
10524
10525 if ( this.morphTargetsRelative ) {
10526
10527 _vector$4.addVectors( this.boundingBox.min, _box$2.min );
10528 this.boundingBox.expandByPoint( _vector$4 );
10529
10530 _vector$4.addVectors( this.boundingBox.max, _box$2.max );
10531 this.boundingBox.expandByPoint( _vector$4 );
10532
10533 } else {
10534
10535 this.boundingBox.expandByPoint( _box$2.min );
10536 this.boundingBox.expandByPoint( _box$2.max );
10537
10538 }
10539
10540 }
10541
10542 }
10543
10544 } else {
10545
10546 this.boundingBox.makeEmpty();
10547
10548 }
10549
10550 if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
10551
10552 console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
10553
10554 }
10555
10556 },
10557
10558 computeBoundingSphere: function () {
10559
10560 if ( this.boundingSphere === null ) {
10561
10562 this.boundingSphere = new Sphere();
10563
10564 }
10565
10566 var position = this.attributes.position;
10567 var morphAttributesPosition = this.morphAttributes.position;
10568
10569 if ( position ) {
10570
10571 // first, find the center of the bounding sphere
10572
10573 var center = this.boundingSphere.center;
10574
10575 _box$2.setFromBufferAttribute( position );
10576
10577 // process morph attributes if present
10578
10579 if ( morphAttributesPosition ) {
10580
10581 for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
10582
10583 var morphAttribute = morphAttributesPosition[ i ];
10584 _boxMorphTargets.setFromBufferAttribute( morphAttribute );
10585
10586 if ( this.morphTargetsRelative ) {
10587
10588 _vector$4.addVectors( _box$2.min, _boxMorphTargets.min );
10589 _box$2.expandByPoint( _vector$4 );
10590
10591 _vector$4.addVectors( _box$2.max, _boxMorphTargets.max );
10592 _box$2.expandByPoint( _vector$4 );
10593
10594 } else {
10595
10596 _box$2.expandByPoint( _boxMorphTargets.min );
10597 _box$2.expandByPoint( _boxMorphTargets.max );
10598
10599 }
10600
10601 }
10602
10603 }
10604
10605 _box$2.getCenter( center );
10606
10607 // second, try to find a boundingSphere with a radius smaller than the
10608 // boundingSphere of the boundingBox: sqrt(3) smaller in the best case
10609
10610 var maxRadiusSq = 0;
10611
10612 for ( var i$1 = 0, il$1 = position.count; i$1 < il$1; i$1 ++ ) {
10613
10614 _vector$4.fromBufferAttribute( position, i$1 );
10615
10616 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) );
10617
10618 }
10619
10620 // process morph attributes if present
10621
10622 if ( morphAttributesPosition ) {
10623
10624 for ( var i$2 = 0, il$2 = morphAttributesPosition.length; i$2 < il$2; i$2 ++ ) {
10625
10626 var morphAttribute$1 = morphAttributesPosition[ i$2 ];
10627 var morphTargetsRelative = this.morphTargetsRelative;
10628
10629 for ( var j = 0, jl = morphAttribute$1.count; j < jl; j ++ ) {
10630
10631 _vector$4.fromBufferAttribute( morphAttribute$1, j );
10632
10633 if ( morphTargetsRelative ) {
10634
10635 _offset.fromBufferAttribute( position, j );
10636 _vector$4.add( _offset );
10637
10638 }
10639
10640 maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$4 ) );
10641
10642 }
10643
10644 }
10645
10646 }
10647
10648 this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
10649
10650 if ( isNaN( this.boundingSphere.radius ) ) {
10651
10652 console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
10653
10654 }
10655
10656 }
10657
10658 },
10659
10660 computeFaceNormals: function () {
10661
10662 // backwards compatibility
10663
10664 },
10665
10666 computeVertexNormals: function () {
10667
10668 var index = this.index;
10669 var positionAttribute = this.getAttribute( 'position' );
10670
10671 if ( positionAttribute !== undefined ) {
10672
10673 var normalAttribute = this.getAttribute( 'normal' );
10674
10675 if ( normalAttribute === undefined ) {
10676
10677 normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 );
10678 this.setAttribute( 'normal', normalAttribute );
10679
10680 } else {
10681
10682 // reset existing normals to zero
10683
10684 for ( var i = 0, il = normalAttribute.count; i < il; i ++ ) {
10685
10686 normalAttribute.setXYZ( i, 0, 0, 0 );
10687
10688 }
10689
10690 }
10691
10692 var pA = new Vector3(), pB = new Vector3(), pC = new Vector3();
10693 var nA = new Vector3(), nB = new Vector3(), nC = new Vector3();
10694 var cb = new Vector3(), ab = new Vector3();
10695
10696 // indexed elements
10697
10698 if ( index ) {
10699
10700 for ( var i$1 = 0, il$1 = index.count; i$1 < il$1; i$1 += 3 ) {
10701
10702 var vA = index.getX( i$1 + 0 );
10703 var vB = index.getX( i$1 + 1 );
10704 var vC = index.getX( i$1 + 2 );
10705
10706 pA.fromBufferAttribute( positionAttribute, vA );
10707 pB.fromBufferAttribute( positionAttribute, vB );
10708 pC.fromBufferAttribute( positionAttribute, vC );
10709
10710 cb.subVectors( pC, pB );
10711 ab.subVectors( pA, pB );
10712 cb.cross( ab );
10713
10714 nA.fromBufferAttribute( normalAttribute, vA );
10715 nB.fromBufferAttribute( normalAttribute, vB );
10716 nC.fromBufferAttribute( normalAttribute, vC );
10717
10718 nA.add( cb );
10719 nB.add( cb );
10720 nC.add( cb );
10721
10722 normalAttribute.setXYZ( vA, nA.x, nA.y, nA.z );
10723 normalAttribute.setXYZ( vB, nB.x, nB.y, nB.z );
10724 normalAttribute.setXYZ( vC, nC.x, nC.y, nC.z );
10725
10726 }
10727
10728 } else {
10729
10730 // non-indexed elements (unconnected triangle soup)
10731
10732 for ( var i$2 = 0, il$2 = positionAttribute.count; i$2 < il$2; i$2 += 3 ) {
10733
10734 pA.fromBufferAttribute( positionAttribute, i$2 + 0 );
10735 pB.fromBufferAttribute( positionAttribute, i$2 + 1 );
10736 pC.fromBufferAttribute( positionAttribute, i$2 + 2 );
10737
10738 cb.subVectors( pC, pB );
10739 ab.subVectors( pA, pB );
10740 cb.cross( ab );
10741
10742 normalAttribute.setXYZ( i$2 + 0, cb.x, cb.y, cb.z );
10743 normalAttribute.setXYZ( i$2 + 1, cb.x, cb.y, cb.z );
10744 normalAttribute.setXYZ( i$2 + 2, cb.x, cb.y, cb.z );
10745
10746 }
10747
10748 }
10749
10750 this.normalizeNormals();
10751
10752 normalAttribute.needsUpdate = true;
10753
10754 }
10755
10756 },
10757
10758 merge: function ( geometry, offset ) {
10759
10760 if ( ! ( geometry && geometry.isBufferGeometry ) ) {
10761
10762 console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
10763 return;
10764
10765 }
10766
10767 if ( offset === undefined ) {
10768
10769 offset = 0;
10770
10771 console.warn(
10772 'THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. '
10773 + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.'
10774 );
10775
10776 }
10777
10778 var attributes = this.attributes;
10779
10780 for ( var key in attributes ) {
10781
10782 if ( geometry.attributes[ key ] === undefined ) { continue; }
10783
10784 var attribute1 = attributes[ key ];
10785 var attributeArray1 = attribute1.array;
10786
10787 var attribute2 = geometry.attributes[ key ];
10788 var attributeArray2 = attribute2.array;
10789
10790 var attributeOffset = attribute2.itemSize * offset;
10791 var length = Math.min( attributeArray2.length, attributeArray1.length - attributeOffset );
10792
10793 for ( var i = 0, j = attributeOffset; i < length; i ++, j ++ ) {
10794
10795 attributeArray1[ j ] = attributeArray2[ i ];
10796
10797 }
10798
10799 }
10800
10801 return this;
10802
10803 },
10804
10805 normalizeNormals: function () {
10806
10807 var normals = this.attributes.normal;
10808
10809 for ( var i = 0, il = normals.count; i < il; i ++ ) {
10810
10811 _vector$4.fromBufferAttribute( normals, i );
10812
10813 _vector$4.normalize();
10814
10815 normals.setXYZ( i, _vector$4.x, _vector$4.y, _vector$4.z );
10816
10817 }
10818
10819 },
10820
10821 toNonIndexed: function () {
10822
10823 function convertBufferAttribute( attribute, indices ) {
10824
10825 var array = attribute.array;
10826 var itemSize = attribute.itemSize;
10827 var normalized = attribute.normalized;
10828
10829 var array2 = new array.constructor( indices.length * itemSize );
10830
10831 var index = 0, index2 = 0;
10832
10833 for ( var i = 0, l = indices.length; i < l; i ++ ) {
10834
10835 index = indices[ i ] * itemSize;
10836
10837 for ( var j = 0; j < itemSize; j ++ ) {
10838
10839 array2[ index2 ++ ] = array[ index ++ ];
10840
10841 }
10842
10843 }
10844
10845 return new BufferAttribute( array2, itemSize, normalized );
10846
10847 }
10848
10849 //
10850
10851 if ( this.index === null ) {
10852
10853 console.warn( 'THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed.' );
10854 return this;
10855
10856 }
10857
10858 var geometry2 = new BufferGeometry();
10859
10860 var indices = this.index.array;
10861 var attributes = this.attributes;
10862
10863 // attributes
10864
10865 for ( var name in attributes ) {
10866
10867 var attribute = attributes[ name ];
10868
10869 var newAttribute = convertBufferAttribute( attribute, indices );
10870
10871 geometry2.setAttribute( name, newAttribute );
10872
10873 }
10874
10875 // morph attributes
10876
10877 var morphAttributes = this.morphAttributes;
10878
10879 for ( var name$1 in morphAttributes ) {
10880
10881 var morphArray = [];
10882 var morphAttribute = morphAttributes[ name$1 ]; // morphAttribute: array of Float32BufferAttributes
10883
10884 for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) {
10885
10886 var attribute$1 = morphAttribute[ i ];
10887
10888 var newAttribute$1 = convertBufferAttribute( attribute$1, indices );
10889
10890 morphArray.push( newAttribute$1 );
10891
10892 }
10893
10894 geometry2.morphAttributes[ name$1 ] = morphArray;
10895
10896 }
10897
10898 geometry2.morphTargetsRelative = this.morphTargetsRelative;
10899
10900 // groups
10901
10902 var groups = this.groups;
10903
10904 for ( var i$1 = 0, l = groups.length; i$1 < l; i$1 ++ ) {
10905
10906 var group = groups[ i$1 ];
10907 geometry2.addGroup( group.start, group.count, group.materialIndex );
10908
10909 }
10910
10911 return geometry2;
10912
10913 },
10914
10915 toJSON: function () {
10916
10917 var data = {
10918 metadata: {
10919 version: 4.5,
10920 type: 'BufferGeometry',
10921 generator: 'BufferGeometry.toJSON'
10922 }
10923 };
10924
10925 // standard BufferGeometry serialization
10926
10927 data.uuid = this.uuid;
10928 data.type = this.type;
10929 if ( this.name !== '' ) { data.name = this.name; }
10930 if ( Object.keys( this.userData ).length > 0 ) { data.userData = this.userData; }
10931
10932 if ( this.parameters !== undefined ) {
10933
10934 var parameters = this.parameters;
10935
10936 for ( var key in parameters ) {
10937
10938 if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; }
10939
10940 }
10941
10942 return data;
10943
10944 }
10945
10946 data.data = { attributes: {} };
10947
10948 var index = this.index;
10949
10950 if ( index !== null ) {
10951
10952 data.data.index = {
10953 type: index.array.constructor.name,
10954 array: Array.prototype.slice.call( index.array )
10955 };
10956
10957 }
10958
10959 var attributes = this.attributes;
10960
10961 for ( var key$1 in attributes ) {
10962
10963 var attribute = attributes[ key$1 ];
10964
10965 var attributeData = attribute.toJSON( data.data );
10966
10967 if ( attribute.name !== '' ) { attributeData.name = attribute.name; }
10968
10969 data.data.attributes[ key$1 ] = attributeData;
10970
10971 }
10972
10973 var morphAttributes = {};
10974 var hasMorphAttributes = false;
10975
10976 for ( var key$2 in this.morphAttributes ) {
10977
10978 var attributeArray = this.morphAttributes[ key$2 ];
10979
10980 var array = [];
10981
10982 for ( var i = 0, il = attributeArray.length; i < il; i ++ ) {
10983
10984 var attribute$1 = attributeArray[ i ];
10985
10986 var attributeData$1 = attribute$1.toJSON( data.data );
10987
10988 if ( attribute$1.name !== '' ) { attributeData$1.name = attribute$1.name; }
10989
10990 array.push( attributeData$1 );
10991
10992 }
10993
10994 if ( array.length > 0 ) {
10995
10996 morphAttributes[ key$2 ] = array;
10997
10998 hasMorphAttributes = true;
10999
11000 }
11001
11002 }
11003
11004 if ( hasMorphAttributes ) {
11005
11006 data.data.morphAttributes = morphAttributes;
11007 data.data.morphTargetsRelative = this.morphTargetsRelative;
11008
11009 }
11010
11011 var groups = this.groups;
11012
11013 if ( groups.length > 0 ) {
11014
11015 data.data.groups = JSON.parse( JSON.stringify( groups ) );
11016
11017 }
11018
11019 var boundingSphere = this.boundingSphere;
11020
11021 if ( boundingSphere !== null ) {
11022
11023 data.data.boundingSphere = {
11024 center: boundingSphere.center.toArray(),
11025 radius: boundingSphere.radius
11026 };
11027
11028 }
11029
11030 return data;
11031
11032 },
11033
11034 clone: function () {
11035
11036 /*
11037 // Handle primitives
11038
11039 const parameters = this.parameters;
11040
11041 if ( parameters !== undefined ) {
11042
11043 const values = [];
11044
11045 for ( const key in parameters ) {
11046
11047 values.push( parameters[ key ] );
11048
11049 }
11050
11051 const geometry = Object.create( this.constructor.prototype );
11052 this.constructor.apply( geometry, values );
11053 return geometry;
11054
11055 }
11056
11057 return new this.constructor().copy( this );
11058 */
11059
11060 return new BufferGeometry().copy( this );
11061
11062 },
11063
11064 copy: function ( source ) {
11065
11066 // reset
11067
11068 this.index = null;
11069 this.attributes = {};
11070 this.morphAttributes = {};
11071 this.groups = [];
11072 this.boundingBox = null;
11073 this.boundingSphere = null;
11074
11075 // used for storing cloned, shared data
11076
11077 var data = {};
11078
11079 // name
11080
11081 this.name = source.name;
11082
11083 // index
11084
11085 var index = source.index;
11086
11087 if ( index !== null ) {
11088
11089 this.setIndex( index.clone( data ) );
11090
11091 }
11092
11093 // attributes
11094
11095 var attributes = source.attributes;
11096
11097 for ( var name in attributes ) {
11098
11099 var attribute = attributes[ name ];
11100 this.setAttribute( name, attribute.clone( data ) );
11101
11102 }
11103
11104 // morph attributes
11105
11106 var morphAttributes = source.morphAttributes;
11107
11108 for ( var name$1 in morphAttributes ) {
11109
11110 var array = [];
11111 var morphAttribute = morphAttributes[ name$1 ]; // morphAttribute: array of Float32BufferAttributes
11112
11113 for ( var i = 0, l = morphAttribute.length; i < l; i ++ ) {
11114
11115 array.push( morphAttribute[ i ].clone( data ) );
11116
11117 }
11118
11119 this.morphAttributes[ name$1 ] = array;
11120
11121 }
11122
11123 this.morphTargetsRelative = source.morphTargetsRelative;
11124
11125 // groups
11126
11127 var groups = source.groups;
11128
11129 for ( var i$1 = 0, l$1 = groups.length; i$1 < l$1; i$1 ++ ) {
11130
11131 var group = groups[ i$1 ];
11132 this.addGroup( group.start, group.count, group.materialIndex );
11133
11134 }
11135
11136 // bounding box
11137
11138 var boundingBox = source.boundingBox;
11139
11140 if ( boundingBox !== null ) {
11141
11142 this.boundingBox = boundingBox.clone();
11143
11144 }
11145
11146 // bounding sphere
11147
11148 var boundingSphere = source.boundingSphere;
11149
11150 if ( boundingSphere !== null ) {
11151
11152 this.boundingSphere = boundingSphere.clone();
11153
11154 }
11155
11156 // draw range
11157
11158 this.drawRange.start = source.drawRange.start;
11159 this.drawRange.count = source.drawRange.count;
11160
11161 // user data
11162
11163 this.userData = source.userData;
11164
11165 return this;
11166
11167 },
11168
11169 dispose: function () {
11170
11171 this.dispatchEvent( { type: 'dispose' } );
11172
11173 }
11174
11175 } );
11176
11177 var _inverseMatrix = new Matrix4();
11178 var _ray = new Ray();
11179 var _sphere = new Sphere();
11180
11181 var _vA = new Vector3();
11182 var _vB = new Vector3();
11183 var _vC = new Vector3();
11184
11185 var _tempA = new Vector3();
11186 var _tempB = new Vector3();
11187 var _tempC = new Vector3();
11188
11189 var _morphA = new Vector3();
11190 var _morphB = new Vector3();
11191 var _morphC = new Vector3();
11192
11193 var _uvA = new Vector2();
11194 var _uvB = new Vector2();
11195 var _uvC = new Vector2();
11196
11197 var _intersectionPoint = new Vector3();
11198 var _intersectionPointWorld = new Vector3();
11199
11200 function Mesh( geometry, material ) {
11201
11202 Object3D.call( this );
11203
11204 this.type = 'Mesh';
11205
11206 this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
11207 this.material = material !== undefined ? material : new MeshBasicMaterial();
11208
11209 this.updateMorphTargets();
11210
11211 }
11212
11213 Mesh.prototype = Object.assign( Object.create( Object3D.prototype ), {
11214
11215 constructor: Mesh,
11216
11217 isMesh: true,
11218
11219 copy: function ( source ) {
11220
11221 Object3D.prototype.copy.call( this, source );
11222
11223 if ( source.morphTargetInfluences !== undefined ) {
11224
11225 this.morphTargetInfluences = source.morphTargetInfluences.slice();
11226
11227 }
11228
11229 if ( source.morphTargetDictionary !== undefined ) {
11230
11231 this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary );
11232
11233 }
11234
11235 this.material = source.material;
11236 this.geometry = source.geometry;
11237
11238 return this;
11239
11240 },
11241
11242 updateMorphTargets: function () {
11243
11244 var geometry = this.geometry;
11245
11246 if ( geometry.isBufferGeometry ) {
11247
11248 var morphAttributes = geometry.morphAttributes;
11249 var keys = Object.keys( morphAttributes );
11250
11251 if ( keys.length > 0 ) {
11252
11253 var morphAttribute = morphAttributes[ keys[ 0 ] ];
11254
11255 if ( morphAttribute !== undefined ) {
11256
11257 this.morphTargetInfluences = [];
11258 this.morphTargetDictionary = {};
11259
11260 for ( var m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
11261
11262 var name = morphAttribute[ m ].name || String( m );
11263
11264 this.morphTargetInfluences.push( 0 );
11265 this.morphTargetDictionary[ name ] = m;
11266
11267 }
11268
11269 }
11270
11271 }
11272
11273 } else {
11274
11275 var morphTargets = geometry.morphTargets;
11276
11277 if ( morphTargets !== undefined && morphTargets.length > 0 ) {
11278
11279 console.error( 'THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
11280
11281 }
11282
11283 }
11284
11285 },
11286
11287 raycast: function ( raycaster, intersects ) {
11288
11289 var geometry = this.geometry;
11290 var material = this.material;
11291 var matrixWorld = this.matrixWorld;
11292
11293 if ( material === undefined ) { return; }
11294
11295 // Checking boundingSphere distance to ray
11296
11297 if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
11298
11299 _sphere.copy( geometry.boundingSphere );
11300 _sphere.applyMatrix4( matrixWorld );
11301
11302 if ( raycaster.ray.intersectsSphere( _sphere ) === false ) { return; }
11303
11304 //
11305
11306 _inverseMatrix.getInverse( matrixWorld );
11307 _ray.copy( raycaster.ray ).applyMatrix4( _inverseMatrix );
11308
11309 // Check boundingBox before continuing
11310
11311 if ( geometry.boundingBox !== null ) {
11312
11313 if ( _ray.intersectsBox( geometry.boundingBox ) === false ) { return; }
11314
11315 }
11316
11317 var intersection;
11318
11319 if ( geometry.isBufferGeometry ) {
11320
11321 var index = geometry.index;
11322 var position = geometry.attributes.position;
11323 var morphPosition = geometry.morphAttributes.position;
11324 var morphTargetsRelative = geometry.morphTargetsRelative;
11325 var uv = geometry.attributes.uv;
11326 var uv2 = geometry.attributes.uv2;
11327 var groups = geometry.groups;
11328 var drawRange = geometry.drawRange;
11329
11330 if ( index !== null ) {
11331
11332 // indexed buffer geometry
11333
11334 if ( Array.isArray( material ) ) {
11335
11336 for ( var i = 0, il = groups.length; i < il; i ++ ) {
11337
11338 var group = groups[ i ];
11339 var groupMaterial = material[ group.materialIndex ];
11340
11341 var start = Math.max( group.start, drawRange.start );
11342 var end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
11343
11344 for ( var j = start, jl = end; j < jl; j += 3 ) {
11345
11346 var a = index.getX( j );
11347 var b = index.getX( j + 1 );
11348 var c = index.getX( j + 2 );
11349
11350 intersection = checkBufferGeometryIntersection( this, groupMaterial, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c );
11351
11352 if ( intersection ) {
11353
11354 intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics
11355 intersection.face.materialIndex = group.materialIndex;
11356 intersects.push( intersection );
11357
11358 }
11359
11360 }
11361
11362 }
11363
11364 } else {
11365
11366 var start$1 = Math.max( 0, drawRange.start );
11367 var end$1 = Math.min( index.count, ( drawRange.start + drawRange.count ) );
11368
11369 for ( var i$1 = start$1, il$1 = end$1; i$1 < il$1; i$1 += 3 ) {
11370
11371 var a$1 = index.getX( i$1 );
11372 var b$1 = index.getX( i$1 + 1 );
11373 var c$1 = index.getX( i$1 + 2 );
11374
11375 intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a$1, b$1, c$1 );
11376
11377 if ( intersection ) {
11378
11379 intersection.faceIndex = Math.floor( i$1 / 3 ); // triangle number in indexed buffer semantics
11380 intersects.push( intersection );
11381
11382 }
11383
11384 }
11385
11386 }
11387
11388 } else if ( position !== undefined ) {
11389
11390 // non-indexed buffer geometry
11391
11392 if ( Array.isArray( material ) ) {
11393
11394 for ( var i$2 = 0, il$2 = groups.length; i$2 < il$2; i$2 ++ ) {
11395
11396 var group$1 = groups[ i$2 ];
11397 var groupMaterial$1 = material[ group$1.materialIndex ];
11398
11399 var start$2 = Math.max( group$1.start, drawRange.start );
11400 var end$2 = Math.min( ( group$1.start + group$1.count ), ( drawRange.start + drawRange.count ) );
11401
11402 for ( var j$1 = start$2, jl$1 = end$2; j$1 < jl$1; j$1 += 3 ) {
11403
11404 var a$2 = j$1;
11405 var b$2 = j$1 + 1;
11406 var c$2 = j$1 + 2;
11407
11408 intersection = checkBufferGeometryIntersection( this, groupMaterial$1, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a$2, b$2, c$2 );
11409
11410 if ( intersection ) {
11411
11412 intersection.faceIndex = Math.floor( j$1 / 3 ); // triangle number in non-indexed buffer semantics
11413 intersection.face.materialIndex = group$1.materialIndex;
11414 intersects.push( intersection );
11415
11416 }
11417
11418 }
11419
11420 }
11421
11422 } else {
11423
11424 var start$3 = Math.max( 0, drawRange.start );
11425 var end$3 = Math.min( position.count, ( drawRange.start + drawRange.count ) );
11426
11427 for ( var i$3 = start$3, il$3 = end$3; i$3 < il$3; i$3 += 3 ) {
11428
11429 var a$3 = i$3;
11430 var b$3 = i$3 + 1;
11431 var c$3 = i$3 + 2;
11432
11433 intersection = checkBufferGeometryIntersection( this, material, raycaster, _ray, position, morphPosition, morphTargetsRelative, uv, uv2, a$3, b$3, c$3 );
11434
11435 if ( intersection ) {
11436
11437 intersection.faceIndex = Math.floor( i$3 / 3 ); // triangle number in non-indexed buffer semantics
11438 intersects.push( intersection );
11439
11440 }
11441
11442 }
11443
11444 }
11445
11446 }
11447
11448 } else if ( geometry.isGeometry ) {
11449
11450 var isMultiMaterial = Array.isArray( material );
11451
11452 var vertices = geometry.vertices;
11453 var faces = geometry.faces;
11454 var uvs;
11455
11456 var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
11457 if ( faceVertexUvs.length > 0 ) { uvs = faceVertexUvs; }
11458
11459 for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
11460
11461 var face = faces[ f ];
11462 var faceMaterial = isMultiMaterial ? material[ face.materialIndex ] : material;
11463
11464 if ( faceMaterial === undefined ) { continue; }
11465
11466 var fvA = vertices[ face.a ];
11467 var fvB = vertices[ face.b ];
11468 var fvC = vertices[ face.c ];
11469
11470 intersection = checkIntersection( this, faceMaterial, raycaster, _ray, fvA, fvB, fvC, _intersectionPoint );
11471
11472 if ( intersection ) {
11473
11474 if ( uvs && uvs[ f ] ) {
11475
11476 var uvs_f = uvs[ f ];
11477 _uvA.copy( uvs_f[ 0 ] );
11478 _uvB.copy( uvs_f[ 1 ] );
11479 _uvC.copy( uvs_f[ 2 ] );
11480
11481 intersection.uv = Triangle.getUV( _intersectionPoint, fvA, fvB, fvC, _uvA, _uvB, _uvC, new Vector2() );
11482
11483 }
11484
11485 intersection.face = face;
11486 intersection.faceIndex = f;
11487 intersects.push( intersection );
11488
11489 }
11490
11491 }
11492
11493 }
11494
11495 }
11496
11497 } );
11498
11499 function checkIntersection( object, material, raycaster, ray, pA, pB, pC, point ) {
11500
11501 var intersect;
11502
11503 if ( material.side === BackSide ) {
11504
11505 intersect = ray.intersectTriangle( pC, pB, pA, true, point );
11506
11507 } else {
11508
11509 intersect = ray.intersectTriangle( pA, pB, pC, material.side !== DoubleSide, point );
11510
11511 }
11512
11513 if ( intersect === null ) { return null; }
11514
11515 _intersectionPointWorld.copy( point );
11516 _intersectionPointWorld.applyMatrix4( object.matrixWorld );
11517
11518 var distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld );
11519
11520 if ( distance < raycaster.near || distance > raycaster.far ) { return null; }
11521
11522 return {
11523 distance: distance,
11524 point: _intersectionPointWorld.clone(),
11525 object: object
11526 };
11527
11528 }
11529
11530 function checkBufferGeometryIntersection( object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c ) {
11531
11532 _vA.fromBufferAttribute( position, a );
11533 _vB.fromBufferAttribute( position, b );
11534 _vC.fromBufferAttribute( position, c );
11535
11536 var morphInfluences = object.morphTargetInfluences;
11537
11538 if ( material.morphTargets && morphPosition && morphInfluences ) {
11539
11540 _morphA.set( 0, 0, 0 );
11541 _morphB.set( 0, 0, 0 );
11542 _morphC.set( 0, 0, 0 );
11543
11544 for ( var i = 0, il = morphPosition.length; i < il; i ++ ) {
11545
11546 var influence = morphInfluences[ i ];
11547 var morphAttribute = morphPosition[ i ];
11548
11549 if ( influence === 0 ) { continue; }
11550
11551 _tempA.fromBufferAttribute( morphAttribute, a );
11552 _tempB.fromBufferAttribute( morphAttribute, b );
11553 _tempC.fromBufferAttribute( morphAttribute, c );
11554
11555 if ( morphTargetsRelative ) {
11556
11557 _morphA.addScaledVector( _tempA, influence );
11558 _morphB.addScaledVector( _tempB, influence );
11559 _morphC.addScaledVector( _tempC, influence );
11560
11561 } else {
11562
11563 _morphA.addScaledVector( _tempA.sub( _vA ), influence );
11564 _morphB.addScaledVector( _tempB.sub( _vB ), influence );
11565 _morphC.addScaledVector( _tempC.sub( _vC ), influence );
11566
11567 }
11568
11569 }
11570
11571 _vA.add( _morphA );
11572 _vB.add( _morphB );
11573 _vC.add( _morphC );
11574
11575 }
11576
11577 if ( object.isSkinnedMesh ) {
11578
11579 object.boneTransform( a, _vA );
11580 object.boneTransform( b, _vB );
11581 object.boneTransform( c, _vC );
11582
11583 }
11584
11585 var intersection = checkIntersection( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint );
11586
11587 if ( intersection ) {
11588
11589 if ( uv ) {
11590
11591 _uvA.fromBufferAttribute( uv, a );
11592 _uvB.fromBufferAttribute( uv, b );
11593 _uvC.fromBufferAttribute( uv, c );
11594
11595 intersection.uv = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
11596
11597 }
11598
11599 if ( uv2 ) {
11600
11601 _uvA.fromBufferAttribute( uv2, a );
11602 _uvB.fromBufferAttribute( uv2, b );
11603 _uvC.fromBufferAttribute( uv2, c );
11604
11605 intersection.uv2 = Triangle.getUV( _intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() );
11606
11607 }
11608
11609 var face = new Face3( a, b, c );
11610 Triangle.getNormal( _vA, _vB, _vC, face.normal );
11611
11612 intersection.face = face;
11613
11614 }
11615
11616 return intersection;
11617
11618 }
11619
11620 var _geometryId = 0; // Geometry uses even numbers as Id
11621 var _m1$3 = new Matrix4();
11622 var _obj$1 = new Object3D();
11623 var _offset$1 = new Vector3();
11624
11625 function Geometry() {
11626
11627 Object.defineProperty( this, 'id', { value: _geometryId += 2 } );
11628
11629 this.uuid = MathUtils.generateUUID();
11630
11631 this.name = '';
11632 this.type = 'Geometry';
11633
11634 this.vertices = [];
11635 this.colors = [];
11636 this.faces = [];
11637 this.faceVertexUvs = [[]];
11638
11639 this.morphTargets = [];
11640 this.morphNormals = [];
11641
11642 this.skinWeights = [];
11643 this.skinIndices = [];
11644
11645 this.lineDistances = [];
11646
11647 this.boundingBox = null;
11648 this.boundingSphere = null;
11649
11650 // update flags
11651
11652 this.elementsNeedUpdate = false;
11653 this.verticesNeedUpdate = false;
11654 this.uvsNeedUpdate = false;
11655 this.normalsNeedUpdate = false;
11656 this.colorsNeedUpdate = false;
11657 this.lineDistancesNeedUpdate = false;
11658 this.groupsNeedUpdate = false;
11659
11660 }
11661
11662 Geometry.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
11663
11664 constructor: Geometry,
11665
11666 isGeometry: true,
11667
11668 applyMatrix4: function ( matrix ) {
11669
11670 var normalMatrix = new Matrix3().getNormalMatrix( matrix );
11671
11672 for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
11673
11674 var vertex = this.vertices[ i ];
11675 vertex.applyMatrix4( matrix );
11676
11677 }
11678
11679 for ( var i$1 = 0, il$1 = this.faces.length; i$1 < il$1; i$1 ++ ) {
11680
11681 var face = this.faces[ i$1 ];
11682 face.normal.applyMatrix3( normalMatrix ).normalize();
11683
11684 for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
11685
11686 face.vertexNormals[ j ].applyMatrix3( normalMatrix ).normalize();
11687
11688 }
11689
11690 }
11691
11692 if ( this.boundingBox !== null ) {
11693
11694 this.computeBoundingBox();
11695
11696 }
11697
11698 if ( this.boundingSphere !== null ) {
11699
11700 this.computeBoundingSphere();
11701
11702 }
11703
11704 this.verticesNeedUpdate = true;
11705 this.normalsNeedUpdate = true;
11706
11707 return this;
11708
11709 },
11710
11711 rotateX: function ( angle ) {
11712
11713 // rotate geometry around world x-axis
11714
11715 _m1$3.makeRotationX( angle );
11716
11717 this.applyMatrix4( _m1$3 );
11718
11719 return this;
11720
11721 },
11722
11723 rotateY: function ( angle ) {
11724
11725 // rotate geometry around world y-axis
11726
11727 _m1$3.makeRotationY( angle );
11728
11729 this.applyMatrix4( _m1$3 );
11730
11731 return this;
11732
11733 },
11734
11735 rotateZ: function ( angle ) {
11736
11737 // rotate geometry around world z-axis
11738
11739 _m1$3.makeRotationZ( angle );
11740
11741 this.applyMatrix4( _m1$3 );
11742
11743 return this;
11744
11745 },
11746
11747 translate: function ( x, y, z ) {
11748
11749 // translate geometry
11750
11751 _m1$3.makeTranslation( x, y, z );
11752
11753 this.applyMatrix4( _m1$3 );
11754
11755 return this;
11756
11757 },
11758
11759 scale: function ( x, y, z ) {
11760
11761 // scale geometry
11762
11763 _m1$3.makeScale( x, y, z );
11764
11765 this.applyMatrix4( _m1$3 );
11766
11767 return this;
11768
11769 },
11770
11771 lookAt: function ( vector ) {
11772
11773 _obj$1.lookAt( vector );
11774
11775 _obj$1.updateMatrix();
11776
11777 this.applyMatrix4( _obj$1.matrix );
11778
11779 return this;
11780
11781 },
11782
11783 fromBufferGeometry: function ( geometry ) {
11784
11785 var scope = this;
11786
11787 var index = geometry.index !== null ? geometry.index : undefined;
11788 var attributes = geometry.attributes;
11789
11790 if ( attributes.position === undefined ) {
11791
11792 console.error( 'THREE.Geometry.fromBufferGeometry(): Position attribute required for conversion.' );
11793 return this;
11794
11795 }
11796
11797 var position = attributes.position;
11798 var normal = attributes.normal;
11799 var color = attributes.color;
11800 var uv = attributes.uv;
11801 var uv2 = attributes.uv2;
11802
11803 if ( uv2 !== undefined ) { this.faceVertexUvs[ 1 ] = []; }
11804
11805 for ( var i = 0; i < position.count; i ++ ) {
11806
11807 scope.vertices.push( new Vector3().fromBufferAttribute( position, i ) );
11808
11809 if ( color !== undefined ) {
11810
11811 scope.colors.push( new Color().fromBufferAttribute( color, i ) );
11812
11813 }
11814
11815 }
11816
11817 function addFace( a, b, c, materialIndex ) {
11818
11819 var vertexColors = ( color === undefined ) ? [] : [
11820 scope.colors[ a ].clone(),
11821 scope.colors[ b ].clone(),
11822 scope.colors[ c ].clone()
11823 ];
11824
11825 var vertexNormals = ( normal === undefined ) ? [] : [
11826 new Vector3().fromBufferAttribute( normal, a ),
11827 new Vector3().fromBufferAttribute( normal, b ),
11828 new Vector3().fromBufferAttribute( normal, c )
11829 ];
11830
11831 var face = new Face3( a, b, c, vertexNormals, vertexColors, materialIndex );
11832
11833 scope.faces.push( face );
11834
11835 if ( uv !== undefined ) {
11836
11837 scope.faceVertexUvs[ 0 ].push( [
11838 new Vector2().fromBufferAttribute( uv, a ),
11839 new Vector2().fromBufferAttribute( uv, b ),
11840 new Vector2().fromBufferAttribute( uv, c )
11841 ] );
11842
11843 }
11844
11845 if ( uv2 !== undefined ) {
11846
11847 scope.faceVertexUvs[ 1 ].push( [
11848 new Vector2().fromBufferAttribute( uv2, a ),
11849 new Vector2().fromBufferAttribute( uv2, b ),
11850 new Vector2().fromBufferAttribute( uv2, c )
11851 ] );
11852
11853 }
11854
11855 }
11856
11857 var groups = geometry.groups;
11858
11859 if ( groups.length > 0 ) {
11860
11861 for ( var i$1 = 0; i$1 < groups.length; i$1 ++ ) {
11862
11863 var group = groups[ i$1 ];
11864
11865 var start = group.start;
11866 var count = group.count;
11867
11868 for ( var j = start, jl = start + count; j < jl; j += 3 ) {
11869
11870 if ( index !== undefined ) {
11871
11872 addFace( index.getX( j ), index.getX( j + 1 ), index.getX( j + 2 ), group.materialIndex );
11873
11874 } else {
11875
11876 addFace( j, j + 1, j + 2, group.materialIndex );
11877
11878 }
11879
11880 }
11881
11882 }
11883
11884 } else {
11885
11886 if ( index !== undefined ) {
11887
11888 for ( var i$2 = 0; i$2 < index.count; i$2 += 3 ) {
11889
11890 addFace( index.getX( i$2 ), index.getX( i$2 + 1 ), index.getX( i$2 + 2 ) );
11891
11892 }
11893
11894 } else {
11895
11896 for ( var i$3 = 0; i$3 < position.count; i$3 += 3 ) {
11897
11898 addFace( i$3, i$3 + 1, i$3 + 2 );
11899
11900 }
11901
11902 }
11903
11904 }
11905
11906 this.computeFaceNormals();
11907
11908 if ( geometry.boundingBox !== null ) {
11909
11910 this.boundingBox = geometry.boundingBox.clone();
11911
11912 }
11913
11914 if ( geometry.boundingSphere !== null ) {
11915
11916 this.boundingSphere = geometry.boundingSphere.clone();
11917
11918 }
11919
11920 return this;
11921
11922 },
11923
11924 center: function () {
11925
11926 this.computeBoundingBox();
11927
11928 this.boundingBox.getCenter( _offset$1 ).negate();
11929
11930 this.translate( _offset$1.x, _offset$1.y, _offset$1.z );
11931
11932 return this;
11933
11934 },
11935
11936 normalize: function () {
11937
11938 this.computeBoundingSphere();
11939
11940 var center = this.boundingSphere.center;
11941 var radius = this.boundingSphere.radius;
11942
11943 var s = radius === 0 ? 1 : 1.0 / radius;
11944
11945 var matrix = new Matrix4();
11946 matrix.set(
11947 s, 0, 0, - s * center.x,
11948 0, s, 0, - s * center.y,
11949 0, 0, s, - s * center.z,
11950 0, 0, 0, 1
11951 );
11952
11953 this.applyMatrix4( matrix );
11954
11955 return this;
11956
11957 },
11958
11959 computeFaceNormals: function () {
11960
11961 var cb = new Vector3(), ab = new Vector3();
11962
11963 for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
11964
11965 var face = this.faces[ f ];
11966
11967 var vA = this.vertices[ face.a ];
11968 var vB = this.vertices[ face.b ];
11969 var vC = this.vertices[ face.c ];
11970
11971 cb.subVectors( vC, vB );
11972 ab.subVectors( vA, vB );
11973 cb.cross( ab );
11974
11975 cb.normalize();
11976
11977 face.normal.copy( cb );
11978
11979 }
11980
11981 },
11982
11983 computeVertexNormals: function ( areaWeighted ) {
11984
11985 if ( areaWeighted === undefined ) { areaWeighted = true; }
11986
11987 var vertices = new Array( this.vertices.length );
11988
11989 for ( var v = 0, vl = this.vertices.length; v < vl; v ++ ) {
11990
11991 vertices[ v ] = new Vector3();
11992
11993 }
11994
11995 if ( areaWeighted ) {
11996
11997 // vertex normals weighted by triangle areas
11998 // http://www.iquilezles.org/www/articles/normals/normals.htm
11999
12000 var cb = new Vector3(), ab = new Vector3();
12001
12002 for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
12003
12004 var face = this.faces[ f ];
12005
12006 var vA = this.vertices[ face.a ];
12007 var vB = this.vertices[ face.b ];
12008 var vC = this.vertices[ face.c ];
12009
12010 cb.subVectors( vC, vB );
12011 ab.subVectors( vA, vB );
12012 cb.cross( ab );
12013
12014 vertices[ face.a ].add( cb );
12015 vertices[ face.b ].add( cb );
12016 vertices[ face.c ].add( cb );
12017
12018 }
12019
12020 } else {
12021
12022 this.computeFaceNormals();
12023
12024 for ( var f$1 = 0, fl$1 = this.faces.length; f$1 < fl$1; f$1 ++ ) {
12025
12026 var face$1 = this.faces[ f$1 ];
12027
12028 vertices[ face$1.a ].add( face$1.normal );
12029 vertices[ face$1.b ].add( face$1.normal );
12030 vertices[ face$1.c ].add( face$1.normal );
12031
12032 }
12033
12034 }
12035
12036 for ( var v$1 = 0, vl$1 = this.vertices.length; v$1 < vl$1; v$1 ++ ) {
12037
12038 vertices[ v$1 ].normalize();
12039
12040 }
12041
12042 for ( var f$2 = 0, fl$2 = this.faces.length; f$2 < fl$2; f$2 ++ ) {
12043
12044 var face$2 = this.faces[ f$2 ];
12045
12046 var vertexNormals = face$2.vertexNormals;
12047
12048 if ( vertexNormals.length === 3 ) {
12049
12050 vertexNormals[ 0 ].copy( vertices[ face$2.a ] );
12051 vertexNormals[ 1 ].copy( vertices[ face$2.b ] );
12052 vertexNormals[ 2 ].copy( vertices[ face$2.c ] );
12053
12054 } else {
12055
12056 vertexNormals[ 0 ] = vertices[ face$2.a ].clone();
12057 vertexNormals[ 1 ] = vertices[ face$2.b ].clone();
12058 vertexNormals[ 2 ] = vertices[ face$2.c ].clone();
12059
12060 }
12061
12062 }
12063
12064 if ( this.faces.length > 0 ) {
12065
12066 this.normalsNeedUpdate = true;
12067
12068 }
12069
12070 },
12071
12072 computeFlatVertexNormals: function () {
12073
12074 this.computeFaceNormals();
12075
12076 for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
12077
12078 var face = this.faces[ f ];
12079
12080 var vertexNormals = face.vertexNormals;
12081
12082 if ( vertexNormals.length === 3 ) {
12083
12084 vertexNormals[ 0 ].copy( face.normal );
12085 vertexNormals[ 1 ].copy( face.normal );
12086 vertexNormals[ 2 ].copy( face.normal );
12087
12088 } else {
12089
12090 vertexNormals[ 0 ] = face.normal.clone();
12091 vertexNormals[ 1 ] = face.normal.clone();
12092 vertexNormals[ 2 ] = face.normal.clone();
12093
12094 }
12095
12096 }
12097
12098 if ( this.faces.length > 0 ) {
12099
12100 this.normalsNeedUpdate = true;
12101
12102 }
12103
12104 },
12105
12106 computeMorphNormals: function () {
12107
12108 // save original normals
12109 // - create temp variables on first access
12110 // otherwise just copy (for faster repeated calls)
12111
12112 for ( var f = 0, fl = this.faces.length; f < fl; f ++ ) {
12113
12114 var face = this.faces[ f ];
12115
12116 if ( ! face.__originalFaceNormal ) {
12117
12118 face.__originalFaceNormal = face.normal.clone();
12119
12120 } else {
12121
12122 face.__originalFaceNormal.copy( face.normal );
12123
12124 }
12125
12126 if ( ! face.__originalVertexNormals ) { face.__originalVertexNormals = []; }
12127
12128 for ( var i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
12129
12130 if ( ! face.__originalVertexNormals[ i ] ) {
12131
12132 face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
12133
12134 } else {
12135
12136 face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
12137
12138 }
12139
12140 }
12141
12142 }
12143
12144 // use temp geometry to compute face and vertex normals for each morph
12145
12146 var tmpGeo = new Geometry();
12147 tmpGeo.faces = this.faces;
12148
12149 for ( var i$1 = 0, il$1 = this.morphTargets.length; i$1 < il$1; i$1 ++ ) {
12150
12151 // create on first access
12152
12153 if ( ! this.morphNormals[ i$1 ] ) {
12154
12155 this.morphNormals[ i$1 ] = {};
12156 this.morphNormals[ i$1 ].faceNormals = [];
12157 this.morphNormals[ i$1 ].vertexNormals = [];
12158
12159 var dstNormalsFace = this.morphNormals[ i$1 ].faceNormals;
12160 var dstNormalsVertex = this.morphNormals[ i$1 ].vertexNormals;
12161
12162 for ( var f$1 = 0, fl$1 = this.faces.length; f$1 < fl$1; f$1 ++ ) {
12163
12164 var faceNormal = new Vector3();
12165 var vertexNormals = { a: new Vector3(), b: new Vector3(), c: new Vector3() };
12166
12167 dstNormalsFace.push( faceNormal );
12168 dstNormalsVertex.push( vertexNormals );
12169
12170 }
12171
12172 }
12173
12174 var morphNormals = this.morphNormals[ i$1 ];
12175
12176 // set vertices to morph target
12177
12178 tmpGeo.vertices = this.morphTargets[ i$1 ].vertices;
12179
12180 // compute morph normals
12181
12182 tmpGeo.computeFaceNormals();
12183 tmpGeo.computeVertexNormals();
12184
12185 // store morph normals
12186
12187 for ( var f$2 = 0, fl$2 = this.faces.length; f$2 < fl$2; f$2 ++ ) {
12188
12189 var face$1 = this.faces[ f$2 ];
12190
12191 var faceNormal$1 = morphNormals.faceNormals[ f$2 ];
12192 var vertexNormals$1 = morphNormals.vertexNormals[ f$2 ];
12193
12194 faceNormal$1.copy( face$1.normal );
12195
12196 vertexNormals$1.a.copy( face$1.vertexNormals[ 0 ] );
12197 vertexNormals$1.b.copy( face$1.vertexNormals[ 1 ] );
12198 vertexNormals$1.c.copy( face$1.vertexNormals[ 2 ] );
12199
12200 }
12201
12202 }
12203
12204 // restore original normals
12205
12206 for ( var f$3 = 0, fl$3 = this.faces.length; f$3 < fl$3; f$3 ++ ) {
12207
12208 var face$2 = this.faces[ f$3 ];
12209
12210 face$2.normal = face$2.__originalFaceNormal;
12211 face$2.vertexNormals = face$2.__originalVertexNormals;
12212
12213 }
12214
12215 },
12216
12217 computeBoundingBox: function () {
12218
12219 if ( this.boundingBox === null ) {
12220
12221 this.boundingBox = new Box3();
12222
12223 }
12224
12225 this.boundingBox.setFromPoints( this.vertices );
12226
12227 },
12228
12229 computeBoundingSphere: function () {
12230
12231 if ( this.boundingSphere === null ) {
12232
12233 this.boundingSphere = new Sphere();
12234
12235 }
12236
12237 this.boundingSphere.setFromPoints( this.vertices );
12238
12239 },
12240
12241 merge: function ( geometry, matrix, materialIndexOffset ) {
12242
12243 if ( ! ( geometry && geometry.isGeometry ) ) {
12244
12245 console.error( 'THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.', geometry );
12246 return;
12247
12248 }
12249
12250 var normalMatrix,
12251 vertexOffset = this.vertices.length,
12252 vertices1 = this.vertices,
12253 vertices2 = geometry.vertices,
12254 faces1 = this.faces,
12255 faces2 = geometry.faces,
12256 colors1 = this.colors,
12257 colors2 = geometry.colors;
12258
12259 if ( materialIndexOffset === undefined ) { materialIndexOffset = 0; }
12260
12261 if ( matrix !== undefined ) {
12262
12263 normalMatrix = new Matrix3().getNormalMatrix( matrix );
12264
12265 }
12266
12267 // vertices
12268
12269 for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
12270
12271 var vertex = vertices2[ i ];
12272
12273 var vertexCopy = vertex.clone();
12274
12275 if ( matrix !== undefined ) { vertexCopy.applyMatrix4( matrix ); }
12276
12277 vertices1.push( vertexCopy );
12278
12279 }
12280
12281 // colors
12282
12283 for ( var i$1 = 0, il$1 = colors2.length; i$1 < il$1; i$1 ++ ) {
12284
12285 colors1.push( colors2[ i$1 ].clone() );
12286
12287 }
12288
12289 // faces
12290
12291 for ( var i$2 = 0, il$2 = faces2.length; i$2 < il$2; i$2 ++ ) {
12292
12293 var face = faces2[ i$2 ], faceCopy = (void 0), normal = (void 0), color = (void 0),
12294 faceVertexNormals = face.vertexNormals,
12295 faceVertexColors = face.vertexColors;
12296
12297 faceCopy = new Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
12298 faceCopy.normal.copy( face.normal );
12299
12300 if ( normalMatrix !== undefined ) {
12301
12302 faceCopy.normal.applyMatrix3( normalMatrix ).normalize();
12303
12304 }
12305
12306 for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
12307
12308 normal = faceVertexNormals[ j ].clone();
12309
12310 if ( normalMatrix !== undefined ) {
12311
12312 normal.applyMatrix3( normalMatrix ).normalize();
12313
12314 }
12315
12316 faceCopy.vertexNormals.push( normal );
12317
12318 }
12319
12320 faceCopy.color.copy( face.color );
12321
12322 for ( var j$1 = 0, jl$1 = faceVertexColors.length; j$1 < jl$1; j$1 ++ ) {
12323
12324 color = faceVertexColors[ j$1 ];
12325 faceCopy.vertexColors.push( color.clone() );
12326
12327 }
12328
12329 faceCopy.materialIndex = face.materialIndex + materialIndexOffset;
12330
12331 faces1.push( faceCopy );
12332
12333 }
12334
12335 // uvs
12336
12337 for ( var i$3 = 0, il$3 = geometry.faceVertexUvs.length; i$3 < il$3; i$3 ++ ) {
12338
12339 var faceVertexUvs2 = geometry.faceVertexUvs[ i$3 ];
12340
12341 if ( this.faceVertexUvs[ i$3 ] === undefined ) { this.faceVertexUvs[ i$3 ] = []; }
12342
12343 for ( var j$2 = 0, jl$2 = faceVertexUvs2.length; j$2 < jl$2; j$2 ++ ) {
12344
12345 var uvs2 = faceVertexUvs2[ j$2 ], uvsCopy = [];
12346
12347 for ( var k = 0, kl = uvs2.length; k < kl; k ++ ) {
12348
12349 uvsCopy.push( uvs2[ k ].clone() );
12350
12351 }
12352
12353 this.faceVertexUvs[ i$3 ].push( uvsCopy );
12354
12355 }
12356
12357 }
12358
12359 },
12360
12361 mergeMesh: function ( mesh ) {
12362
12363 if ( ! ( mesh && mesh.isMesh ) ) {
12364
12365 console.error( 'THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.', mesh );
12366 return;
12367
12368 }
12369
12370 if ( mesh.matrixAutoUpdate ) { mesh.updateMatrix(); }
12371
12372 this.merge( mesh.geometry, mesh.matrix );
12373
12374 },
12375
12376 /*
12377 * Checks for duplicate vertices with hashmap.
12378 * Duplicated vertices are removed
12379 * and faces' vertices are updated.
12380 */
12381
12382 mergeVertices: function () {
12383
12384 var verticesMap = {}; // Hashmap for looking up vertices by position coordinates (and making sure they are unique)
12385 var unique = [], changes = [];
12386
12387 var precisionPoints = 4; // number of decimal points, e.g. 4 for epsilon of 0.0001
12388 var precision = Math.pow( 10, precisionPoints );
12389
12390 for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
12391
12392 var v = this.vertices[ i ];
12393 var key = Math.round( v.x * precision ) + '_' + Math.round( v.y * precision ) + '_' + Math.round( v.z * precision );
12394
12395 if ( verticesMap[ key ] === undefined ) {
12396
12397 verticesMap[ key ] = i;
12398 unique.push( this.vertices[ i ] );
12399 changes[ i ] = unique.length - 1;
12400
12401 } else {
12402
12403 //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
12404 changes[ i ] = changes[ verticesMap[ key ] ];
12405
12406 }
12407
12408 }
12409
12410
12411 // if faces are completely degenerate after merging vertices, we
12412 // have to remove them from the geometry.
12413 var faceIndicesToRemove = [];
12414
12415 for ( var i$1 = 0, il$1 = this.faces.length; i$1 < il$1; i$1 ++ ) {
12416
12417 var face = this.faces[ i$1 ];
12418
12419 face.a = changes[ face.a ];
12420 face.b = changes[ face.b ];
12421 face.c = changes[ face.c ];
12422
12423 var indices = [ face.a, face.b, face.c ];
12424
12425 // if any duplicate vertices are found in a Face3
12426 // we have to remove the face as nothing can be saved
12427 for ( var n = 0; n < 3; n ++ ) {
12428
12429 if ( indices[ n ] === indices[ ( n + 1 ) % 3 ] ) {
12430
12431 faceIndicesToRemove.push( i$1 );
12432 break;
12433
12434 }
12435
12436 }
12437
12438 }
12439
12440 for ( var i$2 = faceIndicesToRemove.length - 1; i$2 >= 0; i$2 -- ) {
12441
12442 var idx = faceIndicesToRemove[ i$2 ];
12443
12444 this.faces.splice( idx, 1 );
12445
12446 for ( var j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
12447
12448 this.faceVertexUvs[ j ].splice( idx, 1 );
12449
12450 }
12451
12452 }
12453
12454 // Use unique set of vertices
12455
12456 var diff = this.vertices.length - unique.length;
12457 this.vertices = unique;
12458 return diff;
12459
12460 },
12461
12462 setFromPoints: function ( points ) {
12463
12464 this.vertices = [];
12465
12466 for ( var i = 0, l = points.length; i < l; i ++ ) {
12467
12468 var point = points[ i ];
12469 this.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
12470
12471 }
12472
12473 return this;
12474
12475 },
12476
12477 sortFacesByMaterialIndex: function () {
12478
12479 var faces = this.faces;
12480 var length = faces.length;
12481
12482 // tag faces
12483
12484 for ( var i = 0; i < length; i ++ ) {
12485
12486 faces[ i ]._id = i;
12487
12488 }
12489
12490 // sort faces
12491
12492 function materialIndexSort( a, b ) {
12493
12494 return a.materialIndex - b.materialIndex;
12495
12496 }
12497
12498 faces.sort( materialIndexSort );
12499
12500 // sort uvs
12501
12502 var uvs1 = this.faceVertexUvs[ 0 ];
12503 var uvs2 = this.faceVertexUvs[ 1 ];
12504
12505 var newUvs1, newUvs2;
12506
12507 if ( uvs1 && uvs1.length === length ) { newUvs1 = []; }
12508 if ( uvs2 && uvs2.length === length ) { newUvs2 = []; }
12509
12510 for ( var i$1 = 0; i$1 < length; i$1 ++ ) {
12511
12512 var id = faces[ i$1 ]._id;
12513
12514 if ( newUvs1 ) { newUvs1.push( uvs1[ id ] ); }
12515 if ( newUvs2 ) { newUvs2.push( uvs2[ id ] ); }
12516
12517 }
12518
12519 if ( newUvs1 ) { this.faceVertexUvs[ 0 ] = newUvs1; }
12520 if ( newUvs2 ) { this.faceVertexUvs[ 1 ] = newUvs2; }
12521
12522 },
12523
12524 toJSON: function () {
12525
12526 var data = {
12527 metadata: {
12528 version: 4.5,
12529 type: 'Geometry',
12530 generator: 'Geometry.toJSON'
12531 }
12532 };
12533
12534 // standard Geometry serialization
12535
12536 data.uuid = this.uuid;
12537 data.type = this.type;
12538 if ( this.name !== '' ) { data.name = this.name; }
12539
12540 if ( this.parameters !== undefined ) {
12541
12542 var parameters = this.parameters;
12543
12544 for ( var key in parameters ) {
12545
12546 if ( parameters[ key ] !== undefined ) { data[ key ] = parameters[ key ]; }
12547
12548 }
12549
12550 return data;
12551
12552 }
12553
12554 var vertices = [];
12555
12556 for ( var i = 0; i < this.vertices.length; i ++ ) {
12557
12558 var vertex = this.vertices[ i ];
12559 vertices.push( vertex.x, vertex.y, vertex.z );
12560
12561 }
12562
12563 var faces = [];
12564 var normals = [];
12565 var normalsHash = {};
12566 var colors = [];
12567 var colorsHash = {};
12568 var uvs = [];
12569 var uvsHash = {};
12570
12571 for ( var i$1 = 0; i$1 < this.faces.length; i$1 ++ ) {
12572
12573 var face = this.faces[ i$1 ];
12574
12575 var hasMaterial = true;
12576 var hasFaceUv = false; // deprecated
12577 var hasFaceVertexUv = this.faceVertexUvs[ 0 ][ i$1 ] !== undefined;
12578 var hasFaceNormal = face.normal.length() > 0;
12579 var hasFaceVertexNormal = face.vertexNormals.length > 0;
12580 var hasFaceColor = face.color.r !== 1 || face.color.g !== 1 || face.color.b !== 1;
12581 var hasFaceVertexColor = face.vertexColors.length > 0;
12582
12583 var faceType = 0;
12584
12585 faceType = setBit( faceType, 0, 0 ); // isQuad
12586 faceType = setBit( faceType, 1, hasMaterial );
12587 faceType = setBit( faceType, 2, hasFaceUv );
12588 faceType = setBit( faceType, 3, hasFaceVertexUv );
12589 faceType = setBit( faceType, 4, hasFaceNormal );
12590 faceType = setBit( faceType, 5, hasFaceVertexNormal );
12591 faceType = setBit( faceType, 6, hasFaceColor );
12592 faceType = setBit( faceType, 7, hasFaceVertexColor );
12593
12594 faces.push( faceType );
12595 faces.push( face.a, face.b, face.c );
12596 faces.push( face.materialIndex );
12597
12598 if ( hasFaceVertexUv ) {
12599
12600 var faceVertexUvs = this.faceVertexUvs[ 0 ][ i$1 ];
12601
12602 faces.push(
12603 getUvIndex( faceVertexUvs[ 0 ] ),
12604 getUvIndex( faceVertexUvs[ 1 ] ),
12605 getUvIndex( faceVertexUvs[ 2 ] )
12606 );
12607
12608 }
12609
12610 if ( hasFaceNormal ) {
12611
12612 faces.push( getNormalIndex( face.normal ) );
12613
12614 }
12615
12616 if ( hasFaceVertexNormal ) {
12617
12618 var vertexNormals = face.vertexNormals;
12619
12620 faces.push(
12621 getNormalIndex( vertexNormals[ 0 ] ),
12622 getNormalIndex( vertexNormals[ 1 ] ),
12623 getNormalIndex( vertexNormals[ 2 ] )
12624 );
12625
12626 }
12627
12628 if ( hasFaceColor ) {
12629
12630 faces.push( getColorIndex( face.color ) );
12631
12632 }
12633
12634 if ( hasFaceVertexColor ) {
12635
12636 var vertexColors = face.vertexColors;
12637
12638 faces.push(
12639 getColorIndex( vertexColors[ 0 ] ),
12640 getColorIndex( vertexColors[ 1 ] ),
12641 getColorIndex( vertexColors[ 2 ] )
12642 );
12643
12644 }
12645
12646 }
12647
12648 function setBit( value, position, enabled ) {
12649
12650 return enabled ? value | ( 1 << position ) : value & ( ~ ( 1 << position ) );
12651
12652 }
12653
12654 function getNormalIndex( normal ) {
12655
12656 var hash = normal.x.toString() + normal.y.toString() + normal.z.toString();
12657
12658 if ( normalsHash[ hash ] !== undefined ) {
12659
12660 return normalsHash[ hash ];
12661
12662 }
12663
12664 normalsHash[ hash ] = normals.length / 3;
12665 normals.push( normal.x, normal.y, normal.z );
12666
12667 return normalsHash[ hash ];
12668
12669 }
12670
12671 function getColorIndex( color ) {
12672
12673 var hash = color.r.toString() + color.g.toString() + color.b.toString();
12674
12675 if ( colorsHash[ hash ] !== undefined ) {
12676
12677 return colorsHash[ hash ];
12678
12679 }
12680
12681 colorsHash[ hash ] = colors.length;
12682 colors.push( color.getHex() );
12683
12684 return colorsHash[ hash ];
12685
12686 }
12687
12688 function getUvIndex( uv ) {
12689
12690 var hash = uv.x.toString() + uv.y.toString();
12691
12692 if ( uvsHash[ hash ] !== undefined ) {
12693
12694 return uvsHash[ hash ];
12695
12696 }
12697
12698 uvsHash[ hash ] = uvs.length / 2;
12699 uvs.push( uv.x, uv.y );
12700
12701 return uvsHash[ hash ];
12702
12703 }
12704
12705 data.data = {};
12706
12707 data.data.vertices = vertices;
12708 data.data.normals = normals;
12709 if ( colors.length > 0 ) { data.data.colors = colors; }
12710 if ( uvs.length > 0 ) { data.data.uvs = [ uvs ]; } // temporal backward compatibility
12711 data.data.faces = faces;
12712
12713 return data;
12714
12715 },
12716
12717 clone: function () {
12718
12719 /*
12720 // Handle primitives
12721
12722 const parameters = this.parameters;
12723
12724 if ( parameters !== undefined ) {
12725
12726 const values = [];
12727
12728 for ( const key in parameters ) {
12729
12730 values.push( parameters[ key ] );
12731
12732 }
12733
12734 const geometry = Object.create( this.constructor.prototype );
12735 this.constructor.apply( geometry, values );
12736 return geometry;
12737
12738 }
12739
12740 return new this.constructor().copy( this );
12741 */
12742
12743 return new Geometry().copy( this );
12744
12745 },
12746
12747 copy: function ( source ) {
12748
12749 // reset
12750
12751 this.vertices = [];
12752 this.colors = [];
12753 this.faces = [];
12754 this.faceVertexUvs = [[]];
12755 this.morphTargets = [];
12756 this.morphNormals = [];
12757 this.skinWeights = [];
12758 this.skinIndices = [];
12759 this.lineDistances = [];
12760 this.boundingBox = null;
12761 this.boundingSphere = null;
12762
12763 // name
12764
12765 this.name = source.name;
12766
12767 // vertices
12768
12769 var vertices = source.vertices;
12770
12771 for ( var i = 0, il = vertices.length; i < il; i ++ ) {
12772
12773 this.vertices.push( vertices[ i ].clone() );
12774
12775 }
12776
12777 // colors
12778
12779 var colors = source.colors;
12780
12781 for ( var i$1 = 0, il$1 = colors.length; i$1 < il$1; i$1 ++ ) {
12782
12783 this.colors.push( colors[ i$1 ].clone() );
12784
12785 }
12786
12787 // faces
12788
12789 var faces = source.faces;
12790
12791 for ( var i$2 = 0, il$2 = faces.length; i$2 < il$2; i$2 ++ ) {
12792
12793 this.faces.push( faces[ i$2 ].clone() );
12794
12795 }
12796
12797 // face vertex uvs
12798
12799 for ( var i$3 = 0, il$3 = source.faceVertexUvs.length; i$3 < il$3; i$3 ++ ) {
12800
12801 var faceVertexUvs = source.faceVertexUvs[ i$3 ];
12802
12803 if ( this.faceVertexUvs[ i$3 ] === undefined ) {
12804
12805 this.faceVertexUvs[ i$3 ] = [];
12806
12807 }
12808
12809 for ( var j = 0, jl = faceVertexUvs.length; j < jl; j ++ ) {
12810
12811 var uvs = faceVertexUvs[ j ], uvsCopy = [];
12812
12813 for ( var k = 0, kl = uvs.length; k < kl; k ++ ) {
12814
12815 var uv = uvs[ k ];
12816
12817 uvsCopy.push( uv.clone() );
12818
12819 }
12820
12821 this.faceVertexUvs[ i$3 ].push( uvsCopy );
12822
12823 }
12824
12825 }
12826
12827 // morph targets
12828
12829 var morphTargets = source.morphTargets;
12830
12831 for ( var i$4 = 0, il$4 = morphTargets.length; i$4 < il$4; i$4 ++ ) {
12832
12833 var morphTarget = {};
12834 morphTarget.name = morphTargets[ i$4 ].name;
12835
12836 // vertices
12837
12838 if ( morphTargets[ i$4 ].vertices !== undefined ) {
12839
12840 morphTarget.vertices = [];
12841
12842 for ( var j$1 = 0, jl$1 = morphTargets[ i$4 ].vertices.length; j$1 < jl$1; j$1 ++ ) {
12843
12844 morphTarget.vertices.push( morphTargets[ i$4 ].vertices[ j$1 ].clone() );
12845
12846 }
12847
12848 }
12849
12850 // normals
12851
12852 if ( morphTargets[ i$4 ].normals !== undefined ) {
12853
12854 morphTarget.normals = [];
12855
12856 for ( var j$2 = 0, jl$2 = morphTargets[ i$4 ].normals.length; j$2 < jl$2; j$2 ++ ) {
12857
12858 morphTarget.normals.push( morphTargets[ i$4 ].normals[ j$2 ].clone() );
12859
12860 }
12861
12862 }
12863
12864 this.morphTargets.push( morphTarget );
12865
12866 }
12867
12868 // morph normals
12869
12870 var morphNormals = source.morphNormals;
12871
12872 for ( var i$5 = 0, il$5 = morphNormals.length; i$5 < il$5; i$5 ++ ) {
12873
12874 var morphNormal = {};
12875
12876 // vertex normals
12877
12878 if ( morphNormals[ i$5 ].vertexNormals !== undefined ) {
12879
12880 morphNormal.vertexNormals = [];
12881
12882 for ( var j$3 = 0, jl$3 = morphNormals[ i$5 ].vertexNormals.length; j$3 < jl$3; j$3 ++ ) {
12883
12884 var srcVertexNormal = morphNormals[ i$5 ].vertexNormals[ j$3 ];
12885 var destVertexNormal = {};
12886
12887 destVertexNormal.a = srcVertexNormal.a.clone();
12888 destVertexNormal.b = srcVertexNormal.b.clone();
12889 destVertexNormal.c = srcVertexNormal.c.clone();
12890
12891 morphNormal.vertexNormals.push( destVertexNormal );
12892
12893 }
12894
12895 }
12896
12897 // face normals
12898
12899 if ( morphNormals[ i$5 ].faceNormals !== undefined ) {
12900
12901 morphNormal.faceNormals = [];
12902
12903 for ( var j$4 = 0, jl$4 = morphNormals[ i$5 ].faceNormals.length; j$4 < jl$4; j$4 ++ ) {
12904
12905 morphNormal.faceNormals.push( morphNormals[ i$5 ].faceNormals[ j$4 ].clone() );
12906
12907 }
12908
12909 }
12910
12911 this.morphNormals.push( morphNormal );
12912
12913 }
12914
12915 // skin weights
12916
12917 var skinWeights = source.skinWeights;
12918
12919 for ( var i$6 = 0, il$6 = skinWeights.length; i$6 < il$6; i$6 ++ ) {
12920
12921 this.skinWeights.push( skinWeights[ i$6 ].clone() );
12922
12923 }
12924
12925 // skin indices
12926
12927 var skinIndices = source.skinIndices;
12928
12929 for ( var i$7 = 0, il$7 = skinIndices.length; i$7 < il$7; i$7 ++ ) {
12930
12931 this.skinIndices.push( skinIndices[ i$7 ].clone() );
12932
12933 }
12934
12935 // line distances
12936
12937 var lineDistances = source.lineDistances;
12938
12939 for ( var i$8 = 0, il$8 = lineDistances.length; i$8 < il$8; i$8 ++ ) {
12940
12941 this.lineDistances.push( lineDistances[ i$8 ] );
12942
12943 }
12944
12945 // bounding box
12946
12947 var boundingBox = source.boundingBox;
12948
12949 if ( boundingBox !== null ) {
12950
12951 this.boundingBox = boundingBox.clone();
12952
12953 }
12954
12955 // bounding sphere
12956
12957 var boundingSphere = source.boundingSphere;
12958
12959 if ( boundingSphere !== null ) {
12960
12961 this.boundingSphere = boundingSphere.clone();
12962
12963 }
12964
12965 // update flags
12966
12967 this.elementsNeedUpdate = source.elementsNeedUpdate;
12968 this.verticesNeedUpdate = source.verticesNeedUpdate;
12969 this.uvsNeedUpdate = source.uvsNeedUpdate;
12970 this.normalsNeedUpdate = source.normalsNeedUpdate;
12971 this.colorsNeedUpdate = source.colorsNeedUpdate;
12972 this.lineDistancesNeedUpdate = source.lineDistancesNeedUpdate;
12973 this.groupsNeedUpdate = source.groupsNeedUpdate;
12974
12975 return this;
12976
12977 },
12978
12979 dispose: function () {
12980
12981 this.dispatchEvent( { type: 'dispose' } );
12982
12983 }
12984
12985 } );
12986
12987 // BoxGeometry
12988
12989 function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
12990
12991 Geometry.call(this);
12992
12993 this.type = 'BoxGeometry';
12994
12995 this.parameters = {
12996 width: width,
12997 height: height,
12998 depth: depth,
12999 widthSegments: widthSegments,
13000 heightSegments: heightSegments,
13001 depthSegments: depthSegments
13002 };
13003
13004 this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
13005 this.mergeVertices();
13006
13007 }
13008
13009 BoxGeometry.prototype = Object.create( Geometry.prototype );
13010 BoxGeometry.prototype.constructor = BoxGeometry;
13011
13012 // BoxBufferGeometry
13013
13014 function BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
13015 if ( width === void 0 ) width = 1;
13016 if ( height === void 0 ) height = 1;
13017 if ( depth === void 0 ) depth = 1;
13018 if ( widthSegments === void 0 ) widthSegments = 1;
13019 if ( heightSegments === void 0 ) heightSegments = 1;
13020 if ( depthSegments === void 0 ) depthSegments = 1;
13021
13022
13023 BufferGeometry.call(this);
13024
13025 this.type = 'BoxBufferGeometry';
13026
13027 this.parameters = {
13028 width: width,
13029 height: height,
13030 depth: depth,
13031 widthSegments: widthSegments,
13032 heightSegments: heightSegments,
13033 depthSegments: depthSegments
13034 };
13035
13036 var scope = this;
13037
13038 // segments
13039
13040 widthSegments = Math.floor( widthSegments );
13041 heightSegments = Math.floor( heightSegments );
13042 depthSegments = Math.floor( depthSegments );
13043
13044 // buffers
13045
13046 var indices = [];
13047 var vertices = [];
13048 var normals = [];
13049 var uvs = [];
13050
13051 // helper variables
13052
13053 var numberOfVertices = 0;
13054 var groupStart = 0;
13055
13056 // build each side of the box geometry
13057
13058 buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
13059 buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
13060 buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
13061 buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
13062 buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
13063 buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
13064
13065 // build geometry
13066
13067 this.setIndex( indices );
13068 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
13069 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
13070 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
13071
13072 function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
13073
13074 var segmentWidth = width / gridX;
13075 var segmentHeight = height / gridY;
13076
13077 var widthHalf = width / 2;
13078 var heightHalf = height / 2;
13079 var depthHalf = depth / 2;
13080
13081 var gridX1 = gridX + 1;
13082 var gridY1 = gridY + 1;
13083
13084 var vertexCounter = 0;
13085 var groupCount = 0;
13086
13087 var vector = new Vector3();
13088
13089 // generate vertices, normals and uvs
13090
13091 for ( var iy = 0; iy < gridY1; iy ++ ) {
13092
13093 var y = iy * segmentHeight - heightHalf;
13094
13095 for ( var ix = 0; ix < gridX1; ix ++ ) {
13096
13097 var x = ix * segmentWidth - widthHalf;
13098
13099 // set values to correct vector component
13100
13101 vector[ u ] = x * udir;
13102 vector[ v ] = y * vdir;
13103 vector[ w ] = depthHalf;
13104
13105 // now apply vector to vertex buffer
13106
13107 vertices.push( vector.x, vector.y, vector.z );
13108
13109 // set values to correct vector component
13110
13111 vector[ u ] = 0;
13112 vector[ v ] = 0;
13113 vector[ w ] = depth > 0 ? 1 : - 1;
13114
13115 // now apply vector to normal buffer
13116
13117 normals.push( vector.x, vector.y, vector.z );
13118
13119 // uvs
13120
13121 uvs.push( ix / gridX );
13122 uvs.push( 1 - ( iy / gridY ) );
13123
13124 // counters
13125
13126 vertexCounter += 1;
13127
13128 }
13129
13130 }
13131
13132 // indices
13133
13134 // 1. you need three indices to draw a single face
13135 // 2. a single segment consists of two faces
13136 // 3. so we need to generate six (2*3) indices per segment
13137
13138 for ( var iy$1 = 0; iy$1 < gridY; iy$1 ++ ) {
13139
13140 for ( var ix$1 = 0; ix$1 < gridX; ix$1 ++ ) {
13141
13142 var a = numberOfVertices + ix$1 + gridX1 * iy$1;
13143 var b = numberOfVertices + ix$1 + gridX1 * ( iy$1 + 1 );
13144 var c = numberOfVertices + ( ix$1 + 1 ) + gridX1 * ( iy$1 + 1 );
13145 var d = numberOfVertices + ( ix$1 + 1 ) + gridX1 * iy$1;
13146
13147 // faces
13148
13149 indices.push( a, b, d );
13150 indices.push( b, c, d );
13151
13152 // increase counter
13153
13154 groupCount += 6;
13155
13156 }
13157
13158 }
13159
13160 // add a group to the geometry. this will ensure multi material support
13161
13162 scope.addGroup( groupStart, groupCount, materialIndex );
13163
13164 // calculate new start value for groups
13165
13166 groupStart += groupCount;
13167
13168 // update total number of vertices
13169
13170 numberOfVertices += vertexCounter;
13171
13172 }
13173
13174 }
13175
13176 BoxBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
13177 BoxBufferGeometry.prototype.constructor = BoxBufferGeometry;
13178
13179 /**
13180 * Uniform Utilities
13181 */
13182
13183 function cloneUniforms( src ) {
13184
13185 var dst = {};
13186
13187 for ( var u in src ) {
13188
13189 dst[ u ] = {};
13190
13191 for ( var p in src[ u ] ) {
13192
13193 var property = src[ u ][ p ];
13194
13195 if ( property && ( property.isColor ||
13196 property.isMatrix3 || property.isMatrix4 ||
13197 property.isVector2 || property.isVector3 || property.isVector4 ||
13198 property.isTexture ) ) {
13199
13200 dst[ u ][ p ] = property.clone();
13201
13202 } else if ( Array.isArray( property ) ) {
13203
13204 dst[ u ][ p ] = property.slice();
13205
13206 } else {
13207
13208 dst[ u ][ p ] = property;
13209
13210 }
13211
13212 }
13213
13214 }
13215
13216 return dst;
13217
13218 }
13219
13220 function mergeUniforms( uniforms ) {
13221
13222 var merged = {};
13223
13224 for ( var u = 0; u < uniforms.length; u ++ ) {
13225
13226 var tmp = cloneUniforms( uniforms[ u ] );
13227
13228 for ( var p in tmp ) {
13229
13230 merged[ p ] = tmp[ p ];
13231
13232 }
13233
13234 }
13235
13236 return merged;
13237
13238 }
13239
13240 // Legacy
13241
13242 var UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms };
13243
13244 var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
13245
13246 var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";
13247
13248 /**
13249 * parameters = {
13250 * defines: { "label" : "value" },
13251 * uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
13252 *
13253 * fragmentShader: <string>,
13254 * vertexShader: <string>,
13255 *
13256 * wireframe: <boolean>,
13257 * wireframeLinewidth: <float>,
13258 *
13259 * lights: <bool>,
13260 *
13261 * skinning: <bool>,
13262 * morphTargets: <bool>,
13263 * morphNormals: <bool>
13264 * }
13265 */
13266
13267 function ShaderMaterial( parameters ) {
13268
13269 Material.call( this );
13270
13271 this.type = 'ShaderMaterial';
13272
13273 this.defines = {};
13274 this.uniforms = {};
13275
13276 this.vertexShader = default_vertex;
13277 this.fragmentShader = default_fragment;
13278
13279 this.linewidth = 1;
13280
13281 this.wireframe = false;
13282 this.wireframeLinewidth = 1;
13283
13284 this.fog = false; // set to use scene fog
13285 this.lights = false; // set to use scene lights
13286 this.clipping = false; // set to use user-defined clipping planes
13287
13288 this.skinning = false; // set to use skinning attribute streams
13289 this.morphTargets = false; // set to use morph targets
13290 this.morphNormals = false; // set to use morph normals
13291
13292 this.extensions = {
13293 derivatives: false, // set to use derivatives
13294 fragDepth: false, // set to use fragment depth values
13295 drawBuffers: false, // set to use draw buffers
13296 shaderTextureLOD: false // set to use shader texture LOD
13297 };
13298
13299 // When rendered geometry doesn't include these attributes but the material does,
13300 // use these default values in WebGL. This avoids errors when buffer data is missing.
13301 this.defaultAttributeValues = {
13302 'color': [ 1, 1, 1 ],
13303 'uv': [ 0, 0 ],
13304 'uv2': [ 0, 0 ]
13305 };
13306
13307 this.index0AttributeName = undefined;
13308 this.uniformsNeedUpdate = false;
13309
13310 if ( parameters !== undefined ) {
13311
13312 if ( parameters.attributes !== undefined ) {
13313
13314 console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );
13315
13316 }
13317
13318 this.setValues( parameters );
13319
13320 }
13321
13322 }
13323
13324 ShaderMaterial.prototype = Object.create( Material.prototype );
13325 ShaderMaterial.prototype.constructor = ShaderMaterial;
13326
13327 ShaderMaterial.prototype.isShaderMaterial = true;
13328
13329 ShaderMaterial.prototype.copy = function ( source ) {
13330
13331 Material.prototype.copy.call( this, source );
13332
13333 this.fragmentShader = source.fragmentShader;
13334 this.vertexShader = source.vertexShader;
13335
13336 this.uniforms = cloneUniforms( source.uniforms );
13337
13338 this.defines = Object.assign( {}, source.defines );
13339
13340 this.wireframe = source.wireframe;
13341 this.wireframeLinewidth = source.wireframeLinewidth;
13342
13343 this.lights = source.lights;
13344 this.clipping = source.clipping;
13345
13346 this.skinning = source.skinning;
13347
13348 this.morphTargets = source.morphTargets;
13349 this.morphNormals = source.morphNormals;
13350
13351 this.extensions = Object.assign( {}, source.extensions );
13352
13353 return this;
13354
13355 };
13356
13357 ShaderMaterial.prototype.toJSON = function ( meta ) {
13358
13359 var data = Material.prototype.toJSON.call( this, meta );
13360
13361 data.uniforms = {};
13362
13363 for ( var name in this.uniforms ) {
13364
13365 var uniform = this.uniforms[ name ];
13366 var value = uniform.value;
13367
13368 if ( value && value.isTexture ) {
13369
13370 data.uniforms[ name ] = {
13371 type: 't',
13372 value: value.toJSON( meta ).uuid
13373 };
13374
13375 } else if ( value && value.isColor ) {
13376
13377 data.uniforms[ name ] = {
13378 type: 'c',
13379 value: value.getHex()
13380 };
13381
13382 } else if ( value && value.isVector2 ) {
13383
13384 data.uniforms[ name ] = {
13385 type: 'v2',
13386 value: value.toArray()
13387 };
13388
13389 } else if ( value && value.isVector3 ) {
13390
13391 data.uniforms[ name ] = {
13392 type: 'v3',
13393 value: value.toArray()
13394 };
13395
13396 } else if ( value && value.isVector4 ) {
13397
13398 data.uniforms[ name ] = {
13399 type: 'v4',
13400 value: value.toArray()
13401 };
13402
13403 } else if ( value && value.isMatrix3 ) {
13404
13405 data.uniforms[ name ] = {
13406 type: 'm3',
13407 value: value.toArray()
13408 };
13409
13410 } else if ( value && value.isMatrix4 ) {
13411
13412 data.uniforms[ name ] = {
13413 type: 'm4',
13414 value: value.toArray()
13415 };
13416
13417 } else {
13418
13419 data.uniforms[ name ] = {
13420 value: value
13421 };
13422
13423 // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far
13424
13425 }
13426
13427 }
13428
13429 if ( Object.keys( this.defines ).length > 0 ) { data.defines = this.defines; }
13430
13431 data.vertexShader = this.vertexShader;
13432 data.fragmentShader = this.fragmentShader;
13433
13434 var extensions = {};
13435
13436 for ( var key in this.extensions ) {
13437
13438 if ( this.extensions[ key ] === true ) { extensions[ key ] = true; }
13439
13440 }
13441
13442 if ( Object.keys( extensions ).length > 0 ) { data.extensions = extensions; }
13443
13444 return data;
13445
13446 };
13447
13448 function Camera() {
13449
13450 Object3D.call( this );
13451
13452 this.type = 'Camera';
13453
13454 this.matrixWorldInverse = new Matrix4();
13455
13456 this.projectionMatrix = new Matrix4();
13457 this.projectionMatrixInverse = new Matrix4();
13458
13459 }
13460
13461 Camera.prototype = Object.assign( Object.create( Object3D.prototype ), {
13462
13463 constructor: Camera,
13464
13465 isCamera: true,
13466
13467 copy: function ( source, recursive ) {
13468
13469 Object3D.prototype.copy.call( this, source, recursive );
13470
13471 this.matrixWorldInverse.copy( source.matrixWorldInverse );
13472
13473 this.projectionMatrix.copy( source.projectionMatrix );
13474 this.projectionMatrixInverse.copy( source.projectionMatrixInverse );
13475
13476 return this;
13477
13478 },
13479
13480 getWorldDirection: function ( target ) {
13481
13482 if ( target === undefined ) {
13483
13484 console.warn( 'THREE.Camera: .getWorldDirection() target is now required' );
13485 target = new Vector3();
13486
13487 }
13488
13489 this.updateMatrixWorld( true );
13490
13491 var e = this.matrixWorld.elements;
13492
13493 return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize();
13494
13495 },
13496
13497 updateMatrixWorld: function ( force ) {
13498
13499 Object3D.prototype.updateMatrixWorld.call( this, force );
13500
13501 this.matrixWorldInverse.getInverse( this.matrixWorld );
13502
13503 },
13504
13505 updateWorldMatrix: function ( updateParents, updateChildren ) {
13506
13507 Object3D.prototype.updateWorldMatrix.call( this, updateParents, updateChildren );
13508
13509 this.matrixWorldInverse.getInverse( this.matrixWorld );
13510
13511 },
13512
13513 clone: function () {
13514
13515 return new this.constructor().copy( this );
13516
13517 }
13518
13519 } );
13520
13521 function PerspectiveCamera( fov, aspect, near, far ) {
13522
13523 Camera.call( this );
13524
13525 this.type = 'PerspectiveCamera';
13526
13527 this.fov = fov !== undefined ? fov : 50;
13528 this.zoom = 1;
13529
13530 this.near = near !== undefined ? near : 0.1;
13531 this.far = far !== undefined ? far : 2000;
13532 this.focus = 10;
13533
13534 this.aspect = aspect !== undefined ? aspect : 1;
13535 this.view = null;
13536
13537 this.filmGauge = 35; // width of the film (default in millimeters)
13538 this.filmOffset = 0; // horizontal film offset (same unit as gauge)
13539
13540 this.updateProjectionMatrix();
13541
13542 }
13543
13544 PerspectiveCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
13545
13546 constructor: PerspectiveCamera,
13547
13548 isPerspectiveCamera: true,
13549
13550 copy: function ( source, recursive ) {
13551
13552 Camera.prototype.copy.call( this, source, recursive );
13553
13554 this.fov = source.fov;
13555 this.zoom = source.zoom;
13556
13557 this.near = source.near;
13558 this.far = source.far;
13559 this.focus = source.focus;
13560
13561 this.aspect = source.aspect;
13562 this.view = source.view === null ? null : Object.assign( {}, source.view );
13563
13564 this.filmGauge = source.filmGauge;
13565 this.filmOffset = source.filmOffset;
13566
13567 return this;
13568
13569 },
13570
13571 /**
13572 * Sets the FOV by focal length in respect to the current .filmGauge.
13573 *
13574 * The default film gauge is 35, so that the focal length can be specified for
13575 * a 35mm (full frame) camera.
13576 *
13577 * Values for focal length and film gauge must have the same unit.
13578 */
13579 setFocalLength: function ( focalLength ) {
13580
13581 // see http://www.bobatkins.com/photography/technical/field_of_view.html
13582 var vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
13583
13584 this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope );
13585 this.updateProjectionMatrix();
13586
13587 },
13588
13589 /**
13590 * Calculates the focal length from the current .fov and .filmGauge.
13591 */
13592 getFocalLength: function () {
13593
13594 var vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov );
13595
13596 return 0.5 * this.getFilmHeight() / vExtentSlope;
13597
13598 },
13599
13600 getEffectiveFOV: function () {
13601
13602 return MathUtils.RAD2DEG * 2 * Math.atan(
13603 Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom );
13604
13605 },
13606
13607 getFilmWidth: function () {
13608
13609 // film not completely covered in portrait format (aspect < 1)
13610 return this.filmGauge * Math.min( this.aspect, 1 );
13611
13612 },
13613
13614 getFilmHeight: function () {
13615
13616 // film not completely covered in landscape format (aspect > 1)
13617 return this.filmGauge / Math.max( this.aspect, 1 );
13618
13619 },
13620
13621 /**
13622 * Sets an offset in a larger frustum. This is useful for multi-window or
13623 * multi-monitor/multi-machine setups.
13624 *
13625 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
13626 * the monitors are in grid like this
13627 *
13628 * +---+---+---+
13629 * | A | B | C |
13630 * +---+---+---+
13631 * | D | E | F |
13632 * +---+---+---+
13633 *
13634 * then for each monitor you would call it like this
13635 *
13636 * const w = 1920;
13637 * const h = 1080;
13638 * const fullWidth = w * 3;
13639 * const fullHeight = h * 2;
13640 *
13641 * --A--
13642 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
13643 * --B--
13644 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
13645 * --C--
13646 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
13647 * --D--
13648 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
13649 * --E--
13650 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
13651 * --F--
13652 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
13653 *
13654 * Note there is no reason monitors have to be the same size or in a grid.
13655 */
13656 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
13657
13658 this.aspect = fullWidth / fullHeight;
13659
13660 if ( this.view === null ) {
13661
13662 this.view = {
13663 enabled: true,
13664 fullWidth: 1,
13665 fullHeight: 1,
13666 offsetX: 0,
13667 offsetY: 0,
13668 width: 1,
13669 height: 1
13670 };
13671
13672 }
13673
13674 this.view.enabled = true;
13675 this.view.fullWidth = fullWidth;
13676 this.view.fullHeight = fullHeight;
13677 this.view.offsetX = x;
13678 this.view.offsetY = y;
13679 this.view.width = width;
13680 this.view.height = height;
13681
13682 this.updateProjectionMatrix();
13683
13684 },
13685
13686 clearViewOffset: function () {
13687
13688 if ( this.view !== null ) {
13689
13690 this.view.enabled = false;
13691
13692 }
13693
13694 this.updateProjectionMatrix();
13695
13696 },
13697
13698 updateProjectionMatrix: function () {
13699
13700 var near = this.near,
13701 top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom,
13702 height = 2 * top,
13703 width = this.aspect * height,
13704 left = - 0.5 * width,
13705 view = this.view;
13706
13707 if ( this.view !== null && this.view.enabled ) {
13708
13709 var fullWidth = view.fullWidth,
13710 fullHeight = view.fullHeight;
13711
13712 left += view.offsetX * width / fullWidth;
13713 top -= view.offsetY * height / fullHeight;
13714 width *= view.width / fullWidth;
13715 height *= view.height / fullHeight;
13716
13717 }
13718
13719 var skew = this.filmOffset;
13720 if ( skew !== 0 ) { left += near * skew / this.getFilmWidth(); }
13721
13722 this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far );
13723
13724 this.projectionMatrixInverse.getInverse( this.projectionMatrix );
13725
13726 },
13727
13728 toJSON: function ( meta ) {
13729
13730 var data = Object3D.prototype.toJSON.call( this, meta );
13731
13732 data.object.fov = this.fov;
13733 data.object.zoom = this.zoom;
13734
13735 data.object.near = this.near;
13736 data.object.far = this.far;
13737 data.object.focus = this.focus;
13738
13739 data.object.aspect = this.aspect;
13740
13741 if ( this.view !== null ) { data.object.view = Object.assign( {}, this.view ); }
13742
13743 data.object.filmGauge = this.filmGauge;
13744 data.object.filmOffset = this.filmOffset;
13745
13746 return data;
13747
13748 }
13749
13750 } );
13751
13752 var fov = 90, aspect = 1;
13753
13754 function CubeCamera( near, far, renderTarget ) {
13755
13756 Object3D.call( this );
13757
13758 this.type = 'CubeCamera';
13759
13760 if ( renderTarget.isWebGLCubeRenderTarget !== true ) {
13761
13762 console.error( 'THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.' );
13763 return;
13764
13765 }
13766
13767 this.renderTarget = renderTarget;
13768
13769 var cameraPX = new PerspectiveCamera( fov, aspect, near, far );
13770 cameraPX.layers = this.layers;
13771 cameraPX.up.set( 0, - 1, 0 );
13772 cameraPX.lookAt( new Vector3( 1, 0, 0 ) );
13773 this.add( cameraPX );
13774
13775 var cameraNX = new PerspectiveCamera( fov, aspect, near, far );
13776 cameraNX.layers = this.layers;
13777 cameraNX.up.set( 0, - 1, 0 );
13778 cameraNX.lookAt( new Vector3( - 1, 0, 0 ) );
13779 this.add( cameraNX );
13780
13781 var cameraPY = new PerspectiveCamera( fov, aspect, near, far );
13782 cameraPY.layers = this.layers;
13783 cameraPY.up.set( 0, 0, 1 );
13784 cameraPY.lookAt( new Vector3( 0, 1, 0 ) );
13785 this.add( cameraPY );
13786
13787 var cameraNY = new PerspectiveCamera( fov, aspect, near, far );
13788 cameraNY.layers = this.layers;
13789 cameraNY.up.set( 0, 0, - 1 );
13790 cameraNY.lookAt( new Vector3( 0, - 1, 0 ) );
13791 this.add( cameraNY );
13792
13793 var cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
13794 cameraPZ.layers = this.layers;
13795 cameraPZ.up.set( 0, - 1, 0 );
13796 cameraPZ.lookAt( new Vector3( 0, 0, 1 ) );
13797 this.add( cameraPZ );
13798
13799 var cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
13800 cameraNZ.layers = this.layers;
13801 cameraNZ.up.set( 0, - 1, 0 );
13802 cameraNZ.lookAt( new Vector3( 0, 0, - 1 ) );
13803 this.add( cameraNZ );
13804
13805 this.update = function ( renderer, scene ) {
13806
13807 if ( this.parent === null ) { this.updateMatrixWorld(); }
13808
13809 var currentXrEnabled = renderer.xr.enabled;
13810 var currentRenderTarget = renderer.getRenderTarget();
13811
13812 renderer.xr.enabled = false;
13813
13814 var generateMipmaps = renderTarget.texture.generateMipmaps;
13815
13816 renderTarget.texture.generateMipmaps = false;
13817
13818 renderer.setRenderTarget( renderTarget, 0 );
13819 renderer.render( scene, cameraPX );
13820
13821 renderer.setRenderTarget( renderTarget, 1 );
13822 renderer.render( scene, cameraNX );
13823
13824 renderer.setRenderTarget( renderTarget, 2 );
13825 renderer.render( scene, cameraPY );
13826
13827 renderer.setRenderTarget( renderTarget, 3 );
13828 renderer.render( scene, cameraNY );
13829
13830 renderer.setRenderTarget( renderTarget, 4 );
13831 renderer.render( scene, cameraPZ );
13832
13833 renderTarget.texture.generateMipmaps = generateMipmaps;
13834
13835 renderer.setRenderTarget( renderTarget, 5 );
13836 renderer.render( scene, cameraNZ );
13837
13838 renderer.setRenderTarget( currentRenderTarget );
13839
13840 renderer.xr.enabled = currentXrEnabled;
13841
13842 };
13843
13844 this.clear = function ( renderer, color, depth, stencil ) {
13845
13846 var currentRenderTarget = renderer.getRenderTarget();
13847
13848 for ( var i = 0; i < 6; i ++ ) {
13849
13850 renderer.setRenderTarget( renderTarget, i );
13851
13852 renderer.clear( color, depth, stencil );
13853
13854 }
13855
13856 renderer.setRenderTarget( currentRenderTarget );
13857
13858 };
13859
13860 }
13861
13862 CubeCamera.prototype = Object.create( Object3D.prototype );
13863 CubeCamera.prototype.constructor = CubeCamera;
13864
13865 function WebGLCubeRenderTarget( size, options, dummy ) {
13866
13867 if ( Number.isInteger( options ) ) {
13868
13869 console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' );
13870
13871 options = dummy;
13872
13873 }
13874
13875 WebGLRenderTarget.call( this, size, size, options );
13876
13877 }
13878
13879 WebGLCubeRenderTarget.prototype = Object.create( WebGLRenderTarget.prototype );
13880 WebGLCubeRenderTarget.prototype.constructor = WebGLCubeRenderTarget;
13881
13882 WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;
13883
13884 WebGLCubeRenderTarget.prototype.fromEquirectangularTexture = function ( renderer, texture ) {
13885
13886 this.texture.type = texture.type;
13887 this.texture.format = RGBAFormat; // see #18859
13888 this.texture.encoding = texture.encoding;
13889
13890 this.texture.generateMipmaps = texture.generateMipmaps;
13891 this.texture.minFilter = texture.minFilter;
13892 this.texture.magFilter = texture.magFilter;
13893
13894 var scene = new Scene();
13895
13896 var shader = {
13897
13898 uniforms: {
13899 tEquirect: { value: null },
13900 },
13901
13902 vertexShader: /* glsl */"\n\n\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t#include <begin_vertex>\n\t\t\t\t#include <project_vertex>\n\n\t\t\t}\n\t\t",
13903
13904 fragmentShader: /* glsl */"\n\n\t\t\tuniform sampler2D tEquirect;\n\n\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t#include <common>\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t}\n\t\t"
13905 };
13906
13907 var material = new ShaderMaterial( {
13908
13909 name: 'CubemapFromEquirect',
13910
13911 uniforms: cloneUniforms( shader.uniforms ),
13912 vertexShader: shader.vertexShader,
13913 fragmentShader: shader.fragmentShader,
13914 side: BackSide,
13915 blending: NoBlending
13916
13917 } );
13918
13919 material.uniforms.tEquirect.value = texture;
13920
13921 var mesh = new Mesh( new BoxBufferGeometry( 5, 5, 5 ), material );
13922
13923 scene.add( mesh );
13924
13925 var camera = new CubeCamera( 1, 10, this );
13926 camera.update( renderer, scene );
13927
13928 mesh.geometry.dispose();
13929 mesh.material.dispose();
13930
13931 return this;
13932
13933 };
13934
13935 function DataTexture( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
13936
13937 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
13938
13939 this.image = { data: data || null, width: width || 1, height: height || 1 };
13940
13941 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
13942 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
13943
13944 this.generateMipmaps = false;
13945 this.flipY = false;
13946 this.unpackAlignment = 1;
13947
13948 this.needsUpdate = true;
13949
13950 }
13951
13952 DataTexture.prototype = Object.create( Texture.prototype );
13953 DataTexture.prototype.constructor = DataTexture;
13954
13955 DataTexture.prototype.isDataTexture = true;
13956
13957 var _sphere$1 = new Sphere();
13958 var _vector$5 = new Vector3();
13959
13960 function Frustum( p0, p1, p2, p3, p4, p5 ) {
13961
13962 this.planes = [
13963
13964 ( p0 !== undefined ) ? p0 : new Plane(),
13965 ( p1 !== undefined ) ? p1 : new Plane(),
13966 ( p2 !== undefined ) ? p2 : new Plane(),
13967 ( p3 !== undefined ) ? p3 : new Plane(),
13968 ( p4 !== undefined ) ? p4 : new Plane(),
13969 ( p5 !== undefined ) ? p5 : new Plane()
13970
13971 ];
13972
13973 }
13974
13975 Object.assign( Frustum.prototype, {
13976
13977 set: function ( p0, p1, p2, p3, p4, p5 ) {
13978
13979 var planes = this.planes;
13980
13981 planes[ 0 ].copy( p0 );
13982 planes[ 1 ].copy( p1 );
13983 planes[ 2 ].copy( p2 );
13984 planes[ 3 ].copy( p3 );
13985 planes[ 4 ].copy( p4 );
13986 planes[ 5 ].copy( p5 );
13987
13988 return this;
13989
13990 },
13991
13992 clone: function () {
13993
13994 return new this.constructor().copy( this );
13995
13996 },
13997
13998 copy: function ( frustum ) {
13999
14000 var planes = this.planes;
14001
14002 for ( var i = 0; i < 6; i ++ ) {
14003
14004 planes[ i ].copy( frustum.planes[ i ] );
14005
14006 }
14007
14008 return this;
14009
14010 },
14011
14012 setFromProjectionMatrix: function ( m ) {
14013
14014 var planes = this.planes;
14015 var me = m.elements;
14016 var me0 = me[ 0 ], me1 = me[ 1 ], me2 = me[ 2 ], me3 = me[ 3 ];
14017 var me4 = me[ 4 ], me5 = me[ 5 ], me6 = me[ 6 ], me7 = me[ 7 ];
14018 var me8 = me[ 8 ], me9 = me[ 9 ], me10 = me[ 10 ], me11 = me[ 11 ];
14019 var me12 = me[ 12 ], me13 = me[ 13 ], me14 = me[ 14 ], me15 = me[ 15 ];
14020
14021 planes[ 0 ].setComponents( me3 - me0, me7 - me4, me11 - me8, me15 - me12 ).normalize();
14022 planes[ 1 ].setComponents( me3 + me0, me7 + me4, me11 + me8, me15 + me12 ).normalize();
14023 planes[ 2 ].setComponents( me3 + me1, me7 + me5, me11 + me9, me15 + me13 ).normalize();
14024 planes[ 3 ].setComponents( me3 - me1, me7 - me5, me11 - me9, me15 - me13 ).normalize();
14025 planes[ 4 ].setComponents( me3 - me2, me7 - me6, me11 - me10, me15 - me14 ).normalize();
14026 planes[ 5 ].setComponents( me3 + me2, me7 + me6, me11 + me10, me15 + me14 ).normalize();
14027
14028 return this;
14029
14030 },
14031
14032 intersectsObject: function ( object ) {
14033
14034 var geometry = object.geometry;
14035
14036 if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
14037
14038 _sphere$1.copy( geometry.boundingSphere ).applyMatrix4( object.matrixWorld );
14039
14040 return this.intersectsSphere( _sphere$1 );
14041
14042 },
14043
14044 intersectsSprite: function ( sprite ) {
14045
14046 _sphere$1.center.set( 0, 0, 0 );
14047 _sphere$1.radius = 0.7071067811865476;
14048 _sphere$1.applyMatrix4( sprite.matrixWorld );
14049
14050 return this.intersectsSphere( _sphere$1 );
14051
14052 },
14053
14054 intersectsSphere: function ( sphere ) {
14055
14056 var planes = this.planes;
14057 var center = sphere.center;
14058 var negRadius = - sphere.radius;
14059
14060 for ( var i = 0; i < 6; i ++ ) {
14061
14062 var distance = planes[ i ].distanceToPoint( center );
14063
14064 if ( distance < negRadius ) {
14065
14066 return false;
14067
14068 }
14069
14070 }
14071
14072 return true;
14073
14074 },
14075
14076 intersectsBox: function ( box ) {
14077
14078 var planes = this.planes;
14079
14080 for ( var i = 0; i < 6; i ++ ) {
14081
14082 var plane = planes[ i ];
14083
14084 // corner at max distance
14085
14086 _vector$5.x = plane.normal.x > 0 ? box.max.x : box.min.x;
14087 _vector$5.y = plane.normal.y > 0 ? box.max.y : box.min.y;
14088 _vector$5.z = plane.normal.z > 0 ? box.max.z : box.min.z;
14089
14090 if ( plane.distanceToPoint( _vector$5 ) < 0 ) {
14091
14092 return false;
14093
14094 }
14095
14096 }
14097
14098 return true;
14099
14100 },
14101
14102 containsPoint: function ( point ) {
14103
14104 var planes = this.planes;
14105
14106 for ( var i = 0; i < 6; i ++ ) {
14107
14108 if ( planes[ i ].distanceToPoint( point ) < 0 ) {
14109
14110 return false;
14111
14112 }
14113
14114 }
14115
14116 return true;
14117
14118 }
14119
14120 } );
14121
14122 /**
14123 * Uniforms library for shared webgl shaders
14124 */
14125
14126 var UniformsLib = {
14127
14128 common: {
14129
14130 diffuse: { value: new Color( 0xeeeeee ) },
14131 opacity: { value: 1.0 },
14132
14133 map: { value: null },
14134 uvTransform: { value: new Matrix3() },
14135 uv2Transform: { value: new Matrix3() },
14136
14137 alphaMap: { value: null },
14138
14139 },
14140
14141 specularmap: {
14142
14143 specularMap: { value: null },
14144
14145 },
14146
14147 envmap: {
14148
14149 envMap: { value: null },
14150 flipEnvMap: { value: - 1 },
14151 reflectivity: { value: 1.0 },
14152 refractionRatio: { value: 0.98 },
14153 maxMipLevel: { value: 0 }
14154
14155 },
14156
14157 aomap: {
14158
14159 aoMap: { value: null },
14160 aoMapIntensity: { value: 1 }
14161
14162 },
14163
14164 lightmap: {
14165
14166 lightMap: { value: null },
14167 lightMapIntensity: { value: 1 }
14168
14169 },
14170
14171 emissivemap: {
14172
14173 emissiveMap: { value: null }
14174
14175 },
14176
14177 bumpmap: {
14178
14179 bumpMap: { value: null },
14180 bumpScale: { value: 1 }
14181
14182 },
14183
14184 normalmap: {
14185
14186 normalMap: { value: null },
14187 normalScale: { value: new Vector2( 1, 1 ) }
14188
14189 },
14190
14191 displacementmap: {
14192
14193 displacementMap: { value: null },
14194 displacementScale: { value: 1 },
14195 displacementBias: { value: 0 }
14196
14197 },
14198
14199 roughnessmap: {
14200
14201 roughnessMap: { value: null }
14202
14203 },
14204
14205 metalnessmap: {
14206
14207 metalnessMap: { value: null }
14208
14209 },
14210
14211 gradientmap: {
14212
14213 gradientMap: { value: null }
14214
14215 },
14216
14217 fog: {
14218
14219 fogDensity: { value: 0.00025 },
14220 fogNear: { value: 1 },
14221 fogFar: { value: 2000 },
14222 fogColor: { value: new Color( 0xffffff ) }
14223
14224 },
14225
14226 lights: {
14227
14228 ambientLightColor: { value: [] },
14229
14230 lightProbe: { value: [] },
14231
14232 directionalLights: { value: [], properties: {
14233 direction: {},
14234 color: {}
14235 } },
14236
14237 directionalLightShadows: { value: [], properties: {
14238 shadowBias: {},
14239 shadowNormalBias: {},
14240 shadowRadius: {},
14241 shadowMapSize: {}
14242 } },
14243
14244 directionalShadowMap: { value: [] },
14245 directionalShadowMatrix: { value: [] },
14246
14247 spotLights: { value: [], properties: {
14248 color: {},
14249 position: {},
14250 direction: {},
14251 distance: {},
14252 coneCos: {},
14253 penumbraCos: {},
14254 decay: {}
14255 } },
14256
14257 spotLightShadows: { value: [], properties: {
14258 shadowBias: {},
14259 shadowNormalBias: {},
14260 shadowRadius: {},
14261 shadowMapSize: {}
14262 } },
14263
14264 spotShadowMap: { value: [] },
14265 spotShadowMatrix: { value: [] },
14266
14267 pointLights: { value: [], properties: {
14268 color: {},
14269 position: {},
14270 decay: {},
14271 distance: {}
14272 } },
14273
14274 pointLightShadows: { value: [], properties: {
14275 shadowBias: {},
14276 shadowNormalBias: {},
14277 shadowRadius: {},
14278 shadowMapSize: {},
14279 shadowCameraNear: {},
14280 shadowCameraFar: {}
14281 } },
14282
14283 pointShadowMap: { value: [] },
14284 pointShadowMatrix: { value: [] },
14285
14286 hemisphereLights: { value: [], properties: {
14287 direction: {},
14288 skyColor: {},
14289 groundColor: {}
14290 } },
14291
14292 // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
14293 rectAreaLights: { value: [], properties: {
14294 color: {},
14295 position: {},
14296 width: {},
14297 height: {}
14298 } }
14299
14300 },
14301
14302 points: {
14303
14304 diffuse: { value: new Color( 0xeeeeee ) },
14305 opacity: { value: 1.0 },
14306 size: { value: 1.0 },
14307 scale: { value: 1.0 },
14308 map: { value: null },
14309 alphaMap: { value: null },
14310 uvTransform: { value: new Matrix3() }
14311
14312 },
14313
14314 sprite: {
14315
14316 diffuse: { value: new Color( 0xeeeeee ) },
14317 opacity: { value: 1.0 },
14318 center: { value: new Vector2( 0.5, 0.5 ) },
14319 rotation: { value: 0.0 },
14320 map: { value: null },
14321 alphaMap: { value: null },
14322 uvTransform: { value: new Matrix3() }
14323
14324 }
14325
14326 };
14327
14328 function WebGLAnimation() {
14329
14330 var context = null;
14331 var isAnimating = false;
14332 var animationLoop = null;
14333 var requestId = null;
14334
14335 function onAnimationFrame( time, frame ) {
14336
14337 animationLoop( time, frame );
14338
14339 requestId = context.requestAnimationFrame( onAnimationFrame );
14340
14341 }
14342
14343 return {
14344
14345 start: function () {
14346
14347 if ( isAnimating === true ) { return; }
14348 if ( animationLoop === null ) { return; }
14349
14350 requestId = context.requestAnimationFrame( onAnimationFrame );
14351
14352 isAnimating = true;
14353
14354 },
14355
14356 stop: function () {
14357
14358 context.cancelAnimationFrame( requestId );
14359
14360 isAnimating = false;
14361
14362 },
14363
14364 setAnimationLoop: function ( callback ) {
14365
14366 animationLoop = callback;
14367
14368 },
14369
14370 setContext: function ( value ) {
14371
14372 context = value;
14373
14374 }
14375
14376 };
14377
14378 }
14379
14380 function WebGLAttributes( gl, capabilities ) {
14381
14382 var isWebGL2 = capabilities.isWebGL2;
14383
14384 var buffers = new WeakMap();
14385
14386 function createBuffer( attribute, bufferType ) {
14387
14388 var array = attribute.array;
14389 var usage = attribute.usage;
14390
14391 var buffer = gl.createBuffer();
14392
14393 gl.bindBuffer( bufferType, buffer );
14394 gl.bufferData( bufferType, array, usage );
14395
14396 attribute.onUploadCallback();
14397
14398 var type = 5126;
14399
14400 if ( array instanceof Float32Array ) {
14401
14402 type = 5126;
14403
14404 } else if ( array instanceof Float64Array ) {
14405
14406 console.warn( 'THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.' );
14407
14408 } else if ( array instanceof Uint16Array ) {
14409
14410 type = 5123;
14411
14412 } else if ( array instanceof Int16Array ) {
14413
14414 type = 5122;
14415
14416 } else if ( array instanceof Uint32Array ) {
14417
14418 type = 5125;
14419
14420 } else if ( array instanceof Int32Array ) {
14421
14422 type = 5124;
14423
14424 } else if ( array instanceof Int8Array ) {
14425
14426 type = 5120;
14427
14428 } else if ( array instanceof Uint8Array ) {
14429
14430 type = 5121;
14431
14432 }
14433
14434 return {
14435 buffer: buffer,
14436 type: type,
14437 bytesPerElement: array.BYTES_PER_ELEMENT,
14438 version: attribute.version
14439 };
14440
14441 }
14442
14443 function updateBuffer( buffer, attribute, bufferType ) {
14444
14445 var array = attribute.array;
14446 var updateRange = attribute.updateRange;
14447
14448 gl.bindBuffer( bufferType, buffer );
14449
14450 if ( updateRange.count === - 1 ) {
14451
14452 // Not using update ranges
14453
14454 gl.bufferSubData( bufferType, 0, array );
14455
14456 } else {
14457
14458 if ( isWebGL2 ) {
14459
14460 gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
14461 array, updateRange.offset, updateRange.count );
14462
14463 } else {
14464
14465 gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
14466 array.subarray( updateRange.offset, updateRange.offset + updateRange.count ) );
14467
14468 }
14469
14470 updateRange.count = - 1; // reset range
14471
14472 }
14473
14474 }
14475
14476 //
14477
14478 function get( attribute ) {
14479
14480 if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; }
14481
14482 return buffers.get( attribute );
14483
14484 }
14485
14486 function remove( attribute ) {
14487
14488 if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; }
14489
14490 var data = buffers.get( attribute );
14491
14492 if ( data ) {
14493
14494 gl.deleteBuffer( data.buffer );
14495
14496 buffers.delete( attribute );
14497
14498 }
14499
14500 }
14501
14502 function update( attribute, bufferType ) {
14503
14504 if ( attribute.isInterleavedBufferAttribute ) { attribute = attribute.data; }
14505
14506 var data = buffers.get( attribute );
14507
14508 if ( data === undefined ) {
14509
14510 buffers.set( attribute, createBuffer( attribute, bufferType ) );
14511
14512 } else if ( data.version < attribute.version ) {
14513
14514 updateBuffer( data.buffer, attribute, bufferType );
14515
14516 data.version = attribute.version;
14517
14518 }
14519
14520 }
14521
14522 return {
14523
14524 get: get,
14525 remove: remove,
14526 update: update
14527
14528 };
14529
14530 }
14531
14532 // PlaneGeometry
14533
14534 function PlaneGeometry( width, height, widthSegments, heightSegments ) {
14535
14536 Geometry.call( this );
14537
14538 this.type = 'PlaneGeometry';
14539
14540 this.parameters = {
14541 width: width,
14542 height: height,
14543 widthSegments: widthSegments,
14544 heightSegments: heightSegments
14545 };
14546
14547 this.fromBufferGeometry( new PlaneBufferGeometry( width, height, widthSegments, heightSegments ) );
14548 this.mergeVertices();
14549
14550 }
14551
14552 PlaneGeometry.prototype = Object.create( Geometry.prototype );
14553 PlaneGeometry.prototype.constructor = PlaneGeometry;
14554
14555 // PlaneBufferGeometry
14556
14557 function PlaneBufferGeometry( width, height, widthSegments, heightSegments ) {
14558
14559 BufferGeometry.call( this );
14560
14561 this.type = 'PlaneBufferGeometry';
14562
14563 this.parameters = {
14564 width: width,
14565 height: height,
14566 widthSegments: widthSegments,
14567 heightSegments: heightSegments
14568 };
14569
14570 width = width || 1;
14571 height = height || 1;
14572
14573 var width_half = width / 2;
14574 var height_half = height / 2;
14575
14576 var gridX = Math.floor( widthSegments ) || 1;
14577 var gridY = Math.floor( heightSegments ) || 1;
14578
14579 var gridX1 = gridX + 1;
14580 var gridY1 = gridY + 1;
14581
14582 var segment_width = width / gridX;
14583 var segment_height = height / gridY;
14584
14585 // buffers
14586
14587 var indices = [];
14588 var vertices = [];
14589 var normals = [];
14590 var uvs = [];
14591
14592 // generate vertices, normals and uvs
14593
14594 for ( var iy = 0; iy < gridY1; iy ++ ) {
14595
14596 var y = iy * segment_height - height_half;
14597
14598 for ( var ix = 0; ix < gridX1; ix ++ ) {
14599
14600 var x = ix * segment_width - width_half;
14601
14602 vertices.push( x, - y, 0 );
14603
14604 normals.push( 0, 0, 1 );
14605
14606 uvs.push( ix / gridX );
14607 uvs.push( 1 - ( iy / gridY ) );
14608
14609 }
14610
14611 }
14612
14613 // indices
14614
14615 for ( var iy$1 = 0; iy$1 < gridY; iy$1 ++ ) {
14616
14617 for ( var ix$1 = 0; ix$1 < gridX; ix$1 ++ ) {
14618
14619 var a = ix$1 + gridX1 * iy$1;
14620 var b = ix$1 + gridX1 * ( iy$1 + 1 );
14621 var c = ( ix$1 + 1 ) + gridX1 * ( iy$1 + 1 );
14622 var d = ( ix$1 + 1 ) + gridX1 * iy$1;
14623
14624 // faces
14625
14626 indices.push( a, b, d );
14627 indices.push( b, c, d );
14628
14629 }
14630
14631 }
14632
14633 // build geometry
14634
14635 this.setIndex( indices );
14636 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
14637 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
14638 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
14639
14640 }
14641
14642 PlaneBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
14643 PlaneBufferGeometry.prototype.constructor = PlaneBufferGeometry;
14644
14645 var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif";
14646
14647 var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
14648
14649 var alphatest_fragment = "#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif";
14650
14651 var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif";
14652
14653 var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
14654
14655 var begin_vertex = "vec3 transformed = vec3( position );";
14656
14657 var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
14658
14659 var bsdfs = "vec2 integrateSpecularBRDF( const in float dotNV, const in float roughness ) {\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\treturn vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\nfloat punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n#else\n\tif( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t}\n\treturn 1.0;\n#endif\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nvec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );\n\tvec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;\n\treturn Fr * fresnel + F0;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + viewDir );\n\tfloat dotNL = saturate( dot( normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nvec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\treturn specularColor * brdf.x + brdf.y;\n}\nvoid BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tvec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );\n\tvec2 brdf = integrateSpecularBRDF( dotNV, roughness );\n\tvec3 FssEss = F * brdf.x + brdf.y;\n\tfloat Ess = brdf.x + brdf.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie(float roughness, float NoH) {\n\tfloat invAlpha = 1.0 / roughness;\n\tfloat cos2h = NoH * NoH;\n\tfloat sin2h = max(1.0 - cos2h, 0.0078125);\treturn (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n}\nfloat V_Neubelt(float NoV, float NoL) {\n\treturn saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n}\nvec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {\n\tvec3 N = geometry.normal;\n\tvec3 V = geometry.viewDir;\n\tvec3 H = normalize( V + L );\n\tfloat dotNH = saturate( dot( N, H ) );\n\treturn specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );\n}\n#endif";
14660
14661 var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tfDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif";
14662
14663 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";
14664
14665 var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
14666
14667 var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";
14668
14669 var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";
14670
14671 var color_fragment = "#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif";
14672
14673 var color_pars_fragment = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
14674
14675 var color_pars_vertex = "#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif";
14676
14677 var color_vertex = "#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif";
14678
14679 var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat linearToRelativeLuminance( const in vec3 color ) {\n\tvec3 weights = vec3( 0.2126, 0.7152, 0.0722 );\n\treturn dot( weights, color.rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\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}";
14680
14681 var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_maxMipLevel 8.0\n#define cubeUV_minMipLevel 4.0\n#define cubeUV_maxTileSize 256.0\n#define cubeUV_minTileSize 16.0\nfloat getFace(vec3 direction) {\n vec3 absDirection = abs(direction);\n float face = -1.0;\n if (absDirection.x > absDirection.z) {\n if (absDirection.x > absDirection.y)\n face = direction.x > 0.0 ? 0.0 : 3.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n } else {\n if (absDirection.z > absDirection.y)\n face = direction.z > 0.0 ? 2.0 : 5.0;\n else\n face = direction.y > 0.0 ? 1.0 : 4.0;\n }\n return face;\n}\nvec2 getUV(vec3 direction, float face) {\n vec2 uv;\n if (face == 0.0) {\n uv = vec2(direction.z, direction.y) / abs(direction.x); } else if (face == 1.0) {\n uv = vec2(-direction.x, -direction.z) / abs(direction.y); } else if (face == 2.0) {\n uv = vec2(-direction.x, direction.y) / abs(direction.z); } else if (face == 3.0) {\n uv = vec2(-direction.z, direction.y) / abs(direction.x); } else if (face == 4.0) {\n uv = vec2(-direction.x, direction.z) / abs(direction.y); } else {\n uv = vec2(direction.x, direction.y) / abs(direction.z); }\n return 0.5 * (uv + 1.0);\n}\nvec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {\n float face = getFace(direction);\n float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);\n mipInt = max(mipInt, cubeUV_minMipLevel);\n float faceSize = exp2(mipInt);\n float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);\n vec2 uv = getUV(direction, face) * (faceSize - 1.0);\n vec2 f = fract(uv);\n uv += 0.5 - f;\n if (face > 2.0) {\n uv.y += faceSize;\n face -= 3.0;\n }\n uv.x += face * faceSize;\n if(mipInt < cubeUV_maxMipLevel){\n uv.y += 2.0 * cubeUV_maxTileSize;\n }\n uv.y += filterInt * 2.0 * cubeUV_minTileSize;\n uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);\n uv *= texelSize;\n vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x += texelSize;\n vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.y += texelSize;\n vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n uv.x -= texelSize;\n vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;\n vec3 tm = mix(tl, tr, f.x);\n vec3 bm = mix(bl, br, f.x);\n return mix(tm, bm, f.y);\n}\n#define r0 1.0\n#define v0 0.339\n#define m0 -2.0\n#define r1 0.8\n#define v1 0.276\n#define m1 -1.0\n#define r4 0.4\n#define v4 0.046\n#define m4 2.0\n#define r5 0.305\n#define v5 0.016\n#define m5 3.0\n#define r6 0.21\n#define v6 0.0038\n#define m6 4.0\nfloat roughnessToMip(float roughness) {\n float mip = 0.0;\n if (roughness >= r1) {\n mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;\n } else if (roughness >= r4) {\n mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;\n } else if (roughness >= r5) {\n mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;\n } else if (roughness >= r6) {\n mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;\n } else {\n mip = -2.0 * log2(1.16 * roughness); }\n return mip;\n}\nvec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {\n float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);\n float mipF = fract(mip);\n float mipInt = floor(mip);\n vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);\n if (mipF == 0.0) {\n return vec4(color0, 1.0);\n } else {\n vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);\n return vec4(mix(color0, color1, mipF), 1.0);\n }\n}\n#endif";
14682
14683 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";
14684
14685 var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
14686
14687 var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif";
14688
14689 var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";
14690
14691 var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";
14692
14693 var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
14694
14695 var encodings_pars_fragment = "\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * value.a * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat M = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.r, max( value.g, value.b ) );\n\tfloat D = max( maxRange / maxRGB, 1.0 );\n\tD = clamp( floor( D ) / 255.0, 0.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value ) {\n\tvec3 Xp_Y_XYZp = cLogLuvM * value.rgb;\n\tXp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract( Le );\n\tvResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;\n\treturn vec4( max( vRGB, 0.0 ), 1.0 );\n}";
14696
14697 var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\t\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\treflectVec = normalize( reflectVec );\n\t\tvec2 sampleUV = equirectUv( reflectVec );\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifndef ENVMAP_TYPE_CUBE_UV\n\t\tenvColor = envMapTexelToLinear( envColor );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif";
14698
14699 var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform int maxMipLevel;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif";
14700
14701 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";
14702
14703 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";
14704
14705 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} 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";
14706
14707 var fog_vertex = "#ifdef USE_FOG\n\tfogDepth = - mvPosition.z;\n#endif";
14708
14709 var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float fogDepth;\n#endif";
14710
14711 var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif";
14712
14713 var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif";
14714
14715 var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn texture2D( gradientMap, coord ).rgb;\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}";
14716
14717 var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\treflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n#endif";
14718
14719 var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
14720
14721 var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif";
14722
14723 var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {\n\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif";
14724
14725 var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\t#ifdef ENVMAP_MODE_REFRACTION\n\t\tuniform float refractionRatio;\n\t#endif\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat sigma = PI * roughness * roughness / ( 1.0 + roughness );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar + log2( sigma );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t vec3 reflectVec = reflect( -viewDir, normal );\n\t\t reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t#else\n\t\t vec3 reflectVec = refract( -viewDir, normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV = equirectUv( reflectVec );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif";
14726
14727 var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
14728
14729 var lights_toon_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\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\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)";
14730
14731 var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
14732
14733 var lights_phong_pars_fragment = "varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\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( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)";
14734
14735 var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;\nmaterial.specularRoughness = min( material.specularRoughness, 1.0 );\n#ifdef REFLECTIVITY\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#endif\n#ifdef CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheen;\n#endif";
14736
14737 var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat specularRoughness;\n\tvec3 specularColor;\n#ifdef CLEARCOAT\n\tfloat clearcoat;\n\tfloat clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tvec3 sheenColor;\n#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearcoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = ccDotNL * directLight.color;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tccIrradiance *= PI;\n\t\t#endif\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t\treflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(\n\t\t\tmaterial.specularRoughness,\n\t\t\tdirectLight.direction,\n\t\t\tgeometry,\n\t\t\tmaterial.sheenColor\n\t\t);\n\t#else\n\t\treflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);\n\t#endif\n\treflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef CLEARCOAT\n\t\tfloat ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );\n\t\tfloat ccDotNL = ccDotNV;\n\t\tfloat clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );\n\t#else\n\t\tfloat clearcoatDHR = 0.0;\n\t#endif\n\tfloat clearcoatInv = 1.0 - clearcoatDHR;\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tBRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );\n\treflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
14738
14739 var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
14740
14741 var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );\n\t#ifdef CLEARCOAT\n\t\tclearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );\n\t#endif\n#endif";
14742
14743 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";
14744
14745 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";
14746
14747 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";
14748
14749 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";
14750
14751 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";
14752
14753 var map_fragment = "#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif";
14754
14755 var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif";
14756
14757 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";
14758
14759 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";
14760
14761 var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif";
14762
14763 var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
14764
14765 var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n#endif";
14766
14767 var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifndef USE_MORPHNORMALS\n\t\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\t\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif";
14768
14769 var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t#endif\n#endif";
14770
14771 var normal_fragment_begin = "#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t\tbitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;";
14772
14773 var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( -vViewPosition, normal, mapN );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif";
14774
14775 var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tfloat scale = sign( st1.t * st0.s - st0.t * st1.s );\n\t\tvec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );\n\t\tvec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );\n\t\tvec3 N = normalize( surf_norm );\n\t\tmat3 tsn = mat3( S, T, N );\n\t\tmapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif";
14776
14777 var clearcoat_normal_fragment_begin = "#ifdef CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif";
14778
14779 var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );\n\t#endif\n#endif";
14780
14781 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";
14782
14783 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}";
14784
14785 var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
14786
14787 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;";
14788
14789 var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
14790
14791 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";
14792
14793 var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif";
14794
14795 var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
14796
14797 var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif";
14798
14799 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";
14800
14801 var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\tvec4 shadowWorldPosition;\n\t#endif\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif";
14802
14803 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}";
14804
14805 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";
14806
14807 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";
14808
14809 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";
14810
14811 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";
14812
14813 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";
14814
14815 var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
14816
14817 var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
14818
14819 var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
14820
14821 var transmissionmap_fragment = "#ifdef USE_TRANSMISSIONMAP\n\ttotalTransmission *= texture2D( transmissionMap, vUv ).r;\n#endif";
14822
14823 var transmissionmap_pars_fragment = "#ifdef USE_TRANSMISSIONMAP\n\tuniform sampler2D transmissionMap;\n#endif";
14824
14825 var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif";
14826
14827 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";
14828
14829 var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif";
14830
14831 var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
14832
14833 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";
14834
14835 var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif";
14836
14837 var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
14838
14839 var background_frag = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
14840
14841 var background_vert = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}";
14842
14843 var cube_frag = "#include <envmap_common_pars_fragment>\nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include <envmap_fragment>\n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
14844
14845 var cube_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
14846
14847 var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}";
14848
14849 var depth_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}";
14850
14851 var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
14852
14853 var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
14854
14855 var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tvec4 texColor = texture2D( tEquirect, sampleUV );\n\tgl_FragColor = mapTexelToLinear( texColor );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
14856
14857 var equirect_vert = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
14858
14859 var linedashed_frag = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
14860
14861 var linedashed_vert = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
14862
14863 var meshbasic_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\n\t\tvec4 lightMapTexel= texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
14864
14865 var meshbasic_vert = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
14866
14867 var meshlambert_frag = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
14868
14869 var meshlambert_vert = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
14870
14871 var meshmatcap_frag = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t\tmatcapColor = matcapTexelToLinear( matcapColor );\n\t#else\n\t\tvec4 matcapColor = vec4( 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
14872
14873 var meshmatcap_vert = "#define MATCAP\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#ifndef FLAT_SHADED\n\t\tvNormal = normalize( transformedNormal );\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}";
14874
14875 var meshtoon_frag = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
14876
14877 var meshtoon_vert = "#define TOON\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
14878
14879 var meshphong_frag = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
14880
14881 var meshphong_vert = "#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
14882
14883 var meshphysical_frag = "#define STANDARD\n#ifdef PHYSICAL\n\t#define REFLECTIVITY\n\t#define CLEARCOAT\n\t#define TRANSMISSION\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef TRANSMISSION\n\tuniform float transmission;\n#endif\n#ifdef REFLECTIVITY\n\tuniform float reflectivity;\n#endif\n#ifdef CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheen;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <transmissionmap_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#ifdef TRANSMISSION\n\t\tfloat totalTransmission = transmission;\n\t#endif\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 <transmissionmap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#ifdef TRANSMISSION\n\t\tdiffuseColor.a *= saturate( 1. - totalTransmission + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );\n\t#endif\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
14884
14885 var meshphysical_vert = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
14886
14887 var normal_frag = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}";
14888
14889 var normal_vert = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}";
14890
14891 var points_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
14892
14893 var points_vert = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}";
14894
14895 var shadow_frag = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
14896
14897 var shadow_vert = "#include <common>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
14898
14899 var sprite_frag = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
14900
14901 var sprite_vert = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
14902
14903 var ShaderChunk = {
14904 alphamap_fragment: alphamap_fragment,
14905 alphamap_pars_fragment: alphamap_pars_fragment,
14906 alphatest_fragment: alphatest_fragment,
14907 aomap_fragment: aomap_fragment,
14908 aomap_pars_fragment: aomap_pars_fragment,
14909 begin_vertex: begin_vertex,
14910 beginnormal_vertex: beginnormal_vertex,
14911 bsdfs: bsdfs,
14912 bumpmap_pars_fragment: bumpmap_pars_fragment,
14913 clipping_planes_fragment: clipping_planes_fragment,
14914 clipping_planes_pars_fragment: clipping_planes_pars_fragment,
14915 clipping_planes_pars_vertex: clipping_planes_pars_vertex,
14916 clipping_planes_vertex: clipping_planes_vertex,
14917 color_fragment: color_fragment,
14918 color_pars_fragment: color_pars_fragment,
14919 color_pars_vertex: color_pars_vertex,
14920 color_vertex: color_vertex,
14921 common: common,
14922 cube_uv_reflection_fragment: cube_uv_reflection_fragment,
14923 defaultnormal_vertex: defaultnormal_vertex,
14924 displacementmap_pars_vertex: displacementmap_pars_vertex,
14925 displacementmap_vertex: displacementmap_vertex,
14926 emissivemap_fragment: emissivemap_fragment,
14927 emissivemap_pars_fragment: emissivemap_pars_fragment,
14928 encodings_fragment: encodings_fragment,
14929 encodings_pars_fragment: encodings_pars_fragment,
14930 envmap_fragment: envmap_fragment,
14931 envmap_common_pars_fragment: envmap_common_pars_fragment,
14932 envmap_pars_fragment: envmap_pars_fragment,
14933 envmap_pars_vertex: envmap_pars_vertex,
14934 envmap_physical_pars_fragment: envmap_physical_pars_fragment,
14935 envmap_vertex: envmap_vertex,
14936 fog_vertex: fog_vertex,
14937 fog_pars_vertex: fog_pars_vertex,
14938 fog_fragment: fog_fragment,
14939 fog_pars_fragment: fog_pars_fragment,
14940 gradientmap_pars_fragment: gradientmap_pars_fragment,
14941 lightmap_fragment: lightmap_fragment,
14942 lightmap_pars_fragment: lightmap_pars_fragment,
14943 lights_lambert_vertex: lights_lambert_vertex,
14944 lights_pars_begin: lights_pars_begin,
14945 lights_toon_fragment: lights_toon_fragment,
14946 lights_toon_pars_fragment: lights_toon_pars_fragment,
14947 lights_phong_fragment: lights_phong_fragment,
14948 lights_phong_pars_fragment: lights_phong_pars_fragment,
14949 lights_physical_fragment: lights_physical_fragment,
14950 lights_physical_pars_fragment: lights_physical_pars_fragment,
14951 lights_fragment_begin: lights_fragment_begin,
14952 lights_fragment_maps: lights_fragment_maps,
14953 lights_fragment_end: lights_fragment_end,
14954 logdepthbuf_fragment: logdepthbuf_fragment,
14955 logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
14956 logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
14957 logdepthbuf_vertex: logdepthbuf_vertex,
14958 map_fragment: map_fragment,
14959 map_pars_fragment: map_pars_fragment,
14960 map_particle_fragment: map_particle_fragment,
14961 map_particle_pars_fragment: map_particle_pars_fragment,
14962 metalnessmap_fragment: metalnessmap_fragment,
14963 metalnessmap_pars_fragment: metalnessmap_pars_fragment,
14964 morphnormal_vertex: morphnormal_vertex,
14965 morphtarget_pars_vertex: morphtarget_pars_vertex,
14966 morphtarget_vertex: morphtarget_vertex,
14967 normal_fragment_begin: normal_fragment_begin,
14968 normal_fragment_maps: normal_fragment_maps,
14969 normalmap_pars_fragment: normalmap_pars_fragment,
14970 clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin,
14971 clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps,
14972 clearcoat_pars_fragment: clearcoat_pars_fragment,
14973 packing: packing,
14974 premultiplied_alpha_fragment: premultiplied_alpha_fragment,
14975 project_vertex: project_vertex,
14976 dithering_fragment: dithering_fragment,
14977 dithering_pars_fragment: dithering_pars_fragment,
14978 roughnessmap_fragment: roughnessmap_fragment,
14979 roughnessmap_pars_fragment: roughnessmap_pars_fragment,
14980 shadowmap_pars_fragment: shadowmap_pars_fragment,
14981 shadowmap_pars_vertex: shadowmap_pars_vertex,
14982 shadowmap_vertex: shadowmap_vertex,
14983 shadowmask_pars_fragment: shadowmask_pars_fragment,
14984 skinbase_vertex: skinbase_vertex,
14985 skinning_pars_vertex: skinning_pars_vertex,
14986 skinning_vertex: skinning_vertex,
14987 skinnormal_vertex: skinnormal_vertex,
14988 specularmap_fragment: specularmap_fragment,
14989 specularmap_pars_fragment: specularmap_pars_fragment,
14990 tonemapping_fragment: tonemapping_fragment,
14991 tonemapping_pars_fragment: tonemapping_pars_fragment,
14992 transmissionmap_fragment: transmissionmap_fragment,
14993 transmissionmap_pars_fragment: transmissionmap_pars_fragment,
14994 uv_pars_fragment: uv_pars_fragment,
14995 uv_pars_vertex: uv_pars_vertex,
14996 uv_vertex: uv_vertex,
14997 uv2_pars_fragment: uv2_pars_fragment,
14998 uv2_pars_vertex: uv2_pars_vertex,
14999 uv2_vertex: uv2_vertex,
15000 worldpos_vertex: worldpos_vertex,
15001
15002 background_frag: background_frag,
15003 background_vert: background_vert,
15004 cube_frag: cube_frag,
15005 cube_vert: cube_vert,
15006 depth_frag: depth_frag,
15007 depth_vert: depth_vert,
15008 distanceRGBA_frag: distanceRGBA_frag,
15009 distanceRGBA_vert: distanceRGBA_vert,
15010 equirect_frag: equirect_frag,
15011 equirect_vert: equirect_vert,
15012 linedashed_frag: linedashed_frag,
15013 linedashed_vert: linedashed_vert,
15014 meshbasic_frag: meshbasic_frag,
15015 meshbasic_vert: meshbasic_vert,
15016 meshlambert_frag: meshlambert_frag,
15017 meshlambert_vert: meshlambert_vert,
15018 meshmatcap_frag: meshmatcap_frag,
15019 meshmatcap_vert: meshmatcap_vert,
15020 meshtoon_frag: meshtoon_frag,
15021 meshtoon_vert: meshtoon_vert,
15022 meshphong_frag: meshphong_frag,
15023 meshphong_vert: meshphong_vert,
15024 meshphysical_frag: meshphysical_frag,
15025 meshphysical_vert: meshphysical_vert,
15026 normal_frag: normal_frag,
15027 normal_vert: normal_vert,
15028 points_frag: points_frag,
15029 points_vert: points_vert,
15030 shadow_frag: shadow_frag,
15031 shadow_vert: shadow_vert,
15032 sprite_frag: sprite_frag,
15033 sprite_vert: sprite_vert
15034 };
15035
15036 var ShaderLib = {
15037
15038 basic: {
15039
15040 uniforms: mergeUniforms( [
15041 UniformsLib.common,
15042 UniformsLib.specularmap,
15043 UniformsLib.envmap,
15044 UniformsLib.aomap,
15045 UniformsLib.lightmap,
15046 UniformsLib.fog
15047 ] ),
15048
15049 vertexShader: ShaderChunk.meshbasic_vert,
15050 fragmentShader: ShaderChunk.meshbasic_frag
15051
15052 },
15053
15054 lambert: {
15055
15056 uniforms: mergeUniforms( [
15057 UniformsLib.common,
15058 UniformsLib.specularmap,
15059 UniformsLib.envmap,
15060 UniformsLib.aomap,
15061 UniformsLib.lightmap,
15062 UniformsLib.emissivemap,
15063 UniformsLib.fog,
15064 UniformsLib.lights,
15065 {
15066 emissive: { value: new Color( 0x000000 ) }
15067 }
15068 ] ),
15069
15070 vertexShader: ShaderChunk.meshlambert_vert,
15071 fragmentShader: ShaderChunk.meshlambert_frag
15072
15073 },
15074
15075 phong: {
15076
15077 uniforms: mergeUniforms( [
15078 UniformsLib.common,
15079 UniformsLib.specularmap,
15080 UniformsLib.envmap,
15081 UniformsLib.aomap,
15082 UniformsLib.lightmap,
15083 UniformsLib.emissivemap,
15084 UniformsLib.bumpmap,
15085 UniformsLib.normalmap,
15086 UniformsLib.displacementmap,
15087 UniformsLib.fog,
15088 UniformsLib.lights,
15089 {
15090 emissive: { value: new Color( 0x000000 ) },
15091 specular: { value: new Color( 0x111111 ) },
15092 shininess: { value: 30 }
15093 }
15094 ] ),
15095
15096 vertexShader: ShaderChunk.meshphong_vert,
15097 fragmentShader: ShaderChunk.meshphong_frag
15098
15099 },
15100
15101 standard: {
15102
15103 uniforms: mergeUniforms( [
15104 UniformsLib.common,
15105 UniformsLib.envmap,
15106 UniformsLib.aomap,
15107 UniformsLib.lightmap,
15108 UniformsLib.emissivemap,
15109 UniformsLib.bumpmap,
15110 UniformsLib.normalmap,
15111 UniformsLib.displacementmap,
15112 UniformsLib.roughnessmap,
15113 UniformsLib.metalnessmap,
15114 UniformsLib.fog,
15115 UniformsLib.lights,
15116 {
15117 emissive: { value: new Color( 0x000000 ) },
15118 roughness: { value: 1.0 },
15119 metalness: { value: 0.0 },
15120 envMapIntensity: { value: 1 } // temporary
15121 }
15122 ] ),
15123
15124 vertexShader: ShaderChunk.meshphysical_vert,
15125 fragmentShader: ShaderChunk.meshphysical_frag
15126
15127 },
15128
15129 toon: {
15130
15131 uniforms: mergeUniforms( [
15132 UniformsLib.common,
15133 UniformsLib.aomap,
15134 UniformsLib.lightmap,
15135 UniformsLib.emissivemap,
15136 UniformsLib.bumpmap,
15137 UniformsLib.normalmap,
15138 UniformsLib.displacementmap,
15139 UniformsLib.gradientmap,
15140 UniformsLib.fog,
15141 UniformsLib.lights,
15142 {
15143 emissive: { value: new Color( 0x000000 ) }
15144 }
15145 ] ),
15146
15147 vertexShader: ShaderChunk.meshtoon_vert,
15148 fragmentShader: ShaderChunk.meshtoon_frag
15149
15150 },
15151
15152 matcap: {
15153
15154 uniforms: mergeUniforms( [
15155 UniformsLib.common,
15156 UniformsLib.bumpmap,
15157 UniformsLib.normalmap,
15158 UniformsLib.displacementmap,
15159 UniformsLib.fog,
15160 {
15161 matcap: { value: null }
15162 }
15163 ] ),
15164
15165 vertexShader: ShaderChunk.meshmatcap_vert,
15166 fragmentShader: ShaderChunk.meshmatcap_frag
15167
15168 },
15169
15170 points: {
15171
15172 uniforms: mergeUniforms( [
15173 UniformsLib.points,
15174 UniformsLib.fog
15175 ] ),
15176
15177 vertexShader: ShaderChunk.points_vert,
15178 fragmentShader: ShaderChunk.points_frag
15179
15180 },
15181
15182 dashed: {
15183
15184 uniforms: mergeUniforms( [
15185 UniformsLib.common,
15186 UniformsLib.fog,
15187 {
15188 scale: { value: 1 },
15189 dashSize: { value: 1 },
15190 totalSize: { value: 2 }
15191 }
15192 ] ),
15193
15194 vertexShader: ShaderChunk.linedashed_vert,
15195 fragmentShader: ShaderChunk.linedashed_frag
15196
15197 },
15198
15199 depth: {
15200
15201 uniforms: mergeUniforms( [
15202 UniformsLib.common,
15203 UniformsLib.displacementmap
15204 ] ),
15205
15206 vertexShader: ShaderChunk.depth_vert,
15207 fragmentShader: ShaderChunk.depth_frag
15208
15209 },
15210
15211 normal: {
15212
15213 uniforms: mergeUniforms( [
15214 UniformsLib.common,
15215 UniformsLib.bumpmap,
15216 UniformsLib.normalmap,
15217 UniformsLib.displacementmap,
15218 {
15219 opacity: { value: 1.0 }
15220 }
15221 ] ),
15222
15223 vertexShader: ShaderChunk.normal_vert,
15224 fragmentShader: ShaderChunk.normal_frag
15225
15226 },
15227
15228 sprite: {
15229
15230 uniforms: mergeUniforms( [
15231 UniformsLib.sprite,
15232 UniformsLib.fog
15233 ] ),
15234
15235 vertexShader: ShaderChunk.sprite_vert,
15236 fragmentShader: ShaderChunk.sprite_frag
15237
15238 },
15239
15240 background: {
15241
15242 uniforms: {
15243 uvTransform: { value: new Matrix3() },
15244 t2D: { value: null },
15245 },
15246
15247 vertexShader: ShaderChunk.background_vert,
15248 fragmentShader: ShaderChunk.background_frag
15249
15250 },
15251 /* -------------------------------------------------------------------------
15252 // Cube map shader
15253 ------------------------------------------------------------------------- */
15254
15255 cube: {
15256
15257 uniforms: mergeUniforms( [
15258 UniformsLib.envmap,
15259 {
15260 opacity: { value: 1.0 }
15261 }
15262 ] ),
15263
15264 vertexShader: ShaderChunk.cube_vert,
15265 fragmentShader: ShaderChunk.cube_frag
15266
15267 },
15268
15269 equirect: {
15270
15271 uniforms: {
15272 tEquirect: { value: null },
15273 },
15274
15275 vertexShader: ShaderChunk.equirect_vert,
15276 fragmentShader: ShaderChunk.equirect_frag
15277
15278 },
15279
15280 distanceRGBA: {
15281
15282 uniforms: mergeUniforms( [
15283 UniformsLib.common,
15284 UniformsLib.displacementmap,
15285 {
15286 referencePosition: { value: new Vector3() },
15287 nearDistance: { value: 1 },
15288 farDistance: { value: 1000 }
15289 }
15290 ] ),
15291
15292 vertexShader: ShaderChunk.distanceRGBA_vert,
15293 fragmentShader: ShaderChunk.distanceRGBA_frag
15294
15295 },
15296
15297 shadow: {
15298
15299 uniforms: mergeUniforms( [
15300 UniformsLib.lights,
15301 UniformsLib.fog,
15302 {
15303 color: { value: new Color( 0x00000 ) },
15304 opacity: { value: 1.0 }
15305 } ] ),
15306
15307 vertexShader: ShaderChunk.shadow_vert,
15308 fragmentShader: ShaderChunk.shadow_frag
15309
15310 }
15311
15312 };
15313
15314 ShaderLib.physical = {
15315
15316 uniforms: mergeUniforms( [
15317 ShaderLib.standard.uniforms,
15318 {
15319 clearcoat: { value: 0 },
15320 clearcoatMap: { value: null },
15321 clearcoatRoughness: { value: 0 },
15322 clearcoatRoughnessMap: { value: null },
15323 clearcoatNormalScale: { value: new Vector2( 1, 1 ) },
15324 clearcoatNormalMap: { value: null },
15325 sheen: { value: new Color( 0x000000 ) },
15326 transmission: { value: 0 },
15327 transmissionMap: { value: null },
15328 }
15329 ] ),
15330
15331 vertexShader: ShaderChunk.meshphysical_vert,
15332 fragmentShader: ShaderChunk.meshphysical_frag
15333
15334 };
15335
15336 function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
15337
15338 var clearColor = new Color( 0x000000 );
15339 var clearAlpha = 0;
15340
15341 var planeMesh;
15342 var boxMesh;
15343
15344 var currentBackground = null;
15345 var currentBackgroundVersion = 0;
15346 var currentTonemapping = null;
15347
15348 function render( renderList, scene, camera, forceClear ) {
15349
15350 var background = scene.isScene === true ? scene.background : null;
15351
15352 // Ignore background in AR
15353 // TODO: Reconsider this.
15354
15355 var xr = renderer.xr;
15356 var session = xr.getSession && xr.getSession();
15357
15358 if ( session && session.environmentBlendMode === 'additive' ) {
15359
15360 background = null;
15361
15362 }
15363
15364 if ( background === null ) {
15365
15366 setClear( clearColor, clearAlpha );
15367
15368 } else if ( background && background.isColor ) {
15369
15370 setClear( background, 1 );
15371 forceClear = true;
15372
15373 }
15374
15375 if ( renderer.autoClear || forceClear ) {
15376
15377 renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
15378
15379 }
15380
15381 if ( background && ( background.isCubeTexture || background.isWebGLCubeRenderTarget || background.mapping === CubeUVReflectionMapping ) ) {
15382
15383 if ( boxMesh === undefined ) {
15384
15385 boxMesh = new Mesh(
15386 new BoxBufferGeometry( 1, 1, 1 ),
15387 new ShaderMaterial( {
15388 name: 'BackgroundCubeMaterial',
15389 uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
15390 vertexShader: ShaderLib.cube.vertexShader,
15391 fragmentShader: ShaderLib.cube.fragmentShader,
15392 side: BackSide,
15393 depthTest: false,
15394 depthWrite: false,
15395 fog: false
15396 } )
15397 );
15398
15399 boxMesh.geometry.deleteAttribute( 'normal' );
15400 boxMesh.geometry.deleteAttribute( 'uv' );
15401
15402 boxMesh.onBeforeRender = function ( renderer, scene, camera ) {
15403
15404 this.matrixWorld.copyPosition( camera.matrixWorld );
15405
15406 };
15407
15408 // enable code injection for non-built-in material
15409 Object.defineProperty( boxMesh.material, 'envMap', {
15410
15411 get: function () {
15412
15413 return this.uniforms.envMap.value;
15414
15415 }
15416
15417 } );
15418
15419 objects.update( boxMesh );
15420
15421 }
15422
15423 var texture = background.isWebGLCubeRenderTarget ? background.texture : background;
15424
15425 boxMesh.material.uniforms.envMap.value = texture;
15426 boxMesh.material.uniforms.flipEnvMap.value = texture.isCubeTexture ? - 1 : 1;
15427
15428 if ( currentBackground !== background ||
15429 currentBackgroundVersion !== texture.version ||
15430 currentTonemapping !== renderer.toneMapping ) {
15431
15432 boxMesh.material.needsUpdate = true;
15433
15434 currentBackground = background;
15435 currentBackgroundVersion = texture.version;
15436 currentTonemapping = renderer.toneMapping;
15437
15438 }
15439
15440 // push to the pre-sorted opaque render list
15441 renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );
15442
15443 } else if ( background && background.isTexture ) {
15444
15445 if ( planeMesh === undefined ) {
15446
15447 planeMesh = new Mesh(
15448 new PlaneBufferGeometry( 2, 2 ),
15449 new ShaderMaterial( {
15450 name: 'BackgroundMaterial',
15451 uniforms: cloneUniforms( ShaderLib.background.uniforms ),
15452 vertexShader: ShaderLib.background.vertexShader,
15453 fragmentShader: ShaderLib.background.fragmentShader,
15454 side: FrontSide,
15455 depthTest: false,
15456 depthWrite: false,
15457 fog: false
15458 } )
15459 );
15460
15461 planeMesh.geometry.deleteAttribute( 'normal' );
15462
15463 // enable code injection for non-built-in material
15464 Object.defineProperty( planeMesh.material, 'map', {
15465
15466 get: function () {
15467
15468 return this.uniforms.t2D.value;
15469
15470 }
15471
15472 } );
15473
15474 objects.update( planeMesh );
15475
15476 }
15477
15478 planeMesh.material.uniforms.t2D.value = background;
15479
15480 if ( background.matrixAutoUpdate === true ) {
15481
15482 background.updateMatrix();
15483
15484 }
15485
15486 planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
15487
15488 if ( currentBackground !== background ||
15489 currentBackgroundVersion !== background.version ||
15490 currentTonemapping !== renderer.toneMapping ) {
15491
15492 planeMesh.material.needsUpdate = true;
15493
15494 currentBackground = background;
15495 currentBackgroundVersion = background.version;
15496 currentTonemapping = renderer.toneMapping;
15497
15498 }
15499
15500
15501 // push to the pre-sorted opaque render list
15502 renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );
15503
15504 }
15505
15506 }
15507
15508 function setClear( color, alpha ) {
15509
15510 state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );
15511
15512 }
15513
15514 return {
15515
15516 getClearColor: function () {
15517
15518 return clearColor;
15519
15520 },
15521 setClearColor: function ( color, alpha ) {
15522
15523 clearColor.set( color );
15524 clearAlpha = alpha !== undefined ? alpha : 1;
15525 setClear( clearColor, clearAlpha );
15526
15527 },
15528 getClearAlpha: function () {
15529
15530 return clearAlpha;
15531
15532 },
15533 setClearAlpha: function ( alpha ) {
15534
15535 clearAlpha = alpha;
15536 setClear( clearColor, clearAlpha );
15537
15538 },
15539 render: render
15540
15541 };
15542
15543 }
15544
15545 function WebGLBindingStates( gl, extensions, attributes, capabilities ) {
15546
15547 var maxVertexAttributes = gl.getParameter( 34921 );
15548
15549 var extension = capabilities.isWebGL2 ? null : extensions.get( 'OES_vertex_array_object' );
15550 var vaoAvailable = capabilities.isWebGL2 || extension !== null;
15551
15552 var bindingStates = {};
15553
15554 var defaultState = createBindingState( null );
15555 var currentState = defaultState;
15556
15557 function setup( object, material, program, geometry, index ) {
15558
15559 var updateBuffers = false;
15560
15561 if ( vaoAvailable ) {
15562
15563 var state = getBindingState( geometry, program, material );
15564
15565 if ( currentState !== state ) {
15566
15567 currentState = state;
15568 bindVertexArrayObject( currentState.object );
15569
15570 }
15571
15572 updateBuffers = needsUpdate( geometry );
15573
15574 if ( updateBuffers ) { saveCache( geometry ); }
15575
15576 } else {
15577
15578 var wireframe = ( material.wireframe === true );
15579
15580 if ( currentState.geometry !== geometry.id ||
15581 currentState.program !== program.id ||
15582 currentState.wireframe !== wireframe ) {
15583
15584 currentState.geometry = geometry.id;
15585 currentState.program = program.id;
15586 currentState.wireframe = wireframe;
15587
15588 updateBuffers = true;
15589
15590 }
15591
15592 }
15593
15594 if ( object.isInstancedMesh === true ) {
15595
15596 updateBuffers = true;
15597
15598 }
15599
15600 if ( index !== null ) {
15601
15602 attributes.update( index, 34963 );
15603
15604 }
15605
15606 if ( updateBuffers ) {
15607
15608 setupVertexAttributes( object, material, program, geometry );
15609
15610 if ( index !== null ) {
15611
15612 gl.bindBuffer( 34963, attributes.get( index ).buffer );
15613
15614 }
15615
15616 }
15617
15618 }
15619
15620 function createVertexArrayObject() {
15621
15622 if ( capabilities.isWebGL2 ) { return gl.createVertexArray(); }
15623
15624 return extension.createVertexArrayOES();
15625
15626 }
15627
15628 function bindVertexArrayObject( vao ) {
15629
15630 if ( capabilities.isWebGL2 ) { return gl.bindVertexArray( vao ); }
15631
15632 return extension.bindVertexArrayOES( vao );
15633
15634 }
15635
15636 function deleteVertexArrayObject( vao ) {
15637
15638 if ( capabilities.isWebGL2 ) { return gl.deleteVertexArray( vao ); }
15639
15640 return extension.deleteVertexArrayOES( vao );
15641
15642 }
15643
15644 function getBindingState( geometry, program, material ) {
15645
15646 var wireframe = ( material.wireframe === true );
15647
15648 var programMap = bindingStates[ geometry.id ];
15649
15650 if ( programMap === undefined ) {
15651
15652 programMap = {};
15653 bindingStates[ geometry.id ] = programMap;
15654
15655 }
15656
15657 var stateMap = programMap[ program.id ];
15658
15659 if ( stateMap === undefined ) {
15660
15661 stateMap = {};
15662 programMap[ program.id ] = stateMap;
15663
15664 }
15665
15666 var state = stateMap[ wireframe ];
15667
15668 if ( state === undefined ) {
15669
15670 state = createBindingState( createVertexArrayObject() );
15671 stateMap[ wireframe ] = state;
15672
15673 }
15674
15675 return state;
15676
15677 }
15678
15679 function createBindingState( vao ) {
15680
15681 var newAttributes = [];
15682 var enabledAttributes = [];
15683 var attributeDivisors = [];
15684
15685 for ( var i = 0; i < maxVertexAttributes; i ++ ) {
15686
15687 newAttributes[ i ] = 0;
15688 enabledAttributes[ i ] = 0;
15689 attributeDivisors[ i ] = 0;
15690
15691 }
15692
15693 return {
15694
15695 // for backward compatibility on non-VAO support browser
15696 geometry: null,
15697 program: null,
15698 wireframe: false,
15699
15700 newAttributes: newAttributes,
15701 enabledAttributes: enabledAttributes,
15702 attributeDivisors: attributeDivisors,
15703 object: vao,
15704 attributes: {}
15705
15706 };
15707
15708 }
15709
15710 function needsUpdate( geometry ) {
15711
15712 var cachedAttributes = currentState.attributes;
15713 var geometryAttributes = geometry.attributes;
15714
15715 if ( Object.keys( cachedAttributes ).length !== Object.keys( geometryAttributes ).length ) { return true; }
15716
15717 for ( var key in geometryAttributes ) {
15718
15719 var cachedAttribute = cachedAttributes[ key ];
15720 var geometryAttribute = geometryAttributes[ key ];
15721
15722 if ( cachedAttribute.attribute !== geometryAttribute ) { return true; }
15723
15724 if ( cachedAttribute.data !== geometryAttribute.data ) { return true; }
15725
15726 }
15727
15728 return false;
15729
15730 }
15731
15732 function saveCache( geometry ) {
15733
15734 var cache = {};
15735 var attributes = geometry.attributes;
15736
15737 for ( var key in attributes ) {
15738
15739 var attribute = attributes[ key ];
15740
15741 var data = {};
15742 data.attribute = attribute;
15743
15744 if ( attribute.data ) {
15745
15746 data.data = attribute.data;
15747
15748 }
15749
15750 cache[ key ] = data;
15751
15752 }
15753
15754 currentState.attributes = cache;
15755
15756 }
15757
15758 function initAttributes() {
15759
15760 var newAttributes = currentState.newAttributes;
15761
15762 for ( var i = 0, il = newAttributes.length; i < il; i ++ ) {
15763
15764 newAttributes[ i ] = 0;
15765
15766 }
15767
15768 }
15769
15770 function enableAttribute( attribute ) {
15771
15772 enableAttributeAndDivisor( attribute, 0 );
15773
15774 }
15775
15776 function enableAttributeAndDivisor( attribute, meshPerAttribute ) {
15777
15778 var newAttributes = currentState.newAttributes;
15779 var enabledAttributes = currentState.enabledAttributes;
15780 var attributeDivisors = currentState.attributeDivisors;
15781
15782 newAttributes[ attribute ] = 1;
15783
15784 if ( enabledAttributes[ attribute ] === 0 ) {
15785
15786 gl.enableVertexAttribArray( attribute );
15787 enabledAttributes[ attribute ] = 1;
15788
15789 }
15790
15791 if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
15792
15793 var extension = capabilities.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' );
15794
15795 extension[ capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute );
15796 attributeDivisors[ attribute ] = meshPerAttribute;
15797
15798 }
15799
15800 }
15801
15802 function disableUnusedAttributes() {
15803
15804 var newAttributes = currentState.newAttributes;
15805 var enabledAttributes = currentState.enabledAttributes;
15806
15807 for ( var i = 0, il = enabledAttributes.length; i < il; i ++ ) {
15808
15809 if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
15810
15811 gl.disableVertexAttribArray( i );
15812 enabledAttributes[ i ] = 0;
15813
15814 }
15815
15816 }
15817
15818 }
15819
15820 function vertexAttribPointer( index, size, type, normalized, stride, offset ) {
15821
15822 if ( capabilities.isWebGL2 === true && ( type === 5124 || type === 5125 ) ) {
15823
15824 gl.vertexAttribIPointer( index, size, type, stride, offset );
15825
15826 } else {
15827
15828 gl.vertexAttribPointer( index, size, type, normalized, stride, offset );
15829
15830 }
15831
15832 }
15833
15834 function setupVertexAttributes( object, material, program, geometry ) {
15835
15836 if ( capabilities.isWebGL2 === false && ( object.isInstancedMesh || geometry.isInstancedBufferGeometry ) ) {
15837
15838 if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) { return; }
15839
15840 }
15841
15842 initAttributes();
15843
15844 var geometryAttributes = geometry.attributes;
15845
15846 var programAttributes = program.getAttributes();
15847
15848 var materialDefaultAttributeValues = material.defaultAttributeValues;
15849
15850 for ( var name in programAttributes ) {
15851
15852 var programAttribute = programAttributes[ name ];
15853
15854 if ( programAttribute >= 0 ) {
15855
15856 var geometryAttribute = geometryAttributes[ name ];
15857
15858 if ( geometryAttribute !== undefined ) {
15859
15860 var normalized = geometryAttribute.normalized;
15861 var size = geometryAttribute.itemSize;
15862
15863 var attribute = attributes.get( geometryAttribute );
15864
15865 // TODO Attribute may not be available on context restore
15866
15867 if ( attribute === undefined ) { continue; }
15868
15869 var buffer = attribute.buffer;
15870 var type = attribute.type;
15871 var bytesPerElement = attribute.bytesPerElement;
15872
15873 if ( geometryAttribute.isInterleavedBufferAttribute ) {
15874
15875 var data = geometryAttribute.data;
15876 var stride = data.stride;
15877 var offset = geometryAttribute.offset;
15878
15879 if ( data && data.isInstancedInterleavedBuffer ) {
15880
15881 enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
15882
15883 if ( geometry._maxInstanceCount === undefined ) {
15884
15885 geometry._maxInstanceCount = data.meshPerAttribute * data.count;
15886
15887 }
15888
15889 } else {
15890
15891 enableAttribute( programAttribute );
15892
15893 }
15894
15895 gl.bindBuffer( 34962, buffer );
15896 vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
15897
15898 } else {
15899
15900 if ( geometryAttribute.isInstancedBufferAttribute ) {
15901
15902 enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
15903
15904 if ( geometry._maxInstanceCount === undefined ) {
15905
15906 geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
15907
15908 }
15909
15910 } else {
15911
15912 enableAttribute( programAttribute );
15913
15914 }
15915
15916 gl.bindBuffer( 34962, buffer );
15917 vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
15918
15919 }
15920
15921 } else if ( name === 'instanceMatrix' ) {
15922
15923 var attribute$1 = attributes.get( object.instanceMatrix );
15924
15925 // TODO Attribute may not be available on context restore
15926
15927 if ( attribute$1 === undefined ) { continue; }
15928
15929 var buffer$1 = attribute$1.buffer;
15930 var type$1 = attribute$1.type;
15931
15932 enableAttributeAndDivisor( programAttribute + 0, 1 );
15933 enableAttributeAndDivisor( programAttribute + 1, 1 );
15934 enableAttributeAndDivisor( programAttribute + 2, 1 );
15935 enableAttributeAndDivisor( programAttribute + 3, 1 );
15936
15937 gl.bindBuffer( 34962, buffer$1 );
15938
15939 gl.vertexAttribPointer( programAttribute + 0, 4, type$1, false, 64, 0 );
15940 gl.vertexAttribPointer( programAttribute + 1, 4, type$1, false, 64, 16 );
15941 gl.vertexAttribPointer( programAttribute + 2, 4, type$1, false, 64, 32 );
15942 gl.vertexAttribPointer( programAttribute + 3, 4, type$1, false, 64, 48 );
15943
15944 } else if ( materialDefaultAttributeValues !== undefined ) {
15945
15946 var value = materialDefaultAttributeValues[ name ];
15947
15948 if ( value !== undefined ) {
15949
15950 switch ( value.length ) {
15951
15952 case 2:
15953 gl.vertexAttrib2fv( programAttribute, value );
15954 break;
15955
15956 case 3:
15957 gl.vertexAttrib3fv( programAttribute, value );
15958 break;
15959
15960 case 4:
15961 gl.vertexAttrib4fv( programAttribute, value );
15962 break;
15963
15964 default:
15965 gl.vertexAttrib1fv( programAttribute, value );
15966
15967 }
15968
15969 }
15970
15971 }
15972
15973 }
15974
15975 }
15976
15977 disableUnusedAttributes();
15978
15979 }
15980
15981 function dispose() {
15982
15983 reset();
15984
15985 for ( var geometryId in bindingStates ) {
15986
15987 var programMap = bindingStates[ geometryId ];
15988
15989 for ( var programId in programMap ) {
15990
15991 var stateMap = programMap[ programId ];
15992
15993 for ( var wireframe in stateMap ) {
15994
15995 deleteVertexArrayObject( stateMap[ wireframe ].object );
15996
15997 delete stateMap[ wireframe ];
15998
15999 }
16000
16001 delete programMap[ programId ];
16002
16003 }
16004
16005 delete bindingStates[ geometryId ];
16006
16007 }
16008
16009 }
16010
16011 function releaseStatesOfGeometry( geometry ) {
16012
16013 if ( bindingStates[ geometry.id ] === undefined ) { return; }
16014
16015 var programMap = bindingStates[ geometry.id ];
16016
16017 for ( var programId in programMap ) {
16018
16019 var stateMap = programMap[ programId ];
16020
16021 for ( var wireframe in stateMap ) {
16022
16023 deleteVertexArrayObject( stateMap[ wireframe ].object );
16024
16025 delete stateMap[ wireframe ];
16026
16027 }
16028
16029 delete programMap[ programId ];
16030
16031 }
16032
16033 delete bindingStates[ geometry.id ];
16034
16035 }
16036
16037 function releaseStatesOfProgram( program ) {
16038
16039 for ( var geometryId in bindingStates ) {
16040
16041 var programMap = bindingStates[ geometryId ];
16042
16043 if ( programMap[ program.id ] === undefined ) { continue; }
16044
16045 var stateMap = programMap[ program.id ];
16046
16047 for ( var wireframe in stateMap ) {
16048
16049 deleteVertexArrayObject( stateMap[ wireframe ].object );
16050
16051 delete stateMap[ wireframe ];
16052
16053 }
16054
16055 delete programMap[ program.id ];
16056
16057 }
16058
16059 }
16060
16061 function reset() {
16062
16063 resetDefaultState();
16064
16065 if ( currentState === defaultState ) { return; }
16066
16067 currentState = defaultState;
16068 bindVertexArrayObject( currentState.object );
16069
16070 }
16071
16072 // for backward-compatilibity
16073
16074 function resetDefaultState() {
16075
16076 defaultState.geometry = null;
16077 defaultState.program = null;
16078 defaultState.wireframe = false;
16079
16080 }
16081
16082 return {
16083
16084 setup: setup,
16085 reset: reset,
16086 resetDefaultState: resetDefaultState,
16087 dispose: dispose,
16088 releaseStatesOfGeometry: releaseStatesOfGeometry,
16089 releaseStatesOfProgram: releaseStatesOfProgram,
16090
16091 initAttributes: initAttributes,
16092 enableAttribute: enableAttribute,
16093 disableUnusedAttributes: disableUnusedAttributes
16094
16095 };
16096
16097 }
16098
16099 function WebGLBufferRenderer( gl, extensions, info, capabilities ) {
16100
16101 var isWebGL2 = capabilities.isWebGL2;
16102
16103 var mode;
16104
16105 function setMode( value ) {
16106
16107 mode = value;
16108
16109 }
16110
16111 function render( start, count ) {
16112
16113 gl.drawArrays( mode, start, count );
16114
16115 info.update( count, mode, 1 );
16116
16117 }
16118
16119 function renderInstances( start, count, primcount ) {
16120
16121 if ( primcount === 0 ) { return; }
16122
16123 var extension, methodName;
16124
16125 if ( isWebGL2 ) {
16126
16127 extension = gl;
16128 methodName = 'drawArraysInstanced';
16129
16130 } else {
16131
16132 extension = extensions.get( 'ANGLE_instanced_arrays' );
16133 methodName = 'drawArraysInstancedANGLE';
16134
16135 if ( extension === null ) {
16136
16137 console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
16138 return;
16139
16140 }
16141
16142 }
16143
16144 extension[ methodName ]( mode, start, count, primcount );
16145
16146 info.update( count, mode, primcount );
16147
16148 }
16149
16150 //
16151
16152 this.setMode = setMode;
16153 this.render = render;
16154 this.renderInstances = renderInstances;
16155
16156 }
16157
16158 function WebGLCapabilities( gl, extensions, parameters ) {
16159
16160 var maxAnisotropy;
16161
16162 function getMaxAnisotropy() {
16163
16164 if ( maxAnisotropy !== undefined ) { return maxAnisotropy; }
16165
16166 var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
16167
16168 if ( extension !== null ) {
16169
16170 maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
16171
16172 } else {
16173
16174 maxAnisotropy = 0;
16175
16176 }
16177
16178 return maxAnisotropy;
16179
16180 }
16181
16182 function getMaxPrecision( precision ) {
16183
16184 if ( precision === 'highp' ) {
16185
16186 if ( gl.getShaderPrecisionFormat( 35633, 36338 ).precision > 0 &&
16187 gl.getShaderPrecisionFormat( 35632, 36338 ).precision > 0 ) {
16188
16189 return 'highp';
16190
16191 }
16192
16193 precision = 'mediump';
16194
16195 }
16196
16197 if ( precision === 'mediump' ) {
16198
16199 if ( gl.getShaderPrecisionFormat( 35633, 36337 ).precision > 0 &&
16200 gl.getShaderPrecisionFormat( 35632, 36337 ).precision > 0 ) {
16201
16202 return 'mediump';
16203
16204 }
16205
16206 }
16207
16208 return 'lowp';
16209
16210 }
16211
16212 /* eslint-disable no-undef */
16213 var isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext ) ||
16214 ( typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext );
16215 /* eslint-enable no-undef */
16216
16217 var precision = parameters.precision !== undefined ? parameters.precision : 'highp';
16218 var maxPrecision = getMaxPrecision( precision );
16219
16220 if ( maxPrecision !== precision ) {
16221
16222 console.warn( 'THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );
16223 precision = maxPrecision;
16224
16225 }
16226
16227 var logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
16228
16229 var maxTextures = gl.getParameter( 34930 );
16230 var maxVertexTextures = gl.getParameter( 35660 );
16231 var maxTextureSize = gl.getParameter( 3379 );
16232 var maxCubemapSize = gl.getParameter( 34076 );
16233
16234 var maxAttributes = gl.getParameter( 34921 );
16235 var maxVertexUniforms = gl.getParameter( 36347 );
16236 var maxVaryings = gl.getParameter( 36348 );
16237 var maxFragmentUniforms = gl.getParameter( 36349 );
16238
16239 var vertexTextures = maxVertexTextures > 0;
16240 var floatFragmentTextures = isWebGL2 || !! extensions.get( 'OES_texture_float' );
16241 var floatVertexTextures = vertexTextures && floatFragmentTextures;
16242
16243 var maxSamples = isWebGL2 ? gl.getParameter( 36183 ) : 0;
16244
16245 return {
16246
16247 isWebGL2: isWebGL2,
16248
16249 getMaxAnisotropy: getMaxAnisotropy,
16250 getMaxPrecision: getMaxPrecision,
16251
16252 precision: precision,
16253 logarithmicDepthBuffer: logarithmicDepthBuffer,
16254
16255 maxTextures: maxTextures,
16256 maxVertexTextures: maxVertexTextures,
16257 maxTextureSize: maxTextureSize,
16258 maxCubemapSize: maxCubemapSize,
16259
16260 maxAttributes: maxAttributes,
16261 maxVertexUniforms: maxVertexUniforms,
16262 maxVaryings: maxVaryings,
16263 maxFragmentUniforms: maxFragmentUniforms,
16264
16265 vertexTextures: vertexTextures,
16266 floatFragmentTextures: floatFragmentTextures,
16267 floatVertexTextures: floatVertexTextures,
16268
16269 maxSamples: maxSamples
16270
16271 };
16272
16273 }
16274
16275 function WebGLClipping() {
16276
16277 var scope = this;
16278
16279 var globalState = null,
16280 numGlobalPlanes = 0,
16281 localClippingEnabled = false,
16282 renderingShadows = false;
16283
16284 var plane = new Plane(),
16285 viewNormalMatrix = new Matrix3(),
16286
16287 uniform = { value: null, needsUpdate: false };
16288
16289 this.uniform = uniform;
16290 this.numPlanes = 0;
16291 this.numIntersection = 0;
16292
16293 this.init = function ( planes, enableLocalClipping, camera ) {
16294
16295 var enabled =
16296 planes.length !== 0 ||
16297 enableLocalClipping ||
16298 // enable state of previous frame - the clipping code has to
16299 // run another frame in order to reset the state:
16300 numGlobalPlanes !== 0 ||
16301 localClippingEnabled;
16302
16303 localClippingEnabled = enableLocalClipping;
16304
16305 globalState = projectPlanes( planes, camera, 0 );
16306 numGlobalPlanes = planes.length;
16307
16308 return enabled;
16309
16310 };
16311
16312 this.beginShadows = function () {
16313
16314 renderingShadows = true;
16315 projectPlanes( null );
16316
16317 };
16318
16319 this.endShadows = function () {
16320
16321 renderingShadows = false;
16322 resetGlobalState();
16323
16324 };
16325
16326 this.setState = function ( planes, clipIntersection, clipShadows, camera, cache, fromCache ) {
16327
16328 if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) {
16329
16330 // there's no local clipping
16331
16332 if ( renderingShadows ) {
16333
16334 // there's no global clipping
16335
16336 projectPlanes( null );
16337
16338 } else {
16339
16340 resetGlobalState();
16341
16342 }
16343
16344 } else {
16345
16346 var nGlobal = renderingShadows ? 0 : numGlobalPlanes,
16347 lGlobal = nGlobal * 4;
16348
16349 var dstArray = cache.clippingState || null;
16350
16351 uniform.value = dstArray; // ensure unique state
16352
16353 dstArray = projectPlanes( planes, camera, lGlobal, fromCache );
16354
16355 for ( var i = 0; i !== lGlobal; ++ i ) {
16356
16357 dstArray[ i ] = globalState[ i ];
16358
16359 }
16360
16361 cache.clippingState = dstArray;
16362 this.numIntersection = clipIntersection ? this.numPlanes : 0;
16363 this.numPlanes += nGlobal;
16364
16365 }
16366
16367
16368 };
16369
16370 function resetGlobalState() {
16371
16372 if ( uniform.value !== globalState ) {
16373
16374 uniform.value = globalState;
16375 uniform.needsUpdate = numGlobalPlanes > 0;
16376
16377 }
16378
16379 scope.numPlanes = numGlobalPlanes;
16380 scope.numIntersection = 0;
16381
16382 }
16383
16384 function projectPlanes( planes, camera, dstOffset, skipTransform ) {
16385
16386 var nPlanes = planes !== null ? planes.length : 0,
16387 dstArray = null;
16388
16389 if ( nPlanes !== 0 ) {
16390
16391 dstArray = uniform.value;
16392
16393 if ( skipTransform !== true || dstArray === null ) {
16394
16395 var flatSize = dstOffset + nPlanes * 4,
16396 viewMatrix = camera.matrixWorldInverse;
16397
16398 viewNormalMatrix.getNormalMatrix( viewMatrix );
16399
16400 if ( dstArray === null || dstArray.length < flatSize ) {
16401
16402 dstArray = new Float32Array( flatSize );
16403
16404 }
16405
16406 for ( var i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) {
16407
16408 plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix );
16409
16410 plane.normal.toArray( dstArray, i4 );
16411 dstArray[ i4 + 3 ] = plane.constant;
16412
16413 }
16414
16415 }
16416
16417 uniform.value = dstArray;
16418 uniform.needsUpdate = true;
16419
16420 }
16421
16422 scope.numPlanes = nPlanes;
16423 scope.numIntersection = 0;
16424
16425 return dstArray;
16426
16427 }
16428
16429 }
16430
16431 function WebGLExtensions( gl ) {
16432
16433 var extensions = {};
16434
16435 return {
16436
16437 has: function ( name ) {
16438
16439 if ( extensions[ name ] !== undefined ) {
16440
16441 return extensions[ name ];
16442
16443 }
16444
16445 var extension;
16446
16447 switch ( name ) {
16448
16449 case 'WEBGL_depth_texture':
16450 extension = gl.getExtension( 'WEBGL_depth_texture' ) || gl.getExtension( 'MOZ_WEBGL_depth_texture' ) || gl.getExtension( 'WEBKIT_WEBGL_depth_texture' );
16451 break;
16452
16453 case 'EXT_texture_filter_anisotropic':
16454 extension = gl.getExtension( 'EXT_texture_filter_anisotropic' ) || gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) || gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
16455 break;
16456
16457 case 'WEBGL_compressed_texture_s3tc':
16458 extension = gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
16459 break;
16460
16461 case 'WEBGL_compressed_texture_pvrtc':
16462 extension = gl.getExtension( 'WEBGL_compressed_texture_pvrtc' ) || gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_pvrtc' );
16463 break;
16464
16465 default:
16466 extension = gl.getExtension( name );
16467
16468 }
16469
16470 extensions[ name ] = extension;
16471
16472 return !! extension;
16473
16474 },
16475
16476 get: function ( name ) {
16477
16478 if ( ! this.has( name ) ) {
16479
16480 console.warn( 'THREE.WebGLRenderer: ' + name + ' extension not supported.' );
16481
16482 }
16483
16484 return extensions[ name ];
16485
16486 }
16487
16488 };
16489
16490 }
16491
16492 function WebGLGeometries( gl, attributes, info, bindingStates ) {
16493
16494 var geometries = new WeakMap();
16495 var wireframeAttributes = new WeakMap();
16496
16497 function onGeometryDispose( event ) {
16498
16499 var geometry = event.target;
16500 var buffergeometry = geometries.get( geometry );
16501
16502 if ( buffergeometry.index !== null ) {
16503
16504 attributes.remove( buffergeometry.index );
16505
16506 }
16507
16508 for ( var name in buffergeometry.attributes ) {
16509
16510 attributes.remove( buffergeometry.attributes[ name ] );
16511
16512 }
16513
16514 geometry.removeEventListener( 'dispose', onGeometryDispose );
16515
16516 geometries.delete( geometry );
16517
16518 var attribute = wireframeAttributes.get( buffergeometry );
16519
16520 if ( attribute ) {
16521
16522 attributes.remove( attribute );
16523 wireframeAttributes.delete( buffergeometry );
16524
16525 }
16526
16527 bindingStates.releaseStatesOfGeometry( geometry );
16528
16529 if ( geometry.isInstancedBufferGeometry === true ) {
16530
16531 delete geometry._maxInstanceCount;
16532
16533 }
16534
16535 //
16536
16537 info.memory.geometries --;
16538
16539 }
16540
16541 function get( object, geometry ) {
16542
16543 var buffergeometry = geometries.get( geometry );
16544
16545 if ( buffergeometry ) { return buffergeometry; }
16546
16547 geometry.addEventListener( 'dispose', onGeometryDispose );
16548
16549 if ( geometry.isBufferGeometry ) {
16550
16551 buffergeometry = geometry;
16552
16553 } else if ( geometry.isGeometry ) {
16554
16555 if ( geometry._bufferGeometry === undefined ) {
16556
16557 geometry._bufferGeometry = new BufferGeometry().setFromObject( object );
16558
16559 }
16560
16561 buffergeometry = geometry._bufferGeometry;
16562
16563 }
16564
16565 geometries.set( geometry, buffergeometry );
16566
16567 info.memory.geometries ++;
16568
16569 return buffergeometry;
16570
16571 }
16572
16573 function update( geometry ) {
16574
16575 var geometryAttributes = geometry.attributes;
16576
16577 // Updating index buffer in VAO now. See WebGLBindingStates.
16578
16579 for ( var name in geometryAttributes ) {
16580
16581 attributes.update( geometryAttributes[ name ], 34962 );
16582
16583 }
16584
16585 // morph targets
16586
16587 var morphAttributes = geometry.morphAttributes;
16588
16589 for ( var name$1 in morphAttributes ) {
16590
16591 var array = morphAttributes[ name$1 ];
16592
16593 for ( var i = 0, l = array.length; i < l; i ++ ) {
16594
16595 attributes.update( array[ i ], 34962 );
16596
16597 }
16598
16599 }
16600
16601 }
16602
16603 function updateWireframeAttribute( geometry ) {
16604
16605 var indices = [];
16606
16607 var geometryIndex = geometry.index;
16608 var geometryPosition = geometry.attributes.position;
16609 var version = 0;
16610
16611 if ( geometryIndex !== null ) {
16612
16613 var array = geometryIndex.array;
16614 version = geometryIndex.version;
16615
16616 for ( var i = 0, l = array.length; i < l; i += 3 ) {
16617
16618 var a = array[ i + 0 ];
16619 var b = array[ i + 1 ];
16620 var c = array[ i + 2 ];
16621
16622 indices.push( a, b, b, c, c, a );
16623
16624 }
16625
16626 } else {
16627
16628 var array$1 = geometryPosition.array;
16629 version = geometryPosition.version;
16630
16631 for ( var i$1 = 0, l$1 = ( array$1.length / 3 ) - 1; i$1 < l$1; i$1 += 3 ) {
16632
16633 var a$1 = i$1 + 0;
16634 var b$1 = i$1 + 1;
16635 var c$1 = i$1 + 2;
16636
16637 indices.push( a$1, b$1, b$1, c$1, c$1, a$1 );
16638
16639 }
16640
16641 }
16642
16643 var attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
16644 attribute.version = version;
16645
16646 // Updating index buffer in VAO now. See WebGLBindingStates
16647
16648 //
16649
16650 var previousAttribute = wireframeAttributes.get( geometry );
16651
16652 if ( previousAttribute ) { attributes.remove( previousAttribute ); }
16653
16654 //
16655
16656 wireframeAttributes.set( geometry, attribute );
16657
16658 }
16659
16660 function getWireframeAttribute( geometry ) {
16661
16662 var currentAttribute = wireframeAttributes.get( geometry );
16663
16664 if ( currentAttribute ) {
16665
16666 var geometryIndex = geometry.index;
16667
16668 if ( geometryIndex !== null ) {
16669
16670 // if the attribute is obsolete, create a new one
16671
16672 if ( currentAttribute.version < geometryIndex.version ) {
16673
16674 updateWireframeAttribute( geometry );
16675
16676 }
16677
16678 }
16679
16680 } else {
16681
16682 updateWireframeAttribute( geometry );
16683
16684 }
16685
16686 return wireframeAttributes.get( geometry );
16687
16688 }
16689
16690 return {
16691
16692 get: get,
16693 update: update,
16694
16695 getWireframeAttribute: getWireframeAttribute
16696
16697 };
16698
16699 }
16700
16701 function WebGLIndexedBufferRenderer( gl, extensions, info, capabilities ) {
16702
16703 var isWebGL2 = capabilities.isWebGL2;
16704
16705 var mode;
16706
16707 function setMode( value ) {
16708
16709 mode = value;
16710
16711 }
16712
16713 var type, bytesPerElement;
16714
16715 function setIndex( value ) {
16716
16717 type = value.type;
16718 bytesPerElement = value.bytesPerElement;
16719
16720 }
16721
16722 function render( start, count ) {
16723
16724 gl.drawElements( mode, count, type, start * bytesPerElement );
16725
16726 info.update( count, mode, 1 );
16727
16728 }
16729
16730 function renderInstances( start, count, primcount ) {
16731
16732 if ( primcount === 0 ) { return; }
16733
16734 var extension, methodName;
16735
16736 if ( isWebGL2 ) {
16737
16738 extension = gl;
16739 methodName = 'drawElementsInstanced';
16740
16741 } else {
16742
16743 extension = extensions.get( 'ANGLE_instanced_arrays' );
16744 methodName = 'drawElementsInstancedANGLE';
16745
16746 if ( extension === null ) {
16747
16748 console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
16749 return;
16750
16751 }
16752
16753 }
16754
16755 extension[ methodName ]( mode, count, type, start * bytesPerElement, primcount );
16756
16757 info.update( count, mode, primcount );
16758
16759 }
16760
16761 //
16762
16763 this.setMode = setMode;
16764 this.setIndex = setIndex;
16765 this.render = render;
16766 this.renderInstances = renderInstances;
16767
16768 }
16769
16770 function WebGLInfo( gl ) {
16771
16772 var memory = {
16773 geometries: 0,
16774 textures: 0
16775 };
16776
16777 var render = {
16778 frame: 0,
16779 calls: 0,
16780 triangles: 0,
16781 points: 0,
16782 lines: 0
16783 };
16784
16785 function update( count, mode, instanceCount ) {
16786
16787 render.calls ++;
16788
16789 switch ( mode ) {
16790
16791 case 4:
16792 render.triangles += instanceCount * ( count / 3 );
16793 break;
16794
16795 case 1:
16796 render.lines += instanceCount * ( count / 2 );
16797 break;
16798
16799 case 3:
16800 render.lines += instanceCount * ( count - 1 );
16801 break;
16802
16803 case 2:
16804 render.lines += instanceCount * count;
16805 break;
16806
16807 case 0:
16808 render.points += instanceCount * count;
16809 break;
16810
16811 default:
16812 console.error( 'THREE.WebGLInfo: Unknown draw mode:', mode );
16813 break;
16814
16815 }
16816
16817 }
16818
16819 function reset() {
16820
16821 render.frame ++;
16822 render.calls = 0;
16823 render.triangles = 0;
16824 render.points = 0;
16825 render.lines = 0;
16826
16827 }
16828
16829 return {
16830 memory: memory,
16831 render: render,
16832 programs: null,
16833 autoReset: true,
16834 reset: reset,
16835 update: update
16836 };
16837
16838 }
16839
16840 function numericalSort( a, b ) {
16841
16842 return a[ 0 ] - b[ 0 ];
16843
16844 }
16845
16846 function absNumericalSort( a, b ) {
16847
16848 return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] );
16849
16850 }
16851
16852 function WebGLMorphtargets( gl ) {
16853
16854 var influencesList = {};
16855 var morphInfluences = new Float32Array( 8 );
16856
16857 var workInfluences = [];
16858
16859 for ( var i = 0; i < 8; i ++ ) {
16860
16861 workInfluences[ i ] = [ i, 0 ];
16862
16863 }
16864
16865 function update( object, geometry, material, program ) {
16866
16867 var objectInfluences = object.morphTargetInfluences;
16868
16869 // When object doesn't have morph target influences defined, we treat it as a 0-length array
16870 // This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences
16871
16872 var length = objectInfluences === undefined ? 0 : objectInfluences.length;
16873
16874 var influences = influencesList[ geometry.id ];
16875
16876 if ( influences === undefined ) {
16877
16878 // initialise list
16879
16880 influences = [];
16881
16882 for ( var i = 0; i < length; i ++ ) {
16883
16884 influences[ i ] = [ i, 0 ];
16885
16886 }
16887
16888 influencesList[ geometry.id ] = influences;
16889
16890 }
16891
16892 // Collect influences
16893
16894 for ( var i$1 = 0; i$1 < length; i$1 ++ ) {
16895
16896 var influence = influences[ i$1 ];
16897
16898 influence[ 0 ] = i$1;
16899 influence[ 1 ] = objectInfluences[ i$1 ];
16900
16901 }
16902
16903 influences.sort( absNumericalSort );
16904
16905 for ( var i$2 = 0; i$2 < 8; i$2 ++ ) {
16906
16907 if ( i$2 < length && influences[ i$2 ][ 1 ] ) {
16908
16909 workInfluences[ i$2 ][ 0 ] = influences[ i$2 ][ 0 ];
16910 workInfluences[ i$2 ][ 1 ] = influences[ i$2 ][ 1 ];
16911
16912 } else {
16913
16914 workInfluences[ i$2 ][ 0 ] = Number.MAX_SAFE_INTEGER;
16915 workInfluences[ i$2 ][ 1 ] = 0;
16916
16917 }
16918
16919 }
16920
16921 workInfluences.sort( numericalSort );
16922
16923 var morphTargets = material.morphTargets && geometry.morphAttributes.position;
16924 var morphNormals = material.morphNormals && geometry.morphAttributes.normal;
16925
16926 var morphInfluencesSum = 0;
16927
16928 for ( var i$3 = 0; i$3 < 8; i$3 ++ ) {
16929
16930 var influence$1 = workInfluences[ i$3 ];
16931 var index = influence$1[ 0 ];
16932 var value = influence$1[ 1 ];
16933
16934 if ( index !== Number.MAX_SAFE_INTEGER && value ) {
16935
16936 if ( morphTargets && geometry.getAttribute( 'morphTarget' + i$3 ) !== morphTargets[ index ] ) {
16937
16938 geometry.setAttribute( 'morphTarget' + i$3, morphTargets[ index ] );
16939
16940 }
16941
16942 if ( morphNormals && geometry.getAttribute( 'morphNormal' + i$3 ) !== morphNormals[ index ] ) {
16943
16944 geometry.setAttribute( 'morphNormal' + i$3, morphNormals[ index ] );
16945
16946 }
16947
16948 morphInfluences[ i$3 ] = value;
16949 morphInfluencesSum += value;
16950
16951 } else {
16952
16953 if ( morphTargets && geometry.getAttribute( 'morphTarget' + i$3 ) !== undefined ) {
16954
16955 geometry.deleteAttribute( 'morphTarget' + i$3 );
16956
16957 }
16958
16959 if ( morphNormals && geometry.getAttribute( 'morphNormal' + i$3 ) !== undefined ) {
16960
16961 geometry.deleteAttribute( 'morphNormal' + i$3 );
16962
16963 }
16964
16965 morphInfluences[ i$3 ] = 0;
16966
16967 }
16968
16969 }
16970
16971 // GLSL shader uses formula baseinfluence * base + sum(target * influence)
16972 // This allows us to switch between absolute morphs and relative morphs without changing shader code
16973 // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence)
16974 var morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
16975
16976 program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence );
16977 program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences );
16978
16979 }
16980
16981 return {
16982
16983 update: update
16984
16985 };
16986
16987 }
16988
16989 function WebGLObjects( gl, geometries, attributes, info ) {
16990
16991 var updateMap = new WeakMap();
16992
16993 function update( object ) {
16994
16995 var frame = info.render.frame;
16996
16997 var geometry = object.geometry;
16998 var buffergeometry = geometries.get( object, geometry );
16999
17000 // Update once per frame
17001
17002 if ( updateMap.get( buffergeometry ) !== frame ) {
17003
17004 if ( geometry.isGeometry ) {
17005
17006 buffergeometry.updateFromObject( object );
17007
17008 }
17009
17010 geometries.update( buffergeometry );
17011
17012 updateMap.set( buffergeometry, frame );
17013
17014 }
17015
17016 if ( object.isInstancedMesh ) {
17017
17018 attributes.update( object.instanceMatrix, 34962 );
17019
17020 }
17021
17022 return buffergeometry;
17023
17024 }
17025
17026 function dispose() {
17027
17028 updateMap = new WeakMap();
17029
17030 }
17031
17032 return {
17033
17034 update: update,
17035 dispose: dispose
17036
17037 };
17038
17039 }
17040
17041 function CubeTexture( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {
17042
17043 images = images !== undefined ? images : [];
17044 mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
17045 format = format !== undefined ? format : RGBFormat;
17046
17047 Texture.call( this, images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
17048
17049 this.flipY = false;
17050
17051 }
17052
17053 CubeTexture.prototype = Object.create( Texture.prototype );
17054 CubeTexture.prototype.constructor = CubeTexture;
17055
17056 CubeTexture.prototype.isCubeTexture = true;
17057
17058 Object.defineProperty( CubeTexture.prototype, 'images', {
17059
17060 get: function () {
17061
17062 return this.image;
17063
17064 },
17065
17066 set: function ( value ) {
17067
17068 this.image = value;
17069
17070 }
17071
17072 } );
17073
17074 function DataTexture2DArray( data, width, height, depth ) {
17075
17076 Texture.call( this, null );
17077
17078 this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 };
17079
17080 this.magFilter = NearestFilter;
17081 this.minFilter = NearestFilter;
17082
17083 this.wrapR = ClampToEdgeWrapping;
17084
17085 this.generateMipmaps = false;
17086 this.flipY = false;
17087
17088 this.needsUpdate = true;
17089
17090 }
17091
17092 DataTexture2DArray.prototype = Object.create( Texture.prototype );
17093 DataTexture2DArray.prototype.constructor = DataTexture2DArray;
17094 DataTexture2DArray.prototype.isDataTexture2DArray = true;
17095
17096 function DataTexture3D( data, width, height, depth ) {
17097
17098 // We're going to add .setXXX() methods for setting properties later.
17099 // Users can still set in DataTexture3D directly.
17100 //
17101 // const texture = new THREE.DataTexture3D( data, width, height, depth );
17102 // texture.anisotropy = 16;
17103 //
17104 // See #14839
17105
17106 Texture.call( this, null );
17107
17108 this.image = { data: data || null, width: width || 1, height: height || 1, depth: depth || 1 };
17109
17110 this.magFilter = NearestFilter;
17111 this.minFilter = NearestFilter;
17112
17113 this.wrapR = ClampToEdgeWrapping;
17114
17115 this.generateMipmaps = false;
17116 this.flipY = false;
17117
17118 this.needsUpdate = true;
17119
17120
17121 }
17122
17123 DataTexture3D.prototype = Object.create( Texture.prototype );
17124 DataTexture3D.prototype.constructor = DataTexture3D;
17125 DataTexture3D.prototype.isDataTexture3D = true;
17126
17127 /**
17128 * Uniforms of a program.
17129 * Those form a tree structure with a special top-level container for the root,
17130 * which you get by calling 'new WebGLUniforms( gl, program )'.
17131 *
17132 *
17133 * Properties of inner nodes including the top-level container:
17134 *
17135 * .seq - array of nested uniforms
17136 * .map - nested uniforms by name
17137 *
17138 *
17139 * Methods of all nodes except the top-level container:
17140 *
17141 * .setValue( gl, value, [textures] )
17142 *
17143 * uploads a uniform value(s)
17144 * the 'textures' parameter is needed for sampler uniforms
17145 *
17146 *
17147 * Static methods of the top-level container (textures factorizations):
17148 *
17149 * .upload( gl, seq, values, textures )
17150 *
17151 * sets uniforms in 'seq' to 'values[id].value'
17152 *
17153 * .seqWithValue( seq, values ) : filteredSeq
17154 *
17155 * filters 'seq' entries with corresponding entry in values
17156 *
17157 *
17158 * Methods of the top-level container (textures factorizations):
17159 *
17160 * .setValue( gl, name, value, textures )
17161 *
17162 * sets uniform with name 'name' to 'value'
17163 *
17164 * .setOptional( gl, obj, prop )
17165 *
17166 * like .set for an optional property of the object
17167 *
17168 */
17169
17170 var emptyTexture = new Texture();
17171 var emptyTexture2dArray = new DataTexture2DArray();
17172 var emptyTexture3d = new DataTexture3D();
17173 var emptyCubeTexture = new CubeTexture();
17174
17175 // --- Utilities ---
17176
17177 // Array Caches (provide typed arrays for temporary by size)
17178
17179 var arrayCacheF32 = [];
17180 var arrayCacheI32 = [];
17181
17182 // Float32Array caches used for uploading Matrix uniforms
17183
17184 var mat4array = new Float32Array( 16 );
17185 var mat3array = new Float32Array( 9 );
17186 var mat2array = new Float32Array( 4 );
17187
17188 // Flattening for arrays of vectors and matrices
17189
17190 function flatten( array, nBlocks, blockSize ) {
17191
17192 var firstElem = array[ 0 ];
17193
17194 if ( firstElem <= 0 || firstElem > 0 ) { return array; }
17195 // unoptimized: ! isNaN( firstElem )
17196 // see http://jacksondunstan.com/articles/983
17197
17198 var n = nBlocks * blockSize,
17199 r = arrayCacheF32[ n ];
17200
17201 if ( r === undefined ) {
17202
17203 r = new Float32Array( n );
17204 arrayCacheF32[ n ] = r;
17205
17206 }
17207
17208 if ( nBlocks !== 0 ) {
17209
17210 firstElem.toArray( r, 0 );
17211
17212 for ( var i = 1, offset = 0; i !== nBlocks; ++ i ) {
17213
17214 offset += blockSize;
17215 array[ i ].toArray( r, offset );
17216
17217 }
17218
17219 }
17220
17221 return r;
17222
17223 }
17224
17225 function arraysEqual( a, b ) {
17226
17227 if ( a.length !== b.length ) { return false; }
17228
17229 for ( var i = 0, l = a.length; i < l; i ++ ) {
17230
17231 if ( a[ i ] !== b[ i ] ) { return false; }
17232
17233 }
17234
17235 return true;
17236
17237 }
17238
17239 function copyArray( a, b ) {
17240
17241 for ( var i = 0, l = b.length; i < l; i ++ ) {
17242
17243 a[ i ] = b[ i ];
17244
17245 }
17246
17247 }
17248
17249 // Texture unit allocation
17250
17251 function allocTexUnits( textures, n ) {
17252
17253 var r = arrayCacheI32[ n ];
17254
17255 if ( r === undefined ) {
17256
17257 r = new Int32Array( n );
17258 arrayCacheI32[ n ] = r;
17259
17260 }
17261
17262 for ( var i = 0; i !== n; ++ i ) {
17263
17264 r[ i ] = textures.allocateTextureUnit();
17265
17266 }
17267
17268 return r;
17269
17270 }
17271
17272 // --- Setters ---
17273
17274 // Note: Defining these methods externally, because they come in a bunch
17275 // and this way their names minify.
17276
17277 // Single scalar
17278
17279 function setValueV1f( gl, v ) {
17280
17281 var cache = this.cache;
17282
17283 if ( cache[ 0 ] === v ) { return; }
17284
17285 gl.uniform1f( this.addr, v );
17286
17287 cache[ 0 ] = v;
17288
17289 }
17290
17291 // Single float vector (from flat array or THREE.VectorN)
17292
17293 function setValueV2f( gl, v ) {
17294
17295 var cache = this.cache;
17296
17297 if ( v.x !== undefined ) {
17298
17299 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y ) {
17300
17301 gl.uniform2f( this.addr, v.x, v.y );
17302
17303 cache[ 0 ] = v.x;
17304 cache[ 1 ] = v.y;
17305
17306 }
17307
17308 } else {
17309
17310 if ( arraysEqual( cache, v ) ) { return; }
17311
17312 gl.uniform2fv( this.addr, v );
17313
17314 copyArray( cache, v );
17315
17316 }
17317
17318 }
17319
17320 function setValueV3f( gl, v ) {
17321
17322 var cache = this.cache;
17323
17324 if ( v.x !== undefined ) {
17325
17326 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z ) {
17327
17328 gl.uniform3f( this.addr, v.x, v.y, v.z );
17329
17330 cache[ 0 ] = v.x;
17331 cache[ 1 ] = v.y;
17332 cache[ 2 ] = v.z;
17333
17334 }
17335
17336 } else if ( v.r !== undefined ) {
17337
17338 if ( cache[ 0 ] !== v.r || cache[ 1 ] !== v.g || cache[ 2 ] !== v.b ) {
17339
17340 gl.uniform3f( this.addr, v.r, v.g, v.b );
17341
17342 cache[ 0 ] = v.r;
17343 cache[ 1 ] = v.g;
17344 cache[ 2 ] = v.b;
17345
17346 }
17347
17348 } else {
17349
17350 if ( arraysEqual( cache, v ) ) { return; }
17351
17352 gl.uniform3fv( this.addr, v );
17353
17354 copyArray( cache, v );
17355
17356 }
17357
17358 }
17359
17360 function setValueV4f( gl, v ) {
17361
17362 var cache = this.cache;
17363
17364 if ( v.x !== undefined ) {
17365
17366 if ( cache[ 0 ] !== v.x || cache[ 1 ] !== v.y || cache[ 2 ] !== v.z || cache[ 3 ] !== v.w ) {
17367
17368 gl.uniform4f( this.addr, v.x, v.y, v.z, v.w );
17369
17370 cache[ 0 ] = v.x;
17371 cache[ 1 ] = v.y;
17372 cache[ 2 ] = v.z;
17373 cache[ 3 ] = v.w;
17374
17375 }
17376
17377 } else {
17378
17379 if ( arraysEqual( cache, v ) ) { return; }
17380
17381 gl.uniform4fv( this.addr, v );
17382
17383 copyArray( cache, v );
17384
17385 }
17386
17387 }
17388
17389 // Single matrix (from flat array or MatrixN)
17390
17391 function setValueM2( gl, v ) {
17392
17393 var cache = this.cache;
17394 var elements = v.elements;
17395
17396 if ( elements === undefined ) {
17397
17398 if ( arraysEqual( cache, v ) ) { return; }
17399
17400 gl.uniformMatrix2fv( this.addr, false, v );
17401
17402 copyArray( cache, v );
17403
17404 } else {
17405
17406 if ( arraysEqual( cache, elements ) ) { return; }
17407
17408 mat2array.set( elements );
17409
17410 gl.uniformMatrix2fv( this.addr, false, mat2array );
17411
17412 copyArray( cache, elements );
17413
17414 }
17415
17416 }
17417
17418 function setValueM3( gl, v ) {
17419
17420 var cache = this.cache;
17421 var elements = v.elements;
17422
17423 if ( elements === undefined ) {
17424
17425 if ( arraysEqual( cache, v ) ) { return; }
17426
17427 gl.uniformMatrix3fv( this.addr, false, v );
17428
17429 copyArray( cache, v );
17430
17431 } else {
17432
17433 if ( arraysEqual( cache, elements ) ) { return; }
17434
17435 mat3array.set( elements );
17436
17437 gl.uniformMatrix3fv( this.addr, false, mat3array );
17438
17439 copyArray( cache, elements );
17440
17441 }
17442
17443 }
17444
17445 function setValueM4( gl, v ) {
17446
17447 var cache = this.cache;
17448 var elements = v.elements;
17449
17450 if ( elements === undefined ) {
17451
17452 if ( arraysEqual( cache, v ) ) { return; }
17453
17454 gl.uniformMatrix4fv( this.addr, false, v );
17455
17456 copyArray( cache, v );
17457
17458 } else {
17459
17460 if ( arraysEqual( cache, elements ) ) { return; }
17461
17462 mat4array.set( elements );
17463
17464 gl.uniformMatrix4fv( this.addr, false, mat4array );
17465
17466 copyArray( cache, elements );
17467
17468 }
17469
17470 }
17471
17472 // Single texture (2D / Cube)
17473
17474 function setValueT1( gl, v, textures ) {
17475
17476 var cache = this.cache;
17477 var unit = textures.allocateTextureUnit();
17478
17479 if ( cache[ 0 ] !== unit ) {
17480
17481 gl.uniform1i( this.addr, unit );
17482 cache[ 0 ] = unit;
17483
17484 }
17485
17486 textures.safeSetTexture2D( v || emptyTexture, unit );
17487
17488 }
17489
17490 function setValueT2DArray1( gl, v, textures ) {
17491
17492 var cache = this.cache;
17493 var unit = textures.allocateTextureUnit();
17494
17495 if ( cache[ 0 ] !== unit ) {
17496
17497 gl.uniform1i( this.addr, unit );
17498 cache[ 0 ] = unit;
17499
17500 }
17501
17502 textures.setTexture2DArray( v || emptyTexture2dArray, unit );
17503
17504 }
17505
17506 function setValueT3D1( gl, v, textures ) {
17507
17508 var cache = this.cache;
17509 var unit = textures.allocateTextureUnit();
17510
17511 if ( cache[ 0 ] !== unit ) {
17512
17513 gl.uniform1i( this.addr, unit );
17514 cache[ 0 ] = unit;
17515
17516 }
17517
17518 textures.setTexture3D( v || emptyTexture3d, unit );
17519
17520 }
17521
17522 function setValueT6( gl, v, textures ) {
17523
17524 var cache = this.cache;
17525 var unit = textures.allocateTextureUnit();
17526
17527 if ( cache[ 0 ] !== unit ) {
17528
17529 gl.uniform1i( this.addr, unit );
17530 cache[ 0 ] = unit;
17531
17532 }
17533
17534 textures.safeSetTextureCube( v || emptyCubeTexture, unit );
17535
17536 }
17537
17538 // Integer / Boolean vectors or arrays thereof (always flat arrays)
17539
17540 function setValueV1i( gl, v ) {
17541
17542 var cache = this.cache;
17543
17544 if ( cache[ 0 ] === v ) { return; }
17545
17546 gl.uniform1i( this.addr, v );
17547
17548 cache[ 0 ] = v;
17549
17550 }
17551
17552 function setValueV2i( gl, v ) {
17553
17554 var cache = this.cache;
17555
17556 if ( arraysEqual( cache, v ) ) { return; }
17557
17558 gl.uniform2iv( this.addr, v );
17559
17560 copyArray( cache, v );
17561
17562 }
17563
17564 function setValueV3i( gl, v ) {
17565
17566 var cache = this.cache;
17567
17568 if ( arraysEqual( cache, v ) ) { return; }
17569
17570 gl.uniform3iv( this.addr, v );
17571
17572 copyArray( cache, v );
17573
17574 }
17575
17576 function setValueV4i( gl, v ) {
17577
17578 var cache = this.cache;
17579
17580 if ( arraysEqual( cache, v ) ) { return; }
17581
17582 gl.uniform4iv( this.addr, v );
17583
17584 copyArray( cache, v );
17585
17586 }
17587
17588 // uint
17589
17590 function setValueV1ui( gl, v ) {
17591
17592 var cache = this.cache;
17593
17594 if ( cache[ 0 ] === v ) { return; }
17595
17596 gl.uniform1ui( this.addr, v );
17597
17598 cache[ 0 ] = v;
17599
17600 }
17601
17602 // Helper to pick the right setter for the singular case
17603
17604 function getSingularSetter( type ) {
17605
17606 switch ( type ) {
17607
17608 case 0x1406: return setValueV1f; // FLOAT
17609 case 0x8b50: return setValueV2f; // _VEC2
17610 case 0x8b51: return setValueV3f; // _VEC3
17611 case 0x8b52: return setValueV4f; // _VEC4
17612
17613 case 0x8b5a: return setValueM2; // _MAT2
17614 case 0x8b5b: return setValueM3; // _MAT3
17615 case 0x8b5c: return setValueM4; // _MAT4
17616
17617 case 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL
17618 case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2
17619 case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3
17620 case 0x8b55: case 0x8b59: return setValueV4i; // _VEC4
17621
17622 case 0x1405: return setValueV1ui; // UINT
17623
17624 case 0x8b5e: // SAMPLER_2D
17625 case 0x8d66: // SAMPLER_EXTERNAL_OES
17626 case 0x8dca: // INT_SAMPLER_2D
17627 case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
17628 case 0x8b62: // SAMPLER_2D_SHADOW
17629 return setValueT1;
17630
17631 case 0x8b5f: // SAMPLER_3D
17632 case 0x8dcb: // INT_SAMPLER_3D
17633 case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D
17634 return setValueT3D1;
17635
17636 case 0x8b60: // SAMPLER_CUBE
17637 case 0x8dcc: // INT_SAMPLER_CUBE
17638 case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
17639 case 0x8dc5: // SAMPLER_CUBE_SHADOW
17640 return setValueT6;
17641
17642 case 0x8dc1: // SAMPLER_2D_ARRAY
17643 case 0x8dcf: // INT_SAMPLER_2D_ARRAY
17644 case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY
17645 case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW
17646 return setValueT2DArray1;
17647
17648 }
17649
17650 }
17651
17652 // Array of scalars
17653 function setValueV1fArray( gl, v ) {
17654
17655 gl.uniform1fv( this.addr, v );
17656
17657 }
17658
17659 // Integer / Boolean vectors or arrays thereof (always flat arrays)
17660 function setValueV1iArray( gl, v ) {
17661
17662 gl.uniform1iv( this.addr, v );
17663
17664 }
17665
17666 function setValueV2iArray( gl, v ) {
17667
17668 gl.uniform2iv( this.addr, v );
17669
17670 }
17671
17672 function setValueV3iArray( gl, v ) {
17673
17674 gl.uniform3iv( this.addr, v );
17675
17676 }
17677
17678 function setValueV4iArray( gl, v ) {
17679
17680 gl.uniform4iv( this.addr, v );
17681
17682 }
17683
17684
17685 // Array of vectors (flat or from THREE classes)
17686
17687 function setValueV2fArray( gl, v ) {
17688
17689 var data = flatten( v, this.size, 2 );
17690
17691 gl.uniform2fv( this.addr, data );
17692
17693 }
17694
17695 function setValueV3fArray( gl, v ) {
17696
17697 var data = flatten( v, this.size, 3 );
17698
17699 gl.uniform3fv( this.addr, data );
17700
17701 }
17702
17703 function setValueV4fArray( gl, v ) {
17704
17705 var data = flatten( v, this.size, 4 );
17706
17707 gl.uniform4fv( this.addr, data );
17708
17709 }
17710
17711 // Array of matrices (flat or from THREE clases)
17712
17713 function setValueM2Array( gl, v ) {
17714
17715 var data = flatten( v, this.size, 4 );
17716
17717 gl.uniformMatrix2fv( this.addr, false, data );
17718
17719 }
17720
17721 function setValueM3Array( gl, v ) {
17722
17723 var data = flatten( v, this.size, 9 );
17724
17725 gl.uniformMatrix3fv( this.addr, false, data );
17726
17727 }
17728
17729 function setValueM4Array( gl, v ) {
17730
17731 var data = flatten( v, this.size, 16 );
17732
17733 gl.uniformMatrix4fv( this.addr, false, data );
17734
17735 }
17736
17737 // Array of textures (2D / Cube)
17738
17739 function setValueT1Array( gl, v, textures ) {
17740
17741 var n = v.length;
17742
17743 var units = allocTexUnits( textures, n );
17744
17745 gl.uniform1iv( this.addr, units );
17746
17747 for ( var i = 0; i !== n; ++ i ) {
17748
17749 textures.safeSetTexture2D( v[ i ] || emptyTexture, units[ i ] );
17750
17751 }
17752
17753 }
17754
17755 function setValueT6Array( gl, v, textures ) {
17756
17757 var n = v.length;
17758
17759 var units = allocTexUnits( textures, n );
17760
17761 gl.uniform1iv( this.addr, units );
17762
17763 for ( var i = 0; i !== n; ++ i ) {
17764
17765 textures.safeSetTextureCube( v[ i ] || emptyCubeTexture, units[ i ] );
17766
17767 }
17768
17769 }
17770
17771 // Helper to pick the right setter for a pure (bottom-level) array
17772
17773 function getPureArraySetter( type ) {
17774
17775 switch ( type ) {
17776
17777 case 0x1406: return setValueV1fArray; // FLOAT
17778 case 0x8b50: return setValueV2fArray; // _VEC2
17779 case 0x8b51: return setValueV3fArray; // _VEC3
17780 case 0x8b52: return setValueV4fArray; // _VEC4
17781
17782 case 0x8b5a: return setValueM2Array; // _MAT2
17783 case 0x8b5b: return setValueM3Array; // _MAT3
17784 case 0x8b5c: return setValueM4Array; // _MAT4
17785
17786 case 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL
17787 case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2
17788 case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3
17789 case 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4
17790
17791 case 0x8b5e: // SAMPLER_2D
17792 case 0x8d66: // SAMPLER_EXTERNAL_OES
17793 case 0x8dca: // INT_SAMPLER_2D
17794 case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
17795 case 0x8b62: // SAMPLER_2D_SHADOW
17796 return setValueT1Array;
17797
17798 case 0x8b60: // SAMPLER_CUBE
17799 case 0x8dcc: // INT_SAMPLER_CUBE
17800 case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
17801 case 0x8dc5: // SAMPLER_CUBE_SHADOW
17802 return setValueT6Array;
17803
17804 }
17805
17806 }
17807
17808 // --- Uniform Classes ---
17809
17810 function SingleUniform( id, activeInfo, addr ) {
17811
17812 this.id = id;
17813 this.addr = addr;
17814 this.cache = [];
17815 this.setValue = getSingularSetter( activeInfo.type );
17816
17817 // this.path = activeInfo.name; // DEBUG
17818
17819 }
17820
17821 function PureArrayUniform( id, activeInfo, addr ) {
17822
17823 this.id = id;
17824 this.addr = addr;
17825 this.cache = [];
17826 this.size = activeInfo.size;
17827 this.setValue = getPureArraySetter( activeInfo.type );
17828
17829 // this.path = activeInfo.name; // DEBUG
17830
17831 }
17832
17833 PureArrayUniform.prototype.updateCache = function ( data ) {
17834
17835 var cache = this.cache;
17836
17837 if ( data instanceof Float32Array && cache.length !== data.length ) {
17838
17839 this.cache = new Float32Array( data.length );
17840
17841 }
17842
17843 copyArray( cache, data );
17844
17845 };
17846
17847 function StructuredUniform( id ) {
17848
17849 this.id = id;
17850
17851 this.seq = [];
17852 this.map = {};
17853
17854 }
17855
17856 StructuredUniform.prototype.setValue = function ( gl, value, textures ) {
17857
17858 var seq = this.seq;
17859
17860 for ( var i = 0, n = seq.length; i !== n; ++ i ) {
17861
17862 var u = seq[ i ];
17863 u.setValue( gl, value[ u.id ], textures );
17864
17865 }
17866
17867 };
17868
17869 // --- Top-level ---
17870
17871 // Parser - builds up the property tree from the path strings
17872
17873 var RePathPart = /([\w\d_]+)(\])?(\[|\.)?/g;
17874
17875 // extracts
17876 // - the identifier (member name or array index)
17877 // - followed by an optional right bracket (found when array index)
17878 // - followed by an optional left bracket or dot (type of subscript)
17879 //
17880 // Note: These portions can be read in a non-overlapping fashion and
17881 // allow straightforward parsing of the hierarchy that WebGL encodes
17882 // in the uniform names.
17883
17884 function addUniform( container, uniformObject ) {
17885
17886 container.seq.push( uniformObject );
17887 container.map[ uniformObject.id ] = uniformObject;
17888
17889 }
17890
17891 function parseUniform( activeInfo, addr, container ) {
17892
17893 var path = activeInfo.name,
17894 pathLength = path.length;
17895
17896 // reset RegExp object, because of the early exit of a previous run
17897 RePathPart.lastIndex = 0;
17898
17899 while ( true ) {
17900
17901 var match = RePathPart.exec( path ),
17902 matchEnd = RePathPart.lastIndex;
17903
17904 var id = match[ 1 ],
17905 idIsIndex = match[ 2 ] === ']',
17906 subscript = match[ 3 ];
17907
17908 if ( idIsIndex ) { id = id | 0; } // convert to integer
17909
17910 if ( subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength ) {
17911
17912 // bare name or "pure" bottom-level array "[0]" suffix
17913
17914 addUniform( container, subscript === undefined ?
17915 new SingleUniform( id, activeInfo, addr ) :
17916 new PureArrayUniform( id, activeInfo, addr ) );
17917
17918 break;
17919
17920 } else {
17921
17922 // step into inner node / create it in case it doesn't exist
17923
17924 var map = container.map;
17925 var next = map[ id ];
17926
17927 if ( next === undefined ) {
17928
17929 next = new StructuredUniform( id );
17930 addUniform( container, next );
17931
17932 }
17933
17934 container = next;
17935
17936 }
17937
17938 }
17939
17940 }
17941
17942 // Root Container
17943
17944 function WebGLUniforms( gl, program ) {
17945
17946 this.seq = [];
17947 this.map = {};
17948
17949 var n = gl.getProgramParameter( program, 35718 );
17950
17951 for ( var i = 0; i < n; ++ i ) {
17952
17953 var info = gl.getActiveUniform( program, i ),
17954 addr = gl.getUniformLocation( program, info.name );
17955
17956 parseUniform( info, addr, this );
17957
17958 }
17959
17960 }
17961
17962 WebGLUniforms.prototype.setValue = function ( gl, name, value, textures ) {
17963
17964 var u = this.map[ name ];
17965
17966 if ( u !== undefined ) { u.setValue( gl, value, textures ); }
17967
17968 };
17969
17970 WebGLUniforms.prototype.setOptional = function ( gl, object, name ) {
17971
17972 var v = object[ name ];
17973
17974 if ( v !== undefined ) { this.setValue( gl, name, v ); }
17975
17976 };
17977
17978
17979 // Static interface
17980
17981 WebGLUniforms.upload = function ( gl, seq, values, textures ) {
17982
17983 for ( var i = 0, n = seq.length; i !== n; ++ i ) {
17984
17985 var u = seq[ i ],
17986 v = values[ u.id ];
17987
17988 if ( v.needsUpdate !== false ) {
17989
17990 // note: always updating when .needsUpdate is undefined
17991 u.setValue( gl, v.value, textures );
17992
17993 }
17994
17995 }
17996
17997 };
17998
17999 WebGLUniforms.seqWithValue = function ( seq, values ) {
18000
18001 var r = [];
18002
18003 for ( var i = 0, n = seq.length; i !== n; ++ i ) {
18004
18005 var u = seq[ i ];
18006 if ( u.id in values ) { r.push( u ); }
18007
18008 }
18009
18010 return r;
18011
18012 };
18013
18014 function WebGLShader( gl, type, string ) {
18015
18016 var shader = gl.createShader( type );
18017
18018 gl.shaderSource( shader, string );
18019 gl.compileShader( shader );
18020
18021 return shader;
18022
18023 }
18024
18025 var programIdCount = 0;
18026
18027 function addLineNumbers( string ) {
18028
18029 var lines = string.split( '\n' );
18030
18031 for ( var i = 0; i < lines.length; i ++ ) {
18032
18033 lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];
18034
18035 }
18036
18037 return lines.join( '\n' );
18038
18039 }
18040
18041 function getEncodingComponents( encoding ) {
18042
18043 switch ( encoding ) {
18044
18045 case LinearEncoding:
18046 return [ 'Linear', '( value )' ];
18047 case sRGBEncoding:
18048 return [ 'sRGB', '( value )' ];
18049 case RGBEEncoding:
18050 return [ 'RGBE', '( value )' ];
18051 case RGBM7Encoding:
18052 return [ 'RGBM', '( value, 7.0 )' ];
18053 case RGBM16Encoding:
18054 return [ 'RGBM', '( value, 16.0 )' ];
18055 case RGBDEncoding:
18056 return [ 'RGBD', '( value, 256.0 )' ];
18057 case GammaEncoding:
18058 return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ];
18059 case LogLuvEncoding:
18060 return [ 'LogLuv', '( value )' ];
18061 default:
18062 console.warn( 'THREE.WebGLProgram: Unsupported encoding:', encoding );
18063 return [ 'Linear', '( value )' ];
18064
18065 }
18066
18067 }
18068
18069 function getShaderErrors( gl, shader, type ) {
18070
18071 var status = gl.getShaderParameter( shader, 35713 );
18072 var log = gl.getShaderInfoLog( shader ).trim();
18073
18074 if ( status && log === '' ) { return ''; }
18075
18076 // --enable-privileged-webgl-extension
18077 // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
18078
18079 var source = gl.getShaderSource( shader );
18080
18081 return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers( source );
18082
18083 }
18084
18085 function getTexelDecodingFunction( functionName, encoding ) {
18086
18087 var components = getEncodingComponents( encoding );
18088 return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }';
18089
18090 }
18091
18092 function getTexelEncodingFunction( functionName, encoding ) {
18093
18094 var components = getEncodingComponents( encoding );
18095 return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }';
18096
18097 }
18098
18099 function getToneMappingFunction( functionName, toneMapping ) {
18100
18101 var toneMappingName;
18102
18103 switch ( toneMapping ) {
18104
18105 case LinearToneMapping:
18106 toneMappingName = 'Linear';
18107 break;
18108
18109 case ReinhardToneMapping:
18110 toneMappingName = 'Reinhard';
18111 break;
18112
18113 case CineonToneMapping:
18114 toneMappingName = 'OptimizedCineon';
18115 break;
18116
18117 case ACESFilmicToneMapping:
18118 toneMappingName = 'ACESFilmic';
18119 break;
18120
18121 case CustomToneMapping:
18122 toneMappingName = 'Custom';
18123 break;
18124
18125 default:
18126 console.warn( 'THREE.WebGLProgram: Unsupported toneMapping:', toneMapping );
18127 toneMappingName = 'Linear';
18128
18129 }
18130
18131 return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';
18132
18133 }
18134
18135 function generateExtensions( parameters ) {
18136
18137 var chunks = [
18138 ( parameters.extensionDerivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ) ? '#extension GL_OES_standard_derivatives : enable' : '',
18139 ( parameters.extensionFragDepth || parameters.logarithmicDepthBuffer ) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '',
18140 ( parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ) ? '#extension GL_EXT_draw_buffers : require' : '',
18141 ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : ''
18142 ];
18143
18144 return chunks.filter( filterEmptyLine ).join( '\n' );
18145
18146 }
18147
18148 function generateDefines( defines ) {
18149
18150 var chunks = [];
18151
18152 for ( var name in defines ) {
18153
18154 var value = defines[ name ];
18155
18156 if ( value === false ) { continue; }
18157
18158 chunks.push( '#define ' + name + ' ' + value );
18159
18160 }
18161
18162 return chunks.join( '\n' );
18163
18164 }
18165
18166 function fetchAttributeLocations( gl, program ) {
18167
18168 var attributes = {};
18169
18170 var n = gl.getProgramParameter( program, 35721 );
18171
18172 for ( var i = 0; i < n; i ++ ) {
18173
18174 var info = gl.getActiveAttrib( program, i );
18175 var name = info.name;
18176
18177 // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i );
18178
18179 attributes[ name ] = gl.getAttribLocation( program, name );
18180
18181 }
18182
18183 return attributes;
18184
18185 }
18186
18187 function filterEmptyLine( string ) {
18188
18189 return string !== '';
18190
18191 }
18192
18193 function replaceLightNums( string, parameters ) {
18194
18195 return string
18196 .replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
18197 .replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
18198 .replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
18199 .replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
18200 .replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights )
18201 .replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows )
18202 .replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows )
18203 .replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows );
18204
18205 }
18206
18207 function replaceClippingPlaneNums( string, parameters ) {
18208
18209 return string
18210 .replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes )
18211 .replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) );
18212
18213 }
18214
18215 // Resolve Includes
18216
18217 var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
18218
18219 function resolveIncludes( string ) {
18220
18221 return string.replace( includePattern, includeReplacer );
18222
18223 }
18224
18225 function includeReplacer( match, include ) {
18226
18227 var string = ShaderChunk[ include ];
18228
18229 if ( string === undefined ) {
18230
18231 throw new Error( 'Can not resolve #include <' + include + '>' );
18232
18233 }
18234
18235 return resolveIncludes( string );
18236
18237 }
18238
18239 // Unroll Loops
18240
18241 var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
18242 var unrollLoopPattern = /#pragma unroll_loop_start[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g;
18243
18244 function unrollLoops( string ) {
18245
18246 return string
18247 .replace( unrollLoopPattern, loopReplacer )
18248 .replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer );
18249
18250 }
18251
18252 function deprecatedLoopReplacer( match, start, end, snippet ) {
18253
18254 console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' );
18255 return loopReplacer( match, start, end, snippet );
18256
18257 }
18258
18259 function loopReplacer( match, start, end, snippet ) {
18260
18261 var string = '';
18262
18263 for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
18264
18265 string += snippet
18266 .replace( /\[ i \]/g, '[ ' + i + ' ]' )
18267 .replace( /UNROLLED_LOOP_INDEX/g, i );
18268
18269 }
18270
18271 return string;
18272
18273 }
18274
18275 //
18276
18277 function generatePrecision( parameters ) {
18278
18279 var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;";
18280
18281 if ( parameters.precision === "highp" ) {
18282
18283 precisionstring += "\n#define HIGH_PRECISION";
18284
18285 } else if ( parameters.precision === "mediump" ) {
18286
18287 precisionstring += "\n#define MEDIUM_PRECISION";
18288
18289 } else if ( parameters.precision === "lowp" ) {
18290
18291 precisionstring += "\n#define LOW_PRECISION";
18292
18293 }
18294
18295 return precisionstring;
18296
18297 }
18298
18299 function generateShadowMapTypeDefine( parameters ) {
18300
18301 var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
18302
18303 if ( parameters.shadowMapType === PCFShadowMap ) {
18304
18305 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
18306
18307 } else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
18308
18309 shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
18310
18311 } else if ( parameters.shadowMapType === VSMShadowMap ) {
18312
18313 shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';
18314
18315 }
18316
18317 return shadowMapTypeDefine;
18318
18319 }
18320
18321 function generateEnvMapTypeDefine( parameters ) {
18322
18323 var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
18324
18325 if ( parameters.envMap ) {
18326
18327 switch ( parameters.envMapMode ) {
18328
18329 case CubeReflectionMapping:
18330 case CubeRefractionMapping:
18331 envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
18332 break;
18333
18334 case CubeUVReflectionMapping:
18335 case CubeUVRefractionMapping:
18336 envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
18337 break;
18338
18339 case EquirectangularReflectionMapping:
18340 case EquirectangularRefractionMapping:
18341 envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
18342 break;
18343
18344 }
18345
18346 }
18347
18348 return envMapTypeDefine;
18349
18350 }
18351
18352 function generateEnvMapModeDefine( parameters ) {
18353
18354 var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
18355
18356 if ( parameters.envMap ) {
18357
18358 switch ( parameters.envMapMode ) {
18359
18360 case CubeRefractionMapping:
18361 case EquirectangularRefractionMapping:
18362 case CubeUVRefractionMapping:
18363
18364 envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
18365 break;
18366
18367 }
18368
18369 }
18370
18371 return envMapModeDefine;
18372
18373 }
18374
18375 function generateEnvMapBlendingDefine( parameters ) {
18376
18377 var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
18378
18379 if ( parameters.envMap ) {
18380
18381 switch ( parameters.combine ) {
18382
18383 case MultiplyOperation:
18384 envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
18385 break;
18386
18387 case MixOperation:
18388 envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
18389 break;
18390
18391 case AddOperation:
18392 envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
18393 break;
18394
18395 }
18396
18397 }
18398
18399 return envMapBlendingDefine;
18400
18401 }
18402
18403 function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
18404
18405 var gl = renderer.getContext();
18406
18407 var defines = parameters.defines;
18408
18409 var vertexShader = parameters.vertexShader;
18410 var fragmentShader = parameters.fragmentShader;
18411
18412 var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters );
18413 var envMapTypeDefine = generateEnvMapTypeDefine( parameters );
18414 var envMapModeDefine = generateEnvMapModeDefine( parameters );
18415 var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters );
18416
18417
18418 var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
18419
18420 var customExtensions = parameters.isWebGL2 ? '' : generateExtensions( parameters );
18421
18422 var customDefines = generateDefines( defines );
18423
18424 var program = gl.createProgram();
18425
18426 var prefixVertex, prefixFragment;
18427
18428 if ( parameters.isRawShaderMaterial ) {
18429
18430 prefixVertex = [
18431
18432 customDefines
18433
18434 ].filter( filterEmptyLine ).join( '\n' );
18435
18436 if ( prefixVertex.length > 0 ) {
18437
18438 prefixVertex += '\n';
18439
18440 }
18441
18442 prefixFragment = [
18443
18444 customExtensions,
18445 customDefines
18446
18447 ].filter( filterEmptyLine ).join( '\n' );
18448
18449 if ( prefixFragment.length > 0 ) {
18450
18451 prefixFragment += '\n';
18452
18453 }
18454
18455 } else {
18456
18457 prefixVertex = [
18458
18459 generatePrecision( parameters ),
18460
18461 '#define SHADER_NAME ' + parameters.shaderName,
18462
18463 customDefines,
18464
18465 parameters.instancing ? '#define USE_INSTANCING' : '',
18466 parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
18467
18468 '#define GAMMA_FACTOR ' + gammaFactorDefine,
18469
18470 '#define MAX_BONES ' + parameters.maxBones,
18471 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
18472 ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
18473
18474 parameters.map ? '#define USE_MAP' : '',
18475 parameters.envMap ? '#define USE_ENVMAP' : '',
18476 parameters.envMap ? '#define ' + envMapModeDefine : '',
18477 parameters.lightMap ? '#define USE_LIGHTMAP' : '',
18478 parameters.aoMap ? '#define USE_AOMAP' : '',
18479 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
18480 parameters.bumpMap ? '#define USE_BUMPMAP' : '',
18481 parameters.normalMap ? '#define USE_NORMALMAP' : '',
18482 ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
18483 ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
18484
18485 parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
18486 parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
18487 parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
18488 parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
18489 parameters.specularMap ? '#define USE_SPECULARMAP' : '',
18490 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
18491 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
18492 parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
18493 parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
18494
18495 parameters.vertexTangents ? '#define USE_TANGENT' : '',
18496 parameters.vertexColors ? '#define USE_COLOR' : '',
18497 parameters.vertexUvs ? '#define USE_UV' : '',
18498 parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
18499
18500 parameters.flatShading ? '#define FLAT_SHADED' : '',
18501
18502 parameters.skinning ? '#define USE_SKINNING' : '',
18503 parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
18504
18505 parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
18506 parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
18507 parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
18508 parameters.flipSided ? '#define FLIP_SIDED' : '',
18509
18510 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
18511 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
18512
18513 parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
18514
18515 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
18516 ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
18517
18518 'uniform mat4 modelMatrix;',
18519 'uniform mat4 modelViewMatrix;',
18520 'uniform mat4 projectionMatrix;',
18521 'uniform mat4 viewMatrix;',
18522 'uniform mat3 normalMatrix;',
18523 'uniform vec3 cameraPosition;',
18524 'uniform bool isOrthographic;',
18525
18526 '#ifdef USE_INSTANCING',
18527
18528 ' attribute mat4 instanceMatrix;',
18529
18530 '#endif',
18531
18532 'attribute vec3 position;',
18533 'attribute vec3 normal;',
18534 'attribute vec2 uv;',
18535
18536 '#ifdef USE_TANGENT',
18537
18538 ' attribute vec4 tangent;',
18539
18540 '#endif',
18541
18542 '#ifdef USE_COLOR',
18543
18544 ' attribute vec3 color;',
18545
18546 '#endif',
18547
18548 '#ifdef USE_MORPHTARGETS',
18549
18550 ' attribute vec3 morphTarget0;',
18551 ' attribute vec3 morphTarget1;',
18552 ' attribute vec3 morphTarget2;',
18553 ' attribute vec3 morphTarget3;',
18554
18555 ' #ifdef USE_MORPHNORMALS',
18556
18557 ' attribute vec3 morphNormal0;',
18558 ' attribute vec3 morphNormal1;',
18559 ' attribute vec3 morphNormal2;',
18560 ' attribute vec3 morphNormal3;',
18561
18562 ' #else',
18563
18564 ' attribute vec3 morphTarget4;',
18565 ' attribute vec3 morphTarget5;',
18566 ' attribute vec3 morphTarget6;',
18567 ' attribute vec3 morphTarget7;',
18568
18569 ' #endif',
18570
18571 '#endif',
18572
18573 '#ifdef USE_SKINNING',
18574
18575 ' attribute vec4 skinIndex;',
18576 ' attribute vec4 skinWeight;',
18577
18578 '#endif',
18579
18580 '\n'
18581
18582 ].filter( filterEmptyLine ).join( '\n' );
18583
18584 prefixFragment = [
18585
18586 customExtensions,
18587
18588 generatePrecision( parameters ),
18589
18590 '#define SHADER_NAME ' + parameters.shaderName,
18591
18592 customDefines,
18593
18594 parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer
18595
18596 '#define GAMMA_FACTOR ' + gammaFactorDefine,
18597
18598 ( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
18599 ( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
18600
18601 parameters.map ? '#define USE_MAP' : '',
18602 parameters.matcap ? '#define USE_MATCAP' : '',
18603 parameters.envMap ? '#define USE_ENVMAP' : '',
18604 parameters.envMap ? '#define ' + envMapTypeDefine : '',
18605 parameters.envMap ? '#define ' + envMapModeDefine : '',
18606 parameters.envMap ? '#define ' + envMapBlendingDefine : '',
18607 parameters.lightMap ? '#define USE_LIGHTMAP' : '',
18608 parameters.aoMap ? '#define USE_AOMAP' : '',
18609 parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
18610 parameters.bumpMap ? '#define USE_BUMPMAP' : '',
18611 parameters.normalMap ? '#define USE_NORMALMAP' : '',
18612 ( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
18613 ( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
18614 parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
18615 parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
18616 parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
18617 parameters.specularMap ? '#define USE_SPECULARMAP' : '',
18618 parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
18619 parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
18620 parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
18621
18622 parameters.sheen ? '#define USE_SHEEN' : '',
18623 parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
18624
18625 parameters.vertexTangents ? '#define USE_TANGENT' : '',
18626 parameters.vertexColors ? '#define USE_COLOR' : '',
18627 parameters.vertexUvs ? '#define USE_UV' : '',
18628 parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
18629
18630 parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
18631
18632 parameters.flatShading ? '#define FLAT_SHADED' : '',
18633
18634 parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
18635 parameters.flipSided ? '#define FLIP_SIDED' : '',
18636
18637 parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
18638 parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
18639
18640 parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '',
18641
18642 parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',
18643
18644 parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
18645 ( parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
18646
18647 ( ( parameters.extensionShaderTextureLOD || parameters.envMap ) && parameters.rendererExtensionShaderTextureLod ) ? '#define TEXTURE_LOD_EXT' : '',
18648
18649 'uniform mat4 viewMatrix;',
18650 'uniform vec3 cameraPosition;',
18651 'uniform bool isOrthographic;',
18652
18653 ( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
18654 ( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below
18655 ( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
18656
18657 parameters.dithering ? '#define DITHERING' : '',
18658
18659 ShaderChunk[ 'encodings_pars_fragment' ], // this code is required here because it is used by the various encoding/decoding function defined below
18660 parameters.map ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
18661 parameters.matcap ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
18662 parameters.envMap ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
18663 parameters.emissiveMap ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
18664 parameters.lightMap ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '',
18665 getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ),
18666
18667 parameters.depthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '',
18668
18669 '\n'
18670
18671 ].filter( filterEmptyLine ).join( '\n' );
18672
18673 }
18674
18675 vertexShader = resolveIncludes( vertexShader );
18676 vertexShader = replaceLightNums( vertexShader, parameters );
18677 vertexShader = replaceClippingPlaneNums( vertexShader, parameters );
18678
18679 fragmentShader = resolveIncludes( fragmentShader );
18680 fragmentShader = replaceLightNums( fragmentShader, parameters );
18681 fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );
18682
18683 vertexShader = unrollLoops( vertexShader );
18684 fragmentShader = unrollLoops( fragmentShader );
18685
18686 if ( parameters.isWebGL2 && ! parameters.isRawShaderMaterial ) {
18687
18688 // GLSL 3.0 conversion
18689
18690 prefixVertex = [
18691 '#version 300 es\n',
18692 '#define attribute in',
18693 '#define varying out',
18694 '#define texture2D texture'
18695 ].join( '\n' ) + '\n' + prefixVertex;
18696
18697 prefixFragment = [
18698 '#version 300 es\n',
18699 '#define varying in',
18700 'out highp vec4 pc_fragColor;',
18701 '#define gl_FragColor pc_fragColor',
18702 '#define gl_FragDepthEXT gl_FragDepth',
18703 '#define texture2D texture',
18704 '#define textureCube texture',
18705 '#define texture2DProj textureProj',
18706 '#define texture2DLodEXT textureLod',
18707 '#define texture2DProjLodEXT textureProjLod',
18708 '#define textureCubeLodEXT textureLod',
18709 '#define texture2DGradEXT textureGrad',
18710 '#define texture2DProjGradEXT textureProjGrad',
18711 '#define textureCubeGradEXT textureGrad'
18712 ].join( '\n' ) + '\n' + prefixFragment;
18713
18714 }
18715
18716 var vertexGlsl = prefixVertex + vertexShader;
18717 var fragmentGlsl = prefixFragment + fragmentShader;
18718
18719 // console.log( '*VERTEX*', vertexGlsl );
18720 // console.log( '*FRAGMENT*', fragmentGlsl );
18721
18722 var glVertexShader = WebGLShader( gl, 35633, vertexGlsl );
18723 var glFragmentShader = WebGLShader( gl, 35632, fragmentGlsl );
18724
18725 gl.attachShader( program, glVertexShader );
18726 gl.attachShader( program, glFragmentShader );
18727
18728 // Force a particular attribute to index 0.
18729
18730 if ( parameters.index0AttributeName !== undefined ) {
18731
18732 gl.bindAttribLocation( program, 0, parameters.index0AttributeName );
18733
18734 } else if ( parameters.morphTargets === true ) {
18735
18736 // programs with morphTargets displace position out of attribute 0
18737 gl.bindAttribLocation( program, 0, 'position' );
18738
18739 }
18740
18741 gl.linkProgram( program );
18742
18743 // check for link errors
18744 if ( renderer.debug.checkShaderErrors ) {
18745
18746 var programLog = gl.getProgramInfoLog( program ).trim();
18747 var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
18748 var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
18749
18750 var runnable = true;
18751 var haveDiagnostics = true;
18752
18753 if ( gl.getProgramParameter( program, 35714 ) === false ) {
18754
18755 runnable = false;
18756
18757 var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
18758 var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
18759
18760 console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), '35715', gl.getProgramParameter( program, 35715 ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors );
18761
18762 } else if ( programLog !== '' ) {
18763
18764 console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
18765
18766 } else if ( vertexLog === '' || fragmentLog === '' ) {
18767
18768 haveDiagnostics = false;
18769
18770 }
18771
18772 if ( haveDiagnostics ) {
18773
18774 this.diagnostics = {
18775
18776 runnable: runnable,
18777
18778 programLog: programLog,
18779
18780 vertexShader: {
18781
18782 log: vertexLog,
18783 prefix: prefixVertex
18784
18785 },
18786
18787 fragmentShader: {
18788
18789 log: fragmentLog,
18790 prefix: prefixFragment
18791
18792 }
18793
18794 };
18795
18796 }
18797
18798 }
18799
18800 // Clean up
18801
18802 // Crashes in iOS9 and iOS10. #18402
18803 // gl.detachShader( program, glVertexShader );
18804 // gl.detachShader( program, glFragmentShader );
18805
18806 gl.deleteShader( glVertexShader );
18807 gl.deleteShader( glFragmentShader );
18808
18809 // set up caching for uniform locations
18810
18811 var cachedUniforms;
18812
18813 this.getUniforms = function () {
18814
18815 if ( cachedUniforms === undefined ) {
18816
18817 cachedUniforms = new WebGLUniforms( gl, program );
18818
18819 }
18820
18821 return cachedUniforms;
18822
18823 };
18824
18825 // set up caching for attribute locations
18826
18827 var cachedAttributes;
18828
18829 this.getAttributes = function () {
18830
18831 if ( cachedAttributes === undefined ) {
18832
18833 cachedAttributes = fetchAttributeLocations( gl, program );
18834
18835 }
18836
18837 return cachedAttributes;
18838
18839 };
18840
18841 // free resource
18842
18843 this.destroy = function () {
18844
18845 bindingStates.releaseStatesOfProgram( this );
18846
18847 gl.deleteProgram( program );
18848 this.program = undefined;
18849
18850 };
18851
18852 //
18853
18854 this.name = parameters.shaderName;
18855 this.id = programIdCount ++;
18856 this.cacheKey = cacheKey;
18857 this.usedTimes = 1;
18858 this.program = program;
18859 this.vertexShader = glVertexShader;
18860 this.fragmentShader = glFragmentShader;
18861
18862 return this;
18863
18864 }
18865
18866 function WebGLPrograms( renderer, extensions, capabilities, bindingStates ) {
18867
18868 var programs = [];
18869
18870 var isWebGL2 = capabilities.isWebGL2;
18871 var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
18872 var floatVertexTextures = capabilities.floatVertexTextures;
18873 var maxVertexUniforms = capabilities.maxVertexUniforms;
18874 var vertexTextures = capabilities.vertexTextures;
18875
18876 var precision = capabilities.precision;
18877
18878 var shaderIDs = {
18879 MeshDepthMaterial: 'depth',
18880 MeshDistanceMaterial: 'distanceRGBA',
18881 MeshNormalMaterial: 'normal',
18882 MeshBasicMaterial: 'basic',
18883 MeshLambertMaterial: 'lambert',
18884 MeshPhongMaterial: 'phong',
18885 MeshToonMaterial: 'toon',
18886 MeshStandardMaterial: 'physical',
18887 MeshPhysicalMaterial: 'physical',
18888 MeshMatcapMaterial: 'matcap',
18889 LineBasicMaterial: 'basic',
18890 LineDashedMaterial: 'dashed',
18891 PointsMaterial: 'points',
18892 ShadowMaterial: 'shadow',
18893 SpriteMaterial: 'sprite'
18894 };
18895
18896 var parameterNames = [
18897 "precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing",
18898 "map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV",
18899 "lightMap", "lightMapEncoding", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatMap", "clearcoatRoughnessMap", "clearcoatNormalMap", "displacementMap", "specularMap",
18900 "roughnessMap", "metalnessMap", "gradientMap",
18901 "alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "uvsVertexOnly", "fog", "useFog", "fogExp2",
18902 "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
18903 "maxBones", "useVertexTexture", "morphTargets", "morphNormals",
18904 "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
18905 "numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
18906 "numDirLightShadows", "numPointLightShadows", "numSpotLightShadows",
18907 "shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
18908 "alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering",
18909 "sheen", "transmissionMap"
18910 ];
18911
18912 function allocateBones( object ) {
18913
18914 var skeleton = object.skeleton;
18915 var bones = skeleton.bones;
18916
18917 if ( floatVertexTextures ) {
18918
18919 return 1024;
18920
18921 } else {
18922
18923 // default for when object is not specified
18924 // ( for example when prebuilding shader to be used with multiple objects )
18925 //
18926 // - leave some extra space for other uniforms
18927 // - limit here is ANGLE's 254 max uniform vectors
18928 // (up to 54 should be safe)
18929
18930 var nVertexUniforms = maxVertexUniforms;
18931 var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
18932
18933 var maxBones = Math.min( nVertexMatrices, bones.length );
18934
18935 if ( maxBones < bones.length ) {
18936
18937 console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
18938 return 0;
18939
18940 }
18941
18942 return maxBones;
18943
18944 }
18945
18946 }
18947
18948 function getTextureEncodingFromMap( map ) {
18949
18950 var encoding;
18951
18952 if ( ! map ) {
18953
18954 encoding = LinearEncoding;
18955
18956 } else if ( map.isTexture ) {
18957
18958 encoding = map.encoding;
18959
18960 } else if ( map.isWebGLRenderTarget ) {
18961
18962 console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
18963 encoding = map.texture.encoding;
18964
18965 }
18966
18967 return encoding;
18968
18969 }
18970
18971 function getParameters( material, lights, shadows, scene, nClipPlanes, nClipIntersection, object ) {
18972
18973 var fog = scene.fog;
18974 var environment = material.isMeshStandardMaterial ? scene.environment : null;
18975
18976 var envMap = material.envMap || environment;
18977
18978 var shaderID = shaderIDs[ material.type ];
18979
18980 // heuristics to create shader parameters according to lights in the scene
18981 // (not to blow over maxLights budget)
18982
18983 var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
18984
18985 if ( material.precision !== null ) {
18986
18987 precision = capabilities.getMaxPrecision( material.precision );
18988
18989 if ( precision !== material.precision ) {
18990
18991 console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
18992
18993 }
18994
18995 }
18996
18997 var vertexShader, fragmentShader;
18998
18999 if ( shaderID ) {
19000
19001 var shader = ShaderLib[ shaderID ];
19002
19003 vertexShader = shader.vertexShader;
19004 fragmentShader = shader.fragmentShader;
19005
19006 } else {
19007
19008 vertexShader = material.vertexShader;
19009 fragmentShader = material.fragmentShader;
19010
19011 }
19012
19013 var currentRenderTarget = renderer.getRenderTarget();
19014
19015 var parameters = {
19016
19017 isWebGL2: isWebGL2,
19018
19019 shaderID: shaderID,
19020 shaderName: material.type,
19021
19022 vertexShader: vertexShader,
19023 fragmentShader: fragmentShader,
19024 defines: material.defines,
19025
19026 isRawShaderMaterial: material.isRawShaderMaterial,
19027 isShaderMaterial: material.isShaderMaterial,
19028
19029 precision: precision,
19030
19031 instancing: object.isInstancedMesh === true,
19032
19033 supportsVertexTextures: vertexTextures,
19034 outputEncoding: ( currentRenderTarget !== null ) ? getTextureEncodingFromMap( currentRenderTarget.texture ) : renderer.outputEncoding,
19035 map: !! material.map,
19036 mapEncoding: getTextureEncodingFromMap( material.map ),
19037 matcap: !! material.matcap,
19038 matcapEncoding: getTextureEncodingFromMap( material.matcap ),
19039 envMap: !! envMap,
19040 envMapMode: envMap && envMap.mapping,
19041 envMapEncoding: getTextureEncodingFromMap( envMap ),
19042 envMapCubeUV: ( !! envMap ) && ( ( envMap.mapping === CubeUVReflectionMapping ) || ( envMap.mapping === CubeUVRefractionMapping ) ),
19043 lightMap: !! material.lightMap,
19044 lightMapEncoding: getTextureEncodingFromMap( material.lightMap ),
19045 aoMap: !! material.aoMap,
19046 emissiveMap: !! material.emissiveMap,
19047 emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ),
19048 bumpMap: !! material.bumpMap,
19049 normalMap: !! material.normalMap,
19050 objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap,
19051 tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap,
19052 clearcoatMap: !! material.clearcoatMap,
19053 clearcoatRoughnessMap: !! material.clearcoatRoughnessMap,
19054 clearcoatNormalMap: !! material.clearcoatNormalMap,
19055 displacementMap: !! material.displacementMap,
19056 roughnessMap: !! material.roughnessMap,
19057 metalnessMap: !! material.metalnessMap,
19058 specularMap: !! material.specularMap,
19059 alphaMap: !! material.alphaMap,
19060
19061 gradientMap: !! material.gradientMap,
19062
19063 sheen: !! material.sheen,
19064
19065 transmissionMap: !! material.transmissionMap,
19066
19067 combine: material.combine,
19068
19069 vertexTangents: ( material.normalMap && material.vertexTangents ),
19070 vertexColors: material.vertexColors,
19071 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,
19072 uvsVertexOnly: ! ( !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.transmissionMap ) && !! material.displacementMap,
19073
19074 fog: !! fog,
19075 useFog: material.fog,
19076 fogExp2: ( fog && fog.isFogExp2 ),
19077
19078 flatShading: material.flatShading,
19079
19080 sizeAttenuation: material.sizeAttenuation,
19081 logarithmicDepthBuffer: logarithmicDepthBuffer,
19082
19083 skinning: material.skinning && maxBones > 0,
19084 maxBones: maxBones,
19085 useVertexTexture: floatVertexTextures,
19086
19087 morphTargets: material.morphTargets,
19088 morphNormals: material.morphNormals,
19089 maxMorphTargets: renderer.maxMorphTargets,
19090 maxMorphNormals: renderer.maxMorphNormals,
19091
19092 numDirLights: lights.directional.length,
19093 numPointLights: lights.point.length,
19094 numSpotLights: lights.spot.length,
19095 numRectAreaLights: lights.rectArea.length,
19096 numHemiLights: lights.hemi.length,
19097
19098 numDirLightShadows: lights.directionalShadowMap.length,
19099 numPointLightShadows: lights.pointShadowMap.length,
19100 numSpotLightShadows: lights.spotShadowMap.length,
19101
19102 numClippingPlanes: nClipPlanes,
19103 numClipIntersection: nClipIntersection,
19104
19105 dithering: material.dithering,
19106
19107 shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
19108 shadowMapType: renderer.shadowMap.type,
19109
19110 toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
19111 physicallyCorrectLights: renderer.physicallyCorrectLights,
19112
19113 premultipliedAlpha: material.premultipliedAlpha,
19114
19115 alphaTest: material.alphaTest,
19116 doubleSided: material.side === DoubleSide,
19117 flipSided: material.side === BackSide,
19118
19119 depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false,
19120
19121 index0AttributeName: material.index0AttributeName,
19122
19123 extensionDerivatives: material.extensions && material.extensions.derivatives,
19124 extensionFragDepth: material.extensions && material.extensions.fragDepth,
19125 extensionDrawBuffers: material.extensions && material.extensions.drawBuffers,
19126 extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD,
19127
19128 rendererExtensionFragDepth: isWebGL2 || extensions.get( 'EXT_frag_depth' ) !== null,
19129 rendererExtensionDrawBuffers: isWebGL2 || extensions.get( 'WEBGL_draw_buffers' ) !== null,
19130 rendererExtensionShaderTextureLod: isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) !== null,
19131
19132 customProgramCacheKey: material.customProgramCacheKey()
19133
19134 };
19135
19136 return parameters;
19137
19138 }
19139
19140 function getProgramCacheKey( parameters ) {
19141
19142 var array = [];
19143
19144 if ( parameters.shaderID ) {
19145
19146 array.push( parameters.shaderID );
19147
19148 } else {
19149
19150 array.push( parameters.fragmentShader );
19151 array.push( parameters.vertexShader );
19152
19153 }
19154
19155 if ( parameters.defines !== undefined ) {
19156
19157 for ( var name in parameters.defines ) {
19158
19159 array.push( name );
19160 array.push( parameters.defines[ name ] );
19161
19162 }
19163
19164 }
19165
19166 if ( parameters.isRawShaderMaterial === undefined ) {
19167
19168 for ( var i = 0; i < parameterNames.length; i ++ ) {
19169
19170 array.push( parameters[ parameterNames[ i ] ] );
19171
19172 }
19173
19174 array.push( renderer.outputEncoding );
19175 array.push( renderer.gammaFactor );
19176
19177 }
19178
19179 array.push( parameters.customProgramCacheKey );
19180
19181 return array.join();
19182
19183 }
19184
19185 function getUniforms( material ) {
19186
19187 var shaderID = shaderIDs[ material.type ];
19188 var uniforms;
19189
19190 if ( shaderID ) {
19191
19192 var shader = ShaderLib[ shaderID ];
19193 uniforms = UniformsUtils.clone( shader.uniforms );
19194
19195 } else {
19196
19197 uniforms = material.uniforms;
19198
19199 }
19200
19201 return uniforms;
19202
19203 }
19204
19205 function acquireProgram( parameters, cacheKey ) {
19206
19207 var program;
19208
19209 // Check if code has been already compiled
19210 for ( var p = 0, pl = programs.length; p < pl; p ++ ) {
19211
19212 var preexistingProgram = programs[ p ];
19213
19214 if ( preexistingProgram.cacheKey === cacheKey ) {
19215
19216 program = preexistingProgram;
19217 ++ program.usedTimes;
19218
19219 break;
19220
19221 }
19222
19223 }
19224
19225 if ( program === undefined ) {
19226
19227 program = new WebGLProgram( renderer, cacheKey, parameters, bindingStates );
19228 programs.push( program );
19229
19230 }
19231
19232 return program;
19233
19234 }
19235
19236 function releaseProgram( program ) {
19237
19238 if ( -- program.usedTimes === 0 ) {
19239
19240 // Remove from unordered set
19241 var i = programs.indexOf( program );
19242 programs[ i ] = programs[ programs.length - 1 ];
19243 programs.pop();
19244
19245 // Free WebGL resources
19246 program.destroy();
19247
19248 }
19249
19250 }
19251
19252 return {
19253 getParameters: getParameters,
19254 getProgramCacheKey: getProgramCacheKey,
19255 getUniforms: getUniforms,
19256 acquireProgram: acquireProgram,
19257 releaseProgram: releaseProgram,
19258 // Exposed for resource monitoring & error feedback via renderer.info:
19259 programs: programs
19260 };
19261
19262 }
19263
19264 function WebGLProperties() {
19265
19266 var properties = new WeakMap();
19267
19268 function get( object ) {
19269
19270 var map = properties.get( object );
19271
19272 if ( map === undefined ) {
19273
19274 map = {};
19275 properties.set( object, map );
19276
19277 }
19278
19279 return map;
19280
19281 }
19282
19283 function remove( object ) {
19284
19285 properties.delete( object );
19286
19287 }
19288
19289 function update( object, key, value ) {
19290
19291 properties.get( object )[ key ] = value;
19292
19293 }
19294
19295 function dispose() {
19296
19297 properties = new WeakMap();
19298
19299 }
19300
19301 return {
19302 get: get,
19303 remove: remove,
19304 update: update,
19305 dispose: dispose
19306 };
19307
19308 }
19309
19310 function painterSortStable( a, b ) {
19311
19312 if ( a.groupOrder !== b.groupOrder ) {
19313
19314 return a.groupOrder - b.groupOrder;
19315
19316 } else if ( a.renderOrder !== b.renderOrder ) {
19317
19318 return a.renderOrder - b.renderOrder;
19319
19320 } else if ( a.program !== b.program ) {
19321
19322 return a.program.id - b.program.id;
19323
19324 } else if ( a.material.id !== b.material.id ) {
19325
19326 return a.material.id - b.material.id;
19327
19328 } else if ( a.z !== b.z ) {
19329
19330 return a.z - b.z;
19331
19332 } else {
19333
19334 return a.id - b.id;
19335
19336 }
19337
19338 }
19339
19340 function reversePainterSortStable( a, b ) {
19341
19342 if ( a.groupOrder !== b.groupOrder ) {
19343
19344 return a.groupOrder - b.groupOrder;
19345
19346 } else if ( a.renderOrder !== b.renderOrder ) {
19347
19348 return a.renderOrder - b.renderOrder;
19349
19350 } else if ( a.z !== b.z ) {
19351
19352 return b.z - a.z;
19353
19354 } else {
19355
19356 return a.id - b.id;
19357
19358 }
19359
19360 }
19361
19362
19363 function WebGLRenderList( properties ) {
19364
19365 var renderItems = [];
19366 var renderItemsIndex = 0;
19367
19368 var opaque = [];
19369 var transparent = [];
19370
19371 var defaultProgram = { id: - 1 };
19372
19373 function init() {
19374
19375 renderItemsIndex = 0;
19376
19377 opaque.length = 0;
19378 transparent.length = 0;
19379
19380 }
19381
19382 function getNextRenderItem( object, geometry, material, groupOrder, z, group ) {
19383
19384 var renderItem = renderItems[ renderItemsIndex ];
19385 var materialProperties = properties.get( material );
19386
19387 if ( renderItem === undefined ) {
19388
19389 renderItem = {
19390 id: object.id,
19391 object: object,
19392 geometry: geometry,
19393 material: material,
19394 program: materialProperties.program || defaultProgram,
19395 groupOrder: groupOrder,
19396 renderOrder: object.renderOrder,
19397 z: z,
19398 group: group
19399 };
19400
19401 renderItems[ renderItemsIndex ] = renderItem;
19402
19403 } else {
19404
19405 renderItem.id = object.id;
19406 renderItem.object = object;
19407 renderItem.geometry = geometry;
19408 renderItem.material = material;
19409 renderItem.program = materialProperties.program || defaultProgram;
19410 renderItem.groupOrder = groupOrder;
19411 renderItem.renderOrder = object.renderOrder;
19412 renderItem.z = z;
19413 renderItem.group = group;
19414
19415 }
19416
19417 renderItemsIndex ++;
19418
19419 return renderItem;
19420
19421 }
19422
19423 function push( object, geometry, material, groupOrder, z, group ) {
19424
19425 var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
19426
19427 ( material.transparent === true ? transparent : opaque ).push( renderItem );
19428
19429 }
19430
19431 function unshift( object, geometry, material, groupOrder, z, group ) {
19432
19433 var renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
19434
19435 ( material.transparent === true ? transparent : opaque ).unshift( renderItem );
19436
19437 }
19438
19439 function sort( customOpaqueSort, customTransparentSort ) {
19440
19441 if ( opaque.length > 1 ) { opaque.sort( customOpaqueSort || painterSortStable ); }
19442 if ( transparent.length > 1 ) { transparent.sort( customTransparentSort || reversePainterSortStable ); }
19443
19444 }
19445
19446 function finish() {
19447
19448 // Clear references from inactive renderItems in the list
19449
19450 for ( var i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) {
19451
19452 var renderItem = renderItems[ i ];
19453
19454 if ( renderItem.id === null ) { break; }
19455
19456 renderItem.id = null;
19457 renderItem.object = null;
19458 renderItem.geometry = null;
19459 renderItem.material = null;
19460 renderItem.program = null;
19461 renderItem.group = null;
19462
19463 }
19464
19465 }
19466
19467 return {
19468
19469 opaque: opaque,
19470 transparent: transparent,
19471
19472 init: init,
19473 push: push,
19474 unshift: unshift,
19475 finish: finish,
19476
19477 sort: sort
19478 };
19479
19480 }
19481
19482 function WebGLRenderLists( properties ) {
19483
19484 var lists = new WeakMap();
19485
19486 function onSceneDispose( event ) {
19487
19488 var scene = event.target;
19489
19490 scene.removeEventListener( 'dispose', onSceneDispose );
19491
19492 lists.delete( scene );
19493
19494 }
19495
19496 function get( scene, camera ) {
19497
19498 var cameras = lists.get( scene );
19499 var list;
19500
19501 if ( cameras === undefined ) {
19502
19503 list = new WebGLRenderList( properties );
19504 lists.set( scene, new WeakMap() );
19505 lists.get( scene ).set( camera, list );
19506
19507 scene.addEventListener( 'dispose', onSceneDispose );
19508
19509 } else {
19510
19511 list = cameras.get( camera );
19512 if ( list === undefined ) {
19513
19514 list = new WebGLRenderList( properties );
19515 cameras.set( camera, list );
19516
19517 }
19518
19519 }
19520
19521 return list;
19522
19523 }
19524
19525 function dispose() {
19526
19527 lists = new WeakMap();
19528
19529 }
19530
19531 return {
19532 get: get,
19533 dispose: dispose
19534 };
19535
19536 }
19537
19538 function UniformsCache() {
19539
19540 var lights = {};
19541
19542 return {
19543
19544 get: function ( light ) {
19545
19546 if ( lights[ light.id ] !== undefined ) {
19547
19548 return lights[ light.id ];
19549
19550 }
19551
19552 var uniforms;
19553
19554 switch ( light.type ) {
19555
19556 case 'DirectionalLight':
19557 uniforms = {
19558 direction: new Vector3(),
19559 color: new Color()
19560 };
19561 break;
19562
19563 case 'SpotLight':
19564 uniforms = {
19565 position: new Vector3(),
19566 direction: new Vector3(),
19567 color: new Color(),
19568 distance: 0,
19569 coneCos: 0,
19570 penumbraCos: 0,
19571 decay: 0
19572 };
19573 break;
19574
19575 case 'PointLight':
19576 uniforms = {
19577 position: new Vector3(),
19578 color: new Color(),
19579 distance: 0,
19580 decay: 0
19581 };
19582 break;
19583
19584 case 'HemisphereLight':
19585 uniforms = {
19586 direction: new Vector3(),
19587 skyColor: new Color(),
19588 groundColor: new Color()
19589 };
19590 break;
19591
19592 case 'RectAreaLight':
19593 uniforms = {
19594 color: new Color(),
19595 position: new Vector3(),
19596 halfWidth: new Vector3(),
19597 halfHeight: new Vector3()
19598 };
19599 break;
19600
19601 }
19602
19603 lights[ light.id ] = uniforms;
19604
19605 return uniforms;
19606
19607 }
19608
19609 };
19610
19611 }
19612
19613 function ShadowUniformsCache() {
19614
19615 var lights = {};
19616
19617 return {
19618
19619 get: function ( light ) {
19620
19621 if ( lights[ light.id ] !== undefined ) {
19622
19623 return lights[ light.id ];
19624
19625 }
19626
19627 var uniforms;
19628
19629 switch ( light.type ) {
19630
19631 case 'DirectionalLight':
19632 uniforms = {
19633 shadowBias: 0,
19634 shadowNormalBias: 0,
19635 shadowRadius: 1,
19636 shadowMapSize: new Vector2()
19637 };
19638 break;
19639
19640 case 'SpotLight':
19641 uniforms = {
19642 shadowBias: 0,
19643 shadowNormalBias: 0,
19644 shadowRadius: 1,
19645 shadowMapSize: new Vector2()
19646 };
19647 break;
19648
19649 case 'PointLight':
19650 uniforms = {
19651 shadowBias: 0,
19652 shadowNormalBias: 0,
19653 shadowRadius: 1,
19654 shadowMapSize: new Vector2(),
19655 shadowCameraNear: 1,
19656 shadowCameraFar: 1000
19657 };
19658 break;
19659
19660 // TODO (abelnation): set RectAreaLight shadow uniforms
19661
19662 }
19663
19664 lights[ light.id ] = uniforms;
19665
19666 return uniforms;
19667
19668 }
19669
19670 };
19671
19672 }
19673
19674
19675
19676 var nextVersion = 0;
19677
19678 function shadowCastingLightsFirst( lightA, lightB ) {
19679
19680 return ( lightB.castShadow ? 1 : 0 ) - ( lightA.castShadow ? 1 : 0 );
19681
19682 }
19683
19684 function WebGLLights() {
19685
19686 var cache = new UniformsCache();
19687
19688 var shadowCache = ShadowUniformsCache();
19689
19690 var state = {
19691
19692 version: 0,
19693
19694 hash: {
19695 directionalLength: - 1,
19696 pointLength: - 1,
19697 spotLength: - 1,
19698 rectAreaLength: - 1,
19699 hemiLength: - 1,
19700
19701 numDirectionalShadows: - 1,
19702 numPointShadows: - 1,
19703 numSpotShadows: - 1
19704 },
19705
19706 ambient: [ 0, 0, 0 ],
19707 probe: [],
19708 directional: [],
19709 directionalShadow: [],
19710 directionalShadowMap: [],
19711 directionalShadowMatrix: [],
19712 spot: [],
19713 spotShadow: [],
19714 spotShadowMap: [],
19715 spotShadowMatrix: [],
19716 rectArea: [],
19717 point: [],
19718 pointShadow: [],
19719 pointShadowMap: [],
19720 pointShadowMatrix: [],
19721 hemi: []
19722
19723 };
19724
19725 for ( var i = 0; i < 9; i ++ ) { state.probe.push( new Vector3() ); }
19726
19727 var vector3 = new Vector3();
19728 var matrix4 = new Matrix4();
19729 var matrix42 = new Matrix4();
19730
19731 function setup( lights, shadows, camera ) {
19732
19733 var r = 0, g = 0, b = 0;
19734
19735 for ( var i = 0; i < 9; i ++ ) { state.probe[ i ].set( 0, 0, 0 ); }
19736
19737 var directionalLength = 0;
19738 var pointLength = 0;
19739 var spotLength = 0;
19740 var rectAreaLength = 0;
19741 var hemiLength = 0;
19742
19743 var numDirectionalShadows = 0;
19744 var numPointShadows = 0;
19745 var numSpotShadows = 0;
19746
19747 var viewMatrix = camera.matrixWorldInverse;
19748
19749 lights.sort( shadowCastingLightsFirst );
19750
19751 for ( var i$1 = 0, l = lights.length; i$1 < l; i$1 ++ ) {
19752
19753 var light = lights[ i$1 ];
19754
19755 var color = light.color;
19756 var intensity = light.intensity;
19757 var distance = light.distance;
19758
19759 var shadowMap = ( light.shadow && light.shadow.map ) ? light.shadow.map.texture : null;
19760
19761 if ( light.isAmbientLight ) {
19762
19763 r += color.r * intensity;
19764 g += color.g * intensity;
19765 b += color.b * intensity;
19766
19767 } else if ( light.isLightProbe ) {
19768
19769 for ( var j = 0; j < 9; j ++ ) {
19770
19771 state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity );
19772
19773 }
19774
19775 } else if ( light.isDirectionalLight ) {
19776
19777 var uniforms = cache.get( light );
19778
19779 uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
19780 uniforms.direction.setFromMatrixPosition( light.matrixWorld );
19781 vector3.setFromMatrixPosition( light.target.matrixWorld );
19782 uniforms.direction.sub( vector3 );
19783 uniforms.direction.transformDirection( viewMatrix );
19784
19785 if ( light.castShadow ) {
19786
19787 var shadow = light.shadow;
19788
19789 var shadowUniforms = shadowCache.get( light );
19790
19791 shadowUniforms.shadowBias = shadow.bias;
19792 shadowUniforms.shadowNormalBias = shadow.normalBias;
19793 shadowUniforms.shadowRadius = shadow.radius;
19794 shadowUniforms.shadowMapSize = shadow.mapSize;
19795
19796 state.directionalShadow[ directionalLength ] = shadowUniforms;
19797 state.directionalShadowMap[ directionalLength ] = shadowMap;
19798 state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
19799
19800 numDirectionalShadows ++;
19801
19802 }
19803
19804 state.directional[ directionalLength ] = uniforms;
19805
19806 directionalLength ++;
19807
19808 } else if ( light.isSpotLight ) {
19809
19810 var uniforms$1 = cache.get( light );
19811
19812 uniforms$1.position.setFromMatrixPosition( light.matrixWorld );
19813 uniforms$1.position.applyMatrix4( viewMatrix );
19814
19815 uniforms$1.color.copy( color ).multiplyScalar( intensity );
19816 uniforms$1.distance = distance;
19817
19818 uniforms$1.direction.setFromMatrixPosition( light.matrixWorld );
19819 vector3.setFromMatrixPosition( light.target.matrixWorld );
19820 uniforms$1.direction.sub( vector3 );
19821 uniforms$1.direction.transformDirection( viewMatrix );
19822
19823 uniforms$1.coneCos = Math.cos( light.angle );
19824 uniforms$1.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
19825 uniforms$1.decay = light.decay;
19826
19827 if ( light.castShadow ) {
19828
19829 var shadow$1 = light.shadow;
19830
19831 var shadowUniforms$1 = shadowCache.get( light );
19832
19833 shadowUniforms$1.shadowBias = shadow$1.bias;
19834 shadowUniforms$1.shadowNormalBias = shadow$1.normalBias;
19835 shadowUniforms$1.shadowRadius = shadow$1.radius;
19836 shadowUniforms$1.shadowMapSize = shadow$1.mapSize;
19837
19838 state.spotShadow[ spotLength ] = shadowUniforms$1;
19839 state.spotShadowMap[ spotLength ] = shadowMap;
19840 state.spotShadowMatrix[ spotLength ] = light.shadow.matrix;
19841
19842 numSpotShadows ++;
19843
19844 }
19845
19846 state.spot[ spotLength ] = uniforms$1;
19847
19848 spotLength ++;
19849
19850 } else if ( light.isRectAreaLight ) {
19851
19852 var uniforms$2 = cache.get( light );
19853
19854 // (a) intensity is the total visible light emitted
19855 //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) );
19856
19857 // (b) intensity is the brightness of the light
19858 uniforms$2.color.copy( color ).multiplyScalar( intensity );
19859
19860 uniforms$2.position.setFromMatrixPosition( light.matrixWorld );
19861 uniforms$2.position.applyMatrix4( viewMatrix );
19862
19863 // extract local rotation of light to derive width/height half vectors
19864 matrix42.identity();
19865 matrix4.copy( light.matrixWorld );
19866 matrix4.premultiply( viewMatrix );
19867 matrix42.extractRotation( matrix4 );
19868
19869 uniforms$2.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
19870 uniforms$2.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
19871
19872 uniforms$2.halfWidth.applyMatrix4( matrix42 );
19873 uniforms$2.halfHeight.applyMatrix4( matrix42 );
19874
19875 // TODO (abelnation): RectAreaLight distance?
19876 // uniforms.distance = distance;
19877
19878 state.rectArea[ rectAreaLength ] = uniforms$2;
19879
19880 rectAreaLength ++;
19881
19882 } else if ( light.isPointLight ) {
19883
19884 var uniforms$3 = cache.get( light );
19885
19886 uniforms$3.position.setFromMatrixPosition( light.matrixWorld );
19887 uniforms$3.position.applyMatrix4( viewMatrix );
19888
19889 uniforms$3.color.copy( light.color ).multiplyScalar( light.intensity );
19890 uniforms$3.distance = light.distance;
19891 uniforms$3.decay = light.decay;
19892
19893 if ( light.castShadow ) {
19894
19895 var shadow$2 = light.shadow;
19896
19897 var shadowUniforms$2 = shadowCache.get( light );
19898
19899 shadowUniforms$2.shadowBias = shadow$2.bias;
19900 shadowUniforms$2.shadowNormalBias = shadow$2.normalBias;
19901 shadowUniforms$2.shadowRadius = shadow$2.radius;
19902 shadowUniforms$2.shadowMapSize = shadow$2.mapSize;
19903 shadowUniforms$2.shadowCameraNear = shadow$2.camera.near;
19904 shadowUniforms$2.shadowCameraFar = shadow$2.camera.far;
19905
19906 state.pointShadow[ pointLength ] = shadowUniforms$2;
19907 state.pointShadowMap[ pointLength ] = shadowMap;
19908 state.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
19909
19910 numPointShadows ++;
19911
19912 }
19913
19914 state.point[ pointLength ] = uniforms$3;
19915
19916 pointLength ++;
19917
19918 } else if ( light.isHemisphereLight ) {
19919
19920 var uniforms$4 = cache.get( light );
19921
19922 uniforms$4.direction.setFromMatrixPosition( light.matrixWorld );
19923 uniforms$4.direction.transformDirection( viewMatrix );
19924 uniforms$4.direction.normalize();
19925
19926 uniforms$4.skyColor.copy( light.color ).multiplyScalar( intensity );
19927 uniforms$4.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
19928
19929 state.hemi[ hemiLength ] = uniforms$4;
19930
19931 hemiLength ++;
19932
19933 }
19934
19935 }
19936
19937 state.ambient[ 0 ] = r;
19938 state.ambient[ 1 ] = g;
19939 state.ambient[ 2 ] = b;
19940
19941 var hash = state.hash;
19942
19943 if ( hash.directionalLength !== directionalLength ||
19944 hash.pointLength !== pointLength ||
19945 hash.spotLength !== spotLength ||
19946 hash.rectAreaLength !== rectAreaLength ||
19947 hash.hemiLength !== hemiLength ||
19948 hash.numDirectionalShadows !== numDirectionalShadows ||
19949 hash.numPointShadows !== numPointShadows ||
19950 hash.numSpotShadows !== numSpotShadows ) {
19951
19952 state.directional.length = directionalLength;
19953 state.spot.length = spotLength;
19954 state.rectArea.length = rectAreaLength;
19955 state.point.length = pointLength;
19956 state.hemi.length = hemiLength;
19957
19958 state.directionalShadow.length = numDirectionalShadows;
19959 state.directionalShadowMap.length = numDirectionalShadows;
19960 state.pointShadow.length = numPointShadows;
19961 state.pointShadowMap.length = numPointShadows;
19962 state.spotShadow.length = numSpotShadows;
19963 state.spotShadowMap.length = numSpotShadows;
19964 state.directionalShadowMatrix.length = numDirectionalShadows;
19965 state.pointShadowMatrix.length = numPointShadows;
19966 state.spotShadowMatrix.length = numSpotShadows;
19967
19968 hash.directionalLength = directionalLength;
19969 hash.pointLength = pointLength;
19970 hash.spotLength = spotLength;
19971 hash.rectAreaLength = rectAreaLength;
19972 hash.hemiLength = hemiLength;
19973
19974 hash.numDirectionalShadows = numDirectionalShadows;
19975 hash.numPointShadows = numPointShadows;
19976 hash.numSpotShadows = numSpotShadows;
19977
19978 state.version = nextVersion ++;
19979
19980 }
19981
19982 }
19983
19984 return {
19985 setup: setup,
19986 state: state
19987 };
19988
19989 }
19990
19991 function WebGLRenderState() {
19992
19993 var lights = new WebGLLights();
19994
19995 var lightsArray = [];
19996 var shadowsArray = [];
19997
19998 function init() {
19999
20000 lightsArray.length = 0;
20001 shadowsArray.length = 0;
20002
20003 }
20004
20005 function pushLight( light ) {
20006
20007 lightsArray.push( light );
20008
20009 }
20010
20011 function pushShadow( shadowLight ) {
20012
20013 shadowsArray.push( shadowLight );
20014
20015 }
20016
20017 function setupLights( camera ) {
20018
20019 lights.setup( lightsArray, shadowsArray, camera );
20020
20021 }
20022
20023 var state = {
20024 lightsArray: lightsArray,
20025 shadowsArray: shadowsArray,
20026
20027 lights: lights
20028 };
20029
20030 return {
20031 init: init,
20032 state: state,
20033 setupLights: setupLights,
20034
20035 pushLight: pushLight,
20036 pushShadow: pushShadow
20037 };
20038
20039 }
20040
20041 function WebGLRenderStates() {
20042
20043 var renderStates = new WeakMap();
20044
20045 function onSceneDispose( event ) {
20046
20047 var scene = event.target;
20048
20049 scene.removeEventListener( 'dispose', onSceneDispose );
20050
20051 renderStates.delete( scene );
20052
20053 }
20054
20055 function get( scene, camera ) {
20056
20057 var renderState;
20058
20059 if ( renderStates.has( scene ) === false ) {
20060
20061 renderState = new WebGLRenderState();
20062 renderStates.set( scene, new WeakMap() );
20063 renderStates.get( scene ).set( camera, renderState );
20064
20065 scene.addEventListener( 'dispose', onSceneDispose );
20066
20067 } else {
20068
20069 if ( renderStates.get( scene ).has( camera ) === false ) {
20070
20071 renderState = new WebGLRenderState();
20072 renderStates.get( scene ).set( camera, renderState );
20073
20074 } else {
20075
20076 renderState = renderStates.get( scene ).get( camera );
20077
20078 }
20079
20080 }
20081
20082 return renderState;
20083
20084 }
20085
20086 function dispose() {
20087
20088 renderStates = new WeakMap();
20089
20090 }
20091
20092 return {
20093 get: get,
20094 dispose: dispose
20095 };
20096
20097 }
20098
20099 /**
20100 * parameters = {
20101 *
20102 * opacity: <float>,
20103 *
20104 * map: new THREE.Texture( <Image> ),
20105 *
20106 * alphaMap: new THREE.Texture( <Image> ),
20107 *
20108 * displacementMap: new THREE.Texture( <Image> ),
20109 * displacementScale: <float>,
20110 * displacementBias: <float>,
20111 *
20112 * wireframe: <boolean>,
20113 * wireframeLinewidth: <float>
20114 * }
20115 */
20116
20117 function MeshDepthMaterial( parameters ) {
20118
20119 Material.call( this );
20120
20121 this.type = 'MeshDepthMaterial';
20122
20123 this.depthPacking = BasicDepthPacking;
20124
20125 this.skinning = false;
20126 this.morphTargets = false;
20127
20128 this.map = null;
20129
20130 this.alphaMap = null;
20131
20132 this.displacementMap = null;
20133 this.displacementScale = 1;
20134 this.displacementBias = 0;
20135
20136 this.wireframe = false;
20137 this.wireframeLinewidth = 1;
20138
20139 this.fog = false;
20140
20141 this.setValues( parameters );
20142
20143 }
20144
20145 MeshDepthMaterial.prototype = Object.create( Material.prototype );
20146 MeshDepthMaterial.prototype.constructor = MeshDepthMaterial;
20147
20148 MeshDepthMaterial.prototype.isMeshDepthMaterial = true;
20149
20150 MeshDepthMaterial.prototype.copy = function ( source ) {
20151
20152 Material.prototype.copy.call( this, source );
20153
20154 this.depthPacking = source.depthPacking;
20155
20156 this.skinning = source.skinning;
20157 this.morphTargets = source.morphTargets;
20158
20159 this.map = source.map;
20160
20161 this.alphaMap = source.alphaMap;
20162
20163 this.displacementMap = source.displacementMap;
20164 this.displacementScale = source.displacementScale;
20165 this.displacementBias = source.displacementBias;
20166
20167 this.wireframe = source.wireframe;
20168 this.wireframeLinewidth = source.wireframeLinewidth;
20169
20170 return this;
20171
20172 };
20173
20174 /**
20175 * parameters = {
20176 *
20177 * referencePosition: <float>,
20178 * nearDistance: <float>,
20179 * farDistance: <float>,
20180 *
20181 * skinning: <bool>,
20182 * morphTargets: <bool>,
20183 *
20184 * map: new THREE.Texture( <Image> ),
20185 *
20186 * alphaMap: new THREE.Texture( <Image> ),
20187 *
20188 * displacementMap: new THREE.Texture( <Image> ),
20189 * displacementScale: <float>,
20190 * displacementBias: <float>
20191 *
20192 * }
20193 */
20194
20195 function MeshDistanceMaterial( parameters ) {
20196
20197 Material.call( this );
20198
20199 this.type = 'MeshDistanceMaterial';
20200
20201 this.referencePosition = new Vector3();
20202 this.nearDistance = 1;
20203 this.farDistance = 1000;
20204
20205 this.skinning = false;
20206 this.morphTargets = false;
20207
20208 this.map = null;
20209
20210 this.alphaMap = null;
20211
20212 this.displacementMap = null;
20213 this.displacementScale = 1;
20214 this.displacementBias = 0;
20215
20216 this.fog = false;
20217
20218 this.setValues( parameters );
20219
20220 }
20221
20222 MeshDistanceMaterial.prototype = Object.create( Material.prototype );
20223 MeshDistanceMaterial.prototype.constructor = MeshDistanceMaterial;
20224
20225 MeshDistanceMaterial.prototype.isMeshDistanceMaterial = true;
20226
20227 MeshDistanceMaterial.prototype.copy = function ( source ) {
20228
20229 Material.prototype.copy.call( this, source );
20230
20231 this.referencePosition.copy( source.referencePosition );
20232 this.nearDistance = source.nearDistance;
20233 this.farDistance = source.farDistance;
20234
20235 this.skinning = source.skinning;
20236 this.morphTargets = source.morphTargets;
20237
20238 this.map = source.map;
20239
20240 this.alphaMap = source.alphaMap;
20241
20242 this.displacementMap = source.displacementMap;
20243 this.displacementScale = source.displacementScale;
20244 this.displacementBias = source.displacementBias;
20245
20246 return this;
20247
20248 };
20249
20250 var vsm_frag = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n float mean = 0.0;\n float squared_mean = 0.0;\n\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy ) / resolution ) );\n for ( float i = -1.0; i < 1.0 ; i += SAMPLE_RATE) {\n #ifdef HORIZONAL_PASS\n vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( i, 0.0 ) * radius ) / resolution ) );\n mean += distribution.x;\n squared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n #else\n float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, i ) * radius ) / resolution ) );\n mean += depth;\n squared_mean += depth * depth;\n #endif\n }\n mean = mean * HALF_SAMPLE_RATE;\n squared_mean = squared_mean * HALF_SAMPLE_RATE;\n float std_dev = sqrt( squared_mean - mean * mean );\n gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
20251
20252 var vsm_vert = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}";
20253
20254 function WebGLShadowMap( _renderer, _objects, maxTextureSize ) {
20255
20256 var _frustum = new Frustum();
20257
20258 var _shadowMapSize = new Vector2(),
20259 _viewportSize = new Vector2(),
20260
20261 _viewport = new Vector4(),
20262
20263 _depthMaterials = [],
20264 _distanceMaterials = [],
20265
20266 _materialCache = {};
20267
20268 var shadowSide = { 0: BackSide, 1: FrontSide, 2: DoubleSide };
20269
20270 var shadowMaterialVertical = new ShaderMaterial( {
20271
20272 defines: {
20273 SAMPLE_RATE: 2.0 / 8.0,
20274 HALF_SAMPLE_RATE: 1.0 / 8.0
20275 },
20276
20277 uniforms: {
20278 shadow_pass: { value: null },
20279 resolution: { value: new Vector2() },
20280 radius: { value: 4.0 }
20281 },
20282
20283 vertexShader: vsm_vert,
20284
20285 fragmentShader: vsm_frag
20286
20287 } );
20288
20289 var shadowMaterialHorizonal = shadowMaterialVertical.clone();
20290 shadowMaterialHorizonal.defines.HORIZONAL_PASS = 1;
20291
20292 var fullScreenTri = new BufferGeometry();
20293 fullScreenTri.setAttribute(
20294 "position",
20295 new BufferAttribute(
20296 new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ),
20297 3
20298 )
20299 );
20300
20301 var fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical );
20302
20303 var scope = this;
20304
20305 this.enabled = false;
20306
20307 this.autoUpdate = true;
20308 this.needsUpdate = false;
20309
20310 this.type = PCFShadowMap;
20311
20312 this.render = function ( lights, scene, camera ) {
20313
20314 if ( scope.enabled === false ) { return; }
20315 if ( scope.autoUpdate === false && scope.needsUpdate === false ) { return; }
20316
20317 if ( lights.length === 0 ) { return; }
20318
20319 var currentRenderTarget = _renderer.getRenderTarget();
20320 var activeCubeFace = _renderer.getActiveCubeFace();
20321 var activeMipmapLevel = _renderer.getActiveMipmapLevel();
20322
20323 var _state = _renderer.state;
20324
20325 // Set GL state for depth map.
20326 _state.setBlending( NoBlending );
20327 _state.buffers.color.setClear( 1, 1, 1, 1 );
20328 _state.buffers.depth.setTest( true );
20329 _state.setScissorTest( false );
20330
20331 // render depth map
20332
20333 for ( var i = 0, il = lights.length; i < il; i ++ ) {
20334
20335 var light = lights[ i ];
20336 var shadow = light.shadow;
20337
20338 if ( shadow.autoUpdate === false && shadow.needsUpdate === false ) { continue; }
20339
20340 if ( shadow === undefined ) {
20341
20342 console.warn( 'THREE.WebGLShadowMap:', light, 'has no shadow.' );
20343 continue;
20344
20345 }
20346
20347 _shadowMapSize.copy( shadow.mapSize );
20348
20349 var shadowFrameExtents = shadow.getFrameExtents();
20350
20351 _shadowMapSize.multiply( shadowFrameExtents );
20352
20353 _viewportSize.copy( shadow.mapSize );
20354
20355 if ( _shadowMapSize.x > maxTextureSize || _shadowMapSize.y > maxTextureSize ) {
20356
20357 if ( _shadowMapSize.x > maxTextureSize ) {
20358
20359 _viewportSize.x = Math.floor( maxTextureSize / shadowFrameExtents.x );
20360 _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
20361 shadow.mapSize.x = _viewportSize.x;
20362
20363 }
20364
20365 if ( _shadowMapSize.y > maxTextureSize ) {
20366
20367 _viewportSize.y = Math.floor( maxTextureSize / shadowFrameExtents.y );
20368 _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
20369 shadow.mapSize.y = _viewportSize.y;
20370
20371 }
20372
20373 }
20374
20375 if ( shadow.map === null && ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {
20376
20377 var pars = { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat, stencilBuffer: false };
20378
20379 shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
20380 shadow.map.texture.name = light.name + ".shadowMap";
20381
20382 shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars );
20383
20384 shadow.camera.updateProjectionMatrix();
20385
20386 }
20387
20388 if ( shadow.map === null ) {
20389
20390 var pars$1 = { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat, stencilBuffer: false };
20391
20392 shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, pars$1 );
20393 shadow.map.texture.name = light.name + ".shadowMap";
20394
20395 shadow.camera.updateProjectionMatrix();
20396
20397 }
20398
20399 _renderer.setRenderTarget( shadow.map );
20400 _renderer.clear();
20401
20402 var viewportCount = shadow.getViewportCount();
20403
20404 for ( var vp = 0; vp < viewportCount; vp ++ ) {
20405
20406 var viewport = shadow.getViewport( vp );
20407
20408 _viewport.set(
20409 _viewportSize.x * viewport.x,
20410 _viewportSize.y * viewport.y,
20411 _viewportSize.x * viewport.z,
20412 _viewportSize.y * viewport.w
20413 );
20414
20415 _state.viewport( _viewport );
20416
20417 shadow.updateMatrices( light, vp );
20418
20419 _frustum = shadow.getFrustum();
20420
20421 renderObject( scene, camera, shadow.camera, light, this.type );
20422
20423 }
20424
20425 // do blur pass for VSM
20426
20427 if ( ! shadow.isPointLightShadow && this.type === VSMShadowMap ) {
20428
20429 VSMPass( shadow, camera );
20430
20431 }
20432
20433 shadow.needsUpdate = false;
20434
20435 }
20436
20437 scope.needsUpdate = false;
20438
20439 _renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel );
20440
20441 };
20442
20443 function VSMPass( shadow, camera ) {
20444
20445 var geometry = _objects.update( fullScreenMesh );
20446
20447 // vertical pass
20448
20449 shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;
20450 shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
20451 shadowMaterialVertical.uniforms.radius.value = shadow.radius;
20452 _renderer.setRenderTarget( shadow.mapPass );
20453 _renderer.clear();
20454 _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null );
20455
20456 // horizonal pass
20457
20458 shadowMaterialHorizonal.uniforms.shadow_pass.value = shadow.mapPass.texture;
20459 shadowMaterialHorizonal.uniforms.resolution.value = shadow.mapSize;
20460 shadowMaterialHorizonal.uniforms.radius.value = shadow.radius;
20461 _renderer.setRenderTarget( shadow.map );
20462 _renderer.clear();
20463 _renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizonal, fullScreenMesh, null );
20464
20465 }
20466
20467 function getDepthMaterialVariant( useMorphing, useSkinning, useInstancing ) {
20468
20469 var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2;
20470
20471 var material = _depthMaterials[ index ];
20472
20473 if ( material === undefined ) {
20474
20475 material = new MeshDepthMaterial( {
20476
20477 depthPacking: RGBADepthPacking,
20478
20479 morphTargets: useMorphing,
20480 skinning: useSkinning
20481
20482 } );
20483
20484 _depthMaterials[ index ] = material;
20485
20486 }
20487
20488 return material;
20489
20490 }
20491
20492 function getDistanceMaterialVariant( useMorphing, useSkinning, useInstancing ) {
20493
20494 var index = useMorphing << 0 | useSkinning << 1 | useInstancing << 2;
20495
20496 var material = _distanceMaterials[ index ];
20497
20498 if ( material === undefined ) {
20499
20500 material = new MeshDistanceMaterial( {
20501
20502 morphTargets: useMorphing,
20503 skinning: useSkinning
20504
20505 } );
20506
20507 _distanceMaterials[ index ] = material;
20508
20509 }
20510
20511 return material;
20512
20513 }
20514
20515 function getDepthMaterial( object, geometry, material, light, shadowCameraNear, shadowCameraFar, type ) {
20516
20517 var result = null;
20518
20519 var getMaterialVariant = getDepthMaterialVariant;
20520 var customMaterial = object.customDepthMaterial;
20521
20522 if ( light.isPointLight === true ) {
20523
20524 getMaterialVariant = getDistanceMaterialVariant;
20525 customMaterial = object.customDistanceMaterial;
20526
20527 }
20528
20529 if ( customMaterial === undefined ) {
20530
20531 var useMorphing = false;
20532
20533 if ( material.morphTargets === true ) {
20534
20535 useMorphing = geometry.morphAttributes && geometry.morphAttributes.position && geometry.morphAttributes.position.length > 0;
20536
20537 }
20538
20539 var useSkinning = false;
20540
20541 if ( object.isSkinnedMesh === true ) {
20542
20543 if ( material.skinning === true ) {
20544
20545 useSkinning = true;
20546
20547 } else {
20548
20549 console.warn( 'THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:', object );
20550
20551 }
20552
20553 }
20554
20555 var useInstancing = object.isInstancedMesh === true;
20556
20557 result = getMaterialVariant( useMorphing, useSkinning, useInstancing );
20558
20559 } else {
20560
20561 result = customMaterial;
20562
20563 }
20564
20565 if ( _renderer.localClippingEnabled &&
20566 material.clipShadows === true &&
20567 material.clippingPlanes.length !== 0 ) {
20568
20569 // in this case we need a unique material instance reflecting the
20570 // appropriate state
20571
20572 var keyA = result.uuid, keyB = material.uuid;
20573
20574 var materialsForVariant = _materialCache[ keyA ];
20575
20576 if ( materialsForVariant === undefined ) {
20577
20578 materialsForVariant = {};
20579 _materialCache[ keyA ] = materialsForVariant;
20580
20581 }
20582
20583 var cachedMaterial = materialsForVariant[ keyB ];
20584
20585 if ( cachedMaterial === undefined ) {
20586
20587 cachedMaterial = result.clone();
20588 materialsForVariant[ keyB ] = cachedMaterial;
20589
20590 }
20591
20592 result = cachedMaterial;
20593
20594 }
20595
20596 result.visible = material.visible;
20597 result.wireframe = material.wireframe;
20598
20599 if ( type === VSMShadowMap ) {
20600
20601 result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side;
20602
20603 } else {
20604
20605 result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ];
20606
20607 }
20608
20609 result.clipShadows = material.clipShadows;
20610 result.clippingPlanes = material.clippingPlanes;
20611 result.clipIntersection = material.clipIntersection;
20612
20613 result.wireframeLinewidth = material.wireframeLinewidth;
20614 result.linewidth = material.linewidth;
20615
20616 if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) {
20617
20618 result.referencePosition.setFromMatrixPosition( light.matrixWorld );
20619 result.nearDistance = shadowCameraNear;
20620 result.farDistance = shadowCameraFar;
20621
20622 }
20623
20624 return result;
20625
20626 }
20627
20628 function renderObject( object, camera, shadowCamera, light, type ) {
20629
20630 if ( object.visible === false ) { return; }
20631
20632 var visible = object.layers.test( camera.layers );
20633
20634 if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
20635
20636 if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {
20637
20638 object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
20639
20640 var geometry = _objects.update( object );
20641 var material = object.material;
20642
20643 if ( Array.isArray( material ) ) {
20644
20645 var groups = geometry.groups;
20646
20647 for ( var k = 0, kl = groups.length; k < kl; k ++ ) {
20648
20649 var group = groups[ k ];
20650 var groupMaterial = material[ group.materialIndex ];
20651
20652 if ( groupMaterial && groupMaterial.visible ) {
20653
20654 var depthMaterial = getDepthMaterial( object, geometry, groupMaterial, light, shadowCamera.near, shadowCamera.far, type );
20655
20656 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
20657
20658 }
20659
20660 }
20661
20662 } else if ( material.visible ) {
20663
20664 var depthMaterial$1 = getDepthMaterial( object, geometry, material, light, shadowCamera.near, shadowCamera.far, type );
20665
20666 _renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial$1, object, null );
20667
20668 }
20669
20670 }
20671
20672 }
20673
20674 var children = object.children;
20675
20676 for ( var i = 0, l = children.length; i < l; i ++ ) {
20677
20678 renderObject( children[ i ], camera, shadowCamera, light, type );
20679
20680 }
20681
20682 }
20683
20684 }
20685
20686 function WebGLState( gl, extensions, capabilities ) {
20687
20688 var isWebGL2 = capabilities.isWebGL2;
20689
20690 function ColorBuffer() {
20691
20692 var locked = false;
20693
20694 var color = new Vector4();
20695 var currentColorMask = null;
20696 var currentColorClear = new Vector4( 0, 0, 0, 0 );
20697
20698 return {
20699
20700 setMask: function ( colorMask ) {
20701
20702 if ( currentColorMask !== colorMask && ! locked ) {
20703
20704 gl.colorMask( colorMask, colorMask, colorMask, colorMask );
20705 currentColorMask = colorMask;
20706
20707 }
20708
20709 },
20710
20711 setLocked: function ( lock ) {
20712
20713 locked = lock;
20714
20715 },
20716
20717 setClear: function ( r, g, b, a, premultipliedAlpha ) {
20718
20719 if ( premultipliedAlpha === true ) {
20720
20721 r *= a; g *= a; b *= a;
20722
20723 }
20724
20725 color.set( r, g, b, a );
20726
20727 if ( currentColorClear.equals( color ) === false ) {
20728
20729 gl.clearColor( r, g, b, a );
20730 currentColorClear.copy( color );
20731
20732 }
20733
20734 },
20735
20736 reset: function () {
20737
20738 locked = false;
20739
20740 currentColorMask = null;
20741 currentColorClear.set( - 1, 0, 0, 0 ); // set to invalid state
20742
20743 }
20744
20745 };
20746
20747 }
20748
20749 function DepthBuffer() {
20750
20751 var locked = false;
20752
20753 var currentDepthMask = null;
20754 var currentDepthFunc = null;
20755 var currentDepthClear = null;
20756
20757 return {
20758
20759 setTest: function ( depthTest ) {
20760
20761 if ( depthTest ) {
20762
20763 enable( 2929 );
20764
20765 } else {
20766
20767 disable( 2929 );
20768
20769 }
20770
20771 },
20772
20773 setMask: function ( depthMask ) {
20774
20775 if ( currentDepthMask !== depthMask && ! locked ) {
20776
20777 gl.depthMask( depthMask );
20778 currentDepthMask = depthMask;
20779
20780 }
20781
20782 },
20783
20784 setFunc: function ( depthFunc ) {
20785
20786 if ( currentDepthFunc !== depthFunc ) {
20787
20788 if ( depthFunc ) {
20789
20790 switch ( depthFunc ) {
20791
20792 case NeverDepth:
20793
20794 gl.depthFunc( 512 );
20795 break;
20796
20797 case AlwaysDepth:
20798
20799 gl.depthFunc( 519 );
20800 break;
20801
20802 case LessDepth:
20803
20804 gl.depthFunc( 513 );
20805 break;
20806
20807 case LessEqualDepth:
20808
20809 gl.depthFunc( 515 );
20810 break;
20811
20812 case EqualDepth:
20813
20814 gl.depthFunc( 514 );
20815 break;
20816
20817 case GreaterEqualDepth:
20818
20819 gl.depthFunc( 518 );
20820 break;
20821
20822 case GreaterDepth:
20823
20824 gl.depthFunc( 516 );
20825 break;
20826
20827 case NotEqualDepth:
20828
20829 gl.depthFunc( 517 );
20830 break;
20831
20832 default:
20833
20834 gl.depthFunc( 515 );
20835
20836 }
20837
20838 } else {
20839
20840 gl.depthFunc( 515 );
20841
20842 }
20843
20844 currentDepthFunc = depthFunc;
20845
20846 }
20847
20848 },
20849
20850 setLocked: function ( lock ) {
20851
20852 locked = lock;
20853
20854 },
20855
20856 setClear: function ( depth ) {
20857
20858 if ( currentDepthClear !== depth ) {
20859
20860 gl.clearDepth( depth );
20861 currentDepthClear = depth;
20862
20863 }
20864
20865 },
20866
20867 reset: function () {
20868
20869 locked = false;
20870
20871 currentDepthMask = null;
20872 currentDepthFunc = null;
20873 currentDepthClear = null;
20874
20875 }
20876
20877 };
20878
20879 }
20880
20881 function StencilBuffer() {
20882
20883 var locked = false;
20884
20885 var currentStencilMask = null;
20886 var currentStencilFunc = null;
20887 var currentStencilRef = null;
20888 var currentStencilFuncMask = null;
20889 var currentStencilFail = null;
20890 var currentStencilZFail = null;
20891 var currentStencilZPass = null;
20892 var currentStencilClear = null;
20893
20894 return {
20895
20896 setTest: function ( stencilTest ) {
20897
20898 if ( ! locked ) {
20899
20900 if ( stencilTest ) {
20901
20902 enable( 2960 );
20903
20904 } else {
20905
20906 disable( 2960 );
20907
20908 }
20909
20910 }
20911
20912 },
20913
20914 setMask: function ( stencilMask ) {
20915
20916 if ( currentStencilMask !== stencilMask && ! locked ) {
20917
20918 gl.stencilMask( stencilMask );
20919 currentStencilMask = stencilMask;
20920
20921 }
20922
20923 },
20924
20925 setFunc: function ( stencilFunc, stencilRef, stencilMask ) {
20926
20927 if ( currentStencilFunc !== stencilFunc ||
20928 currentStencilRef !== stencilRef ||
20929 currentStencilFuncMask !== stencilMask ) {
20930
20931 gl.stencilFunc( stencilFunc, stencilRef, stencilMask );
20932
20933 currentStencilFunc = stencilFunc;
20934 currentStencilRef = stencilRef;
20935 currentStencilFuncMask = stencilMask;
20936
20937 }
20938
20939 },
20940
20941 setOp: function ( stencilFail, stencilZFail, stencilZPass ) {
20942
20943 if ( currentStencilFail !== stencilFail ||
20944 currentStencilZFail !== stencilZFail ||
20945 currentStencilZPass !== stencilZPass ) {
20946
20947 gl.stencilOp( stencilFail, stencilZFail, stencilZPass );
20948
20949 currentStencilFail = stencilFail;
20950 currentStencilZFail = stencilZFail;
20951 currentStencilZPass = stencilZPass;
20952
20953 }
20954
20955 },
20956
20957 setLocked: function ( lock ) {
20958
20959 locked = lock;
20960
20961 },
20962
20963 setClear: function ( stencil ) {
20964
20965 if ( currentStencilClear !== stencil ) {
20966
20967 gl.clearStencil( stencil );
20968 currentStencilClear = stencil;
20969
20970 }
20971
20972 },
20973
20974 reset: function () {
20975
20976 locked = false;
20977
20978 currentStencilMask = null;
20979 currentStencilFunc = null;
20980 currentStencilRef = null;
20981 currentStencilFuncMask = null;
20982 currentStencilFail = null;
20983 currentStencilZFail = null;
20984 currentStencilZPass = null;
20985 currentStencilClear = null;
20986
20987 }
20988
20989 };
20990
20991 }
20992
20993 //
20994
20995 var colorBuffer = new ColorBuffer();
20996 var depthBuffer = new DepthBuffer();
20997 var stencilBuffer = new StencilBuffer();
20998
20999 var enabledCapabilities = {};
21000
21001 var currentProgram = null;
21002
21003 var currentBlendingEnabled = null;
21004 var currentBlending = null;
21005 var currentBlendEquation = null;
21006 var currentBlendSrc = null;
21007 var currentBlendDst = null;
21008 var currentBlendEquationAlpha = null;
21009 var currentBlendSrcAlpha = null;
21010 var currentBlendDstAlpha = null;
21011 var currentPremultipledAlpha = false;
21012
21013 var currentFlipSided = null;
21014 var currentCullFace = null;
21015
21016 var currentLineWidth = null;
21017
21018 var currentPolygonOffsetFactor = null;
21019 var currentPolygonOffsetUnits = null;
21020
21021 var maxTextures = gl.getParameter( 35661 );
21022
21023 var lineWidthAvailable = false;
21024 var version = 0;
21025 var glVersion = gl.getParameter( 7938 );
21026
21027 if ( glVersion.indexOf( 'WebGL' ) !== - 1 ) {
21028
21029 version = parseFloat( /^WebGL\ ([0-9])/.exec( glVersion )[ 1 ] );
21030 lineWidthAvailable = ( version >= 1.0 );
21031
21032 } else if ( glVersion.indexOf( 'OpenGL ES' ) !== - 1 ) {
21033
21034 version = parseFloat( /^OpenGL\ ES\ ([0-9])/.exec( glVersion )[ 1 ] );
21035 lineWidthAvailable = ( version >= 2.0 );
21036
21037 }
21038
21039 var currentTextureSlot = null;
21040 var currentBoundTextures = {};
21041
21042 var currentScissor = new Vector4();
21043 var currentViewport = new Vector4();
21044
21045 function createTexture( type, target, count ) {
21046
21047 var data = new Uint8Array( 4 ); // 4 is required to match default unpack alignment of 4.
21048 var texture = gl.createTexture();
21049
21050 gl.bindTexture( type, texture );
21051 gl.texParameteri( type, 10241, 9728 );
21052 gl.texParameteri( type, 10240, 9728 );
21053
21054 for ( var i = 0; i < count; i ++ ) {
21055
21056 gl.texImage2D( target + i, 0, 6408, 1, 1, 0, 6408, 5121, data );
21057
21058 }
21059
21060 return texture;
21061
21062 }
21063
21064 var emptyTextures = {};
21065 emptyTextures[ 3553 ] = createTexture( 3553, 3553, 1 );
21066 emptyTextures[ 34067 ] = createTexture( 34067, 34069, 6 );
21067
21068 // init
21069
21070 colorBuffer.setClear( 0, 0, 0, 1 );
21071 depthBuffer.setClear( 1 );
21072 stencilBuffer.setClear( 0 );
21073
21074 enable( 2929 );
21075 depthBuffer.setFunc( LessEqualDepth );
21076
21077 setFlipSided( false );
21078 setCullFace( CullFaceBack );
21079 enable( 2884 );
21080
21081 setBlending( NoBlending );
21082
21083 //
21084
21085 function enable( id ) {
21086
21087 if ( enabledCapabilities[ id ] !== true ) {
21088
21089 gl.enable( id );
21090 enabledCapabilities[ id ] = true;
21091
21092 }
21093
21094 }
21095
21096 function disable( id ) {
21097
21098 if ( enabledCapabilities[ id ] !== false ) {
21099
21100 gl.disable( id );
21101 enabledCapabilities[ id ] = false;
21102
21103 }
21104
21105 }
21106
21107 function useProgram( program ) {
21108
21109 if ( currentProgram !== program ) {
21110
21111 gl.useProgram( program );
21112
21113 currentProgram = program;
21114
21115 return true;
21116
21117 }
21118
21119 return false;
21120
21121 }
21122
21123 var equationToGL = {};
21124 equationToGL[ AddEquation ] = 32774;
21125 equationToGL[ SubtractEquation ] = 32778;
21126 equationToGL[ ReverseSubtractEquation ] = 32779;
21127
21128 if ( isWebGL2 ) {
21129
21130 equationToGL[ MinEquation ] = 32775;
21131 equationToGL[ MaxEquation ] = 32776;
21132
21133 } else {
21134
21135 var extension = extensions.get( 'EXT_blend_minmax' );
21136
21137 if ( extension !== null ) {
21138
21139 equationToGL[ MinEquation ] = extension.MIN_EXT;
21140 equationToGL[ MaxEquation ] = extension.MAX_EXT;
21141
21142 }
21143
21144 }
21145
21146 var factorToGL = {};
21147 factorToGL[ ZeroFactor ] = 0;
21148 factorToGL[ OneFactor ] = 1;
21149 factorToGL[ SrcColorFactor ] = 768;
21150 factorToGL[ SrcAlphaFactor ] = 770;
21151 factorToGL[ SrcAlphaSaturateFactor ] = 776;
21152 factorToGL[ DstColorFactor ] = 774;
21153 factorToGL[ DstAlphaFactor ] = 772;
21154 factorToGL[ OneMinusSrcColorFactor ] = 769;
21155 factorToGL[ OneMinusSrcAlphaFactor ] = 771;
21156 factorToGL[ OneMinusDstColorFactor ] = 775;
21157 factorToGL[ OneMinusDstAlphaFactor ] = 773;
21158
21159 function setBlending( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha ) {
21160
21161 if ( blending === NoBlending ) {
21162
21163 if ( currentBlendingEnabled ) {
21164
21165 disable( 3042 );
21166 currentBlendingEnabled = false;
21167
21168 }
21169
21170 return;
21171
21172 }
21173
21174 if ( ! currentBlendingEnabled ) {
21175
21176 enable( 3042 );
21177 currentBlendingEnabled = true;
21178
21179 }
21180
21181 if ( blending !== CustomBlending ) {
21182
21183 if ( blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha ) {
21184
21185 if ( currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation ) {
21186
21187 gl.blendEquation( 32774 );
21188
21189 currentBlendEquation = AddEquation;
21190 currentBlendEquationAlpha = AddEquation;
21191
21192 }
21193
21194 if ( premultipliedAlpha ) {
21195
21196 switch ( blending ) {
21197
21198 case NormalBlending:
21199 gl.blendFuncSeparate( 1, 771, 1, 771 );
21200 break;
21201
21202 case AdditiveBlending:
21203 gl.blendFunc( 1, 1 );
21204 break;
21205
21206 case SubtractiveBlending:
21207 gl.blendFuncSeparate( 0, 0, 769, 771 );
21208 break;
21209
21210 case MultiplyBlending:
21211 gl.blendFuncSeparate( 0, 768, 0, 770 );
21212 break;
21213
21214 default:
21215 console.error( 'THREE.WebGLState: Invalid blending: ', blending );
21216 break;
21217
21218 }
21219
21220 } else {
21221
21222 switch ( blending ) {
21223
21224 case NormalBlending:
21225 gl.blendFuncSeparate( 770, 771, 1, 771 );
21226 break;
21227
21228 case AdditiveBlending:
21229 gl.blendFunc( 770, 1 );
21230 break;
21231
21232 case SubtractiveBlending:
21233 gl.blendFunc( 0, 769 );
21234 break;
21235
21236 case MultiplyBlending:
21237 gl.blendFunc( 0, 768 );
21238 break;
21239
21240 default:
21241 console.error( 'THREE.WebGLState: Invalid blending: ', blending );
21242 break;
21243
21244 }
21245
21246 }
21247
21248 currentBlendSrc = null;
21249 currentBlendDst = null;
21250 currentBlendSrcAlpha = null;
21251 currentBlendDstAlpha = null;
21252
21253 currentBlending = blending;
21254 currentPremultipledAlpha = premultipliedAlpha;
21255
21256 }
21257
21258 return;
21259
21260 }
21261
21262 // custom blending
21263
21264 blendEquationAlpha = blendEquationAlpha || blendEquation;
21265 blendSrcAlpha = blendSrcAlpha || blendSrc;
21266 blendDstAlpha = blendDstAlpha || blendDst;
21267
21268 if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
21269
21270 gl.blendEquationSeparate( equationToGL[ blendEquation ], equationToGL[ blendEquationAlpha ] );
21271
21272 currentBlendEquation = blendEquation;
21273 currentBlendEquationAlpha = blendEquationAlpha;
21274
21275 }
21276
21277 if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
21278
21279 gl.blendFuncSeparate( factorToGL[ blendSrc ], factorToGL[ blendDst ], factorToGL[ blendSrcAlpha ], factorToGL[ blendDstAlpha ] );
21280
21281 currentBlendSrc = blendSrc;
21282 currentBlendDst = blendDst;
21283 currentBlendSrcAlpha = blendSrcAlpha;
21284 currentBlendDstAlpha = blendDstAlpha;
21285
21286 }
21287
21288 currentBlending = blending;
21289 currentPremultipledAlpha = null;
21290
21291 }
21292
21293 function setMaterial( material, frontFaceCW ) {
21294
21295 material.side === DoubleSide
21296 ? disable( 2884 )
21297 : enable( 2884 );
21298
21299 var flipSided = ( material.side === BackSide );
21300 if ( frontFaceCW ) { flipSided = ! flipSided; }
21301
21302 setFlipSided( flipSided );
21303
21304 ( material.blending === NormalBlending && material.transparent === false )
21305 ? setBlending( NoBlending )
21306 : setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha );
21307
21308 depthBuffer.setFunc( material.depthFunc );
21309 depthBuffer.setTest( material.depthTest );
21310 depthBuffer.setMask( material.depthWrite );
21311 colorBuffer.setMask( material.colorWrite );
21312
21313 var stencilWrite = material.stencilWrite;
21314 stencilBuffer.setTest( stencilWrite );
21315 if ( stencilWrite ) {
21316
21317 stencilBuffer.setMask( material.stencilWriteMask );
21318 stencilBuffer.setFunc( material.stencilFunc, material.stencilRef, material.stencilFuncMask );
21319 stencilBuffer.setOp( material.stencilFail, material.stencilZFail, material.stencilZPass );
21320
21321 }
21322
21323 setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
21324
21325 }
21326
21327 //
21328
21329 function setFlipSided( flipSided ) {
21330
21331 if ( currentFlipSided !== flipSided ) {
21332
21333 if ( flipSided ) {
21334
21335 gl.frontFace( 2304 );
21336
21337 } else {
21338
21339 gl.frontFace( 2305 );
21340
21341 }
21342
21343 currentFlipSided = flipSided;
21344
21345 }
21346
21347 }
21348
21349 function setCullFace( cullFace ) {
21350
21351 if ( cullFace !== CullFaceNone ) {
21352
21353 enable( 2884 );
21354
21355 if ( cullFace !== currentCullFace ) {
21356
21357 if ( cullFace === CullFaceBack ) {
21358
21359 gl.cullFace( 1029 );
21360
21361 } else if ( cullFace === CullFaceFront ) {
21362
21363 gl.cullFace( 1028 );
21364
21365 } else {
21366
21367 gl.cullFace( 1032 );
21368
21369 }
21370
21371 }
21372
21373 } else {
21374
21375 disable( 2884 );
21376
21377 }
21378
21379 currentCullFace = cullFace;
21380
21381 }
21382
21383 function setLineWidth( width ) {
21384
21385 if ( width !== currentLineWidth ) {
21386
21387 if ( lineWidthAvailable ) { gl.lineWidth( width ); }
21388
21389 currentLineWidth = width;
21390
21391 }
21392
21393 }
21394
21395 function setPolygonOffset( polygonOffset, factor, units ) {
21396
21397 if ( polygonOffset ) {
21398
21399 enable( 32823 );
21400
21401 if ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) {
21402
21403 gl.polygonOffset( factor, units );
21404
21405 currentPolygonOffsetFactor = factor;
21406 currentPolygonOffsetUnits = units;
21407
21408 }
21409
21410 } else {
21411
21412 disable( 32823 );
21413
21414 }
21415
21416 }
21417
21418 function setScissorTest( scissorTest ) {
21419
21420 if ( scissorTest ) {
21421
21422 enable( 3089 );
21423
21424 } else {
21425
21426 disable( 3089 );
21427
21428 }
21429
21430 }
21431
21432 // texture
21433
21434 function activeTexture( webglSlot ) {
21435
21436 if ( webglSlot === undefined ) { webglSlot = 33984 + maxTextures - 1; }
21437
21438 if ( currentTextureSlot !== webglSlot ) {
21439
21440 gl.activeTexture( webglSlot );
21441 currentTextureSlot = webglSlot;
21442
21443 }
21444
21445 }
21446
21447 function bindTexture( webglType, webglTexture ) {
21448
21449 if ( currentTextureSlot === null ) {
21450
21451 activeTexture();
21452
21453 }
21454
21455 var boundTexture = currentBoundTextures[ currentTextureSlot ];
21456
21457 if ( boundTexture === undefined ) {
21458
21459 boundTexture = { type: undefined, texture: undefined };
21460 currentBoundTextures[ currentTextureSlot ] = boundTexture;
21461
21462 }
21463
21464 if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
21465
21466 gl.bindTexture( webglType, webglTexture || emptyTextures[ webglType ] );
21467
21468 boundTexture.type = webglType;
21469 boundTexture.texture = webglTexture;
21470
21471 }
21472
21473 }
21474
21475 function unbindTexture() {
21476
21477 var boundTexture = currentBoundTextures[ currentTextureSlot ];
21478
21479 if ( boundTexture !== undefined && boundTexture.type !== undefined ) {
21480
21481 gl.bindTexture( boundTexture.type, null );
21482
21483 boundTexture.type = undefined;
21484 boundTexture.texture = undefined;
21485
21486 }
21487
21488 }
21489
21490 function compressedTexImage2D() {
21491
21492 try {
21493
21494 gl.compressedTexImage2D.apply( gl, arguments );
21495
21496 } catch ( error ) {
21497
21498 console.error( 'THREE.WebGLState:', error );
21499
21500 }
21501
21502 }
21503
21504 function texImage2D() {
21505
21506 try {
21507
21508 gl.texImage2D.apply( gl, arguments );
21509
21510 } catch ( error ) {
21511
21512 console.error( 'THREE.WebGLState:', error );
21513
21514 }
21515
21516 }
21517
21518 function texImage3D() {
21519
21520 try {
21521
21522 gl.texImage3D.apply( gl, arguments );
21523
21524 } catch ( error ) {
21525
21526 console.error( 'THREE.WebGLState:', error );
21527
21528 }
21529
21530 }
21531
21532 //
21533
21534 function scissor( scissor ) {
21535
21536 if ( currentScissor.equals( scissor ) === false ) {
21537
21538 gl.scissor( scissor.x, scissor.y, scissor.z, scissor.w );
21539 currentScissor.copy( scissor );
21540
21541 }
21542
21543 }
21544
21545 function viewport( viewport ) {
21546
21547 if ( currentViewport.equals( viewport ) === false ) {
21548
21549 gl.viewport( viewport.x, viewport.y, viewport.z, viewport.w );
21550 currentViewport.copy( viewport );
21551
21552 }
21553
21554 }
21555
21556 //
21557
21558 function reset() {
21559
21560 enabledCapabilities = {};
21561
21562 currentTextureSlot = null;
21563 currentBoundTextures = {};
21564
21565 currentProgram = null;
21566
21567 currentBlending = null;
21568
21569 currentFlipSided = null;
21570 currentCullFace = null;
21571
21572 colorBuffer.reset();
21573 depthBuffer.reset();
21574 stencilBuffer.reset();
21575
21576 }
21577
21578 return {
21579
21580 buffers: {
21581 color: colorBuffer,
21582 depth: depthBuffer,
21583 stencil: stencilBuffer
21584 },
21585
21586 enable: enable,
21587 disable: disable,
21588
21589 useProgram: useProgram,
21590
21591 setBlending: setBlending,
21592 setMaterial: setMaterial,
21593
21594 setFlipSided: setFlipSided,
21595 setCullFace: setCullFace,
21596
21597 setLineWidth: setLineWidth,
21598 setPolygonOffset: setPolygonOffset,
21599
21600 setScissorTest: setScissorTest,
21601
21602 activeTexture: activeTexture,
21603 bindTexture: bindTexture,
21604 unbindTexture: unbindTexture,
21605 compressedTexImage2D: compressedTexImage2D,
21606 texImage2D: texImage2D,
21607 texImage3D: texImage3D,
21608
21609 scissor: scissor,
21610 viewport: viewport,
21611
21612 reset: reset
21613
21614 };
21615
21616 }
21617
21618 function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
21619
21620 var isWebGL2 = capabilities.isWebGL2;
21621 var maxTextures = capabilities.maxTextures;
21622 var maxCubemapSize = capabilities.maxCubemapSize;
21623 var maxTextureSize = capabilities.maxTextureSize;
21624 var maxSamples = capabilities.maxSamples;
21625
21626 var _videoTextures = new WeakMap();
21627 var _canvas;
21628
21629 // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
21630 // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
21631 // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
21632
21633 var useOffscreenCanvas = false;
21634
21635 try {
21636
21637 useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined'
21638 && ( new OffscreenCanvas( 1, 1 ).getContext( "2d" ) ) !== null;
21639
21640 } catch ( err ) {
21641
21642 // Ignore any errors
21643
21644 }
21645
21646 function createCanvas( width, height ) {
21647
21648 // Use OffscreenCanvas when available. Specially needed in web workers
21649
21650 return useOffscreenCanvas ?
21651 new OffscreenCanvas( width, height ) :
21652 document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
21653
21654 }
21655
21656 function resizeImage( image, needsPowerOfTwo, needsNewCanvas, maxSize ) {
21657
21658 var scale = 1;
21659
21660 // handle case if texture exceeds max size
21661
21662 if ( image.width > maxSize || image.height > maxSize ) {
21663
21664 scale = maxSize / Math.max( image.width, image.height );
21665
21666 }
21667
21668 // only perform resize if necessary
21669
21670 if ( scale < 1 || needsPowerOfTwo === true ) {
21671
21672 // only perform resize for certain image types
21673
21674 if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
21675 ( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
21676 ( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
21677
21678 var floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor;
21679
21680 var width = floor( scale * image.width );
21681 var height = floor( scale * image.height );
21682
21683 if ( _canvas === undefined ) { _canvas = createCanvas( width, height ); }
21684
21685 // cube textures can't reuse the same canvas
21686
21687 var canvas = needsNewCanvas ? createCanvas( width, height ) : _canvas;
21688
21689 canvas.width = width;
21690 canvas.height = height;
21691
21692 var context = canvas.getContext( '2d' );
21693 context.drawImage( image, 0, 0, width, height );
21694
21695 console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
21696
21697 return canvas;
21698
21699 } else {
21700
21701 if ( 'data' in image ) {
21702
21703 console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
21704
21705 }
21706
21707 return image;
21708
21709 }
21710
21711 }
21712
21713 return image;
21714
21715 }
21716
21717 function isPowerOfTwo( image ) {
21718
21719 return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height );
21720
21721 }
21722
21723 function textureNeedsPowerOfTwo( texture ) {
21724
21725 if ( isWebGL2 ) { return false; }
21726
21727 return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
21728 ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
21729
21730 }
21731
21732 function textureNeedsGenerateMipmaps( texture, supportsMips ) {
21733
21734 return texture.generateMipmaps && supportsMips &&
21735 texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
21736
21737 }
21738
21739 function generateMipmap( target, texture, width, height ) {
21740
21741 _gl.generateMipmap( target );
21742
21743 var textureProperties = properties.get( texture );
21744
21745 // Note: Math.log( x ) * Math.LOG2E used instead of Math.log2( x ) which is not supported by IE11
21746 textureProperties.__maxMipLevel = Math.log( Math.max( width, height ) ) * Math.LOG2E;
21747
21748 }
21749
21750 function getInternalFormat( internalFormatName, glFormat, glType ) {
21751
21752 if ( isWebGL2 === false ) { return glFormat; }
21753
21754 if ( internalFormatName !== null ) {
21755
21756 if ( _gl[ internalFormatName ] !== undefined ) { return _gl[ internalFormatName ]; }
21757
21758 console.warn( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' );
21759
21760 }
21761
21762 var internalFormat = glFormat;
21763
21764 if ( glFormat === 6403 ) {
21765
21766 if ( glType === 5126 ) { internalFormat = 33326; }
21767 if ( glType === 5131 ) { internalFormat = 33325; }
21768 if ( glType === 5121 ) { internalFormat = 33321; }
21769
21770 }
21771
21772 if ( glFormat === 6407 ) {
21773
21774 if ( glType === 5126 ) { internalFormat = 34837; }
21775 if ( glType === 5131 ) { internalFormat = 34843; }
21776 if ( glType === 5121 ) { internalFormat = 32849; }
21777
21778 }
21779
21780 if ( glFormat === 6408 ) {
21781
21782 if ( glType === 5126 ) { internalFormat = 34836; }
21783 if ( glType === 5131 ) { internalFormat = 34842; }
21784 if ( glType === 5121 ) { internalFormat = 32856; }
21785
21786 }
21787
21788 if ( internalFormat === 33325 || internalFormat === 33326 ||
21789 internalFormat === 34842 || internalFormat === 34836 ) {
21790
21791 extensions.get( 'EXT_color_buffer_float' );
21792
21793 }
21794
21795 return internalFormat;
21796
21797 }
21798
21799 // Fallback filters for non-power-of-2 textures
21800
21801 function filterFallback( f ) {
21802
21803 if ( f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter ) {
21804
21805 return 9728;
21806
21807 }
21808
21809 return 9729;
21810
21811 }
21812
21813 //
21814
21815 function onTextureDispose( event ) {
21816
21817 var texture = event.target;
21818
21819 texture.removeEventListener( 'dispose', onTextureDispose );
21820
21821 deallocateTexture( texture );
21822
21823 if ( texture.isVideoTexture ) {
21824
21825 _videoTextures.delete( texture );
21826
21827 }
21828
21829 info.memory.textures --;
21830
21831 }
21832
21833 function onRenderTargetDispose( event ) {
21834
21835 var renderTarget = event.target;
21836
21837 renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
21838
21839 deallocateRenderTarget( renderTarget );
21840
21841 info.memory.textures --;
21842
21843 }
21844
21845 //
21846
21847 function deallocateTexture( texture ) {
21848
21849 var textureProperties = properties.get( texture );
21850
21851 if ( textureProperties.__webglInit === undefined ) { return; }
21852
21853 _gl.deleteTexture( textureProperties.__webglTexture );
21854
21855 properties.remove( texture );
21856
21857 }
21858
21859 function deallocateRenderTarget( renderTarget ) {
21860
21861 var renderTargetProperties = properties.get( renderTarget );
21862 var textureProperties = properties.get( renderTarget.texture );
21863
21864 if ( ! renderTarget ) { return; }
21865
21866 if ( textureProperties.__webglTexture !== undefined ) {
21867
21868 _gl.deleteTexture( textureProperties.__webglTexture );
21869
21870 }
21871
21872 if ( renderTarget.depthTexture ) {
21873
21874 renderTarget.depthTexture.dispose();
21875
21876 }
21877
21878 if ( renderTarget.isWebGLCubeRenderTarget ) {
21879
21880 for ( var i = 0; i < 6; i ++ ) {
21881
21882 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
21883 if ( renderTargetProperties.__webglDepthbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] ); }
21884
21885 }
21886
21887 } else {
21888
21889 _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
21890 if ( renderTargetProperties.__webglDepthbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer ); }
21891 if ( renderTargetProperties.__webglMultisampledFramebuffer ) { _gl.deleteFramebuffer( renderTargetProperties.__webglMultisampledFramebuffer ); }
21892 if ( renderTargetProperties.__webglColorRenderbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglColorRenderbuffer ); }
21893 if ( renderTargetProperties.__webglDepthRenderbuffer ) { _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthRenderbuffer ); }
21894
21895 }
21896
21897 properties.remove( renderTarget.texture );
21898 properties.remove( renderTarget );
21899
21900 }
21901
21902 //
21903
21904 var textureUnits = 0;
21905
21906 function resetTextureUnits() {
21907
21908 textureUnits = 0;
21909
21910 }
21911
21912 function allocateTextureUnit() {
21913
21914 var textureUnit = textureUnits;
21915
21916 if ( textureUnit >= maxTextures ) {
21917
21918 console.warn( 'THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures );
21919
21920 }
21921
21922 textureUnits += 1;
21923
21924 return textureUnit;
21925
21926 }
21927
21928 //
21929
21930 function setTexture2D( texture, slot ) {
21931
21932 var textureProperties = properties.get( texture );
21933
21934 if ( texture.isVideoTexture ) { updateVideoTexture( texture ); }
21935
21936 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
21937
21938 var image = texture.image;
21939
21940 if ( image === undefined ) {
21941
21942 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined' );
21943
21944 } else if ( image.complete === false ) {
21945
21946 console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete' );
21947
21948 } else {
21949
21950 uploadTexture( textureProperties, texture, slot );
21951 return;
21952
21953 }
21954
21955 }
21956
21957 state.activeTexture( 33984 + slot );
21958 state.bindTexture( 3553, textureProperties.__webglTexture );
21959
21960 }
21961
21962 function setTexture2DArray( texture, slot ) {
21963
21964 var textureProperties = properties.get( texture );
21965
21966 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
21967
21968 uploadTexture( textureProperties, texture, slot );
21969 return;
21970
21971 }
21972
21973 state.activeTexture( 33984 + slot );
21974 state.bindTexture( 35866, textureProperties.__webglTexture );
21975
21976 }
21977
21978 function setTexture3D( texture, slot ) {
21979
21980 var textureProperties = properties.get( texture );
21981
21982 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
21983
21984 uploadTexture( textureProperties, texture, slot );
21985 return;
21986
21987 }
21988
21989 state.activeTexture( 33984 + slot );
21990 state.bindTexture( 32879, textureProperties.__webglTexture );
21991
21992 }
21993
21994 function setTextureCube( texture, slot ) {
21995
21996 if ( texture.image.length !== 6 ) { return; }
21997
21998 var textureProperties = properties.get( texture );
21999
22000 if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
22001
22002 initTexture( textureProperties, texture );
22003
22004 state.activeTexture( 33984 + slot );
22005 state.bindTexture( 34067, textureProperties.__webglTexture );
22006
22007 _gl.pixelStorei( 37440, texture.flipY );
22008
22009 var isCompressed = ( texture && ( texture.isCompressedTexture || texture.image[ 0 ].isCompressedTexture ) );
22010 var isDataTexture = ( texture.image[ 0 ] && texture.image[ 0 ].isDataTexture );
22011
22012 var cubeImage = [];
22013
22014 for ( var i = 0; i < 6; i ++ ) {
22015
22016 if ( ! isCompressed && ! isDataTexture ) {
22017
22018 cubeImage[ i ] = resizeImage( texture.image[ i ], false, true, maxCubemapSize );
22019
22020 } else {
22021
22022 cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
22023
22024 }
22025
22026 }
22027
22028 var image = cubeImage[ 0 ],
22029 supportsMips = isPowerOfTwo( image ) || isWebGL2,
22030 glFormat = utils.convert( texture.format ),
22031 glType = utils.convert( texture.type ),
22032 glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
22033
22034 setTextureParameters( 34067, texture, supportsMips );
22035
22036 var mipmaps;
22037
22038 if ( isCompressed ) {
22039
22040 for ( var i$1 = 0; i$1 < 6; i$1 ++ ) {
22041
22042 mipmaps = cubeImage[ i$1 ].mipmaps;
22043
22044 for ( var j = 0; j < mipmaps.length; j ++ ) {
22045
22046 var mipmap = mipmaps[ j ];
22047
22048 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
22049
22050 if ( glFormat !== null ) {
22051
22052 state.compressedTexImage2D( 34069 + i$1, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
22053
22054 } else {
22055
22056 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()' );
22057
22058 }
22059
22060 } else {
22061
22062 state.texImage2D( 34069 + i$1, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
22063
22064 }
22065
22066 }
22067
22068 }
22069
22070 textureProperties.__maxMipLevel = mipmaps.length - 1;
22071
22072 } else {
22073
22074 mipmaps = texture.mipmaps;
22075
22076 for ( var i$2 = 0; i$2 < 6; i$2 ++ ) {
22077
22078 if ( isDataTexture ) {
22079
22080 state.texImage2D( 34069 + i$2, 0, glInternalFormat, cubeImage[ i$2 ].width, cubeImage[ i$2 ].height, 0, glFormat, glType, cubeImage[ i$2 ].data );
22081
22082 for ( var j$1 = 0; j$1 < mipmaps.length; j$1 ++ ) {
22083
22084 var mipmap$1 = mipmaps[ j$1 ];
22085 var mipmapImage = mipmap$1.image[ i$2 ].image;
22086
22087 state.texImage2D( 34069 + i$2, j$1 + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data );
22088
22089 }
22090
22091 } else {
22092
22093 state.texImage2D( 34069 + i$2, 0, glInternalFormat, glFormat, glType, cubeImage[ i$2 ] );
22094
22095 for ( var j$2 = 0; j$2 < mipmaps.length; j$2 ++ ) {
22096
22097 var mipmap$2 = mipmaps[ j$2 ];
22098
22099 state.texImage2D( 34069 + i$2, j$2 + 1, glInternalFormat, glFormat, glType, mipmap$2.image[ i$2 ] );
22100
22101 }
22102
22103 }
22104
22105 }
22106
22107 textureProperties.__maxMipLevel = mipmaps.length;
22108
22109 }
22110
22111 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
22112
22113 // We assume images for cube map have the same size.
22114 generateMipmap( 34067, texture, image.width, image.height );
22115
22116 }
22117
22118 textureProperties.__version = texture.version;
22119
22120 if ( texture.onUpdate ) { texture.onUpdate( texture ); }
22121
22122 } else {
22123
22124 state.activeTexture( 33984 + slot );
22125 state.bindTexture( 34067, textureProperties.__webglTexture );
22126
22127 }
22128
22129 }
22130
22131 function setTextureCubeDynamic( texture, slot ) {
22132
22133 state.activeTexture( 33984 + slot );
22134 state.bindTexture( 34067, properties.get( texture ).__webglTexture );
22135
22136 }
22137
22138 var wrappingToGL = {};
22139 wrappingToGL[ RepeatWrapping ] = 10497;
22140 wrappingToGL[ ClampToEdgeWrapping ] = 33071;
22141 wrappingToGL[ MirroredRepeatWrapping ] = 33648;
22142
22143 var filterToGL = {};
22144 filterToGL[ NearestFilter ] = 9728;
22145 filterToGL[ NearestMipmapNearestFilter ] = 9984;
22146 filterToGL[ NearestMipmapLinearFilter ] = 9986;
22147 filterToGL[ LinearFilter ] = 9729;
22148 filterToGL[ LinearMipmapNearestFilter ] = 9985;
22149 filterToGL[ LinearMipmapLinearFilter ] = 9987;
22150
22151 function setTextureParameters( textureType, texture, supportsMips ) {
22152
22153 if ( supportsMips ) {
22154
22155 _gl.texParameteri( textureType, 10242, wrappingToGL[ texture.wrapS ] );
22156 _gl.texParameteri( textureType, 10243, wrappingToGL[ texture.wrapT ] );
22157
22158 if ( textureType === 32879 || textureType === 35866 ) {
22159
22160 _gl.texParameteri( textureType, 32882, wrappingToGL[ texture.wrapR ] );
22161
22162 }
22163
22164 _gl.texParameteri( textureType, 10240, filterToGL[ texture.magFilter ] );
22165 _gl.texParameteri( textureType, 10241, filterToGL[ texture.minFilter ] );
22166
22167 } else {
22168
22169 _gl.texParameteri( textureType, 10242, 33071 );
22170 _gl.texParameteri( textureType, 10243, 33071 );
22171
22172 if ( textureType === 32879 || textureType === 35866 ) {
22173
22174 _gl.texParameteri( textureType, 32882, 33071 );
22175
22176 }
22177
22178 if ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) {
22179
22180 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.' );
22181
22182 }
22183
22184 _gl.texParameteri( textureType, 10240, filterFallback( texture.magFilter ) );
22185 _gl.texParameteri( textureType, 10241, filterFallback( texture.minFilter ) );
22186
22187 if ( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) {
22188
22189 console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.' );
22190
22191 }
22192
22193 }
22194
22195 var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
22196
22197 if ( extension ) {
22198
22199 if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) { return; }
22200 if ( texture.type === HalfFloatType && ( isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) { return; }
22201
22202 if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
22203
22204 _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, capabilities.getMaxAnisotropy() ) );
22205 properties.get( texture ).__currentAnisotropy = texture.anisotropy;
22206
22207 }
22208
22209 }
22210
22211 }
22212
22213 function initTexture( textureProperties, texture ) {
22214
22215 if ( textureProperties.__webglInit === undefined ) {
22216
22217 textureProperties.__webglInit = true;
22218
22219 texture.addEventListener( 'dispose', onTextureDispose );
22220
22221 textureProperties.__webglTexture = _gl.createTexture();
22222
22223 info.memory.textures ++;
22224
22225 }
22226
22227 }
22228
22229 function uploadTexture( textureProperties, texture, slot ) {
22230
22231 var textureType = 3553;
22232
22233 if ( texture.isDataTexture2DArray ) { textureType = 35866; }
22234 if ( texture.isDataTexture3D ) { textureType = 32879; }
22235
22236 initTexture( textureProperties, texture );
22237
22238 state.activeTexture( 33984 + slot );
22239 state.bindTexture( textureType, textureProperties.__webglTexture );
22240
22241 _gl.pixelStorei( 37440, texture.flipY );
22242 _gl.pixelStorei( 37441, texture.premultiplyAlpha );
22243 _gl.pixelStorei( 3317, texture.unpackAlignment );
22244
22245 var needsPowerOfTwo = textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false;
22246 var image = resizeImage( texture.image, needsPowerOfTwo, false, maxTextureSize );
22247
22248 var supportsMips = isPowerOfTwo( image ) || isWebGL2,
22249 glFormat = utils.convert( texture.format );
22250
22251 var glType = utils.convert( texture.type ),
22252 glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType );
22253
22254 setTextureParameters( textureType, texture, supportsMips );
22255
22256 var mipmap;
22257 var mipmaps = texture.mipmaps;
22258
22259 if ( texture.isDepthTexture ) {
22260
22261 // populate depth texture with dummy data
22262
22263 glInternalFormat = 6402;
22264
22265 if ( isWebGL2 ) {
22266
22267 if ( texture.type === FloatType ) {
22268
22269 glInternalFormat = 36012;
22270
22271 } else if ( texture.type === UnsignedIntType ) {
22272
22273 glInternalFormat = 33190;
22274
22275 } else if ( texture.type === UnsignedInt248Type ) {
22276
22277 glInternalFormat = 35056;
22278
22279 } else {
22280
22281 glInternalFormat = 33189; // WebGL2 requires sized internalformat for glTexImage2D
22282
22283 }
22284
22285 } else {
22286
22287 if ( texture.type === FloatType ) {
22288
22289 console.error( 'WebGLRenderer: Floating point depth texture requires WebGL2.' );
22290
22291 }
22292
22293 }
22294
22295 // validation checks for WebGL 1
22296
22297 if ( texture.format === DepthFormat && glInternalFormat === 6402 ) {
22298
22299 // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
22300 // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
22301 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
22302 if ( texture.type !== UnsignedShortType && texture.type !== UnsignedIntType ) {
22303
22304 console.warn( 'THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.' );
22305
22306 texture.type = UnsignedShortType;
22307 glType = utils.convert( texture.type );
22308
22309 }
22310
22311 }
22312
22313 if ( texture.format === DepthStencilFormat && glInternalFormat === 6402 ) {
22314
22315 // Depth stencil textures need the DEPTH_STENCIL internal format
22316 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
22317 glInternalFormat = 34041;
22318
22319 // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
22320 // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
22321 // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
22322 if ( texture.type !== UnsignedInt248Type ) {
22323
22324 console.warn( 'THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.' );
22325
22326 texture.type = UnsignedInt248Type;
22327 glType = utils.convert( texture.type );
22328
22329 }
22330
22331 }
22332
22333 //
22334
22335 state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null );
22336
22337 } else if ( texture.isDataTexture ) {
22338
22339 // use manually created mipmaps if available
22340 // if there are no manual mipmaps
22341 // set 0 level mipmap and then use GL to generate other mipmap levels
22342
22343 if ( mipmaps.length > 0 && supportsMips ) {
22344
22345 for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
22346
22347 mipmap = mipmaps[ i ];
22348 state.texImage2D( 3553, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
22349
22350 }
22351
22352 texture.generateMipmaps = false;
22353 textureProperties.__maxMipLevel = mipmaps.length - 1;
22354
22355 } else {
22356
22357 state.texImage2D( 3553, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data );
22358 textureProperties.__maxMipLevel = 0;
22359
22360 }
22361
22362 } else if ( texture.isCompressedTexture ) {
22363
22364 for ( var i$1 = 0, il$1 = mipmaps.length; i$1 < il$1; i$1 ++ ) {
22365
22366 mipmap = mipmaps[ i$1 ];
22367
22368 if ( texture.format !== RGBAFormat && texture.format !== RGBFormat ) {
22369
22370 if ( glFormat !== null ) {
22371
22372 state.compressedTexImage2D( 3553, i$1, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
22373
22374 } else {
22375
22376 console.warn( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' );
22377
22378 }
22379
22380 } else {
22381
22382 state.texImage2D( 3553, i$1, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
22383
22384 }
22385
22386 }
22387
22388 textureProperties.__maxMipLevel = mipmaps.length - 1;
22389
22390 } else if ( texture.isDataTexture2DArray ) {
22391
22392 state.texImage3D( 35866, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
22393 textureProperties.__maxMipLevel = 0;
22394
22395 } else if ( texture.isDataTexture3D ) {
22396
22397 state.texImage3D( 32879, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data );
22398 textureProperties.__maxMipLevel = 0;
22399
22400 } else {
22401
22402 // regular Texture (image, video, canvas)
22403
22404 // use manually created mipmaps if available
22405 // if there are no manual mipmaps
22406 // set 0 level mipmap and then use GL to generate other mipmap levels
22407
22408 if ( mipmaps.length > 0 && supportsMips ) {
22409
22410 for ( var i$2 = 0, il$2 = mipmaps.length; i$2 < il$2; i$2 ++ ) {
22411
22412 mipmap = mipmaps[ i$2 ];
22413 state.texImage2D( 3553, i$2, glInternalFormat, glFormat, glType, mipmap );
22414
22415 }
22416
22417 texture.generateMipmaps = false;
22418 textureProperties.__maxMipLevel = mipmaps.length - 1;
22419
22420 } else {
22421
22422 state.texImage2D( 3553, 0, glInternalFormat, glFormat, glType, image );
22423 textureProperties.__maxMipLevel = 0;
22424
22425 }
22426
22427 }
22428
22429 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
22430
22431 generateMipmap( textureType, texture, image.width, image.height );
22432
22433 }
22434
22435 textureProperties.__version = texture.version;
22436
22437 if ( texture.onUpdate ) { texture.onUpdate( texture ); }
22438
22439 }
22440
22441 // Render targets
22442
22443 // Setup storage for target texture and bind it to correct framebuffer
22444 function setupFrameBufferTexture( framebuffer, renderTarget, attachment, textureTarget ) {
22445
22446 var glFormat = utils.convert( renderTarget.texture.format );
22447 var glType = utils.convert( renderTarget.texture.type );
22448 var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
22449 state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
22450 _gl.bindFramebuffer( 36160, framebuffer );
22451 _gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
22452 _gl.bindFramebuffer( 36160, null );
22453
22454 }
22455
22456 // Setup storage for internal depth/stencil buffers and bind to correct framebuffer
22457 function setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) {
22458
22459 _gl.bindRenderbuffer( 36161, renderbuffer );
22460
22461 if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
22462
22463 var glInternalFormat = 33189;
22464
22465 if ( isMultisample ) {
22466
22467 var depthTexture = renderTarget.depthTexture;
22468
22469 if ( depthTexture && depthTexture.isDepthTexture ) {
22470
22471 if ( depthTexture.type === FloatType ) {
22472
22473 glInternalFormat = 36012;
22474
22475 } else if ( depthTexture.type === UnsignedIntType ) {
22476
22477 glInternalFormat = 33190;
22478
22479 }
22480
22481 }
22482
22483 var samples = getRenderTargetSamples( renderTarget );
22484
22485 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
22486
22487 } else {
22488
22489 _gl.renderbufferStorage( 36161, glInternalFormat, renderTarget.width, renderTarget.height );
22490
22491 }
22492
22493 _gl.framebufferRenderbuffer( 36160, 36096, 36161, renderbuffer );
22494
22495 } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
22496
22497 if ( isMultisample ) {
22498
22499 var samples$1 = getRenderTargetSamples( renderTarget );
22500
22501 _gl.renderbufferStorageMultisample( 36161, samples$1, 35056, renderTarget.width, renderTarget.height );
22502
22503 } else {
22504
22505 _gl.renderbufferStorage( 36161, 34041, renderTarget.width, renderTarget.height );
22506
22507 }
22508
22509
22510 _gl.framebufferRenderbuffer( 36160, 33306, 36161, renderbuffer );
22511
22512 } else {
22513
22514 var glFormat = utils.convert( renderTarget.texture.format );
22515 var glType = utils.convert( renderTarget.texture.type );
22516 var glInternalFormat$1 = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
22517
22518 if ( isMultisample ) {
22519
22520 var samples$2 = getRenderTargetSamples( renderTarget );
22521
22522 _gl.renderbufferStorageMultisample( 36161, samples$2, glInternalFormat$1, renderTarget.width, renderTarget.height );
22523
22524 } else {
22525
22526 _gl.renderbufferStorage( 36161, glInternalFormat$1, renderTarget.width, renderTarget.height );
22527
22528 }
22529
22530 }
22531
22532 _gl.bindRenderbuffer( 36161, null );
22533
22534 }
22535
22536 // Setup resources for a Depth Texture for a FBO (needs an extension)
22537 function setupDepthTexture( framebuffer, renderTarget ) {
22538
22539 var isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget );
22540 if ( isCube ) { throw new Error( 'Depth Texture with cube render targets is not supported' ); }
22541
22542 _gl.bindFramebuffer( 36160, framebuffer );
22543
22544 if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
22545
22546 throw new Error( 'renderTarget.depthTexture must be an instance of THREE.DepthTexture' );
22547
22548 }
22549
22550 // upload an empty depth texture with framebuffer size
22551 if ( ! properties.get( renderTarget.depthTexture ).__webglTexture ||
22552 renderTarget.depthTexture.image.width !== renderTarget.width ||
22553 renderTarget.depthTexture.image.height !== renderTarget.height ) {
22554
22555 renderTarget.depthTexture.image.width = renderTarget.width;
22556 renderTarget.depthTexture.image.height = renderTarget.height;
22557 renderTarget.depthTexture.needsUpdate = true;
22558
22559 }
22560
22561 setTexture2D( renderTarget.depthTexture, 0 );
22562
22563 var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
22564
22565 if ( renderTarget.depthTexture.format === DepthFormat ) {
22566
22567 _gl.framebufferTexture2D( 36160, 36096, 3553, webglDepthTexture, 0 );
22568
22569 } else if ( renderTarget.depthTexture.format === DepthStencilFormat ) {
22570
22571 _gl.framebufferTexture2D( 36160, 33306, 3553, webglDepthTexture, 0 );
22572
22573 } else {
22574
22575 throw new Error( 'Unknown depthTexture format' );
22576
22577 }
22578
22579 }
22580
22581 // Setup GL resources for a non-texture depth buffer
22582 function setupDepthRenderbuffer( renderTarget ) {
22583
22584 var renderTargetProperties = properties.get( renderTarget );
22585
22586 var isCube = ( renderTarget.isWebGLCubeRenderTarget === true );
22587
22588 if ( renderTarget.depthTexture ) {
22589
22590 if ( isCube ) { throw new Error( 'target.depthTexture not supported in Cube render targets' ); }
22591
22592 setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );
22593
22594 } else {
22595
22596 if ( isCube ) {
22597
22598 renderTargetProperties.__webglDepthbuffer = [];
22599
22600 for ( var i = 0; i < 6; i ++ ) {
22601
22602 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer[ i ] );
22603 renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
22604 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false );
22605
22606 }
22607
22608 } else {
22609
22610 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );
22611 renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
22612 setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false );
22613
22614 }
22615
22616 }
22617
22618 _gl.bindFramebuffer( 36160, null );
22619
22620 }
22621
22622 // Set up GL resources for the render target
22623 function setupRenderTarget( renderTarget ) {
22624
22625 var renderTargetProperties = properties.get( renderTarget );
22626 var textureProperties = properties.get( renderTarget.texture );
22627
22628 renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
22629
22630 textureProperties.__webglTexture = _gl.createTexture();
22631
22632 info.memory.textures ++;
22633
22634 var isCube = ( renderTarget.isWebGLCubeRenderTarget === true );
22635 var isMultisample = ( renderTarget.isWebGLMultisampleRenderTarget === true );
22636 var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2;
22637
22638 // Handles WebGL2 RGBFormat fallback - #18858
22639
22640 if ( isWebGL2 && renderTarget.texture.format === RGBFormat && ( renderTarget.texture.type === FloatType || renderTarget.texture.type === HalfFloatType ) ) {
22641
22642 renderTarget.texture.format = RGBAFormat;
22643
22644 console.warn( 'THREE.WebGLRenderer: Rendering to textures with RGB format is not supported. Using RGBA format instead.' );
22645
22646 }
22647
22648 // Setup framebuffer
22649
22650 if ( isCube ) {
22651
22652 renderTargetProperties.__webglFramebuffer = [];
22653
22654 for ( var i = 0; i < 6; i ++ ) {
22655
22656 renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
22657
22658 }
22659
22660 } else {
22661
22662 renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
22663
22664 if ( isMultisample ) {
22665
22666 if ( isWebGL2 ) {
22667
22668 renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();
22669 renderTargetProperties.__webglColorRenderbuffer = _gl.createRenderbuffer();
22670
22671 _gl.bindRenderbuffer( 36161, renderTargetProperties.__webglColorRenderbuffer );
22672
22673 var glFormat = utils.convert( renderTarget.texture.format );
22674 var glType = utils.convert( renderTarget.texture.type );
22675 var glInternalFormat = getInternalFormat( renderTarget.texture.internalFormat, glFormat, glType );
22676 var samples = getRenderTargetSamples( renderTarget );
22677 _gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
22678
22679 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );
22680 _gl.framebufferRenderbuffer( 36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer );
22681 _gl.bindRenderbuffer( 36161, null );
22682
22683 if ( renderTarget.depthBuffer ) {
22684
22685 renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();
22686 setupRenderBufferStorage( renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true );
22687
22688 }
22689
22690 _gl.bindFramebuffer( 36160, null );
22691
22692
22693 } else {
22694
22695 console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );
22696
22697 }
22698
22699 }
22700
22701 }
22702
22703 // Setup color buffer
22704
22705 if ( isCube ) {
22706
22707 state.bindTexture( 34067, textureProperties.__webglTexture );
22708 setTextureParameters( 34067, renderTarget.texture, supportsMips );
22709
22710 for ( var i$1 = 0; i$1 < 6; i$1 ++ ) {
22711
22712 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i$1 ], renderTarget, 36064, 34069 + i$1 );
22713
22714 }
22715
22716 if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
22717
22718 generateMipmap( 34067, renderTarget.texture, renderTarget.width, renderTarget.height );
22719
22720 }
22721
22722 state.bindTexture( 34067, null );
22723
22724 } else {
22725
22726 state.bindTexture( 3553, textureProperties.__webglTexture );
22727 setTextureParameters( 3553, renderTarget.texture, supportsMips );
22728 setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, 36064, 3553 );
22729
22730 if ( textureNeedsGenerateMipmaps( renderTarget.texture, supportsMips ) ) {
22731
22732 generateMipmap( 3553, renderTarget.texture, renderTarget.width, renderTarget.height );
22733
22734 }
22735
22736 state.bindTexture( 3553, null );
22737
22738 }
22739
22740 // Setup depth and stencil buffers
22741
22742 if ( renderTarget.depthBuffer ) {
22743
22744 setupDepthRenderbuffer( renderTarget );
22745
22746 }
22747
22748 }
22749
22750 function updateRenderTargetMipmap( renderTarget ) {
22751
22752 var texture = renderTarget.texture;
22753 var supportsMips = isPowerOfTwo( renderTarget ) || isWebGL2;
22754
22755 if ( textureNeedsGenerateMipmaps( texture, supportsMips ) ) {
22756
22757 var target = renderTarget.isWebGLCubeRenderTarget ? 34067 : 3553;
22758 var webglTexture = properties.get( texture ).__webglTexture;
22759
22760 state.bindTexture( target, webglTexture );
22761 generateMipmap( target, texture, renderTarget.width, renderTarget.height );
22762 state.bindTexture( target, null );
22763
22764 }
22765
22766 }
22767
22768 function updateMultisampleRenderTarget( renderTarget ) {
22769
22770 if ( renderTarget.isWebGLMultisampleRenderTarget ) {
22771
22772 if ( isWebGL2 ) {
22773
22774 var renderTargetProperties = properties.get( renderTarget );
22775
22776 _gl.bindFramebuffer( 36008, renderTargetProperties.__webglMultisampledFramebuffer );
22777 _gl.bindFramebuffer( 36009, renderTargetProperties.__webglFramebuffer );
22778
22779 var width = renderTarget.width;
22780 var height = renderTarget.height;
22781 var mask = 16384;
22782
22783 if ( renderTarget.depthBuffer ) { mask |= 256; }
22784 if ( renderTarget.stencilBuffer ) { mask |= 1024; }
22785
22786 _gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, 9728 );
22787
22788 _gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer ); // see #18905
22789
22790 } else {
22791
22792 console.warn( 'THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.' );
22793
22794 }
22795
22796 }
22797
22798 }
22799
22800 function getRenderTargetSamples( renderTarget ) {
22801
22802 return ( isWebGL2 && renderTarget.isWebGLMultisampleRenderTarget ) ?
22803 Math.min( maxSamples, renderTarget.samples ) : 0;
22804
22805 }
22806
22807 function updateVideoTexture( texture ) {
22808
22809 var frame = info.render.frame;
22810
22811 // Check the last frame we updated the VideoTexture
22812
22813 if ( _videoTextures.get( texture ) !== frame ) {
22814
22815 _videoTextures.set( texture, frame );
22816 texture.update();
22817
22818 }
22819
22820 }
22821
22822 // backwards compatibility
22823
22824 var warnedTexture2D = false;
22825 var warnedTextureCube = false;
22826
22827 function safeSetTexture2D( texture, slot ) {
22828
22829 if ( texture && texture.isWebGLRenderTarget ) {
22830
22831 if ( warnedTexture2D === false ) {
22832
22833 console.warn( "THREE.WebGLTextures.safeSetTexture2D: don't use render targets as textures. Use their .texture property instead." );
22834 warnedTexture2D = true;
22835
22836 }
22837
22838 texture = texture.texture;
22839
22840 }
22841
22842 setTexture2D( texture, slot );
22843
22844 }
22845
22846 function safeSetTextureCube( texture, slot ) {
22847
22848 if ( texture && texture.isWebGLCubeRenderTarget ) {
22849
22850 if ( warnedTextureCube === false ) {
22851
22852 console.warn( "THREE.WebGLTextures.safeSetTextureCube: don't use cube render targets as textures. Use their .texture property instead." );
22853 warnedTextureCube = true;
22854
22855 }
22856
22857 texture = texture.texture;
22858
22859 }
22860
22861 // currently relying on the fact that WebGLCubeRenderTarget.texture is a Texture and NOT a CubeTexture
22862 // TODO: unify these code paths
22863 if ( ( texture && texture.isCubeTexture ) ||
22864 ( Array.isArray( texture.image ) && texture.image.length === 6 ) ) {
22865
22866 // CompressedTexture can have Array in image :/
22867
22868 // this function alone should take care of cube textures
22869 setTextureCube( texture, slot );
22870
22871 } else {
22872
22873 // assumed: texture property of THREE.WebGLCubeRenderTarget
22874 setTextureCubeDynamic( texture, slot );
22875
22876 }
22877
22878 }
22879
22880 //
22881
22882 this.allocateTextureUnit = allocateTextureUnit;
22883 this.resetTextureUnits = resetTextureUnits;
22884
22885 this.setTexture2D = setTexture2D;
22886 this.setTexture2DArray = setTexture2DArray;
22887 this.setTexture3D = setTexture3D;
22888 this.setTextureCube = setTextureCube;
22889 this.setTextureCubeDynamic = setTextureCubeDynamic;
22890 this.setupRenderTarget = setupRenderTarget;
22891 this.updateRenderTargetMipmap = updateRenderTargetMipmap;
22892 this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
22893
22894 this.safeSetTexture2D = safeSetTexture2D;
22895 this.safeSetTextureCube = safeSetTextureCube;
22896
22897 }
22898
22899 function WebGLUtils( gl, extensions, capabilities ) {
22900
22901 var isWebGL2 = capabilities.isWebGL2;
22902
22903 function convert( p ) {
22904
22905 var extension;
22906
22907 if ( p === UnsignedByteType ) { return 5121; }
22908 if ( p === UnsignedShort4444Type ) { return 32819; }
22909 if ( p === UnsignedShort5551Type ) { return 32820; }
22910 if ( p === UnsignedShort565Type ) { return 33635; }
22911
22912 if ( p === ByteType ) { return 5120; }
22913 if ( p === ShortType ) { return 5122; }
22914 if ( p === UnsignedShortType ) { return 5123; }
22915 if ( p === IntType ) { return 5124; }
22916 if ( p === UnsignedIntType ) { return 5125; }
22917 if ( p === FloatType ) { return 5126; }
22918
22919 if ( p === HalfFloatType ) {
22920
22921 if ( isWebGL2 ) { return 5131; }
22922
22923 extension = extensions.get( 'OES_texture_half_float' );
22924
22925 if ( extension !== null ) {
22926
22927 return extension.HALF_FLOAT_OES;
22928
22929 } else {
22930
22931 return null;
22932
22933 }
22934
22935 }
22936
22937 if ( p === AlphaFormat ) { return 6406; }
22938 if ( p === RGBFormat ) { return 6407; }
22939 if ( p === RGBAFormat ) { return 6408; }
22940 if ( p === LuminanceFormat ) { return 6409; }
22941 if ( p === LuminanceAlphaFormat ) { return 6410; }
22942 if ( p === DepthFormat ) { return 6402; }
22943 if ( p === DepthStencilFormat ) { return 34041; }
22944 if ( p === RedFormat ) { return 6403; }
22945
22946 // WebGL2 formats.
22947
22948 if ( p === RedIntegerFormat ) { return 36244; }
22949 if ( p === RGFormat ) { return 33319; }
22950 if ( p === RGIntegerFormat ) { return 33320; }
22951 if ( p === RGBIntegerFormat ) { return 36248; }
22952 if ( p === RGBAIntegerFormat ) { return 36249; }
22953
22954 if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format ||
22955 p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
22956
22957 extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
22958
22959 if ( extension !== null ) {
22960
22961 if ( p === RGB_S3TC_DXT1_Format ) { return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; }
22962 if ( p === RGBA_S3TC_DXT1_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; }
22963 if ( p === RGBA_S3TC_DXT3_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; }
22964 if ( p === RGBA_S3TC_DXT5_Format ) { return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; }
22965
22966 } else {
22967
22968 return null;
22969
22970 }
22971
22972 }
22973
22974 if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format ||
22975 p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
22976
22977 extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
22978
22979 if ( extension !== null ) {
22980
22981 if ( p === RGB_PVRTC_4BPPV1_Format ) { return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; }
22982 if ( p === RGB_PVRTC_2BPPV1_Format ) { return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; }
22983 if ( p === RGBA_PVRTC_4BPPV1_Format ) { return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; }
22984 if ( p === RGBA_PVRTC_2BPPV1_Format ) { return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; }
22985
22986 } else {
22987
22988 return null;
22989
22990 }
22991
22992 }
22993
22994 if ( p === RGB_ETC1_Format ) {
22995
22996 extension = extensions.get( 'WEBGL_compressed_texture_etc1' );
22997
22998 if ( extension !== null ) {
22999
23000 return extension.COMPRESSED_RGB_ETC1_WEBGL;
23001
23002 } else {
23003
23004 return null;
23005
23006 }
23007
23008 }
23009
23010 if ( p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format ) {
23011
23012 extension = extensions.get( 'WEBGL_compressed_texture_etc' );
23013
23014 if ( extension !== null ) {
23015
23016 if ( p === RGB_ETC2_Format ) { return extension.COMPRESSED_RGB8_ETC2; }
23017 if ( p === RGBA_ETC2_EAC_Format ) { return extension.COMPRESSED_RGBA8_ETC2_EAC; }
23018
23019 }
23020
23021 }
23022
23023 if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format ||
23024 p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format ||
23025 p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format ||
23026 p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format ||
23027 p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ||
23028 p === SRGB8_ALPHA8_ASTC_4x4_Format || p === SRGB8_ALPHA8_ASTC_5x4_Format || p === SRGB8_ALPHA8_ASTC_5x5_Format ||
23029 p === SRGB8_ALPHA8_ASTC_6x5_Format || p === SRGB8_ALPHA8_ASTC_6x6_Format || p === SRGB8_ALPHA8_ASTC_8x5_Format ||
23030 p === SRGB8_ALPHA8_ASTC_8x6_Format || p === SRGB8_ALPHA8_ASTC_8x8_Format || p === SRGB8_ALPHA8_ASTC_10x5_Format ||
23031 p === SRGB8_ALPHA8_ASTC_10x6_Format || p === SRGB8_ALPHA8_ASTC_10x8_Format || p === SRGB8_ALPHA8_ASTC_10x10_Format ||
23032 p === SRGB8_ALPHA8_ASTC_12x10_Format || p === SRGB8_ALPHA8_ASTC_12x12_Format ) {
23033
23034 extension = extensions.get( 'WEBGL_compressed_texture_astc' );
23035
23036 if ( extension !== null ) {
23037
23038 // TODO Complete?
23039
23040 return p;
23041
23042 } else {
23043
23044 return null;
23045
23046 }
23047
23048 }
23049
23050 if ( p === RGBA_BPTC_Format ) {
23051
23052 extension = extensions.get( 'EXT_texture_compression_bptc' );
23053
23054 if ( extension !== null ) {
23055
23056 // TODO Complete?
23057
23058 return p;
23059
23060 } else {
23061
23062 return null;
23063
23064 }
23065
23066 }
23067
23068 if ( p === UnsignedInt248Type ) {
23069
23070 if ( isWebGL2 ) { return 34042; }
23071
23072 extension = extensions.get( 'WEBGL_depth_texture' );
23073
23074 if ( extension !== null ) {
23075
23076 return extension.UNSIGNED_INT_24_8_WEBGL;
23077
23078 } else {
23079
23080 return null;
23081
23082 }
23083
23084 }
23085
23086 }
23087
23088 return { convert: convert };
23089
23090 }
23091
23092 function ArrayCamera( array ) {
23093
23094 PerspectiveCamera.call( this );
23095
23096 this.cameras = array || [];
23097
23098 }
23099
23100 ArrayCamera.prototype = Object.assign( Object.create( PerspectiveCamera.prototype ), {
23101
23102 constructor: ArrayCamera,
23103
23104 isArrayCamera: true
23105
23106 } );
23107
23108 function Group() {
23109
23110 Object3D.call( this );
23111
23112 this.type = 'Group';
23113
23114 }
23115
23116 Group.prototype = Object.assign( Object.create( Object3D.prototype ), {
23117
23118 constructor: Group,
23119
23120 isGroup: true
23121
23122 } );
23123
23124 function WebXRController() {
23125
23126 this._targetRay = null;
23127 this._grip = null;
23128 this._hand = null;
23129
23130 }
23131
23132 Object.assign( WebXRController.prototype, {
23133
23134 constructor: WebXRController,
23135
23136 getHandSpace: function () {
23137
23138 if ( this._hand === null ) {
23139
23140 this._hand = new Group();
23141 this._hand.matrixAutoUpdate = false;
23142 this._hand.visible = false;
23143
23144 this._hand.joints = [];
23145 this._hand.inputState = { pinching: false };
23146
23147 if ( window.XRHand ) {
23148
23149 for ( var i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i ++ ) {
23150
23151 // The transform of this joint will be updated with the joint pose on each frame
23152 var joint = new Group();
23153 joint.matrixAutoUpdate = false;
23154 joint.visible = false;
23155 this._hand.joints.push( joint );
23156 // ??
23157 this._hand.add( joint );
23158
23159 }
23160
23161 }
23162
23163 }
23164
23165 return this._hand;
23166
23167 },
23168
23169 getTargetRaySpace: function () {
23170
23171 if ( this._targetRay === null ) {
23172
23173 this._targetRay = new Group();
23174 this._targetRay.matrixAutoUpdate = false;
23175 this._targetRay.visible = false;
23176
23177 }
23178
23179 return this._targetRay;
23180
23181 },
23182
23183 getGripSpace: function () {
23184
23185 if ( this._grip === null ) {
23186
23187 this._grip = new Group();
23188 this._grip.matrixAutoUpdate = false;
23189 this._grip.visible = false;
23190
23191 }
23192
23193 return this._grip;
23194
23195 },
23196
23197 dispatchEvent: function ( event ) {
23198
23199 if ( this._targetRay !== null ) {
23200
23201 this._targetRay.dispatchEvent( event );
23202
23203 }
23204
23205 if ( this._grip !== null ) {
23206
23207 this._grip.dispatchEvent( event );
23208
23209 }
23210
23211 if ( this._hand !== null ) {
23212
23213 this._hand.dispatchEvent( event );
23214
23215 }
23216
23217 return this;
23218
23219 },
23220
23221 disconnect: function ( inputSource ) {
23222
23223 this.dispatchEvent( { type: 'disconnected', data: inputSource } );
23224
23225 if ( this._targetRay !== null ) {
23226
23227 this._targetRay.visible = false;
23228
23229 }
23230
23231 if ( this._grip !== null ) {
23232
23233 this._grip.visible = false;
23234
23235 }
23236
23237 if ( this._hand !== null ) {
23238
23239 this._hand.visible = false;
23240
23241 }
23242
23243 return this;
23244
23245 },
23246
23247 update: function ( inputSource, frame, referenceSpace ) {
23248
23249 var inputPose = null;
23250 var gripPose = null;
23251 var handPose = null;
23252
23253 var targetRay = this._targetRay;
23254 var grip = this._grip;
23255 var hand = this._hand;
23256
23257 if ( inputSource ) {
23258
23259 if ( inputSource.hand ) {
23260
23261 handPose = true;
23262
23263 for ( var i = 0; i <= window.XRHand.LITTLE_PHALANX_TIP; i ++ ) {
23264
23265 if ( inputSource.hand[ i ] ) {
23266
23267 // Update the joints groups with the XRJoint poses
23268 var jointPose = frame.getJointPose( inputSource.hand[ i ], referenceSpace );
23269 var joint = hand.joints[ i ];
23270
23271 if ( jointPose !== null ) {
23272
23273 joint.matrix.fromArray( jointPose.transform.matrix );
23274 joint.matrix.decompose( joint.position, joint.rotation, joint.scale );
23275 joint.jointRadius = jointPose.radius;
23276
23277 }
23278
23279 joint.visible = jointPose !== null;
23280
23281 // Custom events
23282
23283 // Check pinch
23284 var indexTip = hand.joints[ window.XRHand.INDEX_PHALANX_TIP ];
23285 var thumbTip = hand.joints[ window.XRHand.THUMB_PHALANX_TIP ];
23286 var distance = indexTip.position.distanceTo( thumbTip.position );
23287
23288 var distanceToPinch = 0.02;
23289 var threshold = 0.005;
23290
23291 if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {
23292
23293 hand.inputState.pinching = false;
23294 this.dispatchEvent( {
23295 type: "pinchend",
23296 handedness: inputSource.handedness,
23297 target: this
23298 } );
23299
23300 } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {
23301
23302 hand.inputState.pinching = true;
23303 this.dispatchEvent( {
23304 type: "pinchstart",
23305 handedness: inputSource.handedness,
23306 target: this
23307 } );
23308
23309 }
23310
23311 }
23312
23313 }
23314
23315 } else {
23316
23317 if ( targetRay !== null ) {
23318
23319 inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace );
23320
23321 if ( inputPose !== null ) {
23322
23323 targetRay.matrix.fromArray( inputPose.transform.matrix );
23324 targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale );
23325
23326 }
23327
23328 }
23329
23330 if ( grip !== null && inputSource.gripSpace ) {
23331
23332 gripPose = frame.getPose( inputSource.gripSpace, referenceSpace );
23333
23334 if ( gripPose !== null ) {
23335
23336 grip.matrix.fromArray( gripPose.transform.matrix );
23337 grip.matrix.decompose( grip.position, grip.rotation, grip.scale );
23338
23339 }
23340
23341 }
23342
23343 }
23344
23345 }
23346
23347 if ( targetRay !== null ) {
23348
23349 targetRay.visible = ( inputPose !== null );
23350
23351 }
23352
23353 if ( grip !== null ) {
23354
23355 grip.visible = ( gripPose !== null );
23356
23357 }
23358
23359 if ( hand !== null ) {
23360
23361 hand.visible = ( handPose !== null );
23362
23363 }
23364
23365 return this;
23366
23367 }
23368
23369 } );
23370
23371 function WebXRManager( renderer, gl ) {
23372
23373 var scope = this;
23374
23375 var session = null;
23376
23377 var framebufferScaleFactor = 1.0;
23378
23379 var referenceSpace = null;
23380 var referenceSpaceType = 'local-floor';
23381
23382 var pose = null;
23383
23384 var controllers = [];
23385 var inputSourcesMap = new Map();
23386
23387 //
23388
23389 var cameraL = new PerspectiveCamera();
23390 cameraL.layers.enable( 1 );
23391 cameraL.viewport = new Vector4();
23392
23393 var cameraR = new PerspectiveCamera();
23394 cameraR.layers.enable( 2 );
23395 cameraR.viewport = new Vector4();
23396
23397 var cameras = [ cameraL, cameraR ];
23398
23399 var cameraVR = new ArrayCamera();
23400 cameraVR.layers.enable( 1 );
23401 cameraVR.layers.enable( 2 );
23402
23403 var _currentDepthNear = null;
23404 var _currentDepthFar = null;
23405
23406 //
23407
23408 this.enabled = false;
23409
23410 this.isPresenting = false;
23411
23412 this.getController = function ( index ) {
23413
23414 var controller = controllers[ index ];
23415
23416 if ( controller === undefined ) {
23417
23418 controller = new WebXRController();
23419 controllers[ index ] = controller;
23420
23421 }
23422
23423 return controller.getTargetRaySpace();
23424
23425 };
23426
23427 this.getControllerGrip = function ( index ) {
23428
23429 var controller = controllers[ index ];
23430
23431 if ( controller === undefined ) {
23432
23433 controller = new WebXRController();
23434 controllers[ index ] = controller;
23435
23436 }
23437
23438 return controller.getGripSpace();
23439
23440 };
23441
23442 this.getHand = function ( index ) {
23443
23444 var controller = controllers[ index ];
23445
23446 if ( controller === undefined ) {
23447
23448 controller = new WebXRController();
23449 controllers[ index ] = controller;
23450
23451 }
23452
23453 return controller.getHandSpace();
23454
23455 };
23456
23457 //
23458
23459 function onSessionEvent( event ) {
23460
23461 var controller = inputSourcesMap.get( event.inputSource );
23462
23463 if ( controller ) {
23464
23465 controller.dispatchEvent( { type: event.type } );
23466
23467 }
23468
23469 }
23470
23471 function onSessionEnd() {
23472
23473 inputSourcesMap.forEach( function ( controller, inputSource ) {
23474
23475 controller.disconnect( inputSource );
23476
23477 } );
23478
23479 inputSourcesMap.clear();
23480
23481 //
23482
23483 renderer.setFramebuffer( null );
23484 renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
23485 animation.stop();
23486
23487 scope.isPresenting = false;
23488
23489 scope.dispatchEvent( { type: 'sessionend' } );
23490
23491 }
23492
23493 function onRequestReferenceSpace( value ) {
23494
23495 referenceSpace = value;
23496
23497 animation.setContext( session );
23498 animation.start();
23499
23500 scope.isPresenting = true;
23501
23502 scope.dispatchEvent( { type: 'sessionstart' } );
23503
23504 }
23505
23506 this.setFramebufferScaleFactor = function ( value ) {
23507
23508 framebufferScaleFactor = value;
23509
23510 if ( scope.isPresenting === true ) {
23511
23512 console.warn( 'THREE.WebXRManager: Cannot change framebuffer scale while presenting.' );
23513
23514 }
23515
23516 };
23517
23518 this.setReferenceSpaceType = function ( value ) {
23519
23520 referenceSpaceType = value;
23521
23522 if ( scope.isPresenting === true ) {
23523
23524 console.warn( 'THREE.WebXRManager: Cannot change reference space type while presenting.' );
23525
23526 }
23527
23528 };
23529
23530 this.getReferenceSpace = function () {
23531
23532 return referenceSpace;
23533
23534 };
23535
23536 this.getSession = function () {
23537
23538 return session;
23539
23540 };
23541
23542 this.setSession = function ( value ) {
23543
23544 session = value;
23545
23546 if ( session !== null ) {
23547
23548 session.addEventListener( 'select', onSessionEvent );
23549 session.addEventListener( 'selectstart', onSessionEvent );
23550 session.addEventListener( 'selectend', onSessionEvent );
23551 session.addEventListener( 'squeeze', onSessionEvent );
23552 session.addEventListener( 'squeezestart', onSessionEvent );
23553 session.addEventListener( 'squeezeend', onSessionEvent );
23554 session.addEventListener( 'end', onSessionEnd );
23555
23556 var attributes = gl.getContextAttributes();
23557
23558 if ( attributes.xrCompatible !== true ) {
23559
23560 gl.makeXRCompatible();
23561
23562 }
23563
23564 var layerInit = {
23565 antialias: attributes.antialias,
23566 alpha: attributes.alpha,
23567 depth: attributes.depth,
23568 stencil: attributes.stencil,
23569 framebufferScaleFactor: framebufferScaleFactor
23570 };
23571
23572 // eslint-disable-next-line no-undef
23573 var baseLayer = new XRWebGLLayer( session, gl, layerInit );
23574
23575 session.updateRenderState( { baseLayer: baseLayer } );
23576
23577 session.requestReferenceSpace( referenceSpaceType ).then( onRequestReferenceSpace );
23578
23579 //
23580
23581 session.addEventListener( 'inputsourceschange', updateInputSources );
23582
23583 }
23584
23585 };
23586
23587 function updateInputSources( event ) {
23588
23589 var inputSources = session.inputSources;
23590
23591 // Assign inputSources to available controllers
23592
23593 for ( var i = 0; i < controllers.length; i ++ ) {
23594
23595 inputSourcesMap.set( inputSources[ i ], controllers[ i ] );
23596
23597 }
23598
23599 // Notify disconnected
23600
23601 for ( var i$1 = 0; i$1 < event.removed.length; i$1 ++ ) {
23602
23603 var inputSource = event.removed[ i$1 ];
23604 var controller = inputSourcesMap.get( inputSource );
23605
23606 if ( controller ) {
23607
23608 controller.dispatchEvent( { type: 'disconnected', data: inputSource } );
23609 inputSourcesMap.delete( inputSource );
23610
23611 }
23612
23613 }
23614
23615 // Notify connected
23616
23617 for ( var i$2 = 0; i$2 < event.added.length; i$2 ++ ) {
23618
23619 var inputSource$1 = event.added[ i$2 ];
23620 var controller$1 = inputSourcesMap.get( inputSource$1 );
23621
23622 if ( controller$1 ) {
23623
23624 controller$1.dispatchEvent( { type: 'connected', data: inputSource$1 } );
23625
23626 }
23627
23628 }
23629
23630 }
23631
23632 //
23633
23634 var cameraLPos = new Vector3();
23635 var cameraRPos = new Vector3();
23636
23637 /**
23638 * Assumes 2 cameras that are parallel and share an X-axis, and that
23639 * the cameras' projection and world matrices have already been set.
23640 * And that near and far planes are identical for both cameras.
23641 * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
23642 */
23643 function setProjectionFromUnion( camera, cameraL, cameraR ) {
23644
23645 cameraLPos.setFromMatrixPosition( cameraL.matrixWorld );
23646 cameraRPos.setFromMatrixPosition( cameraR.matrixWorld );
23647
23648 var ipd = cameraLPos.distanceTo( cameraRPos );
23649
23650 var projL = cameraL.projectionMatrix.elements;
23651 var projR = cameraR.projectionMatrix.elements;
23652
23653 // VR systems will have identical far and near planes, and
23654 // most likely identical top and bottom frustum extents.
23655 // Use the left camera for these values.
23656 var near = projL[ 14 ] / ( projL[ 10 ] - 1 );
23657 var far = projL[ 14 ] / ( projL[ 10 ] + 1 );
23658 var topFov = ( projL[ 9 ] + 1 ) / projL[ 5 ];
23659 var bottomFov = ( projL[ 9 ] - 1 ) / projL[ 5 ];
23660
23661 var leftFov = ( projL[ 8 ] - 1 ) / projL[ 0 ];
23662 var rightFov = ( projR[ 8 ] + 1 ) / projR[ 0 ];
23663 var left = near * leftFov;
23664 var right = near * rightFov;
23665
23666 // Calculate the new camera's position offset from the
23667 // left camera. xOffset should be roughly half `ipd`.
23668 var zOffset = ipd / ( - leftFov + rightFov );
23669 var xOffset = zOffset * - leftFov;
23670
23671 // TODO: Better way to apply this offset?
23672 cameraL.matrixWorld.decompose( camera.position, camera.quaternion, camera.scale );
23673 camera.translateX( xOffset );
23674 camera.translateZ( zOffset );
23675 camera.matrixWorld.compose( camera.position, camera.quaternion, camera.scale );
23676 camera.matrixWorldInverse.getInverse( camera.matrixWorld );
23677
23678 // Find the union of the frustum values of the cameras and scale
23679 // the values so that the near plane's position does not change in world space,
23680 // although must now be relative to the new union camera.
23681 var near2 = near + zOffset;
23682 var far2 = far + zOffset;
23683 var left2 = left - xOffset;
23684 var right2 = right + ( ipd - xOffset );
23685 var top2 = topFov * far / far2 * near2;
23686 var bottom2 = bottomFov * far / far2 * near2;
23687
23688 camera.projectionMatrix.makePerspective( left2, right2, top2, bottom2, near2, far2 );
23689
23690 }
23691
23692 function updateCamera( camera, parent ) {
23693
23694 if ( parent === null ) {
23695
23696 camera.matrixWorld.copy( camera.matrix );
23697
23698 } else {
23699
23700 camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );
23701
23702 }
23703
23704 camera.matrixWorldInverse.getInverse( camera.matrixWorld );
23705
23706 }
23707
23708 this.getCamera = function ( camera ) {
23709
23710 cameraVR.near = cameraR.near = cameraL.near = camera.near;
23711 cameraVR.far = cameraR.far = cameraL.far = camera.far;
23712
23713 if ( _currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far ) {
23714
23715 // Note that the new renderState won't apply until the next frame. See #18320
23716
23717 session.updateRenderState( {
23718 depthNear: cameraVR.near,
23719 depthFar: cameraVR.far
23720 } );
23721
23722 _currentDepthNear = cameraVR.near;
23723 _currentDepthFar = cameraVR.far;
23724
23725 }
23726
23727 var parent = camera.parent;
23728 var cameras = cameraVR.cameras;
23729
23730 updateCamera( cameraVR, parent );
23731
23732 for ( var i = 0; i < cameras.length; i ++ ) {
23733
23734 updateCamera( cameras[ i ], parent );
23735
23736 }
23737
23738 // update camera and its children
23739
23740 camera.matrixWorld.copy( cameraVR.matrixWorld );
23741
23742 var children = camera.children;
23743
23744 for ( var i$1 = 0, l = children.length; i$1 < l; i$1 ++ ) {
23745
23746 children[ i$1 ].updateMatrixWorld( true );
23747
23748 }
23749
23750 // update projection matrix for proper view frustum culling
23751
23752 if ( cameras.length === 2 ) {
23753
23754 setProjectionFromUnion( cameraVR, cameraL, cameraR );
23755
23756 } else {
23757
23758 // assume single camera setup (AR)
23759
23760 cameraVR.projectionMatrix.copy( cameraL.projectionMatrix );
23761
23762 }
23763
23764 return cameraVR;
23765
23766 };
23767
23768 // Animation Loop
23769
23770 var onAnimationFrameCallback = null;
23771
23772 function onAnimationFrame( time, frame ) {
23773
23774 pose = frame.getViewerPose( referenceSpace );
23775
23776 if ( pose !== null ) {
23777
23778 var views = pose.views;
23779 var baseLayer = session.renderState.baseLayer;
23780
23781 renderer.setFramebuffer( baseLayer.framebuffer );
23782
23783 var cameraVRNeedsUpdate = false;
23784
23785 // check if it's necessary to rebuild cameraVR's camera list
23786
23787 if ( views.length !== cameraVR.cameras.length ) {
23788
23789 cameraVR.cameras.length = 0;
23790 cameraVRNeedsUpdate = true;
23791
23792 }
23793
23794 for ( var i = 0; i < views.length; i ++ ) {
23795
23796 var view = views[ i ];
23797 var viewport = baseLayer.getViewport( view );
23798
23799 var camera = cameras[ i ];
23800 camera.matrix.fromArray( view.transform.matrix );
23801 camera.projectionMatrix.fromArray( view.projectionMatrix );
23802 camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
23803
23804 if ( i === 0 ) {
23805
23806 cameraVR.matrix.copy( camera.matrix );
23807
23808 }
23809
23810 if ( cameraVRNeedsUpdate === true ) {
23811
23812 cameraVR.cameras.push( camera );
23813
23814 }
23815
23816 }
23817
23818 }
23819
23820 //
23821
23822 var inputSources = session.inputSources;
23823
23824 for ( var i$1 = 0; i$1 < controllers.length; i$1 ++ ) {
23825
23826 var controller = controllers[ i$1 ];
23827 var inputSource = inputSources[ i$1 ];
23828
23829 controller.update( inputSource, frame, referenceSpace );
23830
23831 }
23832
23833 if ( onAnimationFrameCallback ) { onAnimationFrameCallback( time, frame ); }
23834
23835 }
23836
23837 var animation = new WebGLAnimation();
23838 animation.setAnimationLoop( onAnimationFrame );
23839
23840 this.setAnimationLoop = function ( callback ) {
23841
23842 onAnimationFrameCallback = callback;
23843
23844 };
23845
23846 this.dispose = function () {};
23847
23848 }
23849
23850 Object.assign( WebXRManager.prototype, EventDispatcher.prototype );
23851
23852 function WebGLMaterials( properties ) {
23853
23854 function refreshFogUniforms( uniforms, fog ) {
23855
23856 uniforms.fogColor.value.copy( fog.color );
23857
23858 if ( fog.isFog ) {
23859
23860 uniforms.fogNear.value = fog.near;
23861 uniforms.fogFar.value = fog.far;
23862
23863 } else if ( fog.isFogExp2 ) {
23864
23865 uniforms.fogDensity.value = fog.density;
23866
23867 }
23868
23869 }
23870
23871 function refreshMaterialUniforms( uniforms, material, environment, pixelRatio, height ) {
23872
23873 if ( material.isMeshBasicMaterial ) {
23874
23875 refreshUniformsCommon( uniforms, material );
23876
23877 } else if ( material.isMeshLambertMaterial ) {
23878
23879 refreshUniformsCommon( uniforms, material );
23880 refreshUniformsLambert( uniforms, material );
23881
23882 } else if ( material.isMeshToonMaterial ) {
23883
23884 refreshUniformsCommon( uniforms, material );
23885 refreshUniformsToon( uniforms, material );
23886
23887 } else if ( material.isMeshPhongMaterial ) {
23888
23889 refreshUniformsCommon( uniforms, material );
23890 refreshUniformsPhong( uniforms, material );
23891
23892 } else if ( material.isMeshStandardMaterial ) {
23893
23894 refreshUniformsCommon( uniforms, material, environment );
23895
23896 if ( material.isMeshPhysicalMaterial ) {
23897
23898 refreshUniformsPhysical( uniforms, material, environment );
23899
23900 } else {
23901
23902 refreshUniformsStandard( uniforms, material, environment );
23903
23904 }
23905
23906 } else if ( material.isMeshMatcapMaterial ) {
23907
23908 refreshUniformsCommon( uniforms, material );
23909 refreshUniformsMatcap( uniforms, material );
23910
23911 } else if ( material.isMeshDepthMaterial ) {
23912
23913 refreshUniformsCommon( uniforms, material );
23914 refreshUniformsDepth( uniforms, material );
23915
23916 } else if ( material.isMeshDistanceMaterial ) {
23917
23918 refreshUniformsCommon( uniforms, material );
23919 refreshUniformsDistance( uniforms, material );
23920
23921 } else if ( material.isMeshNormalMaterial ) {
23922
23923 refreshUniformsCommon( uniforms, material );
23924 refreshUniformsNormal( uniforms, material );
23925
23926 } else if ( material.isLineBasicMaterial ) {
23927
23928 refreshUniformsLine( uniforms, material );
23929
23930 if ( material.isLineDashedMaterial ) {
23931
23932 refreshUniformsDash( uniforms, material );
23933
23934 }
23935
23936 } else if ( material.isPointsMaterial ) {
23937
23938 refreshUniformsPoints( uniforms, material, pixelRatio, height );
23939
23940 } else if ( material.isSpriteMaterial ) {
23941
23942 refreshUniformsSprites( uniforms, material );
23943
23944 } else if ( material.isShadowMaterial ) {
23945
23946 uniforms.color.value.copy( material.color );
23947 uniforms.opacity.value = material.opacity;
23948
23949 } else if ( material.isShaderMaterial ) {
23950
23951 material.uniformsNeedUpdate = false; // #15581
23952
23953 }
23954
23955 }
23956
23957 function refreshUniformsCommon( uniforms, material, environment ) {
23958
23959 uniforms.opacity.value = material.opacity;
23960
23961 if ( material.color ) {
23962
23963 uniforms.diffuse.value.copy( material.color );
23964
23965 }
23966
23967 if ( material.emissive ) {
23968
23969 uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
23970
23971 }
23972
23973 if ( material.map ) {
23974
23975 uniforms.map.value = material.map;
23976
23977 }
23978
23979 if ( material.alphaMap ) {
23980
23981 uniforms.alphaMap.value = material.alphaMap;
23982
23983 }
23984
23985 if ( material.specularMap ) {
23986
23987 uniforms.specularMap.value = material.specularMap;
23988
23989 }
23990
23991 var envMap = material.envMap || environment;
23992
23993 if ( envMap ) {
23994
23995 uniforms.envMap.value = envMap;
23996
23997 uniforms.flipEnvMap.value = envMap.isCubeTexture ? - 1 : 1;
23998
23999 uniforms.reflectivity.value = material.reflectivity;
24000 uniforms.refractionRatio.value = material.refractionRatio;
24001
24002 var maxMipLevel = properties.get( envMap ).__maxMipLevel;
24003
24004 if ( maxMipLevel !== undefined ) {
24005
24006 uniforms.maxMipLevel.value = maxMipLevel;
24007
24008 }
24009
24010 }
24011
24012 if ( material.lightMap ) {
24013
24014 uniforms.lightMap.value = material.lightMap;
24015 uniforms.lightMapIntensity.value = material.lightMapIntensity;
24016
24017 }
24018
24019 if ( material.aoMap ) {
24020
24021 uniforms.aoMap.value = material.aoMap;
24022 uniforms.aoMapIntensity.value = material.aoMapIntensity;
24023
24024 }
24025
24026 // uv repeat and offset setting priorities
24027 // 1. color map
24028 // 2. specular map
24029 // 3. normal map
24030 // 4. bump map
24031 // 5. alpha map
24032 // 6. emissive map
24033
24034 var uvScaleMap;
24035
24036 if ( material.map ) {
24037
24038 uvScaleMap = material.map;
24039
24040 } else if ( material.specularMap ) {
24041
24042 uvScaleMap = material.specularMap;
24043
24044 } else if ( material.displacementMap ) {
24045
24046 uvScaleMap = material.displacementMap;
24047
24048 } else if ( material.normalMap ) {
24049
24050 uvScaleMap = material.normalMap;
24051
24052 } else if ( material.bumpMap ) {
24053
24054 uvScaleMap = material.bumpMap;
24055
24056 } else if ( material.roughnessMap ) {
24057
24058 uvScaleMap = material.roughnessMap;
24059
24060 } else if ( material.metalnessMap ) {
24061
24062 uvScaleMap = material.metalnessMap;
24063
24064 } else if ( material.alphaMap ) {
24065
24066 uvScaleMap = material.alphaMap;
24067
24068 } else if ( material.emissiveMap ) {
24069
24070 uvScaleMap = material.emissiveMap;
24071
24072 }
24073
24074 if ( uvScaleMap !== undefined ) {
24075
24076 // backwards compatibility
24077 if ( uvScaleMap.isWebGLRenderTarget ) {
24078
24079 uvScaleMap = uvScaleMap.texture;
24080
24081 }
24082
24083 if ( uvScaleMap.matrixAutoUpdate === true ) {
24084
24085 uvScaleMap.updateMatrix();
24086
24087 }
24088
24089 uniforms.uvTransform.value.copy( uvScaleMap.matrix );
24090
24091 }
24092
24093 // uv repeat and offset setting priorities for uv2
24094 // 1. ao map
24095 // 2. light map
24096
24097 var uv2ScaleMap;
24098
24099 if ( material.aoMap ) {
24100
24101 uv2ScaleMap = material.aoMap;
24102
24103 } else if ( material.lightMap ) {
24104
24105 uv2ScaleMap = material.lightMap;
24106
24107 }
24108
24109 if ( uv2ScaleMap !== undefined ) {
24110
24111 // backwards compatibility
24112 if ( uv2ScaleMap.isWebGLRenderTarget ) {
24113
24114 uv2ScaleMap = uv2ScaleMap.texture;
24115
24116 }
24117
24118 if ( uv2ScaleMap.matrixAutoUpdate === true ) {
24119
24120 uv2ScaleMap.updateMatrix();
24121
24122 }
24123
24124 uniforms.uv2Transform.value.copy( uv2ScaleMap.matrix );
24125
24126 }
24127
24128 }
24129
24130 function refreshUniformsLine( uniforms, material ) {
24131
24132 uniforms.diffuse.value.copy( material.color );
24133 uniforms.opacity.value = material.opacity;
24134
24135 }
24136
24137 function refreshUniformsDash( uniforms, material ) {
24138
24139 uniforms.dashSize.value = material.dashSize;
24140 uniforms.totalSize.value = material.dashSize + material.gapSize;
24141 uniforms.scale.value = material.scale;
24142
24143 }
24144
24145 function refreshUniformsPoints( uniforms, material, pixelRatio, height ) {
24146
24147 uniforms.diffuse.value.copy( material.color );
24148 uniforms.opacity.value = material.opacity;
24149 uniforms.size.value = material.size * pixelRatio;
24150 uniforms.scale.value = height * 0.5;
24151
24152 if ( material.map ) {
24153
24154 uniforms.map.value = material.map;
24155
24156 }
24157
24158 if ( material.alphaMap ) {
24159
24160 uniforms.alphaMap.value = material.alphaMap;
24161
24162 }
24163
24164 // uv repeat and offset setting priorities
24165 // 1. color map
24166 // 2. alpha map
24167
24168 var uvScaleMap;
24169
24170 if ( material.map ) {
24171
24172 uvScaleMap = material.map;
24173
24174 } else if ( material.alphaMap ) {
24175
24176 uvScaleMap = material.alphaMap;
24177
24178 }
24179
24180 if ( uvScaleMap !== undefined ) {
24181
24182 if ( uvScaleMap.matrixAutoUpdate === true ) {
24183
24184 uvScaleMap.updateMatrix();
24185
24186 }
24187
24188 uniforms.uvTransform.value.copy( uvScaleMap.matrix );
24189
24190 }
24191
24192 }
24193
24194 function refreshUniformsSprites( uniforms, material ) {
24195
24196 uniforms.diffuse.value.copy( material.color );
24197 uniforms.opacity.value = material.opacity;
24198 uniforms.rotation.value = material.rotation;
24199
24200 if ( material.map ) {
24201
24202 uniforms.map.value = material.map;
24203
24204 }
24205
24206 if ( material.alphaMap ) {
24207
24208 uniforms.alphaMap.value = material.alphaMap;
24209
24210 }
24211
24212 // uv repeat and offset setting priorities
24213 // 1. color map
24214 // 2. alpha map
24215
24216 var uvScaleMap;
24217
24218 if ( material.map ) {
24219
24220 uvScaleMap = material.map;
24221
24222 } else if ( material.alphaMap ) {
24223
24224 uvScaleMap = material.alphaMap;
24225
24226 }
24227
24228 if ( uvScaleMap !== undefined ) {
24229
24230 if ( uvScaleMap.matrixAutoUpdate === true ) {
24231
24232 uvScaleMap.updateMatrix();
24233
24234 }
24235
24236 uniforms.uvTransform.value.copy( uvScaleMap.matrix );
24237
24238 }
24239
24240 }
24241
24242 function refreshUniformsLambert( uniforms, material ) {
24243
24244 if ( material.emissiveMap ) {
24245
24246 uniforms.emissiveMap.value = material.emissiveMap;
24247
24248 }
24249
24250 }
24251
24252 function refreshUniformsPhong( uniforms, material ) {
24253
24254 uniforms.specular.value.copy( material.specular );
24255 uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
24256
24257 if ( material.emissiveMap ) {
24258
24259 uniforms.emissiveMap.value = material.emissiveMap;
24260
24261 }
24262
24263 if ( material.bumpMap ) {
24264
24265 uniforms.bumpMap.value = material.bumpMap;
24266 uniforms.bumpScale.value = material.bumpScale;
24267 if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24268
24269 }
24270
24271 if ( material.normalMap ) {
24272
24273 uniforms.normalMap.value = material.normalMap;
24274 uniforms.normalScale.value.copy( material.normalScale );
24275 if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24276
24277 }
24278
24279 if ( material.displacementMap ) {
24280
24281 uniforms.displacementMap.value = material.displacementMap;
24282 uniforms.displacementScale.value = material.displacementScale;
24283 uniforms.displacementBias.value = material.displacementBias;
24284
24285 }
24286
24287 }
24288
24289 function refreshUniformsToon( uniforms, material ) {
24290
24291 if ( material.gradientMap ) {
24292
24293 uniforms.gradientMap.value = material.gradientMap;
24294
24295 }
24296
24297 if ( material.emissiveMap ) {
24298
24299 uniforms.emissiveMap.value = material.emissiveMap;
24300
24301 }
24302
24303 if ( material.bumpMap ) {
24304
24305 uniforms.bumpMap.value = material.bumpMap;
24306 uniforms.bumpScale.value = material.bumpScale;
24307 if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24308
24309 }
24310
24311 if ( material.normalMap ) {
24312
24313 uniforms.normalMap.value = material.normalMap;
24314 uniforms.normalScale.value.copy( material.normalScale );
24315 if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24316
24317 }
24318
24319 if ( material.displacementMap ) {
24320
24321 uniforms.displacementMap.value = material.displacementMap;
24322 uniforms.displacementScale.value = material.displacementScale;
24323 uniforms.displacementBias.value = material.displacementBias;
24324
24325 }
24326
24327 }
24328
24329 function refreshUniformsStandard( uniforms, material, environment ) {
24330
24331 uniforms.roughness.value = material.roughness;
24332 uniforms.metalness.value = material.metalness;
24333
24334 if ( material.roughnessMap ) {
24335
24336 uniforms.roughnessMap.value = material.roughnessMap;
24337
24338 }
24339
24340 if ( material.metalnessMap ) {
24341
24342 uniforms.metalnessMap.value = material.metalnessMap;
24343
24344 }
24345
24346 if ( material.emissiveMap ) {
24347
24348 uniforms.emissiveMap.value = material.emissiveMap;
24349
24350 }
24351
24352 if ( material.bumpMap ) {
24353
24354 uniforms.bumpMap.value = material.bumpMap;
24355 uniforms.bumpScale.value = material.bumpScale;
24356 if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24357
24358 }
24359
24360 if ( material.normalMap ) {
24361
24362 uniforms.normalMap.value = material.normalMap;
24363 uniforms.normalScale.value.copy( material.normalScale );
24364 if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24365
24366 }
24367
24368 if ( material.displacementMap ) {
24369
24370 uniforms.displacementMap.value = material.displacementMap;
24371 uniforms.displacementScale.value = material.displacementScale;
24372 uniforms.displacementBias.value = material.displacementBias;
24373
24374 }
24375
24376 if ( material.envMap || environment ) {
24377
24378 //uniforms.envMap.value = material.envMap; // part of uniforms common
24379 uniforms.envMapIntensity.value = material.envMapIntensity;
24380
24381 }
24382
24383 }
24384
24385 function refreshUniformsPhysical( uniforms, material, environment ) {
24386
24387 refreshUniformsStandard( uniforms, material, environment );
24388
24389 uniforms.reflectivity.value = material.reflectivity; // also part of uniforms common
24390
24391 uniforms.clearcoat.value = material.clearcoat;
24392 uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
24393 if ( material.sheen ) { uniforms.sheen.value.copy( material.sheen ); }
24394
24395 if ( material.clearcoatMap ) {
24396
24397 uniforms.clearcoatMap.value = material.clearcoatMap;
24398
24399 }
24400
24401 if ( material.clearcoatRoughnessMap ) {
24402
24403 uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;
24404
24405 }
24406
24407 if ( material.clearcoatNormalMap ) {
24408
24409 uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale );
24410 uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
24411
24412 if ( material.side === BackSide ) {
24413
24414 uniforms.clearcoatNormalScale.value.negate();
24415
24416 }
24417
24418 }
24419
24420 uniforms.transmission.value = material.transmission;
24421
24422 if ( material.transmissionMap ) {
24423
24424 uniforms.transmissionMap.value = material.transmissionMap;
24425
24426 }
24427
24428 }
24429
24430 function refreshUniformsMatcap( uniforms, material ) {
24431
24432 if ( material.matcap ) {
24433
24434 uniforms.matcap.value = material.matcap;
24435
24436 }
24437
24438 if ( material.bumpMap ) {
24439
24440 uniforms.bumpMap.value = material.bumpMap;
24441 uniforms.bumpScale.value = material.bumpScale;
24442 if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24443
24444 }
24445
24446 if ( material.normalMap ) {
24447
24448 uniforms.normalMap.value = material.normalMap;
24449 uniforms.normalScale.value.copy( material.normalScale );
24450 if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24451
24452 }
24453
24454 if ( material.displacementMap ) {
24455
24456 uniforms.displacementMap.value = material.displacementMap;
24457 uniforms.displacementScale.value = material.displacementScale;
24458 uniforms.displacementBias.value = material.displacementBias;
24459
24460 }
24461
24462 }
24463
24464 function refreshUniformsDepth( uniforms, material ) {
24465
24466 if ( material.displacementMap ) {
24467
24468 uniforms.displacementMap.value = material.displacementMap;
24469 uniforms.displacementScale.value = material.displacementScale;
24470 uniforms.displacementBias.value = material.displacementBias;
24471
24472 }
24473
24474 }
24475
24476 function refreshUniformsDistance( uniforms, material ) {
24477
24478 if ( material.displacementMap ) {
24479
24480 uniforms.displacementMap.value = material.displacementMap;
24481 uniforms.displacementScale.value = material.displacementScale;
24482 uniforms.displacementBias.value = material.displacementBias;
24483
24484 }
24485
24486 uniforms.referencePosition.value.copy( material.referencePosition );
24487 uniforms.nearDistance.value = material.nearDistance;
24488 uniforms.farDistance.value = material.farDistance;
24489
24490 }
24491
24492 function refreshUniformsNormal( uniforms, material ) {
24493
24494 if ( material.bumpMap ) {
24495
24496 uniforms.bumpMap.value = material.bumpMap;
24497 uniforms.bumpScale.value = material.bumpScale;
24498 if ( material.side === BackSide ) { uniforms.bumpScale.value *= - 1; }
24499
24500 }
24501
24502 if ( material.normalMap ) {
24503
24504 uniforms.normalMap.value = material.normalMap;
24505 uniforms.normalScale.value.copy( material.normalScale );
24506 if ( material.side === BackSide ) { uniforms.normalScale.value.negate(); }
24507
24508 }
24509
24510 if ( material.displacementMap ) {
24511
24512 uniforms.displacementMap.value = material.displacementMap;
24513 uniforms.displacementScale.value = material.displacementScale;
24514 uniforms.displacementBias.value = material.displacementBias;
24515
24516 }
24517
24518 }
24519
24520 return {
24521 refreshFogUniforms: refreshFogUniforms,
24522 refreshMaterialUniforms: refreshMaterialUniforms
24523 };
24524
24525 }
24526
24527 function WebGLRenderer( parameters ) {
24528
24529 parameters = parameters || {};
24530
24531 var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' ),
24532 _context = parameters.context !== undefined ? parameters.context : null,
24533
24534 _alpha = parameters.alpha !== undefined ? parameters.alpha : false,
24535 _depth = parameters.depth !== undefined ? parameters.depth : true,
24536 _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
24537 _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
24538 _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
24539 _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
24540 _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',
24541 _failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;
24542
24543 var currentRenderList = null;
24544 var currentRenderState = null;
24545
24546 // public properties
24547
24548 this.domElement = _canvas;
24549
24550 // Debug configuration container
24551 this.debug = {
24552
24553 /**
24554 * Enables error checking and reporting when shader programs are being compiled
24555 * @type {boolean}
24556 */
24557 checkShaderErrors: true
24558 };
24559
24560 // clearing
24561
24562 this.autoClear = true;
24563 this.autoClearColor = true;
24564 this.autoClearDepth = true;
24565 this.autoClearStencil = true;
24566
24567 // scene graph
24568
24569 this.sortObjects = true;
24570
24571 // user-defined clipping
24572
24573 this.clippingPlanes = [];
24574 this.localClippingEnabled = false;
24575
24576 // physically based shading
24577
24578 this.gammaFactor = 2.0; // for backwards compatibility
24579 this.outputEncoding = LinearEncoding;
24580
24581 // physical lights
24582
24583 this.physicallyCorrectLights = false;
24584
24585 // tone mapping
24586
24587 this.toneMapping = NoToneMapping;
24588 this.toneMappingExposure = 1.0;
24589
24590 // morphs
24591
24592 this.maxMorphTargets = 8;
24593 this.maxMorphNormals = 4;
24594
24595 // internal properties
24596
24597 var _this = this;
24598
24599 var _isContextLost = false;
24600
24601 // internal state cache
24602
24603 var _framebuffer = null;
24604
24605 var _currentActiveCubeFace = 0;
24606 var _currentActiveMipmapLevel = 0;
24607 var _currentRenderTarget = null;
24608 var _currentFramebuffer = null;
24609 var _currentMaterialId = - 1;
24610
24611 var _currentCamera = null;
24612 var _currentArrayCamera = null;
24613
24614 var _currentViewport = new Vector4();
24615 var _currentScissor = new Vector4();
24616 var _currentScissorTest = null;
24617
24618 //
24619
24620 var _width = _canvas.width;
24621 var _height = _canvas.height;
24622
24623 var _pixelRatio = 1;
24624 var _opaqueSort = null;
24625 var _transparentSort = null;
24626
24627 var _viewport = new Vector4( 0, 0, _width, _height );
24628 var _scissor = new Vector4( 0, 0, _width, _height );
24629 var _scissorTest = false;
24630
24631 // frustum
24632
24633 var _frustum = new Frustum();
24634
24635 // clipping
24636
24637 var _clipping = new WebGLClipping();
24638 var _clippingEnabled = false;
24639 var _localClippingEnabled = false;
24640
24641 // camera matrices cache
24642
24643 var _projScreenMatrix = new Matrix4();
24644
24645 var _vector3 = new Vector3();
24646
24647 var _emptyScene = { background: null, fog: null, environment: null, overrideMaterial: null, isScene: true };
24648
24649 function getTargetPixelRatio() {
24650
24651 return _currentRenderTarget === null ? _pixelRatio : 1;
24652
24653 }
24654
24655 // initialize
24656
24657 var _gl = _context;
24658
24659 function getContext( contextNames, contextAttributes ) {
24660
24661 for ( var i = 0; i < contextNames.length; i ++ ) {
24662
24663 var contextName = contextNames[ i ];
24664 var context = _canvas.getContext( contextName, contextAttributes );
24665 if ( context !== null ) { return context; }
24666
24667 }
24668
24669 return null;
24670
24671 }
24672
24673 try {
24674
24675 var contextAttributes = {
24676 alpha: _alpha,
24677 depth: _depth,
24678 stencil: _stencil,
24679 antialias: _antialias,
24680 premultipliedAlpha: _premultipliedAlpha,
24681 preserveDrawingBuffer: _preserveDrawingBuffer,
24682 powerPreference: _powerPreference,
24683 failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat
24684 };
24685
24686 // event listeners must be registered before WebGL context is created, see #12753
24687
24688 _canvas.addEventListener( 'webglcontextlost', onContextLost, false );
24689 _canvas.addEventListener( 'webglcontextrestored', onContextRestore, false );
24690
24691 if ( _gl === null ) {
24692
24693 var contextNames = [ 'webgl2', 'webgl', 'experimental-webgl' ];
24694
24695 if ( _this.isWebGL1Renderer === true ) {
24696
24697 contextNames.shift();
24698
24699 }
24700
24701 _gl = getContext( contextNames, contextAttributes );
24702
24703 if ( _gl === null ) {
24704
24705 if ( getContext( contextNames ) ) {
24706
24707 throw new Error( 'Error creating WebGL context with your selected attributes.' );
24708
24709 } else {
24710
24711 throw new Error( 'Error creating WebGL context.' );
24712
24713 }
24714
24715 }
24716
24717 }
24718
24719 // Some experimental-webgl implementations do not have getShaderPrecisionFormat
24720
24721 if ( _gl.getShaderPrecisionFormat === undefined ) {
24722
24723 _gl.getShaderPrecisionFormat = function () {
24724
24725 return { 'rangeMin': 1, 'rangeMax': 1, 'precision': 1 };
24726
24727 };
24728
24729 }
24730
24731 } catch ( error ) {
24732
24733 console.error( 'THREE.WebGLRenderer: ' + error.message );
24734 throw error;
24735
24736 }
24737
24738 var extensions, capabilities, state, info;
24739 var properties, textures, attributes, geometries, objects;
24740 var programCache, materials, renderLists, renderStates;
24741
24742 var background, morphtargets, bufferRenderer, indexedBufferRenderer;
24743
24744 var utils, bindingStates;
24745
24746 function initGLContext() {
24747
24748 extensions = new WebGLExtensions( _gl );
24749
24750 capabilities = new WebGLCapabilities( _gl, extensions, parameters );
24751
24752 if ( capabilities.isWebGL2 === false ) {
24753
24754 extensions.get( 'WEBGL_depth_texture' );
24755 extensions.get( 'OES_texture_float' );
24756 extensions.get( 'OES_texture_half_float' );
24757 extensions.get( 'OES_texture_half_float_linear' );
24758 extensions.get( 'OES_standard_derivatives' );
24759 extensions.get( 'OES_element_index_uint' );
24760 extensions.get( 'OES_vertex_array_object' );
24761 extensions.get( 'ANGLE_instanced_arrays' );
24762
24763 }
24764
24765 extensions.get( 'OES_texture_float_linear' );
24766
24767 utils = new WebGLUtils( _gl, extensions, capabilities );
24768
24769 state = new WebGLState( _gl, extensions, capabilities );
24770 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
24771 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
24772
24773 info = new WebGLInfo( _gl );
24774 properties = new WebGLProperties();
24775 textures = new WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info );
24776 attributes = new WebGLAttributes( _gl, capabilities );
24777 bindingStates = new WebGLBindingStates( _gl, extensions, attributes, capabilities );
24778 geometries = new WebGLGeometries( _gl, attributes, info, bindingStates );
24779 objects = new WebGLObjects( _gl, geometries, attributes, info );
24780 morphtargets = new WebGLMorphtargets( _gl );
24781 programCache = new WebGLPrograms( _this, extensions, capabilities, bindingStates );
24782 materials = new WebGLMaterials( properties );
24783 renderLists = new WebGLRenderLists( properties );
24784 renderStates = new WebGLRenderStates();
24785
24786 background = new WebGLBackground( _this, state, objects, _premultipliedAlpha );
24787
24788 bufferRenderer = new WebGLBufferRenderer( _gl, extensions, info, capabilities );
24789 indexedBufferRenderer = new WebGLIndexedBufferRenderer( _gl, extensions, info, capabilities );
24790
24791 info.programs = programCache.programs;
24792
24793 _this.capabilities = capabilities;
24794 _this.extensions = extensions;
24795 _this.properties = properties;
24796 _this.renderLists = renderLists;
24797 _this.state = state;
24798 _this.info = info;
24799
24800 }
24801
24802 initGLContext();
24803
24804 // xr
24805
24806 var xr = new WebXRManager( _this, _gl );
24807
24808 this.xr = xr;
24809
24810 // shadow map
24811
24812 var shadowMap = new WebGLShadowMap( _this, objects, capabilities.maxTextureSize );
24813
24814 this.shadowMap = shadowMap;
24815
24816 // API
24817
24818 this.getContext = function () {
24819
24820 return _gl;
24821
24822 };
24823
24824 this.getContextAttributes = function () {
24825
24826 return _gl.getContextAttributes();
24827
24828 };
24829
24830 this.forceContextLoss = function () {
24831
24832 var extension = extensions.get( 'WEBGL_lose_context' );
24833 if ( extension ) { extension.loseContext(); }
24834
24835 };
24836
24837 this.forceContextRestore = function () {
24838
24839 var extension = extensions.get( 'WEBGL_lose_context' );
24840 if ( extension ) { extension.restoreContext(); }
24841
24842 };
24843
24844 this.getPixelRatio = function () {
24845
24846 return _pixelRatio;
24847
24848 };
24849
24850 this.setPixelRatio = function ( value ) {
24851
24852 if ( value === undefined ) { return; }
24853
24854 _pixelRatio = value;
24855
24856 this.setSize( _width, _height, false );
24857
24858 };
24859
24860 this.getSize = function ( target ) {
24861
24862 if ( target === undefined ) {
24863
24864 console.warn( 'WebGLRenderer: .getsize() now requires a Vector2 as an argument' );
24865
24866 target = new Vector2();
24867
24868 }
24869
24870 return target.set( _width, _height );
24871
24872 };
24873
24874 this.setSize = function ( width, height, updateStyle ) {
24875
24876 if ( xr.isPresenting ) {
24877
24878 console.warn( 'THREE.WebGLRenderer: Can\'t change size while VR device is presenting.' );
24879 return;
24880
24881 }
24882
24883 _width = width;
24884 _height = height;
24885
24886 _canvas.width = Math.floor( width * _pixelRatio );
24887 _canvas.height = Math.floor( height * _pixelRatio );
24888
24889 if ( updateStyle !== false ) {
24890
24891 _canvas.style.width = width + 'px';
24892 _canvas.style.height = height + 'px';
24893
24894 }
24895
24896 this.setViewport( 0, 0, width, height );
24897
24898 };
24899
24900 this.getDrawingBufferSize = function ( target ) {
24901
24902 if ( target === undefined ) {
24903
24904 console.warn( 'WebGLRenderer: .getdrawingBufferSize() now requires a Vector2 as an argument' );
24905
24906 target = new Vector2();
24907
24908 }
24909
24910 return target.set( _width * _pixelRatio, _height * _pixelRatio ).floor();
24911
24912 };
24913
24914 this.setDrawingBufferSize = function ( width, height, pixelRatio ) {
24915
24916 _width = width;
24917 _height = height;
24918
24919 _pixelRatio = pixelRatio;
24920
24921 _canvas.width = Math.floor( width * pixelRatio );
24922 _canvas.height = Math.floor( height * pixelRatio );
24923
24924 this.setViewport( 0, 0, width, height );
24925
24926 };
24927
24928 this.getCurrentViewport = function ( target ) {
24929
24930 if ( target === undefined ) {
24931
24932 console.warn( 'WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument' );
24933
24934 target = new Vector4();
24935
24936 }
24937
24938 return target.copy( _currentViewport );
24939
24940 };
24941
24942 this.getViewport = function ( target ) {
24943
24944 return target.copy( _viewport );
24945
24946 };
24947
24948 this.setViewport = function ( x, y, width, height ) {
24949
24950 if ( x.isVector4 ) {
24951
24952 _viewport.set( x.x, x.y, x.z, x.w );
24953
24954 } else {
24955
24956 _viewport.set( x, y, width, height );
24957
24958 }
24959
24960 state.viewport( _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor() );
24961
24962 };
24963
24964 this.getScissor = function ( target ) {
24965
24966 return target.copy( _scissor );
24967
24968 };
24969
24970 this.setScissor = function ( x, y, width, height ) {
24971
24972 if ( x.isVector4 ) {
24973
24974 _scissor.set( x.x, x.y, x.z, x.w );
24975
24976 } else {
24977
24978 _scissor.set( x, y, width, height );
24979
24980 }
24981
24982 state.scissor( _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor() );
24983
24984 };
24985
24986 this.getScissorTest = function () {
24987
24988 return _scissorTest;
24989
24990 };
24991
24992 this.setScissorTest = function ( boolean ) {
24993
24994 state.setScissorTest( _scissorTest = boolean );
24995
24996 };
24997
24998 this.setOpaqueSort = function ( method ) {
24999
25000 _opaqueSort = method;
25001
25002 };
25003
25004 this.setTransparentSort = function ( method ) {
25005
25006 _transparentSort = method;
25007
25008 };
25009
25010 // Clearing
25011
25012 this.getClearColor = function () {
25013
25014 return background.getClearColor();
25015
25016 };
25017
25018 this.setClearColor = function () {
25019
25020 background.setClearColor.apply( background, arguments );
25021
25022 };
25023
25024 this.getClearAlpha = function () {
25025
25026 return background.getClearAlpha();
25027
25028 };
25029
25030 this.setClearAlpha = function () {
25031
25032 background.setClearAlpha.apply( background, arguments );
25033
25034 };
25035
25036 this.clear = function ( color, depth, stencil ) {
25037
25038 var bits = 0;
25039
25040 if ( color === undefined || color ) { bits |= 16384; }
25041 if ( depth === undefined || depth ) { bits |= 256; }
25042 if ( stencil === undefined || stencil ) { bits |= 1024; }
25043
25044 _gl.clear( bits );
25045
25046 };
25047
25048 this.clearColor = function () {
25049
25050 this.clear( true, false, false );
25051
25052 };
25053
25054 this.clearDepth = function () {
25055
25056 this.clear( false, true, false );
25057
25058 };
25059
25060 this.clearStencil = function () {
25061
25062 this.clear( false, false, true );
25063
25064 };
25065
25066 //
25067
25068 this.dispose = function () {
25069
25070 _canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
25071 _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false );
25072
25073 renderLists.dispose();
25074 renderStates.dispose();
25075 properties.dispose();
25076 objects.dispose();
25077 bindingStates.dispose();
25078
25079 xr.dispose();
25080
25081 animation.stop();
25082
25083 };
25084
25085 // Events
25086
25087 function onContextLost( event ) {
25088
25089 event.preventDefault();
25090
25091 console.log( 'THREE.WebGLRenderer: Context Lost.' );
25092
25093 _isContextLost = true;
25094
25095 }
25096
25097 function onContextRestore( /* event */ ) {
25098
25099 console.log( 'THREE.WebGLRenderer: Context Restored.' );
25100
25101 _isContextLost = false;
25102
25103 initGLContext();
25104
25105 }
25106
25107 function onMaterialDispose( event ) {
25108
25109 var material = event.target;
25110
25111 material.removeEventListener( 'dispose', onMaterialDispose );
25112
25113 deallocateMaterial( material );
25114
25115 }
25116
25117 // Buffer deallocation
25118
25119 function deallocateMaterial( material ) {
25120
25121 releaseMaterialProgramReference( material );
25122
25123 properties.remove( material );
25124
25125 }
25126
25127
25128 function releaseMaterialProgramReference( material ) {
25129
25130 var programInfo = properties.get( material ).program;
25131
25132 if ( programInfo !== undefined ) {
25133
25134 programCache.releaseProgram( programInfo );
25135
25136 }
25137
25138 }
25139
25140 // Buffer rendering
25141
25142 function renderObjectImmediate( object, program ) {
25143
25144 object.render( function ( object ) {
25145
25146 _this.renderBufferImmediate( object, program );
25147
25148 } );
25149
25150 }
25151
25152 this.renderBufferImmediate = function ( object, program ) {
25153
25154 bindingStates.initAttributes();
25155
25156 var buffers = properties.get( object );
25157
25158 if ( object.hasPositions && ! buffers.position ) { buffers.position = _gl.createBuffer(); }
25159 if ( object.hasNormals && ! buffers.normal ) { buffers.normal = _gl.createBuffer(); }
25160 if ( object.hasUvs && ! buffers.uv ) { buffers.uv = _gl.createBuffer(); }
25161 if ( object.hasColors && ! buffers.color ) { buffers.color = _gl.createBuffer(); }
25162
25163 var programAttributes = program.getAttributes();
25164
25165 if ( object.hasPositions ) {
25166
25167 _gl.bindBuffer( 34962, buffers.position );
25168 _gl.bufferData( 34962, object.positionArray, 35048 );
25169
25170 bindingStates.enableAttribute( programAttributes.position );
25171 _gl.vertexAttribPointer( programAttributes.position, 3, 5126, false, 0, 0 );
25172
25173 }
25174
25175 if ( object.hasNormals ) {
25176
25177 _gl.bindBuffer( 34962, buffers.normal );
25178 _gl.bufferData( 34962, object.normalArray, 35048 );
25179
25180 bindingStates.enableAttribute( programAttributes.normal );
25181 _gl.vertexAttribPointer( programAttributes.normal, 3, 5126, false, 0, 0 );
25182
25183 }
25184
25185 if ( object.hasUvs ) {
25186
25187 _gl.bindBuffer( 34962, buffers.uv );
25188 _gl.bufferData( 34962, object.uvArray, 35048 );
25189
25190 bindingStates.enableAttribute( programAttributes.uv );
25191 _gl.vertexAttribPointer( programAttributes.uv, 2, 5126, false, 0, 0 );
25192
25193 }
25194
25195 if ( object.hasColors ) {
25196
25197 _gl.bindBuffer( 34962, buffers.color );
25198 _gl.bufferData( 34962, object.colorArray, 35048 );
25199
25200 bindingStates.enableAttribute( programAttributes.color );
25201 _gl.vertexAttribPointer( programAttributes.color, 3, 5126, false, 0, 0 );
25202
25203 }
25204
25205 bindingStates.disableUnusedAttributes();
25206
25207 _gl.drawArrays( 4, 0, object.count );
25208
25209 object.count = 0;
25210
25211 };
25212
25213 this.renderBufferDirect = function ( camera, scene, geometry, material, object, group ) {
25214
25215 if ( scene === null ) { scene = _emptyScene; } // renderBufferDirect second parameter used to be fog (could be null)
25216
25217 var frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
25218
25219 var program = setProgram( camera, scene, material, object );
25220
25221 state.setMaterial( material, frontFaceCW );
25222
25223 //
25224
25225 var index = geometry.index;
25226 var position = geometry.attributes.position;
25227
25228 //
25229
25230 if ( index === null ) {
25231
25232 if ( position === undefined || position.count === 0 ) { return; }
25233
25234 } else if ( index.count === 0 ) {
25235
25236 return;
25237
25238 }
25239
25240 //
25241
25242 var rangeFactor = 1;
25243
25244 if ( material.wireframe === true ) {
25245
25246 index = geometries.getWireframeAttribute( geometry );
25247 rangeFactor = 2;
25248
25249 }
25250
25251 if ( material.morphTargets || material.morphNormals ) {
25252
25253 morphtargets.update( object, geometry, material, program );
25254
25255 }
25256
25257 bindingStates.setup( object, material, program, geometry, index );
25258
25259 var attribute;
25260 var renderer = bufferRenderer;
25261
25262 if ( index !== null ) {
25263
25264 attribute = attributes.get( index );
25265
25266 renderer = indexedBufferRenderer;
25267 renderer.setIndex( attribute );
25268
25269 }
25270
25271 //
25272
25273 var dataCount = ( index !== null ) ? index.count : position.count;
25274
25275 var rangeStart = geometry.drawRange.start * rangeFactor;
25276 var rangeCount = geometry.drawRange.count * rangeFactor;
25277
25278 var groupStart = group !== null ? group.start * rangeFactor : 0;
25279 var groupCount = group !== null ? group.count * rangeFactor : Infinity;
25280
25281 var drawStart = Math.max( rangeStart, groupStart );
25282 var drawEnd = Math.min( dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
25283
25284 var drawCount = Math.max( 0, drawEnd - drawStart + 1 );
25285
25286 if ( drawCount === 0 ) { return; }
25287
25288 //
25289
25290 if ( object.isMesh ) {
25291
25292 if ( material.wireframe === true ) {
25293
25294 state.setLineWidth( material.wireframeLinewidth * getTargetPixelRatio() );
25295 renderer.setMode( 1 );
25296
25297 } else {
25298
25299 renderer.setMode( 4 );
25300
25301 }
25302
25303 } else if ( object.isLine ) {
25304
25305 var lineWidth = material.linewidth;
25306
25307 if ( lineWidth === undefined ) { lineWidth = 1; } // Not using Line*Material
25308
25309 state.setLineWidth( lineWidth * getTargetPixelRatio() );
25310
25311 if ( object.isLineSegments ) {
25312
25313 renderer.setMode( 1 );
25314
25315 } else if ( object.isLineLoop ) {
25316
25317 renderer.setMode( 2 );
25318
25319 } else {
25320
25321 renderer.setMode( 3 );
25322
25323 }
25324
25325 } else if ( object.isPoints ) {
25326
25327 renderer.setMode( 0 );
25328
25329 } else if ( object.isSprite ) {
25330
25331 renderer.setMode( 4 );
25332
25333 }
25334
25335 if ( object.isInstancedMesh ) {
25336
25337 renderer.renderInstances( drawStart, drawCount, object.count );
25338
25339 } else if ( geometry.isInstancedBufferGeometry ) {
25340
25341 var instanceCount = Math.min( geometry.instanceCount, geometry._maxInstanceCount );
25342
25343 renderer.renderInstances( drawStart, drawCount, instanceCount );
25344
25345 } else {
25346
25347 renderer.render( drawStart, drawCount );
25348
25349 }
25350
25351 };
25352
25353 // Compile
25354
25355 this.compile = function ( scene, camera ) {
25356
25357 currentRenderState = renderStates.get( scene, camera );
25358 currentRenderState.init();
25359
25360 scene.traverse( function ( object ) {
25361
25362 if ( object.isLight ) {
25363
25364 currentRenderState.pushLight( object );
25365
25366 if ( object.castShadow ) {
25367
25368 currentRenderState.pushShadow( object );
25369
25370 }
25371
25372 }
25373
25374 } );
25375
25376 currentRenderState.setupLights( camera );
25377
25378 var compiled = new WeakMap();
25379
25380 scene.traverse( function ( object ) {
25381
25382 var material = object.material;
25383
25384 if ( material ) {
25385
25386 if ( Array.isArray( material ) ) {
25387
25388 for ( var i = 0; i < material.length; i ++ ) {
25389
25390 var material2 = material[ i ];
25391
25392 if ( compiled.has( material2 ) === false ) {
25393
25394 initMaterial( material2, scene, object );
25395 compiled.set( material2 );
25396
25397 }
25398
25399 }
25400
25401 } else if ( compiled.has( material ) === false ) {
25402
25403 initMaterial( material, scene, object );
25404 compiled.set( material );
25405
25406 }
25407
25408 }
25409
25410 } );
25411
25412 };
25413
25414 // Animation Loop
25415
25416 var onAnimationFrameCallback = null;
25417
25418 function onAnimationFrame( time ) {
25419
25420 if ( xr.isPresenting ) { return; }
25421 if ( onAnimationFrameCallback ) { onAnimationFrameCallback( time ); }
25422
25423 }
25424
25425 var animation = new WebGLAnimation();
25426 animation.setAnimationLoop( onAnimationFrame );
25427
25428 if ( typeof window !== 'undefined' ) { animation.setContext( window ); }
25429
25430 this.setAnimationLoop = function ( callback ) {
25431
25432 onAnimationFrameCallback = callback;
25433 xr.setAnimationLoop( callback );
25434
25435 ( callback === null ) ? animation.stop() : animation.start();
25436
25437 };
25438
25439 // Rendering
25440
25441 this.render = function ( scene, camera ) {
25442
25443 var renderTarget, forceClear;
25444
25445 if ( arguments[ 2 ] !== undefined ) {
25446
25447 console.warn( 'THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.' );
25448 renderTarget = arguments[ 2 ];
25449
25450 }
25451
25452 if ( arguments[ 3 ] !== undefined ) {
25453
25454 console.warn( 'THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.' );
25455 forceClear = arguments[ 3 ];
25456
25457 }
25458
25459 if ( camera !== undefined && camera.isCamera !== true ) {
25460
25461 console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
25462 return;
25463
25464 }
25465
25466 if ( _isContextLost === true ) { return; }
25467
25468 // reset caching for this frame
25469
25470 bindingStates.resetDefaultState();
25471 _currentMaterialId = - 1;
25472 _currentCamera = null;
25473
25474 // update scene graph
25475
25476 if ( scene.autoUpdate === true ) { scene.updateMatrixWorld(); }
25477
25478 // update camera matrices and frustum
25479
25480 if ( camera.parent === null ) { camera.updateMatrixWorld(); }
25481
25482 if ( xr.enabled === true && xr.isPresenting === true ) {
25483
25484 camera = xr.getCamera( camera );
25485
25486 }
25487
25488 //
25489 if ( scene.isScene === true ) { scene.onBeforeRender( _this, scene, camera, renderTarget || _currentRenderTarget ); }
25490
25491 currentRenderState = renderStates.get( scene, camera );
25492 currentRenderState.init();
25493
25494 _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
25495 _frustum.setFromProjectionMatrix( _projScreenMatrix );
25496
25497 _localClippingEnabled = this.localClippingEnabled;
25498 _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
25499
25500 currentRenderList = renderLists.get( scene, camera );
25501 currentRenderList.init();
25502
25503 projectObject( scene, camera, 0, _this.sortObjects );
25504
25505 currentRenderList.finish();
25506
25507 if ( _this.sortObjects === true ) {
25508
25509 currentRenderList.sort( _opaqueSort, _transparentSort );
25510
25511 }
25512
25513 //
25514
25515 if ( _clippingEnabled === true ) { _clipping.beginShadows(); }
25516
25517 var shadowsArray = currentRenderState.state.shadowsArray;
25518
25519 shadowMap.render( shadowsArray, scene, camera );
25520
25521 currentRenderState.setupLights( camera );
25522
25523 if ( _clippingEnabled === true ) { _clipping.endShadows(); }
25524
25525 //
25526
25527 if ( this.info.autoReset === true ) { this.info.reset(); }
25528
25529 if ( renderTarget !== undefined ) {
25530
25531 this.setRenderTarget( renderTarget );
25532
25533 }
25534
25535 //
25536
25537 background.render( currentRenderList, scene, camera, forceClear );
25538
25539 // render scene
25540
25541 var opaqueObjects = currentRenderList.opaque;
25542 var transparentObjects = currentRenderList.transparent;
25543
25544 if ( opaqueObjects.length > 0 ) { renderObjects( opaqueObjects, scene, camera ); }
25545 if ( transparentObjects.length > 0 ) { renderObjects( transparentObjects, scene, camera ); }
25546
25547 //
25548
25549 if ( scene.isScene === true ) { scene.onAfterRender( _this, scene, camera ); }
25550
25551 //
25552
25553 if ( _currentRenderTarget !== null ) {
25554
25555 // Generate mipmap if we're using any kind of mipmap filtering
25556
25557 textures.updateRenderTargetMipmap( _currentRenderTarget );
25558
25559 // resolve multisample renderbuffers to a single-sample texture if necessary
25560
25561 textures.updateMultisampleRenderTarget( _currentRenderTarget );
25562
25563 }
25564
25565 // Ensure depth buffer writing is enabled so it can be cleared on next render
25566
25567 state.buffers.depth.setTest( true );
25568 state.buffers.depth.setMask( true );
25569 state.buffers.color.setMask( true );
25570
25571 state.setPolygonOffset( false );
25572
25573 // _gl.finish();
25574
25575 currentRenderList = null;
25576 currentRenderState = null;
25577
25578 };
25579
25580 function projectObject( object, camera, groupOrder, sortObjects ) {
25581
25582 if ( object.visible === false ) { return; }
25583
25584 var visible = object.layers.test( camera.layers );
25585
25586 if ( visible ) {
25587
25588 if ( object.isGroup ) {
25589
25590 groupOrder = object.renderOrder;
25591
25592 } else if ( object.isLOD ) {
25593
25594 if ( object.autoUpdate === true ) { object.update( camera ); }
25595
25596 } else if ( object.isLight ) {
25597
25598 currentRenderState.pushLight( object );
25599
25600 if ( object.castShadow ) {
25601
25602 currentRenderState.pushShadow( object );
25603
25604 }
25605
25606 } else if ( object.isSprite ) {
25607
25608 if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
25609
25610 if ( sortObjects ) {
25611
25612 _vector3.setFromMatrixPosition( object.matrixWorld )
25613 .applyMatrix4( _projScreenMatrix );
25614
25615 }
25616
25617 var geometry = objects.update( object );
25618 var material = object.material;
25619
25620 if ( material.visible ) {
25621
25622 currentRenderList.push( object, geometry, material, groupOrder, _vector3.z, null );
25623
25624 }
25625
25626 }
25627
25628 } else if ( object.isImmediateRenderObject ) {
25629
25630 if ( sortObjects ) {
25631
25632 _vector3.setFromMatrixPosition( object.matrixWorld )
25633 .applyMatrix4( _projScreenMatrix );
25634
25635 }
25636
25637 currentRenderList.push( object, null, object.material, groupOrder, _vector3.z, null );
25638
25639 } else if ( object.isMesh || object.isLine || object.isPoints ) {
25640
25641 if ( object.isSkinnedMesh ) {
25642
25643 // update skeleton only once in a frame
25644
25645 if ( object.skeleton.frame !== info.render.frame ) {
25646
25647 object.skeleton.update();
25648 object.skeleton.frame = info.render.frame;
25649
25650 }
25651
25652 }
25653
25654 if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
25655
25656 if ( sortObjects ) {
25657
25658 _vector3.setFromMatrixPosition( object.matrixWorld )
25659 .applyMatrix4( _projScreenMatrix );
25660
25661 }
25662
25663 var geometry$1 = objects.update( object );
25664 var material$1 = object.material;
25665
25666 if ( Array.isArray( material$1 ) ) {
25667
25668 var groups = geometry$1.groups;
25669
25670 for ( var i = 0, l = groups.length; i < l; i ++ ) {
25671
25672 var group = groups[ i ];
25673 var groupMaterial = material$1[ group.materialIndex ];
25674
25675 if ( groupMaterial && groupMaterial.visible ) {
25676
25677 currentRenderList.push( object, geometry$1, groupMaterial, groupOrder, _vector3.z, group );
25678
25679 }
25680
25681 }
25682
25683 } else if ( material$1.visible ) {
25684
25685 currentRenderList.push( object, geometry$1, material$1, groupOrder, _vector3.z, null );
25686
25687 }
25688
25689 }
25690
25691 }
25692
25693 }
25694
25695 var children = object.children;
25696
25697 for ( var i$1 = 0, l$1 = children.length; i$1 < l$1; i$1 ++ ) {
25698
25699 projectObject( children[ i$1 ], camera, groupOrder, sortObjects );
25700
25701 }
25702
25703 }
25704
25705 function renderObjects( renderList, scene, camera ) {
25706
25707 var overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
25708
25709 for ( var i = 0, l = renderList.length; i < l; i ++ ) {
25710
25711 var renderItem = renderList[ i ];
25712
25713 var object = renderItem.object;
25714 var geometry = renderItem.geometry;
25715 var material = overrideMaterial === null ? renderItem.material : overrideMaterial;
25716 var group = renderItem.group;
25717
25718 if ( camera.isArrayCamera ) {
25719
25720 _currentArrayCamera = camera;
25721
25722 var cameras = camera.cameras;
25723
25724 for ( var j = 0, jl = cameras.length; j < jl; j ++ ) {
25725
25726 var camera2 = cameras[ j ];
25727
25728 if ( object.layers.test( camera2.layers ) ) {
25729
25730 state.viewport( _currentViewport.copy( camera2.viewport ) );
25731
25732 currentRenderState.setupLights( camera2 );
25733
25734 renderObject( object, scene, camera2, geometry, material, group );
25735
25736 }
25737
25738 }
25739
25740 } else {
25741
25742 _currentArrayCamera = null;
25743
25744 renderObject( object, scene, camera, geometry, material, group );
25745
25746 }
25747
25748 }
25749
25750 }
25751
25752 function renderObject( object, scene, camera, geometry, material, group ) {
25753
25754 object.onBeforeRender( _this, scene, camera, geometry, material, group );
25755 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
25756
25757 object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
25758 object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
25759
25760 if ( object.isImmediateRenderObject ) {
25761
25762 var program = setProgram( camera, scene, material, object );
25763
25764 state.setMaterial( material );
25765
25766 bindingStates.reset();
25767
25768 renderObjectImmediate( object, program );
25769
25770 } else {
25771
25772 _this.renderBufferDirect( camera, scene, geometry, material, object, group );
25773
25774 }
25775
25776 object.onAfterRender( _this, scene, camera, geometry, material, group );
25777 currentRenderState = renderStates.get( scene, _currentArrayCamera || camera );
25778
25779 }
25780
25781 function initMaterial( material, scene, object ) {
25782
25783 if ( scene.isScene !== true ) { scene = _emptyScene; } // scene could be a Mesh, Line, Points, ...
25784
25785 var materialProperties = properties.get( material );
25786
25787 var lights = currentRenderState.state.lights;
25788 var shadowsArray = currentRenderState.state.shadowsArray;
25789
25790 var lightsStateVersion = lights.state.version;
25791
25792 var parameters = programCache.getParameters( material, lights.state, shadowsArray, scene, _clipping.numPlanes, _clipping.numIntersection, object );
25793 var programCacheKey = programCache.getProgramCacheKey( parameters );
25794
25795 var program = materialProperties.program;
25796 var programChange = true;
25797
25798 if ( program === undefined ) {
25799
25800 // new material
25801 material.addEventListener( 'dispose', onMaterialDispose );
25802
25803 } else if ( program.cacheKey !== programCacheKey ) {
25804
25805 // changed glsl or parameters
25806 releaseMaterialProgramReference( material );
25807
25808 } else if ( materialProperties.lightsStateVersion !== lightsStateVersion ) {
25809
25810 materialProperties.lightsStateVersion = lightsStateVersion;
25811
25812 programChange = false;
25813
25814 } else if ( parameters.shaderID !== undefined ) {
25815
25816 // same glsl and uniform list
25817 return;
25818
25819 } else {
25820
25821 // only rebuild uniform list
25822 programChange = false;
25823
25824 }
25825
25826 if ( programChange ) {
25827
25828 parameters.uniforms = programCache.getUniforms( material, parameters );
25829
25830 material.onBeforeCompile( parameters, _this );
25831
25832 program = programCache.acquireProgram( parameters, programCacheKey );
25833
25834 materialProperties.program = program;
25835 materialProperties.uniforms = parameters.uniforms;
25836 materialProperties.outputEncoding = parameters.outputEncoding;
25837
25838 }
25839
25840 var programAttributes = program.getAttributes();
25841
25842 if ( material.morphTargets ) {
25843
25844 material.numSupportedMorphTargets = 0;
25845
25846 for ( var i = 0; i < _this.maxMorphTargets; i ++ ) {
25847
25848 if ( programAttributes[ 'morphTarget' + i ] >= 0 ) {
25849
25850 material.numSupportedMorphTargets ++;
25851
25852 }
25853
25854 }
25855
25856 }
25857
25858 if ( material.morphNormals ) {
25859
25860 material.numSupportedMorphNormals = 0;
25861
25862 for ( var i$1 = 0; i$1 < _this.maxMorphNormals; i$1 ++ ) {
25863
25864 if ( programAttributes[ 'morphNormal' + i$1 ] >= 0 ) {
25865
25866 material.numSupportedMorphNormals ++;
25867
25868 }
25869
25870 }
25871
25872 }
25873
25874 var uniforms = materialProperties.uniforms;
25875
25876 if ( ! material.isShaderMaterial &&
25877 ! material.isRawShaderMaterial ||
25878 material.clipping === true ) {
25879
25880 materialProperties.numClippingPlanes = _clipping.numPlanes;
25881 materialProperties.numIntersection = _clipping.numIntersection;
25882 uniforms.clippingPlanes = _clipping.uniform;
25883
25884 }
25885
25886 materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
25887 materialProperties.fog = scene.fog;
25888
25889 // store the light setup it was created for
25890
25891 materialProperties.needsLights = materialNeedsLights( material );
25892 materialProperties.lightsStateVersion = lightsStateVersion;
25893
25894 if ( materialProperties.needsLights ) {
25895
25896 // wire up the material to this renderer's lighting state
25897
25898 uniforms.ambientLightColor.value = lights.state.ambient;
25899 uniforms.lightProbe.value = lights.state.probe;
25900 uniforms.directionalLights.value = lights.state.directional;
25901 uniforms.directionalLightShadows.value = lights.state.directionalShadow;
25902 uniforms.spotLights.value = lights.state.spot;
25903 uniforms.spotLightShadows.value = lights.state.spotShadow;
25904 uniforms.rectAreaLights.value = lights.state.rectArea;
25905 uniforms.pointLights.value = lights.state.point;
25906 uniforms.pointLightShadows.value = lights.state.pointShadow;
25907 uniforms.hemisphereLights.value = lights.state.hemi;
25908
25909 uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
25910 uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
25911 uniforms.spotShadowMap.value = lights.state.spotShadowMap;
25912 uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix;
25913 uniforms.pointShadowMap.value = lights.state.pointShadowMap;
25914 uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix;
25915 // TODO (abelnation): add area lights shadow info to uniforms
25916
25917 }
25918
25919 var progUniforms = materialProperties.program.getUniforms(),
25920 uniformsList =
25921 WebGLUniforms.seqWithValue( progUniforms.seq, uniforms );
25922
25923 materialProperties.uniformsList = uniformsList;
25924
25925 }
25926
25927 function setProgram( camera, scene, material, object ) {
25928
25929 if ( scene.isScene !== true ) { scene = _emptyScene; } // scene could be a Mesh, Line, Points, ...
25930
25931 textures.resetTextureUnits();
25932
25933 var fog = scene.fog;
25934 var environment = material.isMeshStandardMaterial ? scene.environment : null;
25935 var encoding = ( _currentRenderTarget === null ) ? _this.outputEncoding : _currentRenderTarget.texture.encoding;
25936
25937 var materialProperties = properties.get( material );
25938 var lights = currentRenderState.state.lights;
25939
25940 if ( _clippingEnabled === true ) {
25941
25942 if ( _localClippingEnabled === true || camera !== _currentCamera ) {
25943
25944 var useCache =
25945 camera === _currentCamera &&
25946 material.id === _currentMaterialId;
25947
25948 // we might want to call this function with some ClippingGroup
25949 // object instead of the material, once it becomes feasible
25950 // (#8465, #8379)
25951 _clipping.setState(
25952 material.clippingPlanes, material.clipIntersection, material.clipShadows,
25953 camera, materialProperties, useCache );
25954
25955 }
25956
25957 }
25958
25959 if ( material.version === materialProperties.__version ) {
25960
25961 if ( materialProperties.program === undefined ) {
25962
25963 initMaterial( material, scene, object );
25964
25965 } else if ( material.fog && materialProperties.fog !== fog ) {
25966
25967 initMaterial( material, scene, object );
25968
25969 } else if ( materialProperties.environment !== environment ) {
25970
25971 initMaterial( material, scene, object );
25972
25973 } else if ( materialProperties.needsLights && ( materialProperties.lightsStateVersion !== lights.state.version ) ) {
25974
25975 initMaterial( material, scene, object );
25976
25977 } else if ( materialProperties.numClippingPlanes !== undefined &&
25978 ( materialProperties.numClippingPlanes !== _clipping.numPlanes ||
25979 materialProperties.numIntersection !== _clipping.numIntersection ) ) {
25980
25981 initMaterial( material, scene, object );
25982
25983 } else if ( materialProperties.outputEncoding !== encoding ) {
25984
25985 initMaterial( material, scene, object );
25986
25987 }
25988
25989 } else {
25990
25991 initMaterial( material, scene, object );
25992 materialProperties.__version = material.version;
25993
25994 }
25995
25996 var refreshProgram = false;
25997 var refreshMaterial = false;
25998 var refreshLights = false;
25999
26000 var program = materialProperties.program,
26001 p_uniforms = program.getUniforms(),
26002 m_uniforms = materialProperties.uniforms;
26003
26004 if ( state.useProgram( program.program ) ) {
26005
26006 refreshProgram = true;
26007 refreshMaterial = true;
26008 refreshLights = true;
26009
26010 }
26011
26012 if ( material.id !== _currentMaterialId ) {
26013
26014 _currentMaterialId = material.id;
26015
26016 refreshMaterial = true;
26017
26018 }
26019
26020 if ( refreshProgram || _currentCamera !== camera ) {
26021
26022 p_uniforms.setValue( _gl, 'projectionMatrix', camera.projectionMatrix );
26023
26024 if ( capabilities.logarithmicDepthBuffer ) {
26025
26026 p_uniforms.setValue( _gl, 'logDepthBufFC',
26027 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
26028
26029 }
26030
26031 if ( _currentCamera !== camera ) {
26032
26033 _currentCamera = camera;
26034
26035 // lighting uniforms depend on the camera so enforce an update
26036 // now, in case this material supports lights - or later, when
26037 // the next material that does gets activated:
26038
26039 refreshMaterial = true; // set to true on material change
26040 refreshLights = true; // remains set until update done
26041
26042 }
26043
26044 // load material specific uniforms
26045 // (shader material also gets them for the sake of genericity)
26046
26047 if ( material.isShaderMaterial ||
26048 material.isMeshPhongMaterial ||
26049 material.isMeshToonMaterial ||
26050 material.isMeshStandardMaterial ||
26051 material.envMap ) {
26052
26053 var uCamPos = p_uniforms.map.cameraPosition;
26054
26055 if ( uCamPos !== undefined ) {
26056
26057 uCamPos.setValue( _gl,
26058 _vector3.setFromMatrixPosition( camera.matrixWorld ) );
26059
26060 }
26061
26062 }
26063
26064 if ( material.isMeshPhongMaterial ||
26065 material.isMeshToonMaterial ||
26066 material.isMeshLambertMaterial ||
26067 material.isMeshBasicMaterial ||
26068 material.isMeshStandardMaterial ||
26069 material.isShaderMaterial ) {
26070
26071 p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true );
26072
26073 }
26074
26075 if ( material.isMeshPhongMaterial ||
26076 material.isMeshToonMaterial ||
26077 material.isMeshLambertMaterial ||
26078 material.isMeshBasicMaterial ||
26079 material.isMeshStandardMaterial ||
26080 material.isShaderMaterial ||
26081 material.isShadowMaterial ||
26082 material.skinning ) {
26083
26084 p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse );
26085
26086 }
26087
26088 }
26089
26090 // skinning uniforms must be set even if material didn't change
26091 // auto-setting of texture unit for bone texture must go before other textures
26092 // otherwise textures used for skinning can take over texture units reserved for other material textures
26093
26094 if ( material.skinning ) {
26095
26096 p_uniforms.setOptional( _gl, object, 'bindMatrix' );
26097 p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
26098
26099 var skeleton = object.skeleton;
26100
26101 if ( skeleton ) {
26102
26103 var bones = skeleton.bones;
26104
26105 if ( capabilities.floatVertexTextures ) {
26106
26107 if ( skeleton.boneTexture === undefined ) {
26108
26109 // layout (1 matrix = 4 pixels)
26110 // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
26111 // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
26112 // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
26113 // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
26114 // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
26115
26116
26117 var size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix
26118 size = MathUtils.ceilPowerOfTwo( size );
26119 size = Math.max( size, 4 );
26120
26121 var boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
26122 boneMatrices.set( skeleton.boneMatrices ); // copy current values
26123
26124 var boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );
26125
26126 skeleton.boneMatrices = boneMatrices;
26127 skeleton.boneTexture = boneTexture;
26128 skeleton.boneTextureSize = size;
26129
26130 }
26131
26132 p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );
26133 p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
26134
26135 } else {
26136
26137 p_uniforms.setOptional( _gl, skeleton, 'boneMatrices' );
26138
26139 }
26140
26141 }
26142
26143 }
26144
26145 if ( refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow ) {
26146
26147 materialProperties.receiveShadow = object.receiveShadow;
26148 p_uniforms.setValue( _gl, 'receiveShadow', object.receiveShadow );
26149
26150 }
26151
26152 if ( refreshMaterial ) {
26153
26154 p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
26155
26156 if ( materialProperties.needsLights ) {
26157
26158 // the current material requires lighting info
26159
26160 // note: all lighting uniforms are always set correctly
26161 // they simply reference the renderer's state for their
26162 // values
26163 //
26164 // use the current material's .needsUpdate flags to set
26165 // the GL state when required
26166
26167 markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
26168
26169 }
26170
26171 // refresh uniforms common to several materials
26172
26173 if ( fog && material.fog ) {
26174
26175 materials.refreshFogUniforms( m_uniforms, fog );
26176
26177 }
26178
26179 materials.refreshMaterialUniforms( m_uniforms, material, environment, _pixelRatio, _height );
26180
26181 // RectAreaLight Texture
26182 // TODO (mrdoob): Find a nicer implementation
26183
26184 if ( m_uniforms.ltc_1 !== undefined ) { m_uniforms.ltc_1.value = UniformsLib.LTC_1; }
26185 if ( m_uniforms.ltc_2 !== undefined ) { m_uniforms.ltc_2.value = UniformsLib.LTC_2; }
26186
26187 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
26188
26189 }
26190
26191 if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {
26192
26193 WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
26194 material.uniformsNeedUpdate = false;
26195
26196 }
26197
26198 if ( material.isSpriteMaterial ) {
26199
26200 p_uniforms.setValue( _gl, 'center', object.center );
26201
26202 }
26203
26204 // common matrices
26205
26206 p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
26207 p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
26208 p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
26209
26210 return program;
26211
26212 }
26213
26214 // If uniforms are marked as clean, they don't need to be loaded to the GPU.
26215
26216 function markUniformsLightsNeedsUpdate( uniforms, value ) {
26217
26218 uniforms.ambientLightColor.needsUpdate = value;
26219 uniforms.lightProbe.needsUpdate = value;
26220
26221 uniforms.directionalLights.needsUpdate = value;
26222 uniforms.directionalLightShadows.needsUpdate = value;
26223 uniforms.pointLights.needsUpdate = value;
26224 uniforms.pointLightShadows.needsUpdate = value;
26225 uniforms.spotLights.needsUpdate = value;
26226 uniforms.spotLightShadows.needsUpdate = value;
26227 uniforms.rectAreaLights.needsUpdate = value;
26228 uniforms.hemisphereLights.needsUpdate = value;
26229
26230 }
26231
26232 function materialNeedsLights( material ) {
26233
26234 return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial ||
26235 material.isMeshStandardMaterial || material.isShadowMaterial ||
26236 ( material.isShaderMaterial && material.lights === true );
26237
26238 }
26239
26240 //
26241 this.setFramebuffer = function ( value ) {
26242
26243 if ( _framebuffer !== value && _currentRenderTarget === null ) { _gl.bindFramebuffer( 36160, value ); }
26244
26245 _framebuffer = value;
26246
26247 };
26248
26249 this.getActiveCubeFace = function () {
26250
26251 return _currentActiveCubeFace;
26252
26253 };
26254
26255 this.getActiveMipmapLevel = function () {
26256
26257 return _currentActiveMipmapLevel;
26258
26259 };
26260
26261 this.getRenderTarget = function () {
26262
26263 return _currentRenderTarget;
26264
26265 };
26266
26267 this.setRenderTarget = function ( renderTarget, activeCubeFace, activeMipmapLevel ) {
26268
26269 _currentRenderTarget = renderTarget;
26270 _currentActiveCubeFace = activeCubeFace;
26271 _currentActiveMipmapLevel = activeMipmapLevel;
26272
26273 if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
26274
26275 textures.setupRenderTarget( renderTarget );
26276
26277 }
26278
26279 var framebuffer = _framebuffer;
26280 var isCube = false;
26281
26282 if ( renderTarget ) {
26283
26284 var _webglFramebuffer = properties.get( renderTarget ).__webglFramebuffer;
26285
26286 if ( renderTarget.isWebGLCubeRenderTarget ) {
26287
26288 framebuffer = _webglFramebuffer[ activeCubeFace || 0 ];
26289 isCube = true;
26290
26291 } else if ( renderTarget.isWebGLMultisampleRenderTarget ) {
26292
26293 framebuffer = properties.get( renderTarget ).__webglMultisampledFramebuffer;
26294
26295 } else {
26296
26297 framebuffer = _webglFramebuffer;
26298
26299 }
26300
26301 _currentViewport.copy( renderTarget.viewport );
26302 _currentScissor.copy( renderTarget.scissor );
26303 _currentScissorTest = renderTarget.scissorTest;
26304
26305 } else {
26306
26307 _currentViewport.copy( _viewport ).multiplyScalar( _pixelRatio ).floor();
26308 _currentScissor.copy( _scissor ).multiplyScalar( _pixelRatio ).floor();
26309 _currentScissorTest = _scissorTest;
26310
26311 }
26312
26313 if ( _currentFramebuffer !== framebuffer ) {
26314
26315 _gl.bindFramebuffer( 36160, framebuffer );
26316 _currentFramebuffer = framebuffer;
26317
26318 }
26319
26320 state.viewport( _currentViewport );
26321 state.scissor( _currentScissor );
26322 state.setScissorTest( _currentScissorTest );
26323
26324 if ( isCube ) {
26325
26326 var textureProperties = properties.get( renderTarget.texture );
26327 _gl.framebufferTexture2D( 36160, 36064, 34069 + ( activeCubeFace || 0 ), textureProperties.__webglTexture, activeMipmapLevel || 0 );
26328
26329 }
26330
26331 };
26332
26333 this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex ) {
26334
26335 if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
26336
26337 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
26338 return;
26339
26340 }
26341
26342 var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
26343
26344 if ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) {
26345
26346 framebuffer = framebuffer[ activeCubeFaceIndex ];
26347
26348 }
26349
26350 if ( framebuffer ) {
26351
26352 var restore = false;
26353
26354 if ( framebuffer !== _currentFramebuffer ) {
26355
26356 _gl.bindFramebuffer( 36160, framebuffer );
26357
26358 restore = true;
26359
26360 }
26361
26362 try {
26363
26364 var texture = renderTarget.texture;
26365 var textureFormat = texture.format;
26366 var textureType = texture.type;
26367
26368 if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== _gl.getParameter( 35739 ) ) {
26369
26370 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
26371 return;
26372
26373 }
26374
26375 if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( 35738 ) && // IE11, Edge and Chrome Mac < 52 (#9513)
26376 ! ( textureType === FloatType && ( capabilities.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
26377 ! ( textureType === HalfFloatType && ( capabilities.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {
26378
26379 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
26380 return;
26381
26382 }
26383
26384 if ( _gl.checkFramebufferStatus( 36160 ) === 36053 ) {
26385
26386 // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
26387
26388 if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {
26389
26390 _gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), buffer );
26391
26392 }
26393
26394 } else {
26395
26396 console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
26397
26398 }
26399
26400 } finally {
26401
26402 if ( restore ) {
26403
26404 _gl.bindFramebuffer( 36160, _currentFramebuffer );
26405
26406 }
26407
26408 }
26409
26410 }
26411
26412 };
26413
26414 this.copyFramebufferToTexture = function ( position, texture, level ) {
26415
26416 if ( level === undefined ) { level = 0; }
26417
26418 var levelScale = Math.pow( 2, - level );
26419 var width = Math.floor( texture.image.width * levelScale );
26420 var height = Math.floor( texture.image.height * levelScale );
26421 var glFormat = utils.convert( texture.format );
26422
26423 textures.setTexture2D( texture, 0 );
26424
26425 _gl.copyTexImage2D( 3553, level, glFormat, position.x, position.y, width, height, 0 );
26426
26427 state.unbindTexture();
26428
26429 };
26430
26431 this.copyTextureToTexture = function ( position, srcTexture, dstTexture, level ) {
26432
26433 if ( level === undefined ) { level = 0; }
26434
26435 var width = srcTexture.image.width;
26436 var height = srcTexture.image.height;
26437 var glFormat = utils.convert( dstTexture.format );
26438 var glType = utils.convert( dstTexture.type );
26439
26440 textures.setTexture2D( dstTexture, 0 );
26441
26442 // As another texture upload may have changed pixelStorei
26443 // parameters, make sure they are correct for the dstTexture
26444 _gl.pixelStorei( 37440, dstTexture.flipY );
26445 _gl.pixelStorei( 37441, dstTexture.premultiplyAlpha );
26446 _gl.pixelStorei( 3317, dstTexture.unpackAlignment );
26447
26448 if ( srcTexture.isDataTexture ) {
26449
26450 _gl.texSubImage2D( 3553, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data );
26451
26452 } else {
26453
26454 if ( srcTexture.isCompressedTexture ) {
26455
26456 _gl.compressedTexSubImage2D( 3553, level, position.x, position.y, srcTexture.mipmaps[ 0 ].width, srcTexture.mipmaps[ 0 ].height, glFormat, srcTexture.mipmaps[ 0 ].data );
26457
26458 } else {
26459
26460 _gl.texSubImage2D( 3553, level, position.x, position.y, glFormat, glType, srcTexture.image );
26461
26462 }
26463
26464 }
26465
26466 // Generate mipmaps only when copying level 0
26467 if ( level === 0 && dstTexture.generateMipmaps ) { _gl.generateMipmap( 3553 ); }
26468
26469 state.unbindTexture();
26470
26471 };
26472
26473 this.initTexture = function ( texture ) {
26474
26475 textures.setTexture2D( texture, 0 );
26476
26477 state.unbindTexture();
26478
26479 };
26480
26481 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
26482
26483 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); // eslint-disable-line no-undef
26484
26485 }
26486
26487 }
26488
26489 function WebGL1Renderer( parameters ) {
26490
26491 WebGLRenderer.call( this, parameters );
26492
26493 }
26494
26495 WebGL1Renderer.prototype = Object.assign( Object.create( WebGLRenderer.prototype ), {
26496
26497 constructor: WebGL1Renderer,
26498
26499 isWebGL1Renderer: true
26500
26501 } );
26502
26503 function FogExp2( color, density ) {
26504
26505 this.name = '';
26506
26507 this.color = new Color( color );
26508 this.density = ( density !== undefined ) ? density : 0.00025;
26509
26510 }
26511
26512 Object.assign( FogExp2.prototype, {
26513
26514 isFogExp2: true,
26515
26516 clone: function () {
26517
26518 return new FogExp2( this.color, this.density );
26519
26520 },
26521
26522 toJSON: function ( /* meta */ ) {
26523
26524 return {
26525 type: 'FogExp2',
26526 color: this.color.getHex(),
26527 density: this.density
26528 };
26529
26530 }
26531
26532 } );
26533
26534 function Fog( color, near, far ) {
26535
26536 this.name = '';
26537
26538 this.color = new Color( color );
26539
26540 this.near = ( near !== undefined ) ? near : 1;
26541 this.far = ( far !== undefined ) ? far : 1000;
26542
26543 }
26544
26545 Object.assign( Fog.prototype, {
26546
26547 isFog: true,
26548
26549 clone: function () {
26550
26551 return new Fog( this.color, this.near, this.far );
26552
26553 },
26554
26555 toJSON: function ( /* meta */ ) {
26556
26557 return {
26558 type: 'Fog',
26559 color: this.color.getHex(),
26560 near: this.near,
26561 far: this.far
26562 };
26563
26564 }
26565
26566 } );
26567
26568 function InterleavedBuffer( array, stride ) {
26569
26570 this.array = array;
26571 this.stride = stride;
26572 this.count = array !== undefined ? array.length / stride : 0;
26573
26574 this.usage = StaticDrawUsage;
26575 this.updateRange = { offset: 0, count: - 1 };
26576
26577 this.version = 0;
26578
26579 this.uuid = MathUtils.generateUUID();
26580
26581 }
26582
26583 Object.defineProperty( InterleavedBuffer.prototype, 'needsUpdate', {
26584
26585 set: function ( value ) {
26586
26587 if ( value === true ) { this.version ++; }
26588
26589 }
26590
26591 } );
26592
26593 Object.assign( InterleavedBuffer.prototype, {
26594
26595 isInterleavedBuffer: true,
26596
26597 onUploadCallback: function () {},
26598
26599 setUsage: function ( value ) {
26600
26601 this.usage = value;
26602
26603 return this;
26604
26605 },
26606
26607 copy: function ( source ) {
26608
26609 this.array = new source.array.constructor( source.array );
26610 this.count = source.count;
26611 this.stride = source.stride;
26612 this.usage = source.usage;
26613
26614 return this;
26615
26616 },
26617
26618 copyAt: function ( index1, attribute, index2 ) {
26619
26620 index1 *= this.stride;
26621 index2 *= attribute.stride;
26622
26623 for ( var i = 0, l = this.stride; i < l; i ++ ) {
26624
26625 this.array[ index1 + i ] = attribute.array[ index2 + i ];
26626
26627 }
26628
26629 return this;
26630
26631 },
26632
26633 set: function ( value, offset ) {
26634
26635 if ( offset === undefined ) { offset = 0; }
26636
26637 this.array.set( value, offset );
26638
26639 return this;
26640
26641 },
26642
26643 clone: function ( data ) {
26644
26645 if ( data.arrayBuffers === undefined ) {
26646
26647 data.arrayBuffers = {};
26648
26649 }
26650
26651 if ( this.array.buffer._uuid === undefined ) {
26652
26653 this.array.buffer._uuid = MathUtils.generateUUID();
26654
26655 }
26656
26657 if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
26658
26659 data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer;
26660
26661 }
26662
26663 var array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] );
26664
26665 var ib = new InterleavedBuffer( array, this.stride );
26666 ib.setUsage( this.usage );
26667
26668 return ib;
26669
26670 },
26671
26672 onUpload: function ( callback ) {
26673
26674 this.onUploadCallback = callback;
26675
26676 return this;
26677
26678 },
26679
26680 toJSON: function ( data ) {
26681
26682 if ( data.arrayBuffers === undefined ) {
26683
26684 data.arrayBuffers = {};
26685
26686 }
26687
26688 // generate UUID for array buffer if necessary
26689
26690 if ( this.array.buffer._uuid === undefined ) {
26691
26692 this.array.buffer._uuid = MathUtils.generateUUID();
26693
26694 }
26695
26696 if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
26697
26698 data.arrayBuffers[ this.array.buffer._uuid ] = Array.prototype.slice.call( new Uint32Array( this.array.buffer ) );
26699
26700 }
26701
26702 //
26703
26704 return {
26705 uuid: this.uuid,
26706 buffer: this.array.buffer._uuid,
26707 type: this.array.constructor.name,
26708 stride: this.stride
26709 };
26710
26711 }
26712
26713 } );
26714
26715 var _vector$6 = new Vector3();
26716
26717 function InterleavedBufferAttribute( interleavedBuffer, itemSize, offset, normalized ) {
26718
26719 this.name = '';
26720
26721 this.data = interleavedBuffer;
26722 this.itemSize = itemSize;
26723 this.offset = offset;
26724
26725 this.normalized = normalized === true;
26726
26727 }
26728
26729 Object.defineProperties( InterleavedBufferAttribute.prototype, {
26730
26731 count: {
26732
26733 get: function () {
26734
26735 return this.data.count;
26736
26737 }
26738
26739 },
26740
26741 array: {
26742
26743 get: function () {
26744
26745 return this.data.array;
26746
26747 }
26748
26749 },
26750
26751 needsUpdate: {
26752
26753 set: function ( value ) {
26754
26755 this.data.needsUpdate = value;
26756
26757 }
26758
26759 }
26760
26761 } );
26762
26763 Object.assign( InterleavedBufferAttribute.prototype, {
26764
26765 isInterleavedBufferAttribute: true,
26766
26767 applyMatrix4: function ( m ) {
26768
26769 for ( var i = 0, l = this.data.count; i < l; i ++ ) {
26770
26771 _vector$6.x = this.getX( i );
26772 _vector$6.y = this.getY( i );
26773 _vector$6.z = this.getZ( i );
26774
26775 _vector$6.applyMatrix4( m );
26776
26777 this.setXYZ( i, _vector$6.x, _vector$6.y, _vector$6.z );
26778
26779 }
26780
26781 return this;
26782
26783 },
26784
26785 setX: function ( index, x ) {
26786
26787 this.data.array[ index * this.data.stride + this.offset ] = x;
26788
26789 return this;
26790
26791 },
26792
26793 setY: function ( index, y ) {
26794
26795 this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
26796
26797 return this;
26798
26799 },
26800
26801 setZ: function ( index, z ) {
26802
26803 this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
26804
26805 return this;
26806
26807 },
26808
26809 setW: function ( index, w ) {
26810
26811 this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
26812
26813 return this;
26814
26815 },
26816
26817 getX: function ( index ) {
26818
26819 return this.data.array[ index * this.data.stride + this.offset ];
26820
26821 },
26822
26823 getY: function ( index ) {
26824
26825 return this.data.array[ index * this.data.stride + this.offset + 1 ];
26826
26827 },
26828
26829 getZ: function ( index ) {
26830
26831 return this.data.array[ index * this.data.stride + this.offset + 2 ];
26832
26833 },
26834
26835 getW: function ( index ) {
26836
26837 return this.data.array[ index * this.data.stride + this.offset + 3 ];
26838
26839 },
26840
26841 setXY: function ( index, x, y ) {
26842
26843 index = index * this.data.stride + this.offset;
26844
26845 this.data.array[ index + 0 ] = x;
26846 this.data.array[ index + 1 ] = y;
26847
26848 return this;
26849
26850 },
26851
26852 setXYZ: function ( index, x, y, z ) {
26853
26854 index = index * this.data.stride + this.offset;
26855
26856 this.data.array[ index + 0 ] = x;
26857 this.data.array[ index + 1 ] = y;
26858 this.data.array[ index + 2 ] = z;
26859
26860 return this;
26861
26862 },
26863
26864 setXYZW: function ( index, x, y, z, w ) {
26865
26866 index = index * this.data.stride + this.offset;
26867
26868 this.data.array[ index + 0 ] = x;
26869 this.data.array[ index + 1 ] = y;
26870 this.data.array[ index + 2 ] = z;
26871 this.data.array[ index + 3 ] = w;
26872
26873 return this;
26874
26875 },
26876
26877 clone: function ( data ) {
26878
26879 if ( data === undefined ) {
26880
26881 console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interlaved buffer attribute will deinterleave buffer data.' );
26882
26883 var array = [];
26884
26885 for ( var i = 0; i < this.count; i ++ ) {
26886
26887 var index = i * this.data.stride + this.offset;
26888
26889 for ( var j = 0; j < this.itemSize; j ++ ) {
26890
26891 array.push( this.data.array[ index + j ] );
26892
26893 }
26894
26895 }
26896
26897 return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );
26898
26899 } else {
26900
26901 if ( data.interleavedBuffers === undefined ) {
26902
26903 data.interleavedBuffers = {};
26904
26905 }
26906
26907 if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
26908
26909 data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data );
26910
26911 }
26912
26913 return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized );
26914
26915 }
26916
26917 },
26918
26919 toJSON: function ( data ) {
26920
26921 if ( data === undefined ) {
26922
26923 console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interlaved buffer attribute will deinterleave buffer data.' );
26924
26925 var array = [];
26926
26927 for ( var i = 0; i < this.count; i ++ ) {
26928
26929 var index = i * this.data.stride + this.offset;
26930
26931 for ( var j = 0; j < this.itemSize; j ++ ) {
26932
26933 array.push( this.data.array[ index + j ] );
26934
26935 }
26936
26937 }
26938
26939 // deinterleave data and save it as an ordinary buffer attribute for now
26940
26941 return {
26942 itemSize: this.itemSize,
26943 type: this.array.constructor.name,
26944 array: array,
26945 normalized: this.normalized
26946 };
26947
26948 } else {
26949
26950 // save as true interlaved attribtue
26951
26952 if ( data.interleavedBuffers === undefined ) {
26953
26954 data.interleavedBuffers = {};
26955
26956 }
26957
26958 if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
26959
26960 data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data );
26961
26962 }
26963
26964 return {
26965 isInterleavedBufferAttribute: true,
26966 itemSize: this.itemSize,
26967 data: this.data.uuid,
26968 offset: this.offset,
26969 normalized: this.normalized
26970 };
26971
26972 }
26973
26974 }
26975
26976 } );
26977
26978 /**
26979 * parameters = {
26980 * color: <hex>,
26981 * map: new THREE.Texture( <Image> ),
26982 * alphaMap: new THREE.Texture( <Image> ),
26983 * rotation: <float>,
26984 * sizeAttenuation: <bool>
26985 * }
26986 */
26987
26988 function SpriteMaterial( parameters ) {
26989
26990 Material.call( this );
26991
26992 this.type = 'SpriteMaterial';
26993
26994 this.color = new Color( 0xffffff );
26995
26996 this.map = null;
26997
26998 this.alphaMap = null;
26999
27000 this.rotation = 0;
27001
27002 this.sizeAttenuation = true;
27003
27004 this.transparent = true;
27005
27006 this.setValues( parameters );
27007
27008 }
27009
27010 SpriteMaterial.prototype = Object.create( Material.prototype );
27011 SpriteMaterial.prototype.constructor = SpriteMaterial;
27012 SpriteMaterial.prototype.isSpriteMaterial = true;
27013
27014 SpriteMaterial.prototype.copy = function ( source ) {
27015
27016 Material.prototype.copy.call( this, source );
27017
27018 this.color.copy( source.color );
27019
27020 this.map = source.map;
27021
27022 this.alphaMap = source.alphaMap;
27023
27024 this.rotation = source.rotation;
27025
27026 this.sizeAttenuation = source.sizeAttenuation;
27027
27028 return this;
27029
27030 };
27031
27032 var _geometry;
27033
27034 var _intersectPoint = new Vector3();
27035 var _worldScale = new Vector3();
27036 var _mvPosition = new Vector3();
27037
27038 var _alignedPosition = new Vector2();
27039 var _rotatedPosition = new Vector2();
27040 var _viewWorldMatrix = new Matrix4();
27041
27042 var _vA$1 = new Vector3();
27043 var _vB$1 = new Vector3();
27044 var _vC$1 = new Vector3();
27045
27046 var _uvA$1 = new Vector2();
27047 var _uvB$1 = new Vector2();
27048 var _uvC$1 = new Vector2();
27049
27050 function Sprite( material ) {
27051
27052 Object3D.call( this );
27053
27054 this.type = 'Sprite';
27055
27056 if ( _geometry === undefined ) {
27057
27058 _geometry = new BufferGeometry();
27059
27060 var float32Array = new Float32Array( [
27061 - 0.5, - 0.5, 0, 0, 0,
27062 0.5, - 0.5, 0, 1, 0,
27063 0.5, 0.5, 0, 1, 1,
27064 - 0.5, 0.5, 0, 0, 1
27065 ] );
27066
27067 var interleavedBuffer = new InterleavedBuffer( float32Array, 5 );
27068
27069 _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] );
27070 _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) );
27071 _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) );
27072
27073 }
27074
27075 this.geometry = _geometry;
27076 this.material = ( material !== undefined ) ? material : new SpriteMaterial();
27077
27078 this.center = new Vector2( 0.5, 0.5 );
27079
27080 }
27081
27082 Sprite.prototype = Object.assign( Object.create( Object3D.prototype ), {
27083
27084 constructor: Sprite,
27085
27086 isSprite: true,
27087
27088 raycast: function ( raycaster, intersects ) {
27089
27090 if ( raycaster.camera === null ) {
27091
27092 console.error( 'THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' );
27093
27094 }
27095
27096 _worldScale.setFromMatrixScale( this.matrixWorld );
27097
27098 _viewWorldMatrix.copy( raycaster.camera.matrixWorld );
27099 this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld );
27100
27101 _mvPosition.setFromMatrixPosition( this.modelViewMatrix );
27102
27103 if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) {
27104
27105 _worldScale.multiplyScalar( - _mvPosition.z );
27106
27107 }
27108
27109 var rotation = this.material.rotation;
27110 var sin, cos;
27111
27112 if ( rotation !== 0 ) {
27113
27114 cos = Math.cos( rotation );
27115 sin = Math.sin( rotation );
27116
27117 }
27118
27119 var center = this.center;
27120
27121 transformVertex( _vA$1.set( - 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27122 transformVertex( _vB$1.set( 0.5, - 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27123 transformVertex( _vC$1.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27124
27125 _uvA$1.set( 0, 0 );
27126 _uvB$1.set( 1, 0 );
27127 _uvC$1.set( 1, 1 );
27128
27129 // check first triangle
27130 var intersect = raycaster.ray.intersectTriangle( _vA$1, _vB$1, _vC$1, false, _intersectPoint );
27131
27132 if ( intersect === null ) {
27133
27134 // check second triangle
27135 transformVertex( _vB$1.set( - 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos );
27136 _uvB$1.set( 0, 1 );
27137
27138 intersect = raycaster.ray.intersectTriangle( _vA$1, _vC$1, _vB$1, false, _intersectPoint );
27139 if ( intersect === null ) {
27140
27141 return;
27142
27143 }
27144
27145 }
27146
27147 var distance = raycaster.ray.origin.distanceTo( _intersectPoint );
27148
27149 if ( distance < raycaster.near || distance > raycaster.far ) { return; }
27150
27151 intersects.push( {
27152
27153 distance: distance,
27154 point: _intersectPoint.clone(),
27155 uv: Triangle.getUV( _intersectPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2() ),
27156 face: null,
27157 object: this
27158
27159 } );
27160
27161 },
27162
27163 copy: function ( source ) {
27164
27165 Object3D.prototype.copy.call( this, source );
27166
27167 if ( source.center !== undefined ) { this.center.copy( source.center ); }
27168
27169 this.material = source.material;
27170
27171 return this;
27172
27173 }
27174
27175 } );
27176
27177 function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) {
27178
27179 // compute position in camera space
27180 _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale );
27181
27182 // to check if rotation is not zero
27183 if ( sin !== undefined ) {
27184
27185 _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y );
27186 _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y );
27187
27188 } else {
27189
27190 _rotatedPosition.copy( _alignedPosition );
27191
27192 }
27193
27194
27195 vertexPosition.copy( mvPosition );
27196 vertexPosition.x += _rotatedPosition.x;
27197 vertexPosition.y += _rotatedPosition.y;
27198
27199 // transform to world space
27200 vertexPosition.applyMatrix4( _viewWorldMatrix );
27201
27202 }
27203
27204 var _v1$4 = new Vector3();
27205 var _v2$2 = new Vector3();
27206
27207 function LOD() {
27208
27209 Object3D.call( this );
27210
27211 this._currentLevel = 0;
27212
27213 this.type = 'LOD';
27214
27215 Object.defineProperties( this, {
27216 levels: {
27217 enumerable: true,
27218 value: []
27219 }
27220 } );
27221
27222 this.autoUpdate = true;
27223
27224 }
27225
27226 LOD.prototype = Object.assign( Object.create( Object3D.prototype ), {
27227
27228 constructor: LOD,
27229
27230 isLOD: true,
27231
27232 copy: function ( source ) {
27233
27234 Object3D.prototype.copy.call( this, source, false );
27235
27236 var levels = source.levels;
27237
27238 for ( var i = 0, l = levels.length; i < l; i ++ ) {
27239
27240 var level = levels[ i ];
27241
27242 this.addLevel( level.object.clone(), level.distance );
27243
27244 }
27245
27246 this.autoUpdate = source.autoUpdate;
27247
27248 return this;
27249
27250 },
27251
27252 addLevel: function ( object, distance ) {
27253
27254 if ( distance === undefined ) { distance = 0; }
27255
27256 distance = Math.abs( distance );
27257
27258 var levels = this.levels;
27259
27260 var l;
27261
27262 for ( l = 0; l < levels.length; l ++ ) {
27263
27264 if ( distance < levels[ l ].distance ) {
27265
27266 break;
27267
27268 }
27269
27270 }
27271
27272 levels.splice( l, 0, { distance: distance, object: object } );
27273
27274 this.add( object );
27275
27276 return this;
27277
27278 },
27279
27280 getCurrentLevel: function () {
27281
27282 return this._currentLevel;
27283
27284 },
27285
27286 getObjectForDistance: function ( distance ) {
27287
27288 var levels = this.levels;
27289
27290 if ( levels.length > 0 ) {
27291
27292 var i, l;
27293
27294 for ( i = 1, l = levels.length; i < l; i ++ ) {
27295
27296 if ( distance < levels[ i ].distance ) {
27297
27298 break;
27299
27300 }
27301
27302 }
27303
27304 return levels[ i - 1 ].object;
27305
27306 }
27307
27308 return null;
27309
27310 },
27311
27312 raycast: function ( raycaster, intersects ) {
27313
27314 var levels = this.levels;
27315
27316 if ( levels.length > 0 ) {
27317
27318 _v1$4.setFromMatrixPosition( this.matrixWorld );
27319
27320 var distance = raycaster.ray.origin.distanceTo( _v1$4 );
27321
27322 this.getObjectForDistance( distance ).raycast( raycaster, intersects );
27323
27324 }
27325
27326 },
27327
27328 update: function ( camera ) {
27329
27330 var levels = this.levels;
27331
27332 if ( levels.length > 1 ) {
27333
27334 _v1$4.setFromMatrixPosition( camera.matrixWorld );
27335 _v2$2.setFromMatrixPosition( this.matrixWorld );
27336
27337 var distance = _v1$4.distanceTo( _v2$2 ) / camera.zoom;
27338
27339 levels[ 0 ].object.visible = true;
27340
27341 var i, l;
27342
27343 for ( i = 1, l = levels.length; i < l; i ++ ) {
27344
27345 if ( distance >= levels[ i ].distance ) {
27346
27347 levels[ i - 1 ].object.visible = false;
27348 levels[ i ].object.visible = true;
27349
27350 } else {
27351
27352 break;
27353
27354 }
27355
27356 }
27357
27358 this._currentLevel = i - 1;
27359
27360 for ( ; i < l; i ++ ) {
27361
27362 levels[ i ].object.visible = false;
27363
27364 }
27365
27366 }
27367
27368 },
27369
27370 toJSON: function ( meta ) {
27371
27372 var data = Object3D.prototype.toJSON.call( this, meta );
27373
27374 if ( this.autoUpdate === false ) { data.object.autoUpdate = false; }
27375
27376 data.object.levels = [];
27377
27378 var levels = this.levels;
27379
27380 for ( var i = 0, l = levels.length; i < l; i ++ ) {
27381
27382 var level = levels[ i ];
27383
27384 data.object.levels.push( {
27385 object: level.object.uuid,
27386 distance: level.distance
27387 } );
27388
27389 }
27390
27391 return data;
27392
27393 }
27394
27395 } );
27396
27397 function SkinnedMesh( geometry, material ) {
27398
27399 if ( geometry && geometry.isGeometry ) {
27400
27401 console.error( 'THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.' );
27402
27403 }
27404
27405 Mesh.call( this, geometry, material );
27406
27407 this.type = 'SkinnedMesh';
27408
27409 this.bindMode = 'attached';
27410 this.bindMatrix = new Matrix4();
27411 this.bindMatrixInverse = new Matrix4();
27412
27413 }
27414
27415 SkinnedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
27416
27417 constructor: SkinnedMesh,
27418
27419 isSkinnedMesh: true,
27420
27421 copy: function ( source ) {
27422
27423 Mesh.prototype.copy.call( this, source );
27424
27425 this.bindMode = source.bindMode;
27426 this.bindMatrix.copy( source.bindMatrix );
27427 this.bindMatrixInverse.copy( source.bindMatrixInverse );
27428
27429 this.skeleton = source.skeleton;
27430
27431 return this;
27432
27433 },
27434
27435 bind: function ( skeleton, bindMatrix ) {
27436
27437 this.skeleton = skeleton;
27438
27439 if ( bindMatrix === undefined ) {
27440
27441 this.updateMatrixWorld( true );
27442
27443 this.skeleton.calculateInverses();
27444
27445 bindMatrix = this.matrixWorld;
27446
27447 }
27448
27449 this.bindMatrix.copy( bindMatrix );
27450 this.bindMatrixInverse.getInverse( bindMatrix );
27451
27452 },
27453
27454 pose: function () {
27455
27456 this.skeleton.pose();
27457
27458 },
27459
27460 normalizeSkinWeights: function () {
27461
27462 var vector = new Vector4();
27463
27464 var skinWeight = this.geometry.attributes.skinWeight;
27465
27466 for ( var i = 0, l = skinWeight.count; i < l; i ++ ) {
27467
27468 vector.x = skinWeight.getX( i );
27469 vector.y = skinWeight.getY( i );
27470 vector.z = skinWeight.getZ( i );
27471 vector.w = skinWeight.getW( i );
27472
27473 var scale = 1.0 / vector.manhattanLength();
27474
27475 if ( scale !== Infinity ) {
27476
27477 vector.multiplyScalar( scale );
27478
27479 } else {
27480
27481 vector.set( 1, 0, 0, 0 ); // do something reasonable
27482
27483 }
27484
27485 skinWeight.setXYZW( i, vector.x, vector.y, vector.z, vector.w );
27486
27487 }
27488
27489 },
27490
27491 updateMatrixWorld: function ( force ) {
27492
27493 Mesh.prototype.updateMatrixWorld.call( this, force );
27494
27495 if ( this.bindMode === 'attached' ) {
27496
27497 this.bindMatrixInverse.getInverse( this.matrixWorld );
27498
27499 } else if ( this.bindMode === 'detached' ) {
27500
27501 this.bindMatrixInverse.getInverse( this.bindMatrix );
27502
27503 } else {
27504
27505 console.warn( 'THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode );
27506
27507 }
27508
27509 },
27510
27511 boneTransform: ( function () {
27512
27513 var basePosition = new Vector3();
27514
27515 var skinIndex = new Vector4();
27516 var skinWeight = new Vector4();
27517
27518 var vector = new Vector3();
27519 var matrix = new Matrix4();
27520
27521 return function ( index, target ) {
27522
27523 var skeleton = this.skeleton;
27524 var geometry = this.geometry;
27525
27526 skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
27527 skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
27528
27529 basePosition.fromBufferAttribute( geometry.attributes.position, index ).applyMatrix4( this.bindMatrix );
27530
27531 target.set( 0, 0, 0 );
27532
27533 for ( var i = 0; i < 4; i ++ ) {
27534
27535 var weight = skinWeight.getComponent( i );
27536
27537 if ( weight !== 0 ) {
27538
27539 var boneIndex = skinIndex.getComponent( i );
27540
27541 matrix.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
27542
27543 target.addScaledVector( vector.copy( basePosition ).applyMatrix4( matrix ), weight );
27544
27545 }
27546
27547 }
27548
27549 return target.applyMatrix4( this.bindMatrixInverse );
27550
27551 };
27552
27553 }() )
27554
27555 } );
27556
27557 var _offsetMatrix = new Matrix4();
27558 var _identityMatrix = new Matrix4();
27559
27560 function Skeleton( bones, boneInverses ) {
27561
27562 // copy the bone array
27563
27564 bones = bones || [];
27565
27566 this.bones = bones.slice( 0 );
27567 this.boneMatrices = new Float32Array( this.bones.length * 16 );
27568
27569 this.frame = - 1;
27570
27571 // use the supplied bone inverses or calculate the inverses
27572
27573 if ( boneInverses === undefined ) {
27574
27575 this.calculateInverses();
27576
27577 } else {
27578
27579 if ( this.bones.length === boneInverses.length ) {
27580
27581 this.boneInverses = boneInverses.slice( 0 );
27582
27583 } else {
27584
27585 console.warn( 'THREE.Skeleton boneInverses is the wrong length.' );
27586
27587 this.boneInverses = [];
27588
27589 for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27590
27591 this.boneInverses.push( new Matrix4() );
27592
27593 }
27594
27595 }
27596
27597 }
27598
27599 }
27600
27601 Object.assign( Skeleton.prototype, {
27602
27603 calculateInverses: function () {
27604
27605 this.boneInverses = [];
27606
27607 for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27608
27609 var inverse = new Matrix4();
27610
27611 if ( this.bones[ i ] ) {
27612
27613 inverse.getInverse( this.bones[ i ].matrixWorld );
27614
27615 }
27616
27617 this.boneInverses.push( inverse );
27618
27619 }
27620
27621 },
27622
27623 pose: function () {
27624
27625 // recover the bind-time world matrices
27626
27627 for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27628
27629 var bone = this.bones[ i ];
27630
27631 if ( bone ) {
27632
27633 bone.matrixWorld.getInverse( this.boneInverses[ i ] );
27634
27635 }
27636
27637 }
27638
27639 // compute the local matrices, positions, rotations and scales
27640
27641 for ( var i$1 = 0, il$1 = this.bones.length; i$1 < il$1; i$1 ++ ) {
27642
27643 var bone$1 = this.bones[ i$1 ];
27644
27645 if ( bone$1 ) {
27646
27647 if ( bone$1.parent && bone$1.parent.isBone ) {
27648
27649 bone$1.matrix.getInverse( bone$1.parent.matrixWorld );
27650 bone$1.matrix.multiply( bone$1.matrixWorld );
27651
27652 } else {
27653
27654 bone$1.matrix.copy( bone$1.matrixWorld );
27655
27656 }
27657
27658 bone$1.matrix.decompose( bone$1.position, bone$1.quaternion, bone$1.scale );
27659
27660 }
27661
27662 }
27663
27664 },
27665
27666 update: function () {
27667
27668 var bones = this.bones;
27669 var boneInverses = this.boneInverses;
27670 var boneMatrices = this.boneMatrices;
27671 var boneTexture = this.boneTexture;
27672
27673 // flatten bone matrices to array
27674
27675 for ( var i = 0, il = bones.length; i < il; i ++ ) {
27676
27677 // compute the offset between the current and the original transform
27678
27679 var matrix = bones[ i ] ? bones[ i ].matrixWorld : _identityMatrix;
27680
27681 _offsetMatrix.multiplyMatrices( matrix, boneInverses[ i ] );
27682 _offsetMatrix.toArray( boneMatrices, i * 16 );
27683
27684 }
27685
27686 if ( boneTexture !== undefined ) {
27687
27688 boneTexture.needsUpdate = true;
27689
27690 }
27691
27692 },
27693
27694 clone: function () {
27695
27696 return new Skeleton( this.bones, this.boneInverses );
27697
27698 },
27699
27700 getBoneByName: function ( name ) {
27701
27702 for ( var i = 0, il = this.bones.length; i < il; i ++ ) {
27703
27704 var bone = this.bones[ i ];
27705
27706 if ( bone.name === name ) {
27707
27708 return bone;
27709
27710 }
27711
27712 }
27713
27714 return undefined;
27715
27716 },
27717
27718 dispose: function ( ) {
27719
27720 if ( this.boneTexture ) {
27721
27722 this.boneTexture.dispose();
27723
27724 this.boneTexture = undefined;
27725
27726 }
27727
27728 }
27729
27730 } );
27731
27732 function Bone() {
27733
27734 Object3D.call( this );
27735
27736 this.type = 'Bone';
27737
27738 }
27739
27740 Bone.prototype = Object.assign( Object.create( Object3D.prototype ), {
27741
27742 constructor: Bone,
27743
27744 isBone: true
27745
27746 } );
27747
27748 var _instanceLocalMatrix = new Matrix4();
27749 var _instanceWorldMatrix = new Matrix4();
27750
27751 var _instanceIntersects = [];
27752
27753 var _mesh = new Mesh();
27754
27755 function InstancedMesh( geometry, material, count ) {
27756
27757 Mesh.call( this, geometry, material );
27758
27759 this.instanceMatrix = new BufferAttribute( new Float32Array( count * 16 ), 16 );
27760
27761 this.count = count;
27762
27763 this.frustumCulled = false;
27764
27765 }
27766
27767 InstancedMesh.prototype = Object.assign( Object.create( Mesh.prototype ), {
27768
27769 constructor: InstancedMesh,
27770
27771 isInstancedMesh: true,
27772
27773 copy: function ( source ) {
27774
27775 Mesh.prototype.copy.call( this, source );
27776
27777 this.instanceMatrix.copy( source.instanceMatrix );
27778 this.count = source.count;
27779
27780 return this;
27781
27782 },
27783
27784 getMatrixAt: function ( index, matrix ) {
27785
27786 matrix.fromArray( this.instanceMatrix.array, index * 16 );
27787
27788 },
27789
27790 raycast: function ( raycaster, intersects ) {
27791
27792 var matrixWorld = this.matrixWorld;
27793 var raycastTimes = this.count;
27794
27795 _mesh.geometry = this.geometry;
27796 _mesh.material = this.material;
27797
27798 if ( _mesh.material === undefined ) { return; }
27799
27800 for ( var instanceId = 0; instanceId < raycastTimes; instanceId ++ ) {
27801
27802 // calculate the world matrix for each instance
27803
27804 this.getMatrixAt( instanceId, _instanceLocalMatrix );
27805
27806 _instanceWorldMatrix.multiplyMatrices( matrixWorld, _instanceLocalMatrix );
27807
27808 // the mesh represents this single instance
27809
27810 _mesh.matrixWorld = _instanceWorldMatrix;
27811
27812 _mesh.raycast( raycaster, _instanceIntersects );
27813
27814 // process the result of raycast
27815
27816 for ( var i = 0, l = _instanceIntersects.length; i < l; i ++ ) {
27817
27818 var intersect = _instanceIntersects[ i ];
27819 intersect.instanceId = instanceId;
27820 intersect.object = this;
27821 intersects.push( intersect );
27822
27823 }
27824
27825 _instanceIntersects.length = 0;
27826
27827 }
27828
27829 },
27830
27831 setMatrixAt: function ( index, matrix ) {
27832
27833 matrix.toArray( this.instanceMatrix.array, index * 16 );
27834
27835 },
27836
27837 updateMorphTargets: function () {
27838
27839 }
27840
27841 } );
27842
27843 /**
27844 * parameters = {
27845 * color: <hex>,
27846 * opacity: <float>,
27847 *
27848 * linewidth: <float>,
27849 * linecap: "round",
27850 * linejoin: "round"
27851 * }
27852 */
27853
27854 function LineBasicMaterial( parameters ) {
27855
27856 Material.call( this );
27857
27858 this.type = 'LineBasicMaterial';
27859
27860 this.color = new Color( 0xffffff );
27861
27862 this.linewidth = 1;
27863 this.linecap = 'round';
27864 this.linejoin = 'round';
27865
27866 this.morphTargets = false;
27867
27868 this.setValues( parameters );
27869
27870 }
27871
27872 LineBasicMaterial.prototype = Object.create( Material.prototype );
27873 LineBasicMaterial.prototype.constructor = LineBasicMaterial;
27874
27875 LineBasicMaterial.prototype.isLineBasicMaterial = true;
27876
27877 LineBasicMaterial.prototype.copy = function ( source ) {
27878
27879 Material.prototype.copy.call( this, source );
27880
27881 this.color.copy( source.color );
27882
27883 this.linewidth = source.linewidth;
27884 this.linecap = source.linecap;
27885 this.linejoin = source.linejoin;
27886
27887 this.morphTargets = source.morphTargets;
27888
27889 return this;
27890
27891 };
27892
27893 var _start = new Vector3();
27894 var _end = new Vector3();
27895 var _inverseMatrix$1 = new Matrix4();
27896 var _ray$1 = new Ray();
27897 var _sphere$2 = new Sphere();
27898
27899 function Line( geometry, material, mode ) {
27900
27901 if ( mode === 1 ) {
27902
27903 console.error( 'THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.' );
27904
27905 }
27906
27907 Object3D.call( this );
27908
27909 this.type = 'Line';
27910
27911 this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
27912 this.material = material !== undefined ? material : new LineBasicMaterial();
27913
27914 this.updateMorphTargets();
27915
27916 }
27917
27918 Line.prototype = Object.assign( Object.create( Object3D.prototype ), {
27919
27920 constructor: Line,
27921
27922 isLine: true,
27923
27924 copy: function ( source ) {
27925
27926 Object3D.prototype.copy.call( this, source );
27927
27928 this.material = source.material;
27929 this.geometry = source.geometry;
27930
27931 return this;
27932
27933 },
27934
27935 computeLineDistances: function () {
27936
27937 var geometry = this.geometry;
27938
27939 if ( geometry.isBufferGeometry ) {
27940
27941 // we assume non-indexed geometry
27942
27943 if ( geometry.index === null ) {
27944
27945 var positionAttribute = geometry.attributes.position;
27946 var lineDistances = [ 0 ];
27947
27948 for ( var i = 1, l = positionAttribute.count; i < l; i ++ ) {
27949
27950 _start.fromBufferAttribute( positionAttribute, i - 1 );
27951 _end.fromBufferAttribute( positionAttribute, i );
27952
27953 lineDistances[ i ] = lineDistances[ i - 1 ];
27954 lineDistances[ i ] += _start.distanceTo( _end );
27955
27956 }
27957
27958 geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
27959
27960 } else {
27961
27962 console.warn( 'THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
27963
27964 }
27965
27966 } else if ( geometry.isGeometry ) {
27967
27968 var vertices = geometry.vertices;
27969 var lineDistances$1 = geometry.lineDistances;
27970
27971 lineDistances$1[ 0 ] = 0;
27972
27973 for ( var i$1 = 1, l$1 = vertices.length; i$1 < l$1; i$1 ++ ) {
27974
27975 lineDistances$1[ i$1 ] = lineDistances$1[ i$1 - 1 ];
27976 lineDistances$1[ i$1 ] += vertices[ i$1 - 1 ].distanceTo( vertices[ i$1 ] );
27977
27978 }
27979
27980 }
27981
27982 return this;
27983
27984 },
27985
27986 raycast: function ( raycaster, intersects ) {
27987
27988 var geometry = this.geometry;
27989 var matrixWorld = this.matrixWorld;
27990 var threshold = raycaster.params.Line.threshold;
27991
27992 // Checking boundingSphere distance to ray
27993
27994 if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
27995
27996 _sphere$2.copy( geometry.boundingSphere );
27997 _sphere$2.applyMatrix4( matrixWorld );
27998 _sphere$2.radius += threshold;
27999
28000 if ( raycaster.ray.intersectsSphere( _sphere$2 ) === false ) { return; }
28001
28002 //
28003
28004 _inverseMatrix$1.getInverse( matrixWorld );
28005 _ray$1.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$1 );
28006
28007 var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
28008 var localThresholdSq = localThreshold * localThreshold;
28009
28010 var vStart = new Vector3();
28011 var vEnd = new Vector3();
28012 var interSegment = new Vector3();
28013 var interRay = new Vector3();
28014 var step = ( this && this.isLineSegments ) ? 2 : 1;
28015
28016 if ( geometry.isBufferGeometry ) {
28017
28018 var index = geometry.index;
28019 var attributes = geometry.attributes;
28020 var positions = attributes.position.array;
28021
28022 if ( index !== null ) {
28023
28024 var indices = index.array;
28025
28026 for ( var i = 0, l = indices.length - 1; i < l; i += step ) {
28027
28028 var a = indices[ i ];
28029 var b = indices[ i + 1 ];
28030
28031 vStart.fromArray( positions, a * 3 );
28032 vEnd.fromArray( positions, b * 3 );
28033
28034 var distSq = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
28035
28036 if ( distSq > localThresholdSq ) { continue; }
28037
28038 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
28039
28040 var distance = raycaster.ray.origin.distanceTo( interRay );
28041
28042 if ( distance < raycaster.near || distance > raycaster.far ) { continue; }
28043
28044 intersects.push( {
28045
28046 distance: distance,
28047 // What do we want? intersection point on the ray or on the segment??
28048 // point: raycaster.ray.at( distance ),
28049 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
28050 index: i,
28051 face: null,
28052 faceIndex: null,
28053 object: this
28054
28055 } );
28056
28057 }
28058
28059 } else {
28060
28061 for ( var i$1 = 0, l$1 = positions.length / 3 - 1; i$1 < l$1; i$1 += step ) {
28062
28063 vStart.fromArray( positions, 3 * i$1 );
28064 vEnd.fromArray( positions, 3 * i$1 + 3 );
28065
28066 var distSq$1 = _ray$1.distanceSqToSegment( vStart, vEnd, interRay, interSegment );
28067
28068 if ( distSq$1 > localThresholdSq ) { continue; }
28069
28070 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
28071
28072 var distance$1 = raycaster.ray.origin.distanceTo( interRay );
28073
28074 if ( distance$1 < raycaster.near || distance$1 > raycaster.far ) { continue; }
28075
28076 intersects.push( {
28077
28078 distance: distance$1,
28079 // What do we want? intersection point on the ray or on the segment??
28080 // point: raycaster.ray.at( distance ),
28081 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
28082 index: i$1,
28083 face: null,
28084 faceIndex: null,
28085 object: this
28086
28087 } );
28088
28089 }
28090
28091 }
28092
28093 } else if ( geometry.isGeometry ) {
28094
28095 var vertices = geometry.vertices;
28096 var nbVertices = vertices.length;
28097
28098 for ( var i$2 = 0; i$2 < nbVertices - 1; i$2 += step ) {
28099
28100 var distSq$2 = _ray$1.distanceSqToSegment( vertices[ i$2 ], vertices[ i$2 + 1 ], interRay, interSegment );
28101
28102 if ( distSq$2 > localThresholdSq ) { continue; }
28103
28104 interRay.applyMatrix4( this.matrixWorld ); //Move back to world space for distance calculation
28105
28106 var distance$2 = raycaster.ray.origin.distanceTo( interRay );
28107
28108 if ( distance$2 < raycaster.near || distance$2 > raycaster.far ) { continue; }
28109
28110 intersects.push( {
28111
28112 distance: distance$2,
28113 // What do we want? intersection point on the ray or on the segment??
28114 // point: raycaster.ray.at( distance ),
28115 point: interSegment.clone().applyMatrix4( this.matrixWorld ),
28116 index: i$2,
28117 face: null,
28118 faceIndex: null,
28119 object: this
28120
28121 } );
28122
28123 }
28124
28125 }
28126
28127 },
28128
28129 updateMorphTargets: function () {
28130
28131 var geometry = this.geometry;
28132
28133 if ( geometry.isBufferGeometry ) {
28134
28135 var morphAttributes = geometry.morphAttributes;
28136 var keys = Object.keys( morphAttributes );
28137
28138 if ( keys.length > 0 ) {
28139
28140 var morphAttribute = morphAttributes[ keys[ 0 ] ];
28141
28142 if ( morphAttribute !== undefined ) {
28143
28144 this.morphTargetInfluences = [];
28145 this.morphTargetDictionary = {};
28146
28147 for ( var m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
28148
28149 var name = morphAttribute[ m ].name || String( m );
28150
28151 this.morphTargetInfluences.push( 0 );
28152 this.morphTargetDictionary[ name ] = m;
28153
28154 }
28155
28156 }
28157
28158 }
28159
28160 } else {
28161
28162 var morphTargets = geometry.morphTargets;
28163
28164 if ( morphTargets !== undefined && morphTargets.length > 0 ) {
28165
28166 console.error( 'THREE.Line.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
28167
28168 }
28169
28170 }
28171
28172 }
28173
28174 } );
28175
28176 var _start$1 = new Vector3();
28177 var _end$1 = new Vector3();
28178
28179 function LineSegments( geometry, material ) {
28180
28181 Line.call( this, geometry, material );
28182
28183 this.type = 'LineSegments';
28184
28185 }
28186
28187 LineSegments.prototype = Object.assign( Object.create( Line.prototype ), {
28188
28189 constructor: LineSegments,
28190
28191 isLineSegments: true,
28192
28193 computeLineDistances: function () {
28194
28195 var geometry = this.geometry;
28196
28197 if ( geometry.isBufferGeometry ) {
28198
28199 // we assume non-indexed geometry
28200
28201 if ( geometry.index === null ) {
28202
28203 var positionAttribute = geometry.attributes.position;
28204 var lineDistances = [];
28205
28206 for ( var i = 0, l = positionAttribute.count; i < l; i += 2 ) {
28207
28208 _start$1.fromBufferAttribute( positionAttribute, i );
28209 _end$1.fromBufferAttribute( positionAttribute, i + 1 );
28210
28211 lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
28212 lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
28213
28214 }
28215
28216 geometry.setAttribute( 'lineDistance', new Float32BufferAttribute( lineDistances, 1 ) );
28217
28218 } else {
28219
28220 console.warn( 'THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.' );
28221
28222 }
28223
28224 } else if ( geometry.isGeometry ) {
28225
28226 var vertices = geometry.vertices;
28227 var lineDistances$1 = geometry.lineDistances;
28228
28229 for ( var i$1 = 0, l$1 = vertices.length; i$1 < l$1; i$1 += 2 ) {
28230
28231 _start$1.copy( vertices[ i$1 ] );
28232 _end$1.copy( vertices[ i$1 + 1 ] );
28233
28234 lineDistances$1[ i$1 ] = ( i$1 === 0 ) ? 0 : lineDistances$1[ i$1 - 1 ];
28235 lineDistances$1[ i$1 + 1 ] = lineDistances$1[ i$1 ] + _start$1.distanceTo( _end$1 );
28236
28237 }
28238
28239 }
28240
28241 return this;
28242
28243 }
28244
28245 } );
28246
28247 function LineLoop( geometry, material ) {
28248
28249 Line.call( this, geometry, material );
28250
28251 this.type = 'LineLoop';
28252
28253 }
28254
28255 LineLoop.prototype = Object.assign( Object.create( Line.prototype ), {
28256
28257 constructor: LineLoop,
28258
28259 isLineLoop: true,
28260
28261 } );
28262
28263 /**
28264 * parameters = {
28265 * color: <hex>,
28266 * opacity: <float>,
28267 * map: new THREE.Texture( <Image> ),
28268 * alphaMap: new THREE.Texture( <Image> ),
28269 *
28270 * size: <float>,
28271 * sizeAttenuation: <bool>
28272 *
28273 * morphTargets: <bool>
28274 * }
28275 */
28276
28277 function PointsMaterial( parameters ) {
28278
28279 Material.call( this );
28280
28281 this.type = 'PointsMaterial';
28282
28283 this.color = new Color( 0xffffff );
28284
28285 this.map = null;
28286
28287 this.alphaMap = null;
28288
28289 this.size = 1;
28290 this.sizeAttenuation = true;
28291
28292 this.morphTargets = false;
28293
28294 this.setValues( parameters );
28295
28296 }
28297
28298 PointsMaterial.prototype = Object.create( Material.prototype );
28299 PointsMaterial.prototype.constructor = PointsMaterial;
28300
28301 PointsMaterial.prototype.isPointsMaterial = true;
28302
28303 PointsMaterial.prototype.copy = function ( source ) {
28304
28305 Material.prototype.copy.call( this, source );
28306
28307 this.color.copy( source.color );
28308
28309 this.map = source.map;
28310
28311 this.alphaMap = source.alphaMap;
28312
28313 this.size = source.size;
28314 this.sizeAttenuation = source.sizeAttenuation;
28315
28316 this.morphTargets = source.morphTargets;
28317
28318 return this;
28319
28320 };
28321
28322 var _inverseMatrix$2 = new Matrix4();
28323 var _ray$2 = new Ray();
28324 var _sphere$3 = new Sphere();
28325 var _position$1 = new Vector3();
28326
28327 function Points( geometry, material ) {
28328
28329 Object3D.call( this );
28330
28331 this.type = 'Points';
28332
28333 this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
28334 this.material = material !== undefined ? material : new PointsMaterial();
28335
28336 this.updateMorphTargets();
28337
28338 }
28339
28340 Points.prototype = Object.assign( Object.create( Object3D.prototype ), {
28341
28342 constructor: Points,
28343
28344 isPoints: true,
28345
28346 copy: function ( source ) {
28347
28348 Object3D.prototype.copy.call( this, source );
28349
28350 this.material = source.material;
28351 this.geometry = source.geometry;
28352
28353 return this;
28354
28355 },
28356
28357 raycast: function ( raycaster, intersects ) {
28358
28359 var geometry = this.geometry;
28360 var matrixWorld = this.matrixWorld;
28361 var threshold = raycaster.params.Points.threshold;
28362
28363 // Checking boundingSphere distance to ray
28364
28365 if ( geometry.boundingSphere === null ) { geometry.computeBoundingSphere(); }
28366
28367 _sphere$3.copy( geometry.boundingSphere );
28368 _sphere$3.applyMatrix4( matrixWorld );
28369 _sphere$3.radius += threshold;
28370
28371 if ( raycaster.ray.intersectsSphere( _sphere$3 ) === false ) { return; }
28372
28373 //
28374
28375 _inverseMatrix$2.getInverse( matrixWorld );
28376 _ray$2.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$2 );
28377
28378 var localThreshold = threshold / ( ( this.scale.x + this.scale.y + this.scale.z ) / 3 );
28379 var localThresholdSq = localThreshold * localThreshold;
28380
28381 if ( geometry.isBufferGeometry ) {
28382
28383 var index = geometry.index;
28384 var attributes = geometry.attributes;
28385 var positions = attributes.position.array;
28386
28387 if ( index !== null ) {
28388
28389 var indices = index.array;
28390
28391 for ( var i = 0, il = indices.length; i < il; i ++ ) {
28392
28393 var a = indices[ i ];
28394
28395 _position$1.fromArray( positions, a * 3 );
28396
28397 testPoint( _position$1, a, localThresholdSq, matrixWorld, raycaster, intersects, this );
28398
28399 }
28400
28401 } else {
28402
28403 for ( var i$1 = 0, l = positions.length / 3; i$1 < l; i$1 ++ ) {
28404
28405 _position$1.fromArray( positions, i$1 * 3 );
28406
28407 testPoint( _position$1, i$1, localThresholdSq, matrixWorld, raycaster, intersects, this );
28408
28409 }
28410
28411 }
28412
28413 } else {
28414
28415 var vertices = geometry.vertices;
28416
28417 for ( var i$2 = 0, l$1 = vertices.length; i$2 < l$1; i$2 ++ ) {
28418
28419 testPoint( vertices[ i$2 ], i$2, localThresholdSq, matrixWorld, raycaster, intersects, this );
28420
28421 }
28422
28423 }
28424
28425 },
28426
28427 updateMorphTargets: function () {
28428
28429 var geometry = this.geometry;
28430
28431 if ( geometry.isBufferGeometry ) {
28432
28433 var morphAttributes = geometry.morphAttributes;
28434 var keys = Object.keys( morphAttributes );
28435
28436 if ( keys.length > 0 ) {
28437
28438 var morphAttribute = morphAttributes[ keys[ 0 ] ];
28439
28440 if ( morphAttribute !== undefined ) {
28441
28442 this.morphTargetInfluences = [];
28443 this.morphTargetDictionary = {};
28444
28445 for ( var m = 0, ml = morphAttribute.length; m < ml; m ++ ) {
28446
28447 var name = morphAttribute[ m ].name || String( m );
28448
28449 this.morphTargetInfluences.push( 0 );
28450 this.morphTargetDictionary[ name ] = m;
28451
28452 }
28453
28454 }
28455
28456 }
28457
28458 } else {
28459
28460 var morphTargets = geometry.morphTargets;
28461
28462 if ( morphTargets !== undefined && morphTargets.length > 0 ) {
28463
28464 console.error( 'THREE.Points.updateMorphTargets() does not support THREE.Geometry. Use THREE.BufferGeometry instead.' );
28465
28466 }
28467
28468 }
28469
28470 }
28471
28472 } );
28473
28474 function testPoint( point, index, localThresholdSq, matrixWorld, raycaster, intersects, object ) {
28475
28476 var rayPointDistanceSq = _ray$2.distanceSqToPoint( point );
28477
28478 if ( rayPointDistanceSq < localThresholdSq ) {
28479
28480 var intersectPoint = new Vector3();
28481
28482 _ray$2.closestPointToPoint( point, intersectPoint );
28483 intersectPoint.applyMatrix4( matrixWorld );
28484
28485 var distance = raycaster.ray.origin.distanceTo( intersectPoint );
28486
28487 if ( distance < raycaster.near || distance > raycaster.far ) { return; }
28488
28489 intersects.push( {
28490
28491 distance: distance,
28492 distanceToRay: Math.sqrt( rayPointDistanceSq ),
28493 point: intersectPoint,
28494 index: index,
28495 face: null,
28496 object: object
28497
28498 } );
28499
28500 }
28501
28502 }
28503
28504 function VideoTexture( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
28505
28506 Texture.call( this, video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
28507
28508 this.format = format !== undefined ? format : RGBFormat;
28509
28510 this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
28511 this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
28512
28513 this.generateMipmaps = false;
28514
28515 var scope = this;
28516
28517 function updateVideo() {
28518
28519 scope.needsUpdate = true;
28520 video.requestVideoFrameCallback( updateVideo );
28521
28522 }
28523
28524 if ( 'requestVideoFrameCallback' in video ) {
28525
28526 video.requestVideoFrameCallback( updateVideo );
28527
28528 }
28529
28530 }
28531
28532 VideoTexture.prototype = Object.assign( Object.create( Texture.prototype ), {
28533
28534 constructor: VideoTexture,
28535
28536 isVideoTexture: true,
28537
28538 update: function () {
28539
28540 var video = this.image;
28541 var hasVideoFrameCallback = 'requestVideoFrameCallback' in video;
28542
28543 if ( hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA ) {
28544
28545 this.needsUpdate = true;
28546
28547 }
28548
28549 }
28550
28551 } );
28552
28553 function CompressedTexture( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding ) {
28554
28555 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding );
28556
28557 this.image = { width: width, height: height };
28558 this.mipmaps = mipmaps;
28559
28560 // no flipping for cube textures
28561 // (also flipping doesn't work for compressed textures )
28562
28563 this.flipY = false;
28564
28565 // can't generate mipmaps for compressed textures
28566 // mips must be embedded in DDS files
28567
28568 this.generateMipmaps = false;
28569
28570 }
28571
28572 CompressedTexture.prototype = Object.create( Texture.prototype );
28573 CompressedTexture.prototype.constructor = CompressedTexture;
28574
28575 CompressedTexture.prototype.isCompressedTexture = true;
28576
28577 function CanvasTexture( canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
28578
28579 Texture.call( this, canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
28580
28581 this.needsUpdate = true;
28582
28583 }
28584
28585 CanvasTexture.prototype = Object.create( Texture.prototype );
28586 CanvasTexture.prototype.constructor = CanvasTexture;
28587 CanvasTexture.prototype.isCanvasTexture = true;
28588
28589 function DepthTexture( width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format ) {
28590
28591 format = format !== undefined ? format : DepthFormat;
28592
28593 if ( format !== DepthFormat && format !== DepthStencilFormat ) {
28594
28595 throw new Error( 'DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat' );
28596
28597 }
28598
28599 if ( type === undefined && format === DepthFormat ) { type = UnsignedShortType; }
28600 if ( type === undefined && format === DepthStencilFormat ) { type = UnsignedInt248Type; }
28601
28602 Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
28603
28604 this.image = { width: width, height: height };
28605
28606 this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
28607 this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
28608
28609 this.flipY = false;
28610 this.generateMipmaps = false;
28611
28612 }
28613
28614 DepthTexture.prototype = Object.create( Texture.prototype );
28615 DepthTexture.prototype.constructor = DepthTexture;
28616 DepthTexture.prototype.isDepthTexture = true;
28617
28618 function WireframeGeometry( geometry ) {
28619
28620 BufferGeometry.call( this );
28621
28622 this.type = 'WireframeGeometry';
28623
28624 // buffer
28625
28626 var vertices = [];
28627
28628 // helper variables
28629
28630 var edge = [ 0, 0 ], edges = {};
28631 var keys = [ 'a', 'b', 'c' ];
28632
28633 // different logic for Geometry and BufferGeometry
28634
28635 if ( geometry && geometry.isGeometry ) {
28636
28637 // create a data structure that contains all edges without duplicates
28638
28639 var faces = geometry.faces;
28640
28641 for ( var i = 0, l = faces.length; i < l; i ++ ) {
28642
28643 var face = faces[ i ];
28644
28645 for ( var j = 0; j < 3; j ++ ) {
28646
28647 var edge1 = face[ keys[ j ] ];
28648 var edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
28649 edge[ 0 ] = Math.min( edge1, edge2 ); // sorting prevents duplicates
28650 edge[ 1 ] = Math.max( edge1, edge2 );
28651
28652 var key = edge[ 0 ] + ',' + edge[ 1 ];
28653
28654 if ( edges[ key ] === undefined ) {
28655
28656 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
28657
28658 }
28659
28660 }
28661
28662 }
28663
28664 // generate vertices
28665
28666 for ( var key$1 in edges ) {
28667
28668 var e = edges[ key$1 ];
28669
28670 var vertex = geometry.vertices[ e.index1 ];
28671 vertices.push( vertex.x, vertex.y, vertex.z );
28672
28673 vertex = geometry.vertices[ e.index2 ];
28674 vertices.push( vertex.x, vertex.y, vertex.z );
28675
28676 }
28677
28678 } else if ( geometry && geometry.isBufferGeometry ) {
28679
28680 var vertex$1 = new Vector3();
28681
28682 if ( geometry.index !== null ) {
28683
28684 // indexed BufferGeometry
28685
28686 var position = geometry.attributes.position;
28687 var indices = geometry.index;
28688 var groups = geometry.groups;
28689
28690 if ( groups.length === 0 ) {
28691
28692 groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
28693
28694 }
28695
28696 // create a data structure that contains all eges without duplicates
28697
28698 for ( var o = 0, ol = groups.length; o < ol; ++ o ) {
28699
28700 var group = groups[ o ];
28701
28702 var start = group.start;
28703 var count = group.count;
28704
28705 for ( var i$1 = start, l$1 = ( start + count ); i$1 < l$1; i$1 += 3 ) {
28706
28707 for ( var j$1 = 0; j$1 < 3; j$1 ++ ) {
28708
28709 var edge1$1 = indices.getX( i$1 + j$1 );
28710 var edge2$1 = indices.getX( i$1 + ( j$1 + 1 ) % 3 );
28711 edge[ 0 ] = Math.min( edge1$1, edge2$1 ); // sorting prevents duplicates
28712 edge[ 1 ] = Math.max( edge1$1, edge2$1 );
28713
28714 var key$2 = edge[ 0 ] + ',' + edge[ 1 ];
28715
28716 if ( edges[ key$2 ] === undefined ) {
28717
28718 edges[ key$2 ] = { index1: edge[ 0 ], index2: edge[ 1 ] };
28719
28720 }
28721
28722 }
28723
28724 }
28725
28726 }
28727
28728 // generate vertices
28729
28730 for ( var key$3 in edges ) {
28731
28732 var e$1 = edges[ key$3 ];
28733
28734 vertex$1.fromBufferAttribute( position, e$1.index1 );
28735 vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
28736
28737 vertex$1.fromBufferAttribute( position, e$1.index2 );
28738 vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
28739
28740 }
28741
28742 } else {
28743
28744 // non-indexed BufferGeometry
28745
28746 var position$1 = geometry.attributes.position;
28747
28748 for ( var i$2 = 0, l$2 = ( position$1.count / 3 ); i$2 < l$2; i$2 ++ ) {
28749
28750 for ( var j$2 = 0; j$2 < 3; j$2 ++ ) {
28751
28752 // three edges per triangle, an edge is represented as (index1, index2)
28753 // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
28754
28755 var index1 = 3 * i$2 + j$2;
28756 vertex$1.fromBufferAttribute( position$1, index1 );
28757 vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
28758
28759 var index2 = 3 * i$2 + ( ( j$2 + 1 ) % 3 );
28760 vertex$1.fromBufferAttribute( position$1, index2 );
28761 vertices.push( vertex$1.x, vertex$1.y, vertex$1.z );
28762
28763 }
28764
28765 }
28766
28767 }
28768
28769 }
28770
28771 // build geometry
28772
28773 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
28774
28775 }
28776
28777 WireframeGeometry.prototype = Object.create( BufferGeometry.prototype );
28778 WireframeGeometry.prototype.constructor = WireframeGeometry;
28779
28780 /**
28781 * Parametric Surfaces Geometry
28782 * based on the brilliant article by @prideout https://prideout.net/blog/old/blog/index.html@p=44.html
28783 */
28784
28785 // ParametricGeometry
28786
28787 function ParametricGeometry( func, slices, stacks ) {
28788
28789 Geometry.call( this );
28790
28791 this.type = 'ParametricGeometry';
28792
28793 this.parameters = {
28794 func: func,
28795 slices: slices,
28796 stacks: stacks
28797 };
28798
28799 this.fromBufferGeometry( new ParametricBufferGeometry( func, slices, stacks ) );
28800 this.mergeVertices();
28801
28802 }
28803
28804 ParametricGeometry.prototype = Object.create( Geometry.prototype );
28805 ParametricGeometry.prototype.constructor = ParametricGeometry;
28806
28807 // ParametricBufferGeometry
28808
28809 function ParametricBufferGeometry( func, slices, stacks ) {
28810
28811 BufferGeometry.call( this );
28812
28813 this.type = 'ParametricBufferGeometry';
28814
28815 this.parameters = {
28816 func: func,
28817 slices: slices,
28818 stacks: stacks
28819 };
28820
28821 // buffers
28822
28823 var indices = [];
28824 var vertices = [];
28825 var normals = [];
28826 var uvs = [];
28827
28828 var EPS = 0.00001;
28829
28830 var normal = new Vector3();
28831
28832 var p0 = new Vector3(), p1 = new Vector3();
28833 var pu = new Vector3(), pv = new Vector3();
28834
28835 if ( func.length < 3 ) {
28836
28837 console.error( 'THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.' );
28838
28839 }
28840
28841 // generate vertices, normals and uvs
28842
28843 var sliceCount = slices + 1;
28844
28845 for ( var i = 0; i <= stacks; i ++ ) {
28846
28847 var v = i / stacks;
28848
28849 for ( var j = 0; j <= slices; j ++ ) {
28850
28851 var u = j / slices;
28852
28853 // vertex
28854
28855 func( u, v, p0 );
28856 vertices.push( p0.x, p0.y, p0.z );
28857
28858 // normal
28859
28860 // approximate tangent vectors via finite differences
28861
28862 if ( u - EPS >= 0 ) {
28863
28864 func( u - EPS, v, p1 );
28865 pu.subVectors( p0, p1 );
28866
28867 } else {
28868
28869 func( u + EPS, v, p1 );
28870 pu.subVectors( p1, p0 );
28871
28872 }
28873
28874 if ( v - EPS >= 0 ) {
28875
28876 func( u, v - EPS, p1 );
28877 pv.subVectors( p0, p1 );
28878
28879 } else {
28880
28881 func( u, v + EPS, p1 );
28882 pv.subVectors( p1, p0 );
28883
28884 }
28885
28886 // cross product of tangent vectors returns surface normal
28887
28888 normal.crossVectors( pu, pv ).normalize();
28889 normals.push( normal.x, normal.y, normal.z );
28890
28891 // uv
28892
28893 uvs.push( u, v );
28894
28895 }
28896
28897 }
28898
28899 // generate indices
28900
28901 for ( var i$1 = 0; i$1 < stacks; i$1 ++ ) {
28902
28903 for ( var j$1 = 0; j$1 < slices; j$1 ++ ) {
28904
28905 var a = i$1 * sliceCount + j$1;
28906 var b = i$1 * sliceCount + j$1 + 1;
28907 var c = ( i$1 + 1 ) * sliceCount + j$1 + 1;
28908 var d = ( i$1 + 1 ) * sliceCount + j$1;
28909
28910 // faces one and two
28911
28912 indices.push( a, b, d );
28913 indices.push( b, c, d );
28914
28915 }
28916
28917 }
28918
28919 // build geometry
28920
28921 this.setIndex( indices );
28922 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
28923 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
28924 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
28925
28926 }
28927
28928 ParametricBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
28929 ParametricBufferGeometry.prototype.constructor = ParametricBufferGeometry;
28930
28931 // PolyhedronGeometry
28932
28933 function PolyhedronGeometry( vertices, indices, radius, detail ) {
28934
28935 Geometry.call( this );
28936
28937 this.type = 'PolyhedronGeometry';
28938
28939 this.parameters = {
28940 vertices: vertices,
28941 indices: indices,
28942 radius: radius,
28943 detail: detail
28944 };
28945
28946 this.fromBufferGeometry( new PolyhedronBufferGeometry( vertices, indices, radius, detail ) );
28947 this.mergeVertices();
28948
28949 }
28950
28951 PolyhedronGeometry.prototype = Object.create( Geometry.prototype );
28952 PolyhedronGeometry.prototype.constructor = PolyhedronGeometry;
28953
28954 // PolyhedronBufferGeometry
28955
28956 function PolyhedronBufferGeometry( vertices, indices, radius, detail ) {
28957
28958 BufferGeometry.call( this );
28959
28960 this.type = 'PolyhedronBufferGeometry';
28961
28962 this.parameters = {
28963 vertices: vertices,
28964 indices: indices,
28965 radius: radius,
28966 detail: detail
28967 };
28968
28969 radius = radius || 1;
28970 detail = detail || 0;
28971
28972 // default buffer data
28973
28974 var vertexBuffer = [];
28975 var uvBuffer = [];
28976
28977 // the subdivision creates the vertex buffer data
28978
28979 subdivide( detail );
28980
28981 // all vertices should lie on a conceptual sphere with a given radius
28982
28983 applyRadius( radius );
28984
28985 // finally, create the uv data
28986
28987 generateUVs();
28988
28989 // build non-indexed geometry
28990
28991 this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );
28992 this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );
28993 this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );
28994
28995 if ( detail === 0 ) {
28996
28997 this.computeVertexNormals(); // flat normals
28998
28999 } else {
29000
29001 this.normalizeNormals(); // smooth normals
29002
29003 }
29004
29005 // helper functions
29006
29007 function subdivide( detail ) {
29008
29009 var a = new Vector3();
29010 var b = new Vector3();
29011 var c = new Vector3();
29012
29013 // iterate over all faces and apply a subdivison with the given detail value
29014
29015 for ( var i = 0; i < indices.length; i += 3 ) {
29016
29017 // get the vertices of the face
29018
29019 getVertexByIndex( indices[ i + 0 ], a );
29020 getVertexByIndex( indices[ i + 1 ], b );
29021 getVertexByIndex( indices[ i + 2 ], c );
29022
29023 // perform subdivision
29024
29025 subdivideFace( a, b, c, detail );
29026
29027 }
29028
29029 }
29030
29031 function subdivideFace( a, b, c, detail ) {
29032
29033 var cols = Math.pow( 2, detail );
29034
29035 // we use this multidimensional array as a data structure for creating the subdivision
29036
29037 var v = [];
29038
29039 // construct all of the vertices for this subdivision
29040
29041 for ( var i = 0; i <= cols; i ++ ) {
29042
29043 v[ i ] = [];
29044
29045 var aj = a.clone().lerp( c, i / cols );
29046 var bj = b.clone().lerp( c, i / cols );
29047
29048 var rows = cols - i;
29049
29050 for ( var j = 0; j <= rows; j ++ ) {
29051
29052 if ( j === 0 && i === cols ) {
29053
29054 v[ i ][ j ] = aj;
29055
29056 } else {
29057
29058 v[ i ][ j ] = aj.clone().lerp( bj, j / rows );
29059
29060 }
29061
29062 }
29063
29064 }
29065
29066 // construct all of the faces
29067
29068 for ( var i$1 = 0; i$1 < cols; i$1 ++ ) {
29069
29070 for ( var j$1 = 0; j$1 < 2 * ( cols - i$1 ) - 1; j$1 ++ ) {
29071
29072 var k = Math.floor( j$1 / 2 );
29073
29074 if ( j$1 % 2 === 0 ) {
29075
29076 pushVertex( v[ i$1 ][ k + 1 ] );
29077 pushVertex( v[ i$1 + 1 ][ k ] );
29078 pushVertex( v[ i$1 ][ k ] );
29079
29080 } else {
29081
29082 pushVertex( v[ i$1 ][ k + 1 ] );
29083 pushVertex( v[ i$1 + 1 ][ k + 1 ] );
29084 pushVertex( v[ i$1 + 1 ][ k ] );
29085
29086 }
29087
29088 }
29089
29090 }
29091
29092 }
29093
29094 function applyRadius( radius ) {
29095
29096 var vertex = new Vector3();
29097
29098 // iterate over the entire buffer and apply the radius to each vertex
29099
29100 for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
29101
29102 vertex.x = vertexBuffer[ i + 0 ];
29103 vertex.y = vertexBuffer[ i + 1 ];
29104 vertex.z = vertexBuffer[ i + 2 ];
29105
29106 vertex.normalize().multiplyScalar( radius );
29107
29108 vertexBuffer[ i + 0 ] = vertex.x;
29109 vertexBuffer[ i + 1 ] = vertex.y;
29110 vertexBuffer[ i + 2 ] = vertex.z;
29111
29112 }
29113
29114 }
29115
29116 function generateUVs() {
29117
29118 var vertex = new Vector3();
29119
29120 for ( var i = 0; i < vertexBuffer.length; i += 3 ) {
29121
29122 vertex.x = vertexBuffer[ i + 0 ];
29123 vertex.y = vertexBuffer[ i + 1 ];
29124 vertex.z = vertexBuffer[ i + 2 ];
29125
29126 var u = azimuth( vertex ) / 2 / Math.PI + 0.5;
29127 var v = inclination( vertex ) / Math.PI + 0.5;
29128 uvBuffer.push( u, 1 - v );
29129
29130 }
29131
29132 correctUVs();
29133
29134 correctSeam();
29135
29136 }
29137
29138 function correctSeam() {
29139
29140 // handle case when face straddles the seam, see #3269
29141
29142 for ( var i = 0; i < uvBuffer.length; i += 6 ) {
29143
29144 // uv data of a single face
29145
29146 var x0 = uvBuffer[ i + 0 ];
29147 var x1 = uvBuffer[ i + 2 ];
29148 var x2 = uvBuffer[ i + 4 ];
29149
29150 var max = Math.max( x0, x1, x2 );
29151 var min = Math.min( x0, x1, x2 );
29152
29153 // 0.9 is somewhat arbitrary
29154
29155 if ( max > 0.9 && min < 0.1 ) {
29156
29157 if ( x0 < 0.2 ) { uvBuffer[ i + 0 ] += 1; }
29158 if ( x1 < 0.2 ) { uvBuffer[ i + 2 ] += 1; }
29159 if ( x2 < 0.2 ) { uvBuffer[ i + 4 ] += 1; }
29160
29161 }
29162
29163 }
29164
29165 }
29166
29167 function pushVertex( vertex ) {
29168
29169 vertexBuffer.push( vertex.x, vertex.y, vertex.z );
29170
29171 }
29172
29173 function getVertexByIndex( index, vertex ) {
29174
29175 var stride = index * 3;
29176
29177 vertex.x = vertices[ stride + 0 ];
29178 vertex.y = vertices[ stride + 1 ];
29179 vertex.z = vertices[ stride + 2 ];
29180
29181 }
29182
29183 function correctUVs() {
29184
29185 var a = new Vector3();
29186 var b = new Vector3();
29187 var c = new Vector3();
29188
29189 var centroid = new Vector3();
29190
29191 var uvA = new Vector2();
29192 var uvB = new Vector2();
29193 var uvC = new Vector2();
29194
29195 for ( var i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {
29196
29197 a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );
29198 b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );
29199 c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );
29200
29201 uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );
29202 uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );
29203 uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );
29204
29205 centroid.copy( a ).add( b ).add( c ).divideScalar( 3 );
29206
29207 var azi = azimuth( centroid );
29208
29209 correctUV( uvA, j + 0, a, azi );
29210 correctUV( uvB, j + 2, b, azi );
29211 correctUV( uvC, j + 4, c, azi );
29212
29213 }
29214
29215 }
29216
29217 function correctUV( uv, stride, vector, azimuth ) {
29218
29219 if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {
29220
29221 uvBuffer[ stride ] = uv.x - 1;
29222
29223 }
29224
29225 if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {
29226
29227 uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;
29228
29229 }
29230
29231 }
29232
29233 // Angle around the Y axis, counter-clockwise when looking from above.
29234
29235 function azimuth( vector ) {
29236
29237 return Math.atan2( vector.z, - vector.x );
29238
29239 }
29240
29241
29242 // Angle above the XZ plane.
29243
29244 function inclination( vector ) {
29245
29246 return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
29247
29248 }
29249
29250 }
29251
29252 PolyhedronBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
29253 PolyhedronBufferGeometry.prototype.constructor = PolyhedronBufferGeometry;
29254
29255 // TetrahedronGeometry
29256
29257 function TetrahedronGeometry( radius, detail ) {
29258
29259 Geometry.call( this );
29260
29261 this.type = 'TetrahedronGeometry';
29262
29263 this.parameters = {
29264 radius: radius,
29265 detail: detail
29266 };
29267
29268 this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
29269 this.mergeVertices();
29270
29271 }
29272
29273 TetrahedronGeometry.prototype = Object.create( Geometry.prototype );
29274 TetrahedronGeometry.prototype.constructor = TetrahedronGeometry;
29275
29276 // TetrahedronBufferGeometry
29277
29278 function TetrahedronBufferGeometry( radius, detail ) {
29279
29280 var vertices = [
29281 1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1
29282 ];
29283
29284 var indices = [
29285 2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1
29286 ];
29287
29288 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29289
29290 this.type = 'TetrahedronBufferGeometry';
29291
29292 this.parameters = {
29293 radius: radius,
29294 detail: detail
29295 };
29296
29297 }
29298
29299 TetrahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29300 TetrahedronBufferGeometry.prototype.constructor = TetrahedronBufferGeometry;
29301
29302 // OctahedronGeometry
29303
29304 function OctahedronGeometry( radius, detail ) {
29305
29306 Geometry.call( this );
29307
29308 this.type = 'OctahedronGeometry';
29309
29310 this.parameters = {
29311 radius: radius,
29312 detail: detail
29313 };
29314
29315 this.fromBufferGeometry( new OctahedronBufferGeometry( radius, detail ) );
29316 this.mergeVertices();
29317
29318 }
29319
29320 OctahedronGeometry.prototype = Object.create( Geometry.prototype );
29321 OctahedronGeometry.prototype.constructor = OctahedronGeometry;
29322
29323 // OctahedronBufferGeometry
29324
29325 function OctahedronBufferGeometry( radius, detail ) {
29326
29327 var vertices = [
29328 1, 0, 0, - 1, 0, 0, 0, 1, 0,
29329 0, - 1, 0, 0, 0, 1, 0, 0, - 1
29330 ];
29331
29332 var indices = [
29333 0, 2, 4, 0, 4, 3, 0, 3, 5,
29334 0, 5, 2, 1, 2, 5, 1, 5, 3,
29335 1, 3, 4, 1, 4, 2
29336 ];
29337
29338 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29339
29340 this.type = 'OctahedronBufferGeometry';
29341
29342 this.parameters = {
29343 radius: radius,
29344 detail: detail
29345 };
29346
29347 }
29348
29349 OctahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29350 OctahedronBufferGeometry.prototype.constructor = OctahedronBufferGeometry;
29351
29352 // IcosahedronGeometry
29353
29354 function IcosahedronGeometry( radius, detail ) {
29355
29356 Geometry.call( this );
29357
29358 this.type = 'IcosahedronGeometry';
29359
29360 this.parameters = {
29361 radius: radius,
29362 detail: detail
29363 };
29364
29365 this.fromBufferGeometry( new IcosahedronBufferGeometry( radius, detail ) );
29366 this.mergeVertices();
29367
29368 }
29369
29370 IcosahedronGeometry.prototype = Object.create( Geometry.prototype );
29371 IcosahedronGeometry.prototype.constructor = IcosahedronGeometry;
29372
29373 // IcosahedronBufferGeometry
29374
29375 function IcosahedronBufferGeometry( radius, detail ) {
29376
29377 var t = ( 1 + Math.sqrt( 5 ) ) / 2;
29378
29379 var vertices = [
29380 - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,
29381 0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,
29382 t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1
29383 ];
29384
29385 var indices = [
29386 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
29387 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
29388 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
29389 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
29390 ];
29391
29392 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29393
29394 this.type = 'IcosahedronBufferGeometry';
29395
29396 this.parameters = {
29397 radius: radius,
29398 detail: detail
29399 };
29400
29401 }
29402
29403 IcosahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29404 IcosahedronBufferGeometry.prototype.constructor = IcosahedronBufferGeometry;
29405
29406 // DodecahedronGeometry
29407
29408 function DodecahedronGeometry( radius, detail ) {
29409
29410 Geometry.call( this );
29411
29412 this.type = 'DodecahedronGeometry';
29413
29414 this.parameters = {
29415 radius: radius,
29416 detail: detail
29417 };
29418
29419 this.fromBufferGeometry( new DodecahedronBufferGeometry( radius, detail ) );
29420 this.mergeVertices();
29421
29422 }
29423
29424 DodecahedronGeometry.prototype = Object.create( Geometry.prototype );
29425 DodecahedronGeometry.prototype.constructor = DodecahedronGeometry;
29426
29427 // DodecahedronBufferGeometry
29428
29429 function DodecahedronBufferGeometry( radius, detail ) {
29430
29431 var t = ( 1 + Math.sqrt( 5 ) ) / 2;
29432 var r = 1 / t;
29433
29434 var vertices = [
29435
29436 // (±1, ±1, ±1)
29437 - 1, - 1, - 1, - 1, - 1, 1,
29438 - 1, 1, - 1, - 1, 1, 1,
29439 1, - 1, - 1, 1, - 1, 1,
29440 1, 1, - 1, 1, 1, 1,
29441
29442 // (0, ±1/φ, ±φ)
29443 0, - r, - t, 0, - r, t,
29444 0, r, - t, 0, r, t,
29445
29446 // (±1/φ, ±φ, 0)
29447 - r, - t, 0, - r, t, 0,
29448 r, - t, 0, r, t, 0,
29449
29450 // (±φ, 0, ±1/φ)
29451 - t, 0, - r, t, 0, - r,
29452 - t, 0, r, t, 0, r
29453 ];
29454
29455 var indices = [
29456 3, 11, 7, 3, 7, 15, 3, 15, 13,
29457 7, 19, 17, 7, 17, 6, 7, 6, 15,
29458 17, 4, 8, 17, 8, 10, 17, 10, 6,
29459 8, 0, 16, 8, 16, 2, 8, 2, 10,
29460 0, 12, 1, 0, 1, 18, 0, 18, 16,
29461 6, 10, 2, 6, 2, 13, 6, 13, 15,
29462 2, 16, 18, 2, 18, 3, 2, 3, 13,
29463 18, 1, 9, 18, 9, 11, 18, 11, 3,
29464 4, 14, 12, 4, 12, 0, 4, 0, 8,
29465 11, 9, 5, 11, 5, 19, 11, 19, 7,
29466 19, 5, 14, 19, 14, 4, 19, 4, 17,
29467 1, 12, 14, 1, 14, 5, 1, 5, 9
29468 ];
29469
29470 PolyhedronBufferGeometry.call( this, vertices, indices, radius, detail );
29471
29472 this.type = 'DodecahedronBufferGeometry';
29473
29474 this.parameters = {
29475 radius: radius,
29476 detail: detail
29477 };
29478
29479 }
29480
29481 DodecahedronBufferGeometry.prototype = Object.create( PolyhedronBufferGeometry.prototype );
29482 DodecahedronBufferGeometry.prototype.constructor = DodecahedronBufferGeometry;
29483
29484 // TubeGeometry
29485
29486 function TubeGeometry( path, tubularSegments, radius, radialSegments, closed, taper ) {
29487
29488 Geometry.call( this );
29489
29490 this.type = 'TubeGeometry';
29491
29492 this.parameters = {
29493 path: path,
29494 tubularSegments: tubularSegments,
29495 radius: radius,
29496 radialSegments: radialSegments,
29497 closed: closed
29498 };
29499
29500 if ( taper !== undefined ) { console.warn( 'THREE.TubeGeometry: taper has been removed.' ); }
29501
29502 var bufferGeometry = new TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed );
29503
29504 // expose internals
29505
29506 this.tangents = bufferGeometry.tangents;
29507 this.normals = bufferGeometry.normals;
29508 this.binormals = bufferGeometry.binormals;
29509
29510 // create geometry
29511
29512 this.fromBufferGeometry( bufferGeometry );
29513 this.mergeVertices();
29514
29515 }
29516
29517 TubeGeometry.prototype = Object.create( Geometry.prototype );
29518 TubeGeometry.prototype.constructor = TubeGeometry;
29519
29520 // TubeBufferGeometry
29521
29522 function TubeBufferGeometry( path, tubularSegments, radius, radialSegments, closed ) {
29523
29524 BufferGeometry.call( this );
29525
29526 this.type = 'TubeBufferGeometry';
29527
29528 this.parameters = {
29529 path: path,
29530 tubularSegments: tubularSegments,
29531 radius: radius,
29532 radialSegments: radialSegments,
29533 closed: closed
29534 };
29535
29536 tubularSegments = tubularSegments || 64;
29537 radius = radius || 1;
29538 radialSegments = radialSegments || 8;
29539 closed = closed || false;
29540
29541 var frames = path.computeFrenetFrames( tubularSegments, closed );
29542
29543 // expose internals
29544
29545 this.tangents = frames.tangents;
29546 this.normals = frames.normals;
29547 this.binormals = frames.binormals;
29548
29549 // helper variables
29550
29551 var vertex = new Vector3();
29552 var normal = new Vector3();
29553 var uv = new Vector2();
29554 var P = new Vector3();
29555
29556 // buffer
29557
29558 var vertices = [];
29559 var normals = [];
29560 var uvs = [];
29561 var indices = [];
29562
29563 // create buffer data
29564
29565 generateBufferData();
29566
29567 // build geometry
29568
29569 this.setIndex( indices );
29570 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
29571 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
29572 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
29573
29574 // functions
29575
29576 function generateBufferData() {
29577
29578 for ( var i = 0; i < tubularSegments; i ++ ) {
29579
29580 generateSegment( i );
29581
29582 }
29583
29584 // if the geometry is not closed, generate the last row of vertices and normals
29585 // at the regular position on the given path
29586 //
29587 // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
29588
29589 generateSegment( ( closed === false ) ? tubularSegments : 0 );
29590
29591 // uvs are generated in a separate function.
29592 // this makes it easy compute correct values for closed geometries
29593
29594 generateUVs();
29595
29596 // finally create faces
29597
29598 generateIndices();
29599
29600 }
29601
29602 function generateSegment( i ) {
29603
29604 // we use getPointAt to sample evenly distributed points from the given path
29605
29606 P = path.getPointAt( i / tubularSegments, P );
29607
29608 // retrieve corresponding normal and binormal
29609
29610 var N = frames.normals[ i ];
29611 var B = frames.binormals[ i ];
29612
29613 // generate normals and vertices for the current segment
29614
29615 for ( var j = 0; j <= radialSegments; j ++ ) {
29616
29617 var v = j / radialSegments * Math.PI * 2;
29618
29619 var sin = Math.sin( v );
29620 var cos = - Math.cos( v );
29621
29622 // normal
29623
29624 normal.x = ( cos * N.x + sin * B.x );
29625 normal.y = ( cos * N.y + sin * B.y );
29626 normal.z = ( cos * N.z + sin * B.z );
29627 normal.normalize();
29628
29629 normals.push( normal.x, normal.y, normal.z );
29630
29631 // vertex
29632
29633 vertex.x = P.x + radius * normal.x;
29634 vertex.y = P.y + radius * normal.y;
29635 vertex.z = P.z + radius * normal.z;
29636
29637 vertices.push( vertex.x, vertex.y, vertex.z );
29638
29639 }
29640
29641 }
29642
29643 function generateIndices() {
29644
29645 for ( var j = 1; j <= tubularSegments; j ++ ) {
29646
29647 for ( var i = 1; i <= radialSegments; i ++ ) {
29648
29649 var a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
29650 var b = ( radialSegments + 1 ) * j + ( i - 1 );
29651 var c = ( radialSegments + 1 ) * j + i;
29652 var d = ( radialSegments + 1 ) * ( j - 1 ) + i;
29653
29654 // faces
29655
29656 indices.push( a, b, d );
29657 indices.push( b, c, d );
29658
29659 }
29660
29661 }
29662
29663 }
29664
29665 function generateUVs() {
29666
29667 for ( var i = 0; i <= tubularSegments; i ++ ) {
29668
29669 for ( var j = 0; j <= radialSegments; j ++ ) {
29670
29671 uv.x = i / tubularSegments;
29672 uv.y = j / radialSegments;
29673
29674 uvs.push( uv.x, uv.y );
29675
29676 }
29677
29678 }
29679
29680 }
29681
29682 }
29683
29684 TubeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
29685 TubeBufferGeometry.prototype.constructor = TubeBufferGeometry;
29686
29687 TubeBufferGeometry.prototype.toJSON = function () {
29688
29689 var data = BufferGeometry.prototype.toJSON.call( this );
29690
29691 data.path = this.parameters.path.toJSON();
29692
29693 return data;
29694
29695 };
29696
29697 // TorusKnotGeometry
29698
29699 function TorusKnotGeometry( radius, tube, tubularSegments, radialSegments, p, q, heightScale ) {
29700
29701 Geometry.call( this );
29702
29703 this.type = 'TorusKnotGeometry';
29704
29705 this.parameters = {
29706 radius: radius,
29707 tube: tube,
29708 tubularSegments: tubularSegments,
29709 radialSegments: radialSegments,
29710 p: p,
29711 q: q
29712 };
29713
29714 if ( heightScale !== undefined ) { console.warn( 'THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.' ); }
29715
29716 this.fromBufferGeometry( new TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) );
29717 this.mergeVertices();
29718
29719 }
29720
29721 TorusKnotGeometry.prototype = Object.create( Geometry.prototype );
29722 TorusKnotGeometry.prototype.constructor = TorusKnotGeometry;
29723
29724 // TorusKnotBufferGeometry
29725
29726 function TorusKnotBufferGeometry( radius, tube, tubularSegments, radialSegments, p, q ) {
29727
29728 BufferGeometry.call( this );
29729
29730 this.type = 'TorusKnotBufferGeometry';
29731
29732 this.parameters = {
29733 radius: radius,
29734 tube: tube,
29735 tubularSegments: tubularSegments,
29736 radialSegments: radialSegments,
29737 p: p,
29738 q: q
29739 };
29740
29741 radius = radius || 1;
29742 tube = tube || 0.4;
29743 tubularSegments = Math.floor( tubularSegments ) || 64;
29744 radialSegments = Math.floor( radialSegments ) || 8;
29745 p = p || 2;
29746 q = q || 3;
29747
29748 // buffers
29749
29750 var indices = [];
29751 var vertices = [];
29752 var normals = [];
29753 var uvs = [];
29754
29755 // helper variables
29756
29757 var vertex = new Vector3();
29758 var normal = new Vector3();
29759
29760 var P1 = new Vector3();
29761 var P2 = new Vector3();
29762
29763 var B = new Vector3();
29764 var T = new Vector3();
29765 var N = new Vector3();
29766
29767 // generate vertices, normals and uvs
29768
29769 for ( var i = 0; i <= tubularSegments; ++ i ) {
29770
29771 // the radian "u" is used to calculate the position on the torus curve of the current tubular segement
29772
29773 var u = i / tubularSegments * p * Math.PI * 2;
29774
29775 // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.
29776 // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions
29777
29778 calculatePositionOnCurve( u, p, q, radius, P1 );
29779 calculatePositionOnCurve( u + 0.01, p, q, radius, P2 );
29780
29781 // calculate orthonormal basis
29782
29783 T.subVectors( P2, P1 );
29784 N.addVectors( P2, P1 );
29785 B.crossVectors( T, N );
29786 N.crossVectors( B, T );
29787
29788 // normalize B, N. T can be ignored, we don't use it
29789
29790 B.normalize();
29791 N.normalize();
29792
29793 for ( var j = 0; j <= radialSegments; ++ j ) {
29794
29795 // now calculate the vertices. they are nothing more than an extrusion of the torus curve.
29796 // because we extrude a shape in the xy-plane, there is no need to calculate a z-value.
29797
29798 var v = j / radialSegments * Math.PI * 2;
29799 var cx = - tube * Math.cos( v );
29800 var cy = tube * Math.sin( v );
29801
29802 // now calculate the final vertex position.
29803 // first we orient the extrusion with our basis vectos, then we add it to the current position on the curve
29804
29805 vertex.x = P1.x + ( cx * N.x + cy * B.x );
29806 vertex.y = P1.y + ( cx * N.y + cy * B.y );
29807 vertex.z = P1.z + ( cx * N.z + cy * B.z );
29808
29809 vertices.push( vertex.x, vertex.y, vertex.z );
29810
29811 // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)
29812
29813 normal.subVectors( vertex, P1 ).normalize();
29814
29815 normals.push( normal.x, normal.y, normal.z );
29816
29817 // uv
29818
29819 uvs.push( i / tubularSegments );
29820 uvs.push( j / radialSegments );
29821
29822 }
29823
29824 }
29825
29826 // generate indices
29827
29828 for ( var j$1 = 1; j$1 <= tubularSegments; j$1 ++ ) {
29829
29830 for ( var i$1 = 1; i$1 <= radialSegments; i$1 ++ ) {
29831
29832 // indices
29833
29834 var a = ( radialSegments + 1 ) * ( j$1 - 1 ) + ( i$1 - 1 );
29835 var b = ( radialSegments + 1 ) * j$1 + ( i$1 - 1 );
29836 var c = ( radialSegments + 1 ) * j$1 + i$1;
29837 var d = ( radialSegments + 1 ) * ( j$1 - 1 ) + i$1;
29838
29839 // faces
29840
29841 indices.push( a, b, d );
29842 indices.push( b, c, d );
29843
29844 }
29845
29846 }
29847
29848 // build geometry
29849
29850 this.setIndex( indices );
29851 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
29852 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
29853 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
29854
29855 // this function calculates the current position on the torus curve
29856
29857 function calculatePositionOnCurve( u, p, q, radius, position ) {
29858
29859 var cu = Math.cos( u );
29860 var su = Math.sin( u );
29861 var quOverP = q / p * u;
29862 var cs = Math.cos( quOverP );
29863
29864 position.x = radius * ( 2 + cs ) * 0.5 * cu;
29865 position.y = radius * ( 2 + cs ) * su * 0.5;
29866 position.z = radius * Math.sin( quOverP ) * 0.5;
29867
29868 }
29869
29870 }
29871
29872 TorusKnotBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
29873 TorusKnotBufferGeometry.prototype.constructor = TorusKnotBufferGeometry;
29874
29875 // TorusGeometry
29876
29877 function TorusGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
29878
29879 Geometry.call( this );
29880
29881 this.type = 'TorusGeometry';
29882
29883 this.parameters = {
29884 radius: radius,
29885 tube: tube,
29886 radialSegments: radialSegments,
29887 tubularSegments: tubularSegments,
29888 arc: arc
29889 };
29890
29891 this.fromBufferGeometry( new TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) );
29892 this.mergeVertices();
29893
29894 }
29895
29896 TorusGeometry.prototype = Object.create( Geometry.prototype );
29897 TorusGeometry.prototype.constructor = TorusGeometry;
29898
29899 // TorusBufferGeometry
29900
29901 function TorusBufferGeometry( radius, tube, radialSegments, tubularSegments, arc ) {
29902
29903 BufferGeometry.call( this );
29904
29905 this.type = 'TorusBufferGeometry';
29906
29907 this.parameters = {
29908 radius: radius,
29909 tube: tube,
29910 radialSegments: radialSegments,
29911 tubularSegments: tubularSegments,
29912 arc: arc
29913 };
29914
29915 radius = radius || 1;
29916 tube = tube || 0.4;
29917 radialSegments = Math.floor( radialSegments ) || 8;
29918 tubularSegments = Math.floor( tubularSegments ) || 6;
29919 arc = arc || Math.PI * 2;
29920
29921 // buffers
29922
29923 var indices = [];
29924 var vertices = [];
29925 var normals = [];
29926 var uvs = [];
29927
29928 // helper variables
29929
29930 var center = new Vector3();
29931 var vertex = new Vector3();
29932 var normal = new Vector3();
29933
29934 // generate vertices, normals and uvs
29935
29936 for ( var j = 0; j <= radialSegments; j ++ ) {
29937
29938 for ( var i = 0; i <= tubularSegments; i ++ ) {
29939
29940 var u = i / tubularSegments * arc;
29941 var v = j / radialSegments * Math.PI * 2;
29942
29943 // vertex
29944
29945 vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
29946 vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
29947 vertex.z = tube * Math.sin( v );
29948
29949 vertices.push( vertex.x, vertex.y, vertex.z );
29950
29951 // normal
29952
29953 center.x = radius * Math.cos( u );
29954 center.y = radius * Math.sin( u );
29955 normal.subVectors( vertex, center ).normalize();
29956
29957 normals.push( normal.x, normal.y, normal.z );
29958
29959 // uv
29960
29961 uvs.push( i / tubularSegments );
29962 uvs.push( j / radialSegments );
29963
29964 }
29965
29966 }
29967
29968 // generate indices
29969
29970 for ( var j$1 = 1; j$1 <= radialSegments; j$1 ++ ) {
29971
29972 for ( var i$1 = 1; i$1 <= tubularSegments; i$1 ++ ) {
29973
29974 // indices
29975
29976 var a = ( tubularSegments + 1 ) * j$1 + i$1 - 1;
29977 var b = ( tubularSegments + 1 ) * ( j$1 - 1 ) + i$1 - 1;
29978 var c = ( tubularSegments + 1 ) * ( j$1 - 1 ) + i$1;
29979 var d = ( tubularSegments + 1 ) * j$1 + i$1;
29980
29981 // faces
29982
29983 indices.push( a, b, d );
29984 indices.push( b, c, d );
29985
29986 }
29987
29988 }
29989
29990 // build geometry
29991
29992 this.setIndex( indices );
29993 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
29994 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
29995 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
29996
29997 }
29998
29999 TorusBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
30000 TorusBufferGeometry.prototype.constructor = TorusBufferGeometry;
30001
30002 /**
30003 * Port from https://github.com/mapbox/earcut (v2.2.2)
30004 */
30005
30006 var Earcut = {
30007
30008 triangulate: function ( data, holeIndices, dim ) {
30009
30010 dim = dim || 2;
30011
30012 var hasHoles = holeIndices && holeIndices.length,
30013 outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length,
30014 outerNode = linkedList( data, 0, outerLen, dim, true ),
30015 triangles = [];
30016
30017 if ( ! outerNode || outerNode.next === outerNode.prev ) { return triangles; }
30018
30019 var minX, minY, maxX, maxY, x, y, invSize;
30020
30021 if ( hasHoles ) { outerNode = eliminateHoles( data, holeIndices, outerNode, dim ); }
30022
30023 // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
30024 if ( data.length > 80 * dim ) {
30025
30026 minX = maxX = data[ 0 ];
30027 minY = maxY = data[ 1 ];
30028
30029 for ( var i = dim; i < outerLen; i += dim ) {
30030
30031 x = data[ i ];
30032 y = data[ i + 1 ];
30033 if ( x < minX ) { minX = x; }
30034 if ( y < minY ) { minY = y; }
30035 if ( x > maxX ) { maxX = x; }
30036 if ( y > maxY ) { maxY = y; }
30037
30038 }
30039
30040 // minX, minY and invSize are later used to transform coords into integers for z-order calculation
30041 invSize = Math.max( maxX - minX, maxY - minY );
30042 invSize = invSize !== 0 ? 1 / invSize : 0;
30043
30044 }
30045
30046 earcutLinked( outerNode, triangles, dim, minX, minY, invSize );
30047
30048 return triangles;
30049
30050 }
30051
30052 };
30053
30054 // create a circular doubly linked list from polygon points in the specified winding order
30055 function linkedList( data, start, end, dim, clockwise ) {
30056
30057 var i, last;
30058
30059 if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) {
30060
30061 for ( i = start; i < end; i += dim ) { last = insertNode( i, data[ i ], data[ i + 1 ], last ); }
30062
30063 } else {
30064
30065 for ( i = end - dim; i >= start; i -= dim ) { last = insertNode( i, data[ i ], data[ i + 1 ], last ); }
30066
30067 }
30068
30069 if ( last && equals( last, last.next ) ) {
30070
30071 removeNode( last );
30072 last = last.next;
30073
30074 }
30075
30076 return last;
30077
30078 }
30079
30080 // eliminate colinear or duplicate points
30081 function filterPoints( start, end ) {
30082
30083 if ( ! start ) { return start; }
30084 if ( ! end ) { end = start; }
30085
30086 var p = start,
30087 again;
30088 do {
30089
30090 again = false;
30091
30092 if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) {
30093
30094 removeNode( p );
30095 p = end = p.prev;
30096 if ( p === p.next ) { break; }
30097 again = true;
30098
30099 } else {
30100
30101 p = p.next;
30102
30103 }
30104
30105 } while ( again || p !== end );
30106
30107 return end;
30108
30109 }
30110
30111 // main ear slicing loop which triangulates a polygon (given as a linked list)
30112 function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) {
30113
30114 if ( ! ear ) { return; }
30115
30116 // interlink polygon nodes in z-order
30117 if ( ! pass && invSize ) { indexCurve( ear, minX, minY, invSize ); }
30118
30119 var stop = ear,
30120 prev, next;
30121
30122 // iterate through ears, slicing them one by one
30123 while ( ear.prev !== ear.next ) {
30124
30125 prev = ear.prev;
30126 next = ear.next;
30127
30128 if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) {
30129
30130 // cut off the triangle
30131 triangles.push( prev.i / dim );
30132 triangles.push( ear.i / dim );
30133 triangles.push( next.i / dim );
30134
30135 removeNode( ear );
30136
30137 // skipping the next vertex leads to less sliver triangles
30138 ear = next.next;
30139 stop = next.next;
30140
30141 continue;
30142
30143 }
30144
30145 ear = next;
30146
30147 // if we looped through the whole remaining polygon and can't find any more ears
30148 if ( ear === stop ) {
30149
30150 // try filtering points and slicing again
30151 if ( ! pass ) {
30152
30153 earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 );
30154
30155 // if this didn't work, try curing all small self-intersections locally
30156
30157 } else if ( pass === 1 ) {
30158
30159 ear = cureLocalIntersections( filterPoints( ear ), triangles, dim );
30160 earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 );
30161
30162 // as a last resort, try splitting the remaining polygon into two
30163
30164 } else if ( pass === 2 ) {
30165
30166 splitEarcut( ear, triangles, dim, minX, minY, invSize );
30167
30168 }
30169
30170 break;
30171
30172 }
30173
30174 }
30175
30176 }
30177
30178 // check whether a polygon node forms a valid ear with adjacent nodes
30179 function isEar( ear ) {
30180
30181 var a = ear.prev,
30182 b = ear,
30183 c = ear.next;
30184
30185 if ( area( a, b, c ) >= 0 ) { return false; } // reflex, can't be an ear
30186
30187 // now make sure we don't have other points inside the potential ear
30188 var p = ear.next.next;
30189
30190 while ( p !== ear.prev ) {
30191
30192 if ( pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
30193 area( p.prev, p, p.next ) >= 0 ) { return false; }
30194 p = p.next;
30195
30196 }
30197
30198 return true;
30199
30200 }
30201
30202 function isEarHashed( ear, minX, minY, invSize ) {
30203
30204 var a = ear.prev,
30205 b = ear,
30206 c = ear.next;
30207
30208 if ( area( a, b, c ) >= 0 ) { return false; } // reflex, can't be an ear
30209
30210 // triangle bbox; min & max are calculated like this for speed
30211 var minTX = a.x < b.x ? ( a.x < c.x ? a.x : c.x ) : ( b.x < c.x ? b.x : c.x ),
30212 minTY = a.y < b.y ? ( a.y < c.y ? a.y : c.y ) : ( b.y < c.y ? b.y : c.y ),
30213 maxTX = a.x > b.x ? ( a.x > c.x ? a.x : c.x ) : ( b.x > c.x ? b.x : c.x ),
30214 maxTY = a.y > b.y ? ( a.y > c.y ? a.y : c.y ) : ( b.y > c.y ? b.y : c.y );
30215
30216 // z-order range for the current triangle bbox;
30217 var minZ = zOrder( minTX, minTY, minX, minY, invSize ),
30218 maxZ = zOrder( maxTX, maxTY, minX, minY, invSize );
30219
30220 var p = ear.prevZ,
30221 n = ear.nextZ;
30222
30223 // look for points inside the triangle in both directions
30224 while ( p && p.z >= minZ && n && n.z <= maxZ ) {
30225
30226 if ( p !== ear.prev && p !== ear.next &&
30227 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
30228 area( p.prev, p, p.next ) >= 0 ) { return false; }
30229 p = p.prevZ;
30230
30231 if ( n !== ear.prev && n !== ear.next &&
30232 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&
30233 area( n.prev, n, n.next ) >= 0 ) { return false; }
30234 n = n.nextZ;
30235
30236 }
30237
30238 // look for remaining points in decreasing z-order
30239 while ( p && p.z >= minZ ) {
30240
30241 if ( p !== ear.prev && p !== ear.next &&
30242 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y ) &&
30243 area( p.prev, p, p.next ) >= 0 ) { return false; }
30244 p = p.prevZ;
30245
30246 }
30247
30248 // look for remaining points in increasing z-order
30249 while ( n && n.z <= maxZ ) {
30250
30251 if ( n !== ear.prev && n !== ear.next &&
30252 pointInTriangle( a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y ) &&
30253 area( n.prev, n, n.next ) >= 0 ) { return false; }
30254 n = n.nextZ;
30255
30256 }
30257
30258 return true;
30259
30260 }
30261
30262 // go through all polygon nodes and cure small local self-intersections
30263 function cureLocalIntersections( start, triangles, dim ) {
30264
30265 var p = start;
30266 do {
30267
30268 var a = p.prev,
30269 b = p.next.next;
30270
30271 if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) {
30272
30273 triangles.push( a.i / dim );
30274 triangles.push( p.i / dim );
30275 triangles.push( b.i / dim );
30276
30277 // remove two nodes involved
30278 removeNode( p );
30279 removeNode( p.next );
30280
30281 p = start = b;
30282
30283 }
30284
30285 p = p.next;
30286
30287 } while ( p !== start );
30288
30289 return filterPoints( p );
30290
30291 }
30292
30293 // try splitting polygon into two and triangulate them independently
30294 function splitEarcut( start, triangles, dim, minX, minY, invSize ) {
30295
30296 // look for a valid diagonal that divides the polygon into two
30297 var a = start;
30298 do {
30299
30300 var b = a.next.next;
30301 while ( b !== a.prev ) {
30302
30303 if ( a.i !== b.i && isValidDiagonal( a, b ) ) {
30304
30305 // split the polygon in two by the diagonal
30306 var c = splitPolygon( a, b );
30307
30308 // filter colinear points around the cuts
30309 a = filterPoints( a, a.next );
30310 c = filterPoints( c, c.next );
30311
30312 // run earcut on each half
30313 earcutLinked( a, triangles, dim, minX, minY, invSize );
30314 earcutLinked( c, triangles, dim, minX, minY, invSize );
30315 return;
30316
30317 }
30318
30319 b = b.next;
30320
30321 }
30322
30323 a = a.next;
30324
30325 } while ( a !== start );
30326
30327 }
30328
30329 // link every hole into the outer loop, producing a single-ring polygon without holes
30330 function eliminateHoles( data, holeIndices, outerNode, dim ) {
30331
30332 var queue = [],
30333 i, len, start, end, list;
30334
30335 for ( i = 0, len = holeIndices.length; i < len; i ++ ) {
30336
30337 start = holeIndices[ i ] * dim;
30338 end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length;
30339 list = linkedList( data, start, end, dim, false );
30340 if ( list === list.next ) { list.steiner = true; }
30341 queue.push( getLeftmost( list ) );
30342
30343 }
30344
30345 queue.sort( compareX );
30346
30347 // process holes from left to right
30348 for ( i = 0; i < queue.length; i ++ ) {
30349
30350 eliminateHole( queue[ i ], outerNode );
30351 outerNode = filterPoints( outerNode, outerNode.next );
30352
30353 }
30354
30355 return outerNode;
30356
30357 }
30358
30359 function compareX( a, b ) {
30360
30361 return a.x - b.x;
30362
30363 }
30364
30365 // find a bridge between vertices that connects hole with an outer ring and and link it
30366 function eliminateHole( hole, outerNode ) {
30367
30368 outerNode = findHoleBridge( hole, outerNode );
30369 if ( outerNode ) {
30370
30371 var b = splitPolygon( outerNode, hole );
30372
30373 // filter collinear points around the cuts
30374 filterPoints( outerNode, outerNode.next );
30375 filterPoints( b, b.next );
30376
30377 }
30378
30379 }
30380
30381 // David Eberly's algorithm for finding a bridge between hole and outer polygon
30382 function findHoleBridge( hole, outerNode ) {
30383
30384 var p = outerNode,
30385 hx = hole.x,
30386 hy = hole.y,
30387 qx = - Infinity,
30388 m;
30389
30390 // find a segment intersected by a ray from the hole's leftmost point to the left;
30391 // segment's endpoint with lesser x will be potential connection point
30392 do {
30393
30394 if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) {
30395
30396 var x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y );
30397 if ( x <= hx && x > qx ) {
30398
30399 qx = x;
30400 if ( x === hx ) {
30401
30402 if ( hy === p.y ) { return p; }
30403 if ( hy === p.next.y ) { return p.next; }
30404
30405 }
30406
30407 m = p.x < p.next.x ? p : p.next;
30408
30409 }
30410
30411 }
30412
30413 p = p.next;
30414
30415 } while ( p !== outerNode );
30416
30417 if ( ! m ) { return null; }
30418
30419 if ( hx === qx ) { return m; } // hole touches outer segment; pick leftmost endpoint
30420
30421 // look for points inside the triangle of hole point, segment intersection and endpoint;
30422 // if there are no points found, we have a valid connection;
30423 // otherwise choose the point of the minimum angle with the ray as connection point
30424
30425 var stop = m,
30426 mx = m.x,
30427 my = m.y,
30428 tanMin = Infinity,
30429 tan;
30430
30431 p = m;
30432
30433 do {
30434
30435 if ( hx >= p.x && p.x >= mx && hx !== p.x &&
30436 pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) {
30437
30438 tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential
30439
30440 if ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) {
30441
30442 m = p;
30443 tanMin = tan;
30444
30445 }
30446
30447 }
30448
30449 p = p.next;
30450
30451 } while ( p !== stop );
30452
30453 return m;
30454
30455 }
30456
30457 // whether sector in vertex m contains sector in vertex p in the same coordinates
30458 function sectorContainsSector( m, p ) {
30459
30460 return area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0;
30461
30462 }
30463
30464 // interlink polygon nodes in z-order
30465 function indexCurve( start, minX, minY, invSize ) {
30466
30467 var p = start;
30468 do {
30469
30470 if ( p.z === null ) { p.z = zOrder( p.x, p.y, minX, minY, invSize ); }
30471 p.prevZ = p.prev;
30472 p.nextZ = p.next;
30473 p = p.next;
30474
30475 } while ( p !== start );
30476
30477 p.prevZ.nextZ = null;
30478 p.prevZ = null;
30479
30480 sortLinked( p );
30481
30482 }
30483
30484 // Simon Tatham's linked list merge sort algorithm
30485 // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
30486 function sortLinked( list ) {
30487
30488 var i, p, q, e, tail, numMerges, pSize, qSize,
30489 inSize = 1;
30490
30491 do {
30492
30493 p = list;
30494 list = null;
30495 tail = null;
30496 numMerges = 0;
30497
30498 while ( p ) {
30499
30500 numMerges ++;
30501 q = p;
30502 pSize = 0;
30503 for ( i = 0; i < inSize; i ++ ) {
30504
30505 pSize ++;
30506 q = q.nextZ;
30507 if ( ! q ) { break; }
30508
30509 }
30510
30511 qSize = inSize;
30512
30513 while ( pSize > 0 || ( qSize > 0 && q ) ) {
30514
30515 if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) {
30516
30517 e = p;
30518 p = p.nextZ;
30519 pSize --;
30520
30521 } else {
30522
30523 e = q;
30524 q = q.nextZ;
30525 qSize --;
30526
30527 }
30528
30529 if ( tail ) { tail.nextZ = e; }
30530 else { list = e; }
30531
30532 e.prevZ = tail;
30533 tail = e;
30534
30535 }
30536
30537 p = q;
30538
30539 }
30540
30541 tail.nextZ = null;
30542 inSize *= 2;
30543
30544 } while ( numMerges > 1 );
30545
30546 return list;
30547
30548 }
30549
30550 // z-order of a point given coords and inverse of the longer side of data bbox
30551 function zOrder( x, y, minX, minY, invSize ) {
30552
30553 // coords are transformed into non-negative 15-bit integer range
30554 x = 32767 * ( x - minX ) * invSize;
30555 y = 32767 * ( y - minY ) * invSize;
30556
30557 x = ( x | ( x << 8 ) ) & 0x00FF00FF;
30558 x = ( x | ( x << 4 ) ) & 0x0F0F0F0F;
30559 x = ( x | ( x << 2 ) ) & 0x33333333;
30560 x = ( x | ( x << 1 ) ) & 0x55555555;
30561
30562 y = ( y | ( y << 8 ) ) & 0x00FF00FF;
30563 y = ( y | ( y << 4 ) ) & 0x0F0F0F0F;
30564 y = ( y | ( y << 2 ) ) & 0x33333333;
30565 y = ( y | ( y << 1 ) ) & 0x55555555;
30566
30567 return x | ( y << 1 );
30568
30569 }
30570
30571 // find the leftmost node of a polygon ring
30572 function getLeftmost( start ) {
30573
30574 var p = start,
30575 leftmost = start;
30576 do {
30577
30578 if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) { leftmost = p; }
30579 p = p.next;
30580
30581 } while ( p !== start );
30582
30583 return leftmost;
30584
30585 }
30586
30587 // check if a point lies within a convex triangle
30588 function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) {
30589
30590 return ( cx - px ) * ( ay - py ) - ( ax - px ) * ( cy - py ) >= 0 &&
30591 ( ax - px ) * ( by - py ) - ( bx - px ) * ( ay - py ) >= 0 &&
30592 ( bx - px ) * ( cy - py ) - ( cx - px ) * ( by - py ) >= 0;
30593
30594 }
30595
30596 // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
30597 function isValidDiagonal( a, b ) {
30598
30599 return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // dones't intersect other edges
30600 ( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) && // locally visible
30601 ( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) || // does not create opposite-facing sectors
30602 equals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 ); // special zero-length case
30603
30604 }
30605
30606 // signed area of a triangle
30607 function area( p, q, r ) {
30608
30609 return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y );
30610
30611 }
30612
30613 // check if two points are equal
30614 function equals( p1, p2 ) {
30615
30616 return p1.x === p2.x && p1.y === p2.y;
30617
30618 }
30619
30620 // check if two segments intersect
30621 function intersects( p1, q1, p2, q2 ) {
30622
30623 var o1 = sign( area( p1, q1, p2 ) );
30624 var o2 = sign( area( p1, q1, q2 ) );
30625 var o3 = sign( area( p2, q2, p1 ) );
30626 var o4 = sign( area( p2, q2, q1 ) );
30627
30628 if ( o1 !== o2 && o3 !== o4 ) { return true; } // general case
30629
30630 if ( o1 === 0 && onSegment( p1, p2, q1 ) ) { return true; } // p1, q1 and p2 are collinear and p2 lies on p1q1
30631 if ( o2 === 0 && onSegment( p1, q2, q1 ) ) { return true; } // p1, q1 and q2 are collinear and q2 lies on p1q1
30632 if ( o3 === 0 && onSegment( p2, p1, q2 ) ) { return true; } // p2, q2 and p1 are collinear and p1 lies on p2q2
30633 if ( o4 === 0 && onSegment( p2, q1, q2 ) ) { return true; } // p2, q2 and q1 are collinear and q1 lies on p2q2
30634
30635 return false;
30636
30637 }
30638
30639 // for collinear points p, q, r, check if point q lies on segment pr
30640 function onSegment( p, q, r ) {
30641
30642 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 );
30643
30644 }
30645
30646 function sign( num ) {
30647
30648 return num > 0 ? 1 : num < 0 ? - 1 : 0;
30649
30650 }
30651
30652 // check if a polygon diagonal intersects any polygon segments
30653 function intersectsPolygon( a, b ) {
30654
30655 var p = a;
30656 do {
30657
30658 if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
30659 intersects( p, p.next, a, b ) ) { return true; }
30660 p = p.next;
30661
30662 } while ( p !== a );
30663
30664 return false;
30665
30666 }
30667
30668 // check if a polygon diagonal is locally inside the polygon
30669 function locallyInside( a, b ) {
30670
30671 return area( a.prev, a, a.next ) < 0 ?
30672 area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 :
30673 area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0;
30674
30675 }
30676
30677 // check if the middle point of a polygon diagonal is inside the polygon
30678 function middleInside( a, b ) {
30679
30680 var p = a,
30681 inside = false,
30682 px = ( a.x + b.x ) / 2,
30683 py = ( a.y + b.y ) / 2;
30684 do {
30685
30686 if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y &&
30687 ( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) )
30688 { inside = ! inside; }
30689 p = p.next;
30690
30691 } while ( p !== a );
30692
30693 return inside;
30694
30695 }
30696
30697 // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
30698 // if one belongs to the outer ring and another to a hole, it merges it into a single ring
30699 function splitPolygon( a, b ) {
30700
30701 var a2 = new Node( a.i, a.x, a.y ),
30702 b2 = new Node( b.i, b.x, b.y ),
30703 an = a.next,
30704 bp = b.prev;
30705
30706 a.next = b;
30707 b.prev = a;
30708
30709 a2.next = an;
30710 an.prev = a2;
30711
30712 b2.next = a2;
30713 a2.prev = b2;
30714
30715 bp.next = b2;
30716 b2.prev = bp;
30717
30718 return b2;
30719
30720 }
30721
30722 // create a node and optionally link it with previous one (in a circular doubly linked list)
30723 function insertNode( i, x, y, last ) {
30724
30725 var p = new Node( i, x, y );
30726
30727 if ( ! last ) {
30728
30729 p.prev = p;
30730 p.next = p;
30731
30732 } else {
30733
30734 p.next = last.next;
30735 p.prev = last;
30736 last.next.prev = p;
30737 last.next = p;
30738
30739 }
30740
30741 return p;
30742
30743 }
30744
30745 function removeNode( p ) {
30746
30747 p.next.prev = p.prev;
30748 p.prev.next = p.next;
30749
30750 if ( p.prevZ ) { p.prevZ.nextZ = p.nextZ; }
30751 if ( p.nextZ ) { p.nextZ.prevZ = p.prevZ; }
30752
30753 }
30754
30755 function Node( i, x, y ) {
30756
30757 // vertex index in coordinates array
30758 this.i = i;
30759
30760 // vertex coordinates
30761 this.x = x;
30762 this.y = y;
30763
30764 // previous and next vertex nodes in a polygon ring
30765 this.prev = null;
30766 this.next = null;
30767
30768 // z-order curve value
30769 this.z = null;
30770
30771 // previous and next nodes in z-order
30772 this.prevZ = null;
30773 this.nextZ = null;
30774
30775 // indicates whether this is a steiner point
30776 this.steiner = false;
30777
30778 }
30779
30780 function signedArea( data, start, end, dim ) {
30781
30782 var sum = 0;
30783 for ( var i = start, j = end - dim; i < end; i += dim ) {
30784
30785 sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] );
30786 j = i;
30787
30788 }
30789
30790 return sum;
30791
30792 }
30793
30794 var ShapeUtils = {
30795
30796 // calculate area of the contour polygon
30797
30798 area: function ( contour ) {
30799
30800 var n = contour.length;
30801 var a = 0.0;
30802
30803 for ( var p = n - 1, q = 0; q < n; p = q ++ ) {
30804
30805 a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
30806
30807 }
30808
30809 return a * 0.5;
30810
30811 },
30812
30813 isClockWise: function ( pts ) {
30814
30815 return ShapeUtils.area( pts ) < 0;
30816
30817 },
30818
30819 triangulateShape: function ( contour, holes ) {
30820
30821 var vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ]
30822 var holeIndices = []; // array of hole indices
30823 var faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ]
30824
30825 removeDupEndPts( contour );
30826 addContour( vertices, contour );
30827
30828 //
30829
30830 var holeIndex = contour.length;
30831
30832 holes.forEach( removeDupEndPts );
30833
30834 for ( var i = 0; i < holes.length; i ++ ) {
30835
30836 holeIndices.push( holeIndex );
30837 holeIndex += holes[ i ].length;
30838 addContour( vertices, holes[ i ] );
30839
30840 }
30841
30842 //
30843
30844 var triangles = Earcut.triangulate( vertices, holeIndices );
30845
30846 //
30847
30848 for ( var i$1 = 0; i$1 < triangles.length; i$1 += 3 ) {
30849
30850 faces.push( triangles.slice( i$1, i$1 + 3 ) );
30851
30852 }
30853
30854 return faces;
30855
30856 }
30857
30858 };
30859
30860 function removeDupEndPts( points ) {
30861
30862 var l = points.length;
30863
30864 if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
30865
30866 points.pop();
30867
30868 }
30869
30870 }
30871
30872 function addContour( vertices, contour ) {
30873
30874 for ( var i = 0; i < contour.length; i ++ ) {
30875
30876 vertices.push( contour[ i ].x );
30877 vertices.push( contour[ i ].y );
30878
30879 }
30880
30881 }
30882
30883 /**
30884 * Creates extruded geometry from a path shape.
30885 *
30886 * parameters = {
30887 *
30888 * curveSegments: <int>, // number of points on the curves
30889 * steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
30890 * depth: <float>, // Depth to extrude the shape
30891 *
30892 * bevelEnabled: <bool>, // turn on bevel
30893 * bevelThickness: <float>, // how deep into the original shape bevel goes
30894 * bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel
30895 * bevelOffset: <float>, // how far from shape outline does bevel start
30896 * bevelSegments: <int>, // number of bevel layers
30897 *
30898 * extrudePath: <THREE.Curve> // curve to extrude shape along
30899 *
30900 * UVGenerator: <Object> // object that provides UV generator functions
30901 *
30902 * }
30903 */
30904
30905 // ExtrudeGeometry
30906
30907 function ExtrudeGeometry( shapes, options ) {
30908
30909 Geometry.call( this );
30910
30911 this.type = 'ExtrudeGeometry';
30912
30913 this.parameters = {
30914 shapes: shapes,
30915 options: options
30916 };
30917
30918 this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) );
30919 this.mergeVertices();
30920
30921 }
30922
30923 ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
30924 ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
30925
30926 ExtrudeGeometry.prototype.toJSON = function () {
30927
30928 var data = Geometry.prototype.toJSON.call( this );
30929
30930 var shapes = this.parameters.shapes;
30931 var options = this.parameters.options;
30932
30933 return toJSON( shapes, options, data );
30934
30935 };
30936
30937 // ExtrudeBufferGeometry
30938
30939 function ExtrudeBufferGeometry( shapes, options ) {
30940
30941 BufferGeometry.call( this );
30942
30943 this.type = 'ExtrudeBufferGeometry';
30944
30945 this.parameters = {
30946 shapes: shapes,
30947 options: options
30948 };
30949
30950 shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
30951
30952 var scope = this;
30953
30954 var verticesArray = [];
30955 var uvArray = [];
30956
30957 for ( var i = 0, l = shapes.length; i < l; i ++ ) {
30958
30959 var shape = shapes[ i ];
30960 addShape( shape );
30961
30962 }
30963
30964 // build geometry
30965
30966 this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
30967 this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );
30968
30969 this.computeVertexNormals();
30970
30971 // functions
30972
30973 function addShape( shape ) {
30974
30975 var placeholder = [];
30976
30977 // options
30978
30979 var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
30980 var steps = options.steps !== undefined ? options.steps : 1;
30981 var depth = options.depth !== undefined ? options.depth : 100;
30982
30983 var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
30984 var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6;
30985 var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2;
30986 var bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;
30987 var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
30988
30989 var extrudePath = options.extrudePath;
30990
30991 var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator;
30992
30993 // deprecated options
30994
30995 if ( options.amount !== undefined ) {
30996
30997 console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' );
30998 depth = options.amount;
30999
31000 }
31001
31002 //
31003
31004 var extrudePts, extrudeByPath = false;
31005 var splineTube, binormal, normal, position2;
31006
31007 if ( extrudePath ) {
31008
31009 extrudePts = extrudePath.getSpacedPoints( steps );
31010
31011 extrudeByPath = true;
31012 bevelEnabled = false; // bevels not supported for path extrusion
31013
31014 // SETUP TNB variables
31015
31016 // TODO1 - have a .isClosed in spline?
31017
31018 splineTube = extrudePath.computeFrenetFrames( steps, false );
31019
31020 // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
31021
31022 binormal = new Vector3();
31023 normal = new Vector3();
31024 position2 = new Vector3();
31025
31026 }
31027
31028 // Safeguards if bevels are not enabled
31029
31030 if ( ! bevelEnabled ) {
31031
31032 bevelSegments = 0;
31033 bevelThickness = 0;
31034 bevelSize = 0;
31035 bevelOffset = 0;
31036
31037 }
31038
31039 // Variables initialization
31040
31041 var shapePoints = shape.extractPoints( curveSegments );
31042
31043 var vertices = shapePoints.shape;
31044 var holes = shapePoints.holes;
31045
31046 var reverse = ! ShapeUtils.isClockWise( vertices );
31047
31048 if ( reverse ) {
31049
31050 vertices = vertices.reverse();
31051
31052 // Maybe we should also check if holes are in the opposite direction, just to be safe ...
31053
31054 for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
31055
31056 var ahole = holes[ h ];
31057
31058 if ( ShapeUtils.isClockWise( ahole ) ) {
31059
31060 holes[ h ] = ahole.reverse();
31061
31062 }
31063
31064 }
31065
31066 }
31067
31068
31069 var faces = ShapeUtils.triangulateShape( vertices, holes );
31070
31071 /* Vertices */
31072
31073 var contour = vertices; // vertices has all points but contour has only points of circumference
31074
31075 for ( var h$1 = 0, hl$1 = holes.length; h$1 < hl$1; h$1 ++ ) {
31076
31077 var ahole$1 = holes[ h$1 ];
31078
31079 vertices = vertices.concat( ahole$1 );
31080
31081 }
31082
31083
31084 function scalePt2( pt, vec, size ) {
31085
31086 if ( ! vec ) { console.error( "THREE.ExtrudeGeometry: vec does not exist" ); }
31087
31088 return vec.clone().multiplyScalar( size ).add( pt );
31089
31090 }
31091
31092 var vlen = vertices.length, flen = faces.length;
31093
31094
31095 // Find directions for point movement
31096
31097
31098 function getBevelVec( inPt, inPrev, inNext ) {
31099
31100 // computes for inPt the corresponding point inPt' on a new contour
31101 // shifted by 1 unit (length of normalized vector) to the left
31102 // if we walk along contour clockwise, this new contour is outside the old one
31103 //
31104 // inPt' is the intersection of the two lines parallel to the two
31105 // adjacent edges of inPt at a distance of 1 unit on the left side.
31106
31107 var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
31108
31109 // good reading for geometry algorithms (here: line-line intersection)
31110 // http://geomalgorithms.com/a05-_intersect-1.html
31111
31112 var v_prev_x = inPt.x - inPrev.x,
31113 v_prev_y = inPt.y - inPrev.y;
31114 var v_next_x = inNext.x - inPt.x,
31115 v_next_y = inNext.y - inPt.y;
31116
31117 var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
31118
31119 // check for collinear edges
31120 var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
31121
31122 if ( Math.abs( collinear0 ) > Number.EPSILON ) {
31123
31124 // not collinear
31125
31126 // length of vectors for normalizing
31127
31128 var v_prev_len = Math.sqrt( v_prev_lensq );
31129 var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
31130
31131 // shift adjacent points by unit vectors to the left
31132
31133 var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
31134 var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
31135
31136 var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
31137 var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
31138
31139 // scaling factor for v_prev to intersection point
31140
31141 var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
31142 ( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
31143 ( v_prev_x * v_next_y - v_prev_y * v_next_x );
31144
31145 // vector from inPt to intersection point
31146
31147 v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
31148 v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
31149
31150 // Don't normalize!, otherwise sharp corners become ugly
31151 // but prevent crazy spikes
31152 var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
31153 if ( v_trans_lensq <= 2 ) {
31154
31155 return new Vector2( v_trans_x, v_trans_y );
31156
31157 } else {
31158
31159 shrink_by = Math.sqrt( v_trans_lensq / 2 );
31160
31161 }
31162
31163 } else {
31164
31165 // handle special case of collinear edges
31166
31167 var direction_eq = false; // assumes: opposite
31168
31169 if ( v_prev_x > Number.EPSILON ) {
31170
31171 if ( v_next_x > Number.EPSILON ) {
31172
31173 direction_eq = true;
31174
31175 }
31176
31177 } else {
31178
31179 if ( v_prev_x < - Number.EPSILON ) {
31180
31181 if ( v_next_x < - Number.EPSILON ) {
31182
31183 direction_eq = true;
31184
31185 }
31186
31187 } else {
31188
31189 if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
31190
31191 direction_eq = true;
31192
31193 }
31194
31195 }
31196
31197 }
31198
31199 if ( direction_eq ) {
31200
31201 // console.log("Warning: lines are a straight sequence");
31202 v_trans_x = - v_prev_y;
31203 v_trans_y = v_prev_x;
31204 shrink_by = Math.sqrt( v_prev_lensq );
31205
31206 } else {
31207
31208 // console.log("Warning: lines are a straight spike");
31209 v_trans_x = v_prev_x;
31210 v_trans_y = v_prev_y;
31211 shrink_by = Math.sqrt( v_prev_lensq / 2 );
31212
31213 }
31214
31215 }
31216
31217 return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
31218
31219 }
31220
31221
31222 var contourMovements = [];
31223
31224 for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
31225
31226 if ( j === il ) { j = 0; }
31227 if ( k === il ) { k = 0; }
31228
31229 // (j)---(i)---(k)
31230 // console.log('i,j,k', i, j , k)
31231
31232 contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
31233
31234 }
31235
31236 var holesMovements = [];
31237 var oneHoleMovements, verticesMovements = contourMovements.concat();
31238
31239 for ( var h$2 = 0, hl$2 = holes.length; h$2 < hl$2; h$2 ++ ) {
31240
31241 var ahole$2 = holes[ h$2 ];
31242
31243 oneHoleMovements = [];
31244
31245 for ( var i$1 = 0, il$1 = ahole$2.length, j$1 = il$1 - 1, k$1 = i$1 + 1; i$1 < il$1; i$1 ++, j$1 ++, k$1 ++ ) {
31246
31247 if ( j$1 === il$1 ) { j$1 = 0; }
31248 if ( k$1 === il$1 ) { k$1 = 0; }
31249
31250 // (j)---(i)---(k)
31251 oneHoleMovements[ i$1 ] = getBevelVec( ahole$2[ i$1 ], ahole$2[ j$1 ], ahole$2[ k$1 ] );
31252
31253 }
31254
31255 holesMovements.push( oneHoleMovements );
31256 verticesMovements = verticesMovements.concat( oneHoleMovements );
31257
31258 }
31259
31260
31261 // Loop bevelSegments, 1 for the front, 1 for the back
31262
31263 for ( var b = 0; b < bevelSegments; b ++ ) {
31264
31265 //for ( b = bevelSegments; b > 0; b -- ) {
31266
31267 var t = b / bevelSegments;
31268 var z = bevelThickness * Math.cos( t * Math.PI / 2 );
31269 var bs$1 = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;
31270
31271 // contract shape
31272
31273 for ( var i$2 = 0, il$2 = contour.length; i$2 < il$2; i$2 ++ ) {
31274
31275 var vert = scalePt2( contour[ i$2 ], contourMovements[ i$2 ], bs$1 );
31276
31277 v( vert.x, vert.y, - z );
31278
31279 }
31280
31281 // expand holes
31282
31283 for ( var h$3 = 0, hl$3 = holes.length; h$3 < hl$3; h$3 ++ ) {
31284
31285 var ahole$3 = holes[ h$3 ];
31286 oneHoleMovements = holesMovements[ h$3 ];
31287
31288 for ( var i$3 = 0, il$3 = ahole$3.length; i$3 < il$3; i$3 ++ ) {
31289
31290 var vert$1 = scalePt2( ahole$3[ i$3 ], oneHoleMovements[ i$3 ], bs$1 );
31291
31292 v( vert$1.x, vert$1.y, - z );
31293
31294 }
31295
31296 }
31297
31298 }
31299
31300 var bs = bevelSize + bevelOffset;
31301
31302 // Back facing vertices
31303
31304 for ( var i$4 = 0; i$4 < vlen; i$4 ++ ) {
31305
31306 var vert$2 = bevelEnabled ? scalePt2( vertices[ i$4 ], verticesMovements[ i$4 ], bs ) : vertices[ i$4 ];
31307
31308 if ( ! extrudeByPath ) {
31309
31310 v( vert$2.x, vert$2.y, 0 );
31311
31312 } else {
31313
31314 // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
31315
31316 normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert$2.x );
31317 binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert$2.y );
31318
31319 position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
31320
31321 v( position2.x, position2.y, position2.z );
31322
31323 }
31324
31325 }
31326
31327 // Add stepped vertices...
31328 // Including front facing vertices
31329
31330 for ( var s = 1; s <= steps; s ++ ) {
31331
31332 for ( var i$5 = 0; i$5 < vlen; i$5 ++ ) {
31333
31334 var vert$3 = bevelEnabled ? scalePt2( vertices[ i$5 ], verticesMovements[ i$5 ], bs ) : vertices[ i$5 ];
31335
31336 if ( ! extrudeByPath ) {
31337
31338 v( vert$3.x, vert$3.y, depth / steps * s );
31339
31340 } else {
31341
31342 // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
31343
31344 normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert$3.x );
31345 binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert$3.y );
31346
31347 position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
31348
31349 v( position2.x, position2.y, position2.z );
31350
31351 }
31352
31353 }
31354
31355 }
31356
31357
31358 // Add bevel segments planes
31359
31360 //for ( b = 1; b <= bevelSegments; b ++ ) {
31361 for ( var b$1 = bevelSegments - 1; b$1 >= 0; b$1 -- ) {
31362
31363 var t$1 = b$1 / bevelSegments;
31364 var z$1 = bevelThickness * Math.cos( t$1 * Math.PI / 2 );
31365 var bs$2 = bevelSize * Math.sin( t$1 * Math.PI / 2 ) + bevelOffset;
31366
31367 // contract shape
31368
31369 for ( var i$6 = 0, il$4 = contour.length; i$6 < il$4; i$6 ++ ) {
31370
31371 var vert$4 = scalePt2( contour[ i$6 ], contourMovements[ i$6 ], bs$2 );
31372 v( vert$4.x, vert$4.y, depth + z$1 );
31373
31374 }
31375
31376 // expand holes
31377
31378 for ( var h$4 = 0, hl$4 = holes.length; h$4 < hl$4; h$4 ++ ) {
31379
31380 var ahole$4 = holes[ h$4 ];
31381 oneHoleMovements = holesMovements[ h$4 ];
31382
31383 for ( var i$7 = 0, il$5 = ahole$4.length; i$7 < il$5; i$7 ++ ) {
31384
31385 var vert$5 = scalePt2( ahole$4[ i$7 ], oneHoleMovements[ i$7 ], bs$2 );
31386
31387 if ( ! extrudeByPath ) {
31388
31389 v( vert$5.x, vert$5.y, depth + z$1 );
31390
31391 } else {
31392
31393 v( vert$5.x, vert$5.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z$1 );
31394
31395 }
31396
31397 }
31398
31399 }
31400
31401 }
31402
31403 /* Faces */
31404
31405 // Top and bottom faces
31406
31407 buildLidFaces();
31408
31409 // Sides faces
31410
31411 buildSideFaces();
31412
31413
31414 ///// Internal functions
31415
31416 function buildLidFaces() {
31417
31418 var start = verticesArray.length / 3;
31419
31420 if ( bevelEnabled ) {
31421
31422 var layer = 0; // steps + 1
31423 var offset = vlen * layer;
31424
31425 // Bottom faces
31426
31427 for ( var i = 0; i < flen; i ++ ) {
31428
31429 var face = faces[ i ];
31430 f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
31431
31432 }
31433
31434 layer = steps + bevelSegments * 2;
31435 offset = vlen * layer;
31436
31437 // Top faces
31438
31439 for ( var i$1 = 0; i$1 < flen; i$1 ++ ) {
31440
31441 var face$1 = faces[ i$1 ];
31442 f3( face$1[ 0 ] + offset, face$1[ 1 ] + offset, face$1[ 2 ] + offset );
31443
31444 }
31445
31446 } else {
31447
31448 // Bottom faces
31449
31450 for ( var i$2 = 0; i$2 < flen; i$2 ++ ) {
31451
31452 var face$2 = faces[ i$2 ];
31453 f3( face$2[ 2 ], face$2[ 1 ], face$2[ 0 ] );
31454
31455 }
31456
31457 // Top faces
31458
31459 for ( var i$3 = 0; i$3 < flen; i$3 ++ ) {
31460
31461 var face$3 = faces[ i$3 ];
31462 f3( face$3[ 0 ] + vlen * steps, face$3[ 1 ] + vlen * steps, face$3[ 2 ] + vlen * steps );
31463
31464 }
31465
31466 }
31467
31468 scope.addGroup( start, verticesArray.length / 3 - start, 0 );
31469
31470 }
31471
31472 // Create faces for the z-sides of the shape
31473
31474 function buildSideFaces() {
31475
31476 var start = verticesArray.length / 3;
31477 var layeroffset = 0;
31478 sidewalls( contour, layeroffset );
31479 layeroffset += contour.length;
31480
31481 for ( var h = 0, hl = holes.length; h < hl; h ++ ) {
31482
31483 var ahole = holes[ h ];
31484 sidewalls( ahole, layeroffset );
31485
31486 //, true
31487 layeroffset += ahole.length;
31488
31489 }
31490
31491
31492 scope.addGroup( start, verticesArray.length / 3 - start, 1 );
31493
31494
31495 }
31496
31497 function sidewalls( contour, layeroffset ) {
31498
31499 var i = contour.length;
31500
31501 while ( -- i >= 0 ) {
31502
31503 var j = i;
31504 var k = i - 1;
31505 if ( k < 0 ) { k = contour.length - 1; }
31506
31507 //console.log('b', i,j, i-1, k,vertices.length);
31508
31509 for ( var s = 0, sl = ( steps + bevelSegments * 2 ); s < sl; s ++ ) {
31510
31511 var slen1 = vlen * s;
31512 var slen2 = vlen * ( s + 1 );
31513
31514 var a = layeroffset + j + slen1,
31515 b = layeroffset + k + slen1,
31516 c = layeroffset + k + slen2,
31517 d = layeroffset + j + slen2;
31518
31519 f4( a, b, c, d );
31520
31521 }
31522
31523 }
31524
31525 }
31526
31527 function v( x, y, z ) {
31528
31529 placeholder.push( x );
31530 placeholder.push( y );
31531 placeholder.push( z );
31532
31533 }
31534
31535
31536 function f3( a, b, c ) {
31537
31538 addVertex( a );
31539 addVertex( b );
31540 addVertex( c );
31541
31542 var nextIndex = verticesArray.length / 3;
31543 var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
31544
31545 addUV( uvs[ 0 ] );
31546 addUV( uvs[ 1 ] );
31547 addUV( uvs[ 2 ] );
31548
31549 }
31550
31551 function f4( a, b, c, d ) {
31552
31553 addVertex( a );
31554 addVertex( b );
31555 addVertex( d );
31556
31557 addVertex( b );
31558 addVertex( c );
31559 addVertex( d );
31560
31561
31562 var nextIndex = verticesArray.length / 3;
31563 var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
31564
31565 addUV( uvs[ 0 ] );
31566 addUV( uvs[ 1 ] );
31567 addUV( uvs[ 3 ] );
31568
31569 addUV( uvs[ 1 ] );
31570 addUV( uvs[ 2 ] );
31571 addUV( uvs[ 3 ] );
31572
31573 }
31574
31575 function addVertex( index ) {
31576
31577 verticesArray.push( placeholder[ index * 3 + 0 ] );
31578 verticesArray.push( placeholder[ index * 3 + 1 ] );
31579 verticesArray.push( placeholder[ index * 3 + 2 ] );
31580
31581 }
31582
31583
31584 function addUV( vector2 ) {
31585
31586 uvArray.push( vector2.x );
31587 uvArray.push( vector2.y );
31588
31589 }
31590
31591 }
31592
31593 }
31594
31595 ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
31596 ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
31597
31598 ExtrudeBufferGeometry.prototype.toJSON = function () {
31599
31600 var data = BufferGeometry.prototype.toJSON.call( this );
31601
31602 var shapes = this.parameters.shapes;
31603 var options = this.parameters.options;
31604
31605 return toJSON( shapes, options, data );
31606
31607 };
31608
31609 //
31610
31611 var WorldUVGenerator = {
31612
31613 generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
31614
31615 var a_x = vertices[ indexA * 3 ];
31616 var a_y = vertices[ indexA * 3 + 1 ];
31617 var b_x = vertices[ indexB * 3 ];
31618 var b_y = vertices[ indexB * 3 + 1 ];
31619 var c_x = vertices[ indexC * 3 ];
31620 var c_y = vertices[ indexC * 3 + 1 ];
31621
31622 return [
31623 new Vector2( a_x, a_y ),
31624 new Vector2( b_x, b_y ),
31625 new Vector2( c_x, c_y )
31626 ];
31627
31628 },
31629
31630 generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {
31631
31632 var a_x = vertices[ indexA * 3 ];
31633 var a_y = vertices[ indexA * 3 + 1 ];
31634 var a_z = vertices[ indexA * 3 + 2 ];
31635 var b_x = vertices[ indexB * 3 ];
31636 var b_y = vertices[ indexB * 3 + 1 ];
31637 var b_z = vertices[ indexB * 3 + 2 ];
31638 var c_x = vertices[ indexC * 3 ];
31639 var c_y = vertices[ indexC * 3 + 1 ];
31640 var c_z = vertices[ indexC * 3 + 2 ];
31641 var d_x = vertices[ indexD * 3 ];
31642 var d_y = vertices[ indexD * 3 + 1 ];
31643 var d_z = vertices[ indexD * 3 + 2 ];
31644
31645 if ( Math.abs( a_y - b_y ) < 0.01 ) {
31646
31647 return [
31648 new Vector2( a_x, 1 - a_z ),
31649 new Vector2( b_x, 1 - b_z ),
31650 new Vector2( c_x, 1 - c_z ),
31651 new Vector2( d_x, 1 - d_z )
31652 ];
31653
31654 } else {
31655
31656 return [
31657 new Vector2( a_y, 1 - a_z ),
31658 new Vector2( b_y, 1 - b_z ),
31659 new Vector2( c_y, 1 - c_z ),
31660 new Vector2( d_y, 1 - d_z )
31661 ];
31662
31663 }
31664
31665 }
31666 };
31667
31668 function toJSON( shapes, options, data ) {
31669
31670 //
31671
31672 data.shapes = [];
31673
31674 if ( Array.isArray( shapes ) ) {
31675
31676 for ( var i = 0, l = shapes.length; i < l; i ++ ) {
31677
31678 var shape = shapes[ i ];
31679
31680 data.shapes.push( shape.uuid );
31681
31682 }
31683
31684 } else {
31685
31686 data.shapes.push( shapes.uuid );
31687
31688 }
31689
31690 //
31691
31692 if ( options.extrudePath !== undefined ) { data.options.extrudePath = options.extrudePath.toJSON(); }
31693
31694 return data;
31695
31696 }
31697
31698 /**
31699 * Text = 3D Text
31700 *
31701 * parameters = {
31702 * font: <THREE.Font>, // font
31703 *
31704 * size: <float>, // size of the text
31705 * height: <float>, // thickness to extrude text
31706 * curveSegments: <int>, // number of points on the curves
31707 *
31708 * bevelEnabled: <bool>, // turn on bevel
31709 * bevelThickness: <float>, // how deep into text bevel goes
31710 * bevelSize: <float>, // how far from text outline (including bevelOffset) is bevel
31711 * bevelOffset: <float> // how far from text outline does bevel start
31712 * }
31713 */
31714
31715 // TextGeometry
31716
31717 function TextGeometry( text, parameters ) {
31718
31719 Geometry.call( this );
31720
31721 this.type = 'TextGeometry';
31722
31723 this.parameters = {
31724 text: text,
31725 parameters: parameters
31726 };
31727
31728 this.fromBufferGeometry( new TextBufferGeometry( text, parameters ) );
31729 this.mergeVertices();
31730
31731 }
31732
31733 TextGeometry.prototype = Object.create( Geometry.prototype );
31734 TextGeometry.prototype.constructor = TextGeometry;
31735
31736 // TextBufferGeometry
31737
31738 function TextBufferGeometry( text, parameters ) {
31739
31740 parameters = parameters || {};
31741
31742 var font = parameters.font;
31743
31744 if ( ! ( font && font.isFont ) ) {
31745
31746 console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );
31747 return new Geometry();
31748
31749 }
31750
31751 var shapes = font.generateShapes( text, parameters.size );
31752
31753 // translate parameters to ExtrudeGeometry API
31754
31755 parameters.depth = parameters.height !== undefined ? parameters.height : 50;
31756
31757 // defaults
31758
31759 if ( parameters.bevelThickness === undefined ) { parameters.bevelThickness = 10; }
31760 if ( parameters.bevelSize === undefined ) { parameters.bevelSize = 8; }
31761 if ( parameters.bevelEnabled === undefined ) { parameters.bevelEnabled = false; }
31762
31763 ExtrudeBufferGeometry.call( this, shapes, parameters );
31764
31765 this.type = 'TextBufferGeometry';
31766
31767 }
31768
31769 TextBufferGeometry.prototype = Object.create( ExtrudeBufferGeometry.prototype );
31770 TextBufferGeometry.prototype.constructor = TextBufferGeometry;
31771
31772 // SphereGeometry
31773
31774 function SphereGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
31775
31776 Geometry.call( this );
31777
31778 this.type = 'SphereGeometry';
31779
31780 this.parameters = {
31781 radius: radius,
31782 widthSegments: widthSegments,
31783 heightSegments: heightSegments,
31784 phiStart: phiStart,
31785 phiLength: phiLength,
31786 thetaStart: thetaStart,
31787 thetaLength: thetaLength
31788 };
31789
31790 this.fromBufferGeometry( new SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) );
31791 this.mergeVertices();
31792
31793 }
31794
31795 SphereGeometry.prototype = Object.create( Geometry.prototype );
31796 SphereGeometry.prototype.constructor = SphereGeometry;
31797
31798 // SphereBufferGeometry
31799
31800 function SphereBufferGeometry( radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength ) {
31801
31802 BufferGeometry.call( this );
31803
31804 this.type = 'SphereBufferGeometry';
31805
31806 this.parameters = {
31807 radius: radius,
31808 widthSegments: widthSegments,
31809 heightSegments: heightSegments,
31810 phiStart: phiStart,
31811 phiLength: phiLength,
31812 thetaStart: thetaStart,
31813 thetaLength: thetaLength
31814 };
31815
31816 radius = radius || 1;
31817
31818 widthSegments = Math.max( 3, Math.floor( widthSegments ) || 8 );
31819 heightSegments = Math.max( 2, Math.floor( heightSegments ) || 6 );
31820
31821 phiStart = phiStart !== undefined ? phiStart : 0;
31822 phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
31823
31824 thetaStart = thetaStart !== undefined ? thetaStart : 0;
31825 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
31826
31827 var thetaEnd = Math.min( thetaStart + thetaLength, Math.PI );
31828
31829 var index = 0;
31830 var grid = [];
31831
31832 var vertex = new Vector3();
31833 var normal = new Vector3();
31834
31835 // buffers
31836
31837 var indices = [];
31838 var vertices = [];
31839 var normals = [];
31840 var uvs = [];
31841
31842 // generate vertices, normals and uvs
31843
31844 for ( var iy = 0; iy <= heightSegments; iy ++ ) {
31845
31846 var verticesRow = [];
31847
31848 var v = iy / heightSegments;
31849
31850 // special case for the poles
31851
31852 var uOffset = 0;
31853
31854 if ( iy == 0 && thetaStart == 0 ) {
31855
31856 uOffset = 0.5 / widthSegments;
31857
31858 } else if ( iy == heightSegments && thetaEnd == Math.PI ) {
31859
31860 uOffset = - 0.5 / widthSegments;
31861
31862 }
31863
31864 for ( var ix = 0; ix <= widthSegments; ix ++ ) {
31865
31866 var u = ix / widthSegments;
31867
31868 // vertex
31869
31870 vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
31871 vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
31872 vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
31873
31874 vertices.push( vertex.x, vertex.y, vertex.z );
31875
31876 // normal
31877
31878 normal.copy( vertex ).normalize();
31879 normals.push( normal.x, normal.y, normal.z );
31880
31881 // uv
31882
31883 uvs.push( u + uOffset, 1 - v );
31884
31885 verticesRow.push( index ++ );
31886
31887 }
31888
31889 grid.push( verticesRow );
31890
31891 }
31892
31893 // indices
31894
31895 for ( var iy$1 = 0; iy$1 < heightSegments; iy$1 ++ ) {
31896
31897 for ( var ix$1 = 0; ix$1 < widthSegments; ix$1 ++ ) {
31898
31899 var a = grid[ iy$1 ][ ix$1 + 1 ];
31900 var b = grid[ iy$1 ][ ix$1 ];
31901 var c = grid[ iy$1 + 1 ][ ix$1 ];
31902 var d = grid[ iy$1 + 1 ][ ix$1 + 1 ];
31903
31904 if ( iy$1 !== 0 || thetaStart > 0 ) { indices.push( a, b, d ); }
31905 if ( iy$1 !== heightSegments - 1 || thetaEnd < Math.PI ) { indices.push( b, c, d ); }
31906
31907 }
31908
31909 }
31910
31911 // build geometry
31912
31913 this.setIndex( indices );
31914 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
31915 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
31916 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
31917
31918 }
31919
31920 SphereBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
31921 SphereBufferGeometry.prototype.constructor = SphereBufferGeometry;
31922
31923 // RingGeometry
31924
31925 function RingGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
31926
31927 Geometry.call( this );
31928
31929 this.type = 'RingGeometry';
31930
31931 this.parameters = {
31932 innerRadius: innerRadius,
31933 outerRadius: outerRadius,
31934 thetaSegments: thetaSegments,
31935 phiSegments: phiSegments,
31936 thetaStart: thetaStart,
31937 thetaLength: thetaLength
31938 };
31939
31940 this.fromBufferGeometry( new RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) );
31941 this.mergeVertices();
31942
31943 }
31944
31945 RingGeometry.prototype = Object.create( Geometry.prototype );
31946 RingGeometry.prototype.constructor = RingGeometry;
31947
31948 // RingBufferGeometry
31949
31950 function RingBufferGeometry( innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength ) {
31951
31952 BufferGeometry.call( this );
31953
31954 this.type = 'RingBufferGeometry';
31955
31956 this.parameters = {
31957 innerRadius: innerRadius,
31958 outerRadius: outerRadius,
31959 thetaSegments: thetaSegments,
31960 phiSegments: phiSegments,
31961 thetaStart: thetaStart,
31962 thetaLength: thetaLength
31963 };
31964
31965 innerRadius = innerRadius || 0.5;
31966 outerRadius = outerRadius || 1;
31967
31968 thetaStart = thetaStart !== undefined ? thetaStart : 0;
31969 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
31970
31971 thetaSegments = thetaSegments !== undefined ? Math.max( 3, thetaSegments ) : 8;
31972 phiSegments = phiSegments !== undefined ? Math.max( 1, phiSegments ) : 1;
31973
31974 // buffers
31975
31976 var indices = [];
31977 var vertices = [];
31978 var normals = [];
31979 var uvs = [];
31980
31981 // some helper variables
31982
31983 var radius = innerRadius;
31984 var radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
31985 var vertex = new Vector3();
31986 var uv = new Vector2();
31987
31988 // generate vertices, normals and uvs
31989
31990 for ( var j = 0; j <= phiSegments; j ++ ) {
31991
31992 for ( var i = 0; i <= thetaSegments; i ++ ) {
31993
31994 // values are generate from the inside of the ring to the outside
31995
31996 var segment = thetaStart + i / thetaSegments * thetaLength;
31997
31998 // vertex
31999
32000 vertex.x = radius * Math.cos( segment );
32001 vertex.y = radius * Math.sin( segment );
32002
32003 vertices.push( vertex.x, vertex.y, vertex.z );
32004
32005 // normal
32006
32007 normals.push( 0, 0, 1 );
32008
32009 // uv
32010
32011 uv.x = ( vertex.x / outerRadius + 1 ) / 2;
32012 uv.y = ( vertex.y / outerRadius + 1 ) / 2;
32013
32014 uvs.push( uv.x, uv.y );
32015
32016 }
32017
32018 // increase the radius for next row of vertices
32019
32020 radius += radiusStep;
32021
32022 }
32023
32024 // indices
32025
32026 for ( var j$1 = 0; j$1 < phiSegments; j$1 ++ ) {
32027
32028 var thetaSegmentLevel = j$1 * ( thetaSegments + 1 );
32029
32030 for ( var i$1 = 0; i$1 < thetaSegments; i$1 ++ ) {
32031
32032 var segment$1 = i$1 + thetaSegmentLevel;
32033
32034 var a = segment$1;
32035 var b = segment$1 + thetaSegments + 1;
32036 var c = segment$1 + thetaSegments + 2;
32037 var d = segment$1 + 1;
32038
32039 // faces
32040
32041 indices.push( a, b, d );
32042 indices.push( b, c, d );
32043
32044 }
32045
32046 }
32047
32048 // build geometry
32049
32050 this.setIndex( indices );
32051 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32052 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
32053 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32054
32055 }
32056
32057 RingBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32058 RingBufferGeometry.prototype.constructor = RingBufferGeometry;
32059
32060 // LatheGeometry
32061
32062 function LatheGeometry( points, segments, phiStart, phiLength ) {
32063
32064 Geometry.call( this );
32065
32066 this.type = 'LatheGeometry';
32067
32068 this.parameters = {
32069 points: points,
32070 segments: segments,
32071 phiStart: phiStart,
32072 phiLength: phiLength
32073 };
32074
32075 this.fromBufferGeometry( new LatheBufferGeometry( points, segments, phiStart, phiLength ) );
32076 this.mergeVertices();
32077
32078 }
32079
32080 LatheGeometry.prototype = Object.create( Geometry.prototype );
32081 LatheGeometry.prototype.constructor = LatheGeometry;
32082
32083 // LatheBufferGeometry
32084
32085 function LatheBufferGeometry( points, segments, phiStart, phiLength ) {
32086
32087 BufferGeometry.call( this );
32088
32089 this.type = 'LatheBufferGeometry';
32090
32091 this.parameters = {
32092 points: points,
32093 segments: segments,
32094 phiStart: phiStart,
32095 phiLength: phiLength
32096 };
32097
32098 segments = Math.floor( segments ) || 12;
32099 phiStart = phiStart || 0;
32100 phiLength = phiLength || Math.PI * 2;
32101
32102 // clamp phiLength so it's in range of [ 0, 2PI ]
32103
32104 phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 );
32105
32106
32107 // buffers
32108
32109 var indices = [];
32110 var vertices = [];
32111 var uvs = [];
32112
32113 // helper variables
32114
32115 var inverseSegments = 1.0 / segments;
32116 var vertex = new Vector3();
32117 var uv = new Vector2();
32118
32119 // generate vertices and uvs
32120
32121 for ( var i = 0; i <= segments; i ++ ) {
32122
32123 var phi = phiStart + i * inverseSegments * phiLength;
32124
32125 var sin = Math.sin( phi );
32126 var cos = Math.cos( phi );
32127
32128 for ( var j = 0; j <= ( points.length - 1 ); j ++ ) {
32129
32130 // vertex
32131
32132 vertex.x = points[ j ].x * sin;
32133 vertex.y = points[ j ].y;
32134 vertex.z = points[ j ].x * cos;
32135
32136 vertices.push( vertex.x, vertex.y, vertex.z );
32137
32138 // uv
32139
32140 uv.x = i / segments;
32141 uv.y = j / ( points.length - 1 );
32142
32143 uvs.push( uv.x, uv.y );
32144
32145
32146 }
32147
32148 }
32149
32150 // indices
32151
32152 for ( var i$1 = 0; i$1 < segments; i$1 ++ ) {
32153
32154 for ( var j$1 = 0; j$1 < ( points.length - 1 ); j$1 ++ ) {
32155
32156 var base = j$1 + i$1 * points.length;
32157
32158 var a = base;
32159 var b = base + points.length;
32160 var c = base + points.length + 1;
32161 var d = base + 1;
32162
32163 // faces
32164
32165 indices.push( a, b, d );
32166 indices.push( b, c, d );
32167
32168 }
32169
32170 }
32171
32172 // build geometry
32173
32174 this.setIndex( indices );
32175 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32176 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32177
32178 // generate normals
32179
32180 this.computeVertexNormals();
32181
32182 // if the geometry is closed, we need to average the normals along the seam.
32183 // because the corresponding vertices are identical (but still have different UVs).
32184
32185 if ( phiLength === Math.PI * 2 ) {
32186
32187 var normals = this.attributes.normal.array;
32188 var n1 = new Vector3();
32189 var n2 = new Vector3();
32190 var n = new Vector3();
32191
32192 // this is the buffer offset for the last line of vertices
32193
32194 var base$1 = segments * points.length * 3;
32195
32196 for ( var i$2 = 0, j$2 = 0; i$2 < points.length; i$2 ++, j$2 += 3 ) {
32197
32198 // select the normal of the vertex in the first line
32199
32200 n1.x = normals[ j$2 + 0 ];
32201 n1.y = normals[ j$2 + 1 ];
32202 n1.z = normals[ j$2 + 2 ];
32203
32204 // select the normal of the vertex in the last line
32205
32206 n2.x = normals[ base$1 + j$2 + 0 ];
32207 n2.y = normals[ base$1 + j$2 + 1 ];
32208 n2.z = normals[ base$1 + j$2 + 2 ];
32209
32210 // average normals
32211
32212 n.addVectors( n1, n2 ).normalize();
32213
32214 // assign the new values to both normals
32215
32216 normals[ j$2 + 0 ] = normals[ base$1 + j$2 + 0 ] = n.x;
32217 normals[ j$2 + 1 ] = normals[ base$1 + j$2 + 1 ] = n.y;
32218 normals[ j$2 + 2 ] = normals[ base$1 + j$2 + 2 ] = n.z;
32219
32220 }
32221
32222 }
32223
32224 }
32225
32226 LatheBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32227 LatheBufferGeometry.prototype.constructor = LatheBufferGeometry;
32228
32229 // ShapeGeometry
32230
32231 function ShapeGeometry( shapes, curveSegments ) {
32232
32233 Geometry.call( this );
32234
32235 this.type = 'ShapeGeometry';
32236
32237 if ( typeof curveSegments === 'object' ) {
32238
32239 console.warn( 'THREE.ShapeGeometry: Options parameter has been removed.' );
32240
32241 curveSegments = curveSegments.curveSegments;
32242
32243 }
32244
32245 this.parameters = {
32246 shapes: shapes,
32247 curveSegments: curveSegments
32248 };
32249
32250 this.fromBufferGeometry( new ShapeBufferGeometry( shapes, curveSegments ) );
32251 this.mergeVertices();
32252
32253 }
32254
32255 ShapeGeometry.prototype = Object.create( Geometry.prototype );
32256 ShapeGeometry.prototype.constructor = ShapeGeometry;
32257
32258 ShapeGeometry.prototype.toJSON = function () {
32259
32260 var data = Geometry.prototype.toJSON.call( this );
32261
32262 var shapes = this.parameters.shapes;
32263
32264 return toJSON$1( shapes, data );
32265
32266 };
32267
32268 // ShapeBufferGeometry
32269
32270 function ShapeBufferGeometry( shapes, curveSegments ) {
32271
32272 BufferGeometry.call( this );
32273
32274 this.type = 'ShapeBufferGeometry';
32275
32276 this.parameters = {
32277 shapes: shapes,
32278 curveSegments: curveSegments
32279 };
32280
32281 curveSegments = curveSegments || 12;
32282
32283 // buffers
32284
32285 var indices = [];
32286 var vertices = [];
32287 var normals = [];
32288 var uvs = [];
32289
32290 // helper variables
32291
32292 var groupStart = 0;
32293 var groupCount = 0;
32294
32295 // allow single and array values for "shapes" parameter
32296
32297 if ( Array.isArray( shapes ) === false ) {
32298
32299 addShape( shapes );
32300
32301 } else {
32302
32303 for ( var i = 0; i < shapes.length; i ++ ) {
32304
32305 addShape( shapes[ i ] );
32306
32307 this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support
32308
32309 groupStart += groupCount;
32310 groupCount = 0;
32311
32312 }
32313
32314 }
32315
32316 // build geometry
32317
32318 this.setIndex( indices );
32319 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32320 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
32321 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32322
32323
32324 // helper functions
32325
32326 function addShape( shape ) {
32327
32328 var indexOffset = vertices.length / 3;
32329 var points = shape.extractPoints( curveSegments );
32330
32331 var shapeVertices = points.shape;
32332 var shapeHoles = points.holes;
32333
32334 // check direction of vertices
32335
32336 if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
32337
32338 shapeVertices = shapeVertices.reverse();
32339
32340 }
32341
32342 for ( var i = 0, l = shapeHoles.length; i < l; i ++ ) {
32343
32344 var shapeHole = shapeHoles[ i ];
32345
32346 if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
32347
32348 shapeHoles[ i ] = shapeHole.reverse();
32349
32350 }
32351
32352 }
32353
32354 var faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
32355
32356 // join vertices of inner and outer paths to a single array
32357
32358 for ( var i$1 = 0, l$1 = shapeHoles.length; i$1 < l$1; i$1 ++ ) {
32359
32360 var shapeHole$1 = shapeHoles[ i$1 ];
32361 shapeVertices = shapeVertices.concat( shapeHole$1 );
32362
32363 }
32364
32365 // vertices, normals, uvs
32366
32367 for ( var i$2 = 0, l$2 = shapeVertices.length; i$2 < l$2; i$2 ++ ) {
32368
32369 var vertex = shapeVertices[ i$2 ];
32370
32371 vertices.push( vertex.x, vertex.y, 0 );
32372 normals.push( 0, 0, 1 );
32373 uvs.push( vertex.x, vertex.y ); // world uvs
32374
32375 }
32376
32377 // incides
32378
32379 for ( var i$3 = 0, l$3 = faces.length; i$3 < l$3; i$3 ++ ) {
32380
32381 var face = faces[ i$3 ];
32382
32383 var a = face[ 0 ] + indexOffset;
32384 var b = face[ 1 ] + indexOffset;
32385 var c = face[ 2 ] + indexOffset;
32386
32387 indices.push( a, b, c );
32388 groupCount += 3;
32389
32390 }
32391
32392 }
32393
32394 }
32395
32396 ShapeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32397 ShapeBufferGeometry.prototype.constructor = ShapeBufferGeometry;
32398
32399 ShapeBufferGeometry.prototype.toJSON = function () {
32400
32401 var data = BufferGeometry.prototype.toJSON.call( this );
32402
32403 var shapes = this.parameters.shapes;
32404
32405 return toJSON$1( shapes, data );
32406
32407 };
32408
32409 //
32410
32411 function toJSON$1( shapes, data ) {
32412
32413 data.shapes = [];
32414
32415 if ( Array.isArray( shapes ) ) {
32416
32417 for ( var i = 0, l = shapes.length; i < l; i ++ ) {
32418
32419 var shape = shapes[ i ];
32420
32421 data.shapes.push( shape.uuid );
32422
32423 }
32424
32425 } else {
32426
32427 data.shapes.push( shapes.uuid );
32428
32429 }
32430
32431 return data;
32432
32433 }
32434
32435 function EdgesGeometry( geometry, thresholdAngle ) {
32436
32437 BufferGeometry.call( this );
32438
32439 this.type = 'EdgesGeometry';
32440
32441 this.parameters = {
32442 thresholdAngle: thresholdAngle
32443 };
32444
32445 thresholdAngle = ( thresholdAngle !== undefined ) ? thresholdAngle : 1;
32446
32447 // buffer
32448
32449 var vertices = [];
32450
32451 // helper variables
32452
32453 var thresholdDot = Math.cos( MathUtils.DEG2RAD * thresholdAngle );
32454 var edge = [ 0, 0 ], edges = {};
32455 var edge1, edge2, key;
32456 var keys = [ 'a', 'b', 'c' ];
32457
32458 // prepare source geometry
32459
32460 var geometry2;
32461
32462 if ( geometry.isBufferGeometry ) {
32463
32464 geometry2 = new Geometry();
32465 geometry2.fromBufferGeometry( geometry );
32466
32467 } else {
32468
32469 geometry2 = geometry.clone();
32470
32471 }
32472
32473 geometry2.mergeVertices();
32474 geometry2.computeFaceNormals();
32475
32476 var sourceVertices = geometry2.vertices;
32477 var faces = geometry2.faces;
32478
32479 // now create a data structure where each entry represents an edge with its adjoining faces
32480
32481 for ( var i = 0, l = faces.length; i < l; i ++ ) {
32482
32483 var face = faces[ i ];
32484
32485 for ( var j = 0; j < 3; j ++ ) {
32486
32487 edge1 = face[ keys[ j ] ];
32488 edge2 = face[ keys[ ( j + 1 ) % 3 ] ];
32489 edge[ 0 ] = Math.min( edge1, edge2 );
32490 edge[ 1 ] = Math.max( edge1, edge2 );
32491
32492 key = edge[ 0 ] + ',' + edge[ 1 ];
32493
32494 if ( edges[ key ] === undefined ) {
32495
32496 edges[ key ] = { index1: edge[ 0 ], index2: edge[ 1 ], face1: i, face2: undefined };
32497
32498 } else {
32499
32500 edges[ key ].face2 = i;
32501
32502 }
32503
32504 }
32505
32506 }
32507
32508 // generate vertices
32509
32510 for ( key in edges ) {
32511
32512 var e = edges[ key ];
32513
32514 // an edge is only rendered if the angle (in degrees) between the face normals of the adjoining faces exceeds this value. default = 1 degree.
32515
32516 if ( e.face2 === undefined || faces[ e.face1 ].normal.dot( faces[ e.face2 ].normal ) <= thresholdDot ) {
32517
32518 var vertex = sourceVertices[ e.index1 ];
32519 vertices.push( vertex.x, vertex.y, vertex.z );
32520
32521 vertex = sourceVertices[ e.index2 ];
32522 vertices.push( vertex.x, vertex.y, vertex.z );
32523
32524 }
32525
32526 }
32527
32528 // build geometry
32529
32530 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32531
32532 }
32533
32534 EdgesGeometry.prototype = Object.create( BufferGeometry.prototype );
32535 EdgesGeometry.prototype.constructor = EdgesGeometry;
32536
32537 // CylinderGeometry
32538
32539 function CylinderGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
32540
32541 Geometry.call( this );
32542
32543 this.type = 'CylinderGeometry';
32544
32545 this.parameters = {
32546 radiusTop: radiusTop,
32547 radiusBottom: radiusBottom,
32548 height: height,
32549 radialSegments: radialSegments,
32550 heightSegments: heightSegments,
32551 openEnded: openEnded,
32552 thetaStart: thetaStart,
32553 thetaLength: thetaLength
32554 };
32555
32556 this.fromBufferGeometry( new CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) );
32557 this.mergeVertices();
32558
32559 }
32560
32561 CylinderGeometry.prototype = Object.create( Geometry.prototype );
32562 CylinderGeometry.prototype.constructor = CylinderGeometry;
32563
32564 // CylinderBufferGeometry
32565
32566 function CylinderBufferGeometry( radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
32567
32568 BufferGeometry.call( this );
32569
32570 this.type = 'CylinderBufferGeometry';
32571
32572 this.parameters = {
32573 radiusTop: radiusTop,
32574 radiusBottom: radiusBottom,
32575 height: height,
32576 radialSegments: radialSegments,
32577 heightSegments: heightSegments,
32578 openEnded: openEnded,
32579 thetaStart: thetaStart,
32580 thetaLength: thetaLength
32581 };
32582
32583 var scope = this;
32584
32585 radiusTop = radiusTop !== undefined ? radiusTop : 1;
32586 radiusBottom = radiusBottom !== undefined ? radiusBottom : 1;
32587 height = height || 1;
32588
32589 radialSegments = Math.floor( radialSegments ) || 8;
32590 heightSegments = Math.floor( heightSegments ) || 1;
32591
32592 openEnded = openEnded !== undefined ? openEnded : false;
32593 thetaStart = thetaStart !== undefined ? thetaStart : 0.0;
32594 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
32595
32596 // buffers
32597
32598 var indices = [];
32599 var vertices = [];
32600 var normals = [];
32601 var uvs = [];
32602
32603 // helper variables
32604
32605 var index = 0;
32606 var indexArray = [];
32607 var halfHeight = height / 2;
32608 var groupStart = 0;
32609
32610 // generate geometry
32611
32612 generateTorso();
32613
32614 if ( openEnded === false ) {
32615
32616 if ( radiusTop > 0 ) { generateCap( true ); }
32617 if ( radiusBottom > 0 ) { generateCap( false ); }
32618
32619 }
32620
32621 // build geometry
32622
32623 this.setIndex( indices );
32624 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32625 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
32626 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32627
32628 function generateTorso() {
32629
32630 var normal = new Vector3();
32631 var vertex = new Vector3();
32632
32633 var groupCount = 0;
32634
32635 // this will be used to calculate the normal
32636 var slope = ( radiusBottom - radiusTop ) / height;
32637
32638 // generate vertices, normals and uvs
32639
32640 for ( var y = 0; y <= heightSegments; y ++ ) {
32641
32642 var indexRow = [];
32643
32644 var v = y / heightSegments;
32645
32646 // calculate the radius of the current row
32647
32648 var radius = v * ( radiusBottom - radiusTop ) + radiusTop;
32649
32650 for ( var x = 0; x <= radialSegments; x ++ ) {
32651
32652 var u = x / radialSegments;
32653
32654 var theta = u * thetaLength + thetaStart;
32655
32656 var sinTheta = Math.sin( theta );
32657 var cosTheta = Math.cos( theta );
32658
32659 // vertex
32660
32661 vertex.x = radius * sinTheta;
32662 vertex.y = - v * height + halfHeight;
32663 vertex.z = radius * cosTheta;
32664 vertices.push( vertex.x, vertex.y, vertex.z );
32665
32666 // normal
32667
32668 normal.set( sinTheta, slope, cosTheta ).normalize();
32669 normals.push( normal.x, normal.y, normal.z );
32670
32671 // uv
32672
32673 uvs.push( u, 1 - v );
32674
32675 // save index of vertex in respective row
32676
32677 indexRow.push( index ++ );
32678
32679 }
32680
32681 // now save vertices of the row in our index array
32682
32683 indexArray.push( indexRow );
32684
32685 }
32686
32687 // generate indices
32688
32689 for ( var x$1 = 0; x$1 < radialSegments; x$1 ++ ) {
32690
32691 for ( var y$1 = 0; y$1 < heightSegments; y$1 ++ ) {
32692
32693 // we use the index array to access the correct indices
32694
32695 var a = indexArray[ y$1 ][ x$1 ];
32696 var b = indexArray[ y$1 + 1 ][ x$1 ];
32697 var c = indexArray[ y$1 + 1 ][ x$1 + 1 ];
32698 var d = indexArray[ y$1 ][ x$1 + 1 ];
32699
32700 // faces
32701
32702 indices.push( a, b, d );
32703 indices.push( b, c, d );
32704
32705 // update group counter
32706
32707 groupCount += 6;
32708
32709 }
32710
32711 }
32712
32713 // add a group to the geometry. this will ensure multi material support
32714
32715 scope.addGroup( groupStart, groupCount, 0 );
32716
32717 // calculate new start value for groups
32718
32719 groupStart += groupCount;
32720
32721 }
32722
32723 function generateCap( top ) {
32724
32725 var centerIndexStart, centerIndexEnd;
32726
32727 var uv = new Vector2();
32728 var vertex = new Vector3();
32729
32730 var groupCount = 0;
32731
32732 var radius = ( top === true ) ? radiusTop : radiusBottom;
32733 var sign = ( top === true ) ? 1 : - 1;
32734
32735 // save the index of the first center vertex
32736 centerIndexStart = index;
32737
32738 // first we generate the center vertex data of the cap.
32739 // because the geometry needs one set of uvs per face,
32740 // we must generate a center vertex per face/segment
32741
32742 for ( var x = 1; x <= radialSegments; x ++ ) {
32743
32744 // vertex
32745
32746 vertices.push( 0, halfHeight * sign, 0 );
32747
32748 // normal
32749
32750 normals.push( 0, sign, 0 );
32751
32752 // uv
32753
32754 uvs.push( 0.5, 0.5 );
32755
32756 // increase index
32757
32758 index ++;
32759
32760 }
32761
32762 // save the index of the last center vertex
32763
32764 centerIndexEnd = index;
32765
32766 // now we generate the surrounding vertices, normals and uvs
32767
32768 for ( var x$1 = 0; x$1 <= radialSegments; x$1 ++ ) {
32769
32770 var u = x$1 / radialSegments;
32771 var theta = u * thetaLength + thetaStart;
32772
32773 var cosTheta = Math.cos( theta );
32774 var sinTheta = Math.sin( theta );
32775
32776 // vertex
32777
32778 vertex.x = radius * sinTheta;
32779 vertex.y = halfHeight * sign;
32780 vertex.z = radius * cosTheta;
32781 vertices.push( vertex.x, vertex.y, vertex.z );
32782
32783 // normal
32784
32785 normals.push( 0, sign, 0 );
32786
32787 // uv
32788
32789 uv.x = ( cosTheta * 0.5 ) + 0.5;
32790 uv.y = ( sinTheta * 0.5 * sign ) + 0.5;
32791 uvs.push( uv.x, uv.y );
32792
32793 // increase index
32794
32795 index ++;
32796
32797 }
32798
32799 // generate indices
32800
32801 for ( var x$2 = 0; x$2 < radialSegments; x$2 ++ ) {
32802
32803 var c = centerIndexStart + x$2;
32804 var i = centerIndexEnd + x$2;
32805
32806 if ( top === true ) {
32807
32808 // face top
32809
32810 indices.push( i, i + 1, c );
32811
32812 } else {
32813
32814 // face bottom
32815
32816 indices.push( i + 1, i, c );
32817
32818 }
32819
32820 groupCount += 3;
32821
32822 }
32823
32824 // add a group to the geometry. this will ensure multi material support
32825
32826 scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );
32827
32828 // calculate new start value for groups
32829
32830 groupStart += groupCount;
32831
32832 }
32833
32834 }
32835
32836 CylinderBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32837 CylinderBufferGeometry.prototype.constructor = CylinderBufferGeometry;
32838
32839 // ConeGeometry
32840
32841 function ConeGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
32842
32843 CylinderGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
32844
32845 this.type = 'ConeGeometry';
32846
32847 this.parameters = {
32848 radius: radius,
32849 height: height,
32850 radialSegments: radialSegments,
32851 heightSegments: heightSegments,
32852 openEnded: openEnded,
32853 thetaStart: thetaStart,
32854 thetaLength: thetaLength
32855 };
32856
32857 }
32858
32859 ConeGeometry.prototype = Object.create( CylinderGeometry.prototype );
32860 ConeGeometry.prototype.constructor = ConeGeometry;
32861
32862 // ConeBufferGeometry
32863
32864 function ConeBufferGeometry( radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength ) {
32865
32866 CylinderBufferGeometry.call( this, 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
32867
32868 this.type = 'ConeBufferGeometry';
32869
32870 this.parameters = {
32871 radius: radius,
32872 height: height,
32873 radialSegments: radialSegments,
32874 heightSegments: heightSegments,
32875 openEnded: openEnded,
32876 thetaStart: thetaStart,
32877 thetaLength: thetaLength
32878 };
32879
32880 }
32881
32882 ConeBufferGeometry.prototype = Object.create( CylinderBufferGeometry.prototype );
32883 ConeBufferGeometry.prototype.constructor = ConeBufferGeometry;
32884
32885 // CircleGeometry
32886
32887 function CircleGeometry( radius, segments, thetaStart, thetaLength ) {
32888
32889 Geometry.call( this );
32890
32891 this.type = 'CircleGeometry';
32892
32893 this.parameters = {
32894 radius: radius,
32895 segments: segments,
32896 thetaStart: thetaStart,
32897 thetaLength: thetaLength
32898 };
32899
32900 this.fromBufferGeometry( new CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) );
32901 this.mergeVertices();
32902
32903 }
32904
32905 CircleGeometry.prototype = Object.create( Geometry.prototype );
32906 CircleGeometry.prototype.constructor = CircleGeometry;
32907
32908 // CircleBufferGeometry
32909
32910 function CircleBufferGeometry( radius, segments, thetaStart, thetaLength ) {
32911
32912 BufferGeometry.call( this );
32913
32914 this.type = 'CircleBufferGeometry';
32915
32916 this.parameters = {
32917 radius: radius,
32918 segments: segments,
32919 thetaStart: thetaStart,
32920 thetaLength: thetaLength
32921 };
32922
32923 radius = radius || 1;
32924 segments = segments !== undefined ? Math.max( 3, segments ) : 8;
32925
32926 thetaStart = thetaStart !== undefined ? thetaStart : 0;
32927 thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
32928
32929 // buffers
32930
32931 var indices = [];
32932 var vertices = [];
32933 var normals = [];
32934 var uvs = [];
32935
32936 // helper variables
32937
32938 var vertex = new Vector3();
32939 var uv = new Vector2();
32940
32941 // center point
32942
32943 vertices.push( 0, 0, 0 );
32944 normals.push( 0, 0, 1 );
32945 uvs.push( 0.5, 0.5 );
32946
32947 for ( var s = 0, i = 3; s <= segments; s ++, i += 3 ) {
32948
32949 var segment = thetaStart + s / segments * thetaLength;
32950
32951 // vertex
32952
32953 vertex.x = radius * Math.cos( segment );
32954 vertex.y = radius * Math.sin( segment );
32955
32956 vertices.push( vertex.x, vertex.y, vertex.z );
32957
32958 // normal
32959
32960 normals.push( 0, 0, 1 );
32961
32962 // uvs
32963
32964 uv.x = ( vertices[ i ] / radius + 1 ) / 2;
32965 uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;
32966
32967 uvs.push( uv.x, uv.y );
32968
32969 }
32970
32971 // indices
32972
32973 for ( var i$1 = 1; i$1 <= segments; i$1 ++ ) {
32974
32975 indices.push( i$1, i$1 + 1, 0 );
32976
32977 }
32978
32979 // build geometry
32980
32981 this.setIndex( indices );
32982 this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
32983 this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
32984 this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
32985
32986 }
32987
32988 CircleBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
32989 CircleBufferGeometry.prototype.constructor = CircleBufferGeometry;
32990
32991 var Geometries = /*#__PURE__*/Object.freeze({
32992 __proto__: null,
32993 WireframeGeometry: WireframeGeometry,
32994 ParametricGeometry: ParametricGeometry,
32995 ParametricBufferGeometry: ParametricBufferGeometry,
32996 TetrahedronGeometry: TetrahedronGeometry,
32997 TetrahedronBufferGeometry: TetrahedronBufferGeometry,
32998 OctahedronGeometry: OctahedronGeometry,
32999 OctahedronBufferGeometry: OctahedronBufferGeometry,
33000 IcosahedronGeometry: IcosahedronGeometry,
33001 IcosahedronBufferGeometry: IcosahedronBufferGeometry,
33002 DodecahedronGeometry: DodecahedronGeometry,
33003 DodecahedronBufferGeometry: DodecahedronBufferGeometry,
33004 PolyhedronGeometry: PolyhedronGeometry,
33005 PolyhedronBufferGeometry: PolyhedronBufferGeometry,
33006 TubeGeometry: TubeGeometry,
33007 TubeBufferGeometry: TubeBufferGeometry,
33008 TorusKnotGeometry: TorusKnotGeometry,
33009 TorusKnotBufferGeometry: TorusKnotBufferGeometry,
33010 TorusGeometry: TorusGeometry,
33011 TorusBufferGeometry: TorusBufferGeometry,
33012 TextGeometry: TextGeometry,
33013 TextBufferGeometry: TextBufferGeometry,
33014 SphereGeometry: SphereGeometry,
33015 SphereBufferGeometry: SphereBufferGeometry,
33016 RingGeometry: RingGeometry,
33017 RingBufferGeometry: RingBufferGeometry,
33018 PlaneGeometry: PlaneGeometry,
33019 PlaneBufferGeometry: PlaneBufferGeometry,
33020 LatheGeometry: LatheGeometry,
33021 LatheBufferGeometry: LatheBufferGeometry,
33022 ShapeGeometry: ShapeGeometry,
33023 ShapeBufferGeometry: ShapeBufferGeometry,
33024 ExtrudeGeometry: ExtrudeGeometry,
33025 ExtrudeBufferGeometry: ExtrudeBufferGeometry,
33026 EdgesGeometry: EdgesGeometry,
33027 ConeGeometry: ConeGeometry,
33028 ConeBufferGeometry: ConeBufferGeometry,
33029 CylinderGeometry: CylinderGeometry,
33030 CylinderBufferGeometry: CylinderBufferGeometry,
33031 CircleGeometry: CircleGeometry,
33032 CircleBufferGeometry: CircleBufferGeometry,
33033 BoxGeometry: BoxGeometry,
33034 BoxBufferGeometry: BoxBufferGeometry
33035 });
33036
33037 /**
33038 * parameters = {
33039 * color: <THREE.Color>
33040 * }
33041 */
33042
33043 function ShadowMaterial( parameters ) {
33044
33045 Material.call( this );
33046
33047 this.type = 'ShadowMaterial';
33048
33049 this.color = new Color( 0x000000 );
33050 this.transparent = true;
33051
33052 this.setValues( parameters );
33053
33054 }
33055
33056 ShadowMaterial.prototype = Object.create( Material.prototype );
33057 ShadowMaterial.prototype.constructor = ShadowMaterial;
33058
33059 ShadowMaterial.prototype.isShadowMaterial = true;
33060
33061 ShadowMaterial.prototype.copy = function ( source ) {
33062
33063 Material.prototype.copy.call( this, source );
33064
33065 this.color.copy( source.color );
33066
33067 return this;
33068
33069 };
33070
33071 function RawShaderMaterial( parameters ) {
33072
33073 ShaderMaterial.call( this, parameters );
33074
33075 this.type = 'RawShaderMaterial';
33076
33077 }
33078
33079 RawShaderMaterial.prototype = Object.create( ShaderMaterial.prototype );
33080 RawShaderMaterial.prototype.constructor = RawShaderMaterial;
33081
33082 RawShaderMaterial.prototype.isRawShaderMaterial = true;
33083
33084 /**
33085 * parameters = {
33086 * color: <hex>,
33087 * roughness: <float>,
33088 * metalness: <float>,
33089 * opacity: <float>,
33090 *
33091 * map: new THREE.Texture( <Image> ),
33092 *
33093 * lightMap: new THREE.Texture( <Image> ),
33094 * lightMapIntensity: <float>
33095 *
33096 * aoMap: new THREE.Texture( <Image> ),
33097 * aoMapIntensity: <float>
33098 *
33099 * emissive: <hex>,
33100 * emissiveIntensity: <float>
33101 * emissiveMap: new THREE.Texture( <Image> ),
33102 *
33103 * bumpMap: new THREE.Texture( <Image> ),
33104 * bumpScale: <float>,
33105 *
33106 * normalMap: new THREE.Texture( <Image> ),
33107 * normalMapType: THREE.TangentSpaceNormalMap,
33108 * normalScale: <Vector2>,
33109 *
33110 * displacementMap: new THREE.Texture( <Image> ),
33111 * displacementScale: <float>,
33112 * displacementBias: <float>,
33113 *
33114 * roughnessMap: new THREE.Texture( <Image> ),
33115 *
33116 * metalnessMap: new THREE.Texture( <Image> ),
33117 *
33118 * alphaMap: new THREE.Texture( <Image> ),
33119 *
33120 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
33121 * envMapIntensity: <float>
33122 *
33123 * refractionRatio: <float>,
33124 *
33125 * wireframe: <boolean>,
33126 * wireframeLinewidth: <float>,
33127 *
33128 * skinning: <bool>,
33129 * morphTargets: <bool>,
33130 * morphNormals: <bool>
33131 * }
33132 */
33133
33134 function MeshStandardMaterial( parameters ) {
33135
33136 Material.call( this );
33137
33138 this.defines = { 'STANDARD': '' };
33139
33140 this.type = 'MeshStandardMaterial';
33141
33142 this.color = new Color( 0xffffff ); // diffuse
33143 this.roughness = 1.0;
33144 this.metalness = 0.0;
33145
33146 this.map = null;
33147
33148 this.lightMap = null;
33149 this.lightMapIntensity = 1.0;
33150
33151 this.aoMap = null;
33152 this.aoMapIntensity = 1.0;
33153
33154 this.emissive = new Color( 0x000000 );
33155 this.emissiveIntensity = 1.0;
33156 this.emissiveMap = null;
33157
33158 this.bumpMap = null;
33159 this.bumpScale = 1;
33160
33161 this.normalMap = null;
33162 this.normalMapType = TangentSpaceNormalMap;
33163 this.normalScale = new Vector2( 1, 1 );
33164
33165 this.displacementMap = null;
33166 this.displacementScale = 1;
33167 this.displacementBias = 0;
33168
33169 this.roughnessMap = null;
33170
33171 this.metalnessMap = null;
33172
33173 this.alphaMap = null;
33174
33175 this.envMap = null;
33176 this.envMapIntensity = 1.0;
33177
33178 this.refractionRatio = 0.98;
33179
33180 this.wireframe = false;
33181 this.wireframeLinewidth = 1;
33182 this.wireframeLinecap = 'round';
33183 this.wireframeLinejoin = 'round';
33184
33185 this.skinning = false;
33186 this.morphTargets = false;
33187 this.morphNormals = false;
33188
33189 this.vertexTangents = false;
33190
33191 this.setValues( parameters );
33192
33193 }
33194
33195 MeshStandardMaterial.prototype = Object.create( Material.prototype );
33196 MeshStandardMaterial.prototype.constructor = MeshStandardMaterial;
33197
33198 MeshStandardMaterial.prototype.isMeshStandardMaterial = true;
33199
33200 MeshStandardMaterial.prototype.copy = function ( source ) {
33201
33202 Material.prototype.copy.call( this, source );
33203
33204 this.defines = { 'STANDARD': '' };
33205
33206 this.color.copy( source.color );
33207 this.roughness = source.roughness;
33208 this.metalness = source.metalness;
33209
33210 this.map = source.map;
33211
33212 this.lightMap = source.lightMap;
33213 this.lightMapIntensity = source.lightMapIntensity;
33214
33215 this.aoMap = source.aoMap;
33216 this.aoMapIntensity = source.aoMapIntensity;
33217
33218 this.emissive.copy( source.emissive );
33219 this.emissiveMap = source.emissiveMap;
33220 this.emissiveIntensity = source.emissiveIntensity;
33221
33222 this.bumpMap = source.bumpMap;
33223 this.bumpScale = source.bumpScale;
33224
33225 this.normalMap = source.normalMap;
33226 this.normalMapType = source.normalMapType;
33227 this.normalScale.copy( source.normalScale );
33228
33229 this.displacementMap = source.displacementMap;
33230 this.displacementScale = source.displacementScale;
33231 this.displacementBias = source.displacementBias;
33232
33233 this.roughnessMap = source.roughnessMap;
33234
33235 this.metalnessMap = source.metalnessMap;
33236
33237 this.alphaMap = source.alphaMap;
33238
33239 this.envMap = source.envMap;
33240 this.envMapIntensity = source.envMapIntensity;
33241
33242 this.refractionRatio = source.refractionRatio;
33243
33244 this.wireframe = source.wireframe;
33245 this.wireframeLinewidth = source.wireframeLinewidth;
33246 this.wireframeLinecap = source.wireframeLinecap;
33247 this.wireframeLinejoin = source.wireframeLinejoin;
33248
33249 this.skinning = source.skinning;
33250 this.morphTargets = source.morphTargets;
33251 this.morphNormals = source.morphNormals;
33252
33253 this.vertexTangents = source.vertexTangents;
33254
33255 return this;
33256
33257 };
33258
33259 /**
33260 * parameters = {
33261 * clearcoat: <float>,
33262 * clearcoatMap: new THREE.Texture( <Image> ),
33263 * clearcoatRoughness: <float>,
33264 * clearcoatRoughnessMap: new THREE.Texture( <Image> ),
33265 * clearcoatNormalScale: <Vector2>,
33266 * clearcoatNormalMap: new THREE.Texture( <Image> ),
33267 *
33268 * reflectivity: <float>,
33269 *
33270 * sheen: <Color>,
33271 *
33272 * transmission: <float>,
33273 * transmissionMap: new THREE.Texture( <Image> )
33274 * }
33275 */
33276
33277 function MeshPhysicalMaterial( parameters ) {
33278
33279 MeshStandardMaterial.call( this );
33280
33281 this.defines = {
33282
33283 'STANDARD': '',
33284 'PHYSICAL': ''
33285
33286 };
33287
33288 this.type = 'MeshPhysicalMaterial';
33289
33290 this.clearcoat = 0.0;
33291 this.clearcoatMap = null;
33292 this.clearcoatRoughness = 0.0;
33293 this.clearcoatRoughnessMap = null;
33294 this.clearcoatNormalScale = new Vector2( 1, 1 );
33295 this.clearcoatNormalMap = null;
33296
33297 this.reflectivity = 0.5; // maps to F0 = 0.04
33298
33299 this.sheen = null; // null will disable sheen bsdf
33300
33301 this.transmission = 0.0;
33302 this.transmissionMap = null;
33303
33304 this.setValues( parameters );
33305
33306 }
33307
33308 MeshPhysicalMaterial.prototype = Object.create( MeshStandardMaterial.prototype );
33309 MeshPhysicalMaterial.prototype.constructor = MeshPhysicalMaterial;
33310
33311 MeshPhysicalMaterial.prototype.isMeshPhysicalMaterial = true;
33312
33313 MeshPhysicalMaterial.prototype.copy = function ( source ) {
33314
33315 MeshStandardMaterial.prototype.copy.call( this, source );
33316
33317 this.defines = {
33318
33319 'STANDARD': '',
33320 'PHYSICAL': ''
33321
33322 };
33323
33324 this.clearcoat = source.clearcoat;
33325 this.clearcoatMap = source.clearcoatMap;
33326 this.clearcoatRoughness = source.clearcoatRoughness;
33327 this.clearcoatRoughnessMap = source.clearcoatRoughnessMap;
33328 this.clearcoatNormalMap = source.clearcoatNormalMap;
33329 this.clearcoatNormalScale.copy( source.clearcoatNormalScale );
33330
33331 this.reflectivity = source.reflectivity;
33332
33333 if ( source.sheen ) {
33334
33335 this.sheen = ( this.sheen || new Color() ).copy( source.sheen );
33336
33337 } else {
33338
33339 this.sheen = null;
33340
33341 }
33342
33343 this.transmission = source.transmission;
33344 this.transmissionMap = source.transmissionMap;
33345
33346 return this;
33347
33348 };
33349
33350 /**
33351 * parameters = {
33352 * color: <hex>,
33353 * specular: <hex>,
33354 * shininess: <float>,
33355 * opacity: <float>,
33356 *
33357 * map: new THREE.Texture( <Image> ),
33358 *
33359 * lightMap: new THREE.Texture( <Image> ),
33360 * lightMapIntensity: <float>
33361 *
33362 * aoMap: new THREE.Texture( <Image> ),
33363 * aoMapIntensity: <float>
33364 *
33365 * emissive: <hex>,
33366 * emissiveIntensity: <float>
33367 * emissiveMap: new THREE.Texture( <Image> ),
33368 *
33369 * bumpMap: new THREE.Texture( <Image> ),
33370 * bumpScale: <float>,
33371 *
33372 * normalMap: new THREE.Texture( <Image> ),
33373 * normalMapType: THREE.TangentSpaceNormalMap,
33374 * normalScale: <Vector2>,
33375 *
33376 * displacementMap: new THREE.Texture( <Image> ),
33377 * displacementScale: <float>,
33378 * displacementBias: <float>,
33379 *
33380 * specularMap: new THREE.Texture( <Image> ),
33381 *
33382 * alphaMap: new THREE.Texture( <Image> ),
33383 *
33384 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
33385 * combine: THREE.MultiplyOperation,
33386 * reflectivity: <float>,
33387 * refractionRatio: <float>,
33388 *
33389 * wireframe: <boolean>,
33390 * wireframeLinewidth: <float>,
33391 *
33392 * skinning: <bool>,
33393 * morphTargets: <bool>,
33394 * morphNormals: <bool>
33395 * }
33396 */
33397
33398 function MeshPhongMaterial( parameters ) {
33399
33400 Material.call( this );
33401
33402 this.type = 'MeshPhongMaterial';
33403
33404 this.color = new Color( 0xffffff ); // diffuse
33405 this.specular = new Color( 0x111111 );
33406 this.shininess = 30;
33407
33408 this.map = null;
33409
33410 this.lightMap = null;
33411 this.lightMapIntensity = 1.0;
33412
33413 this.aoMap = null;
33414 this.aoMapIntensity = 1.0;
33415
33416 this.emissive = new Color( 0x000000 );
33417 this.emissiveIntensity = 1.0;
33418 this.emissiveMap = null;
33419
33420 this.bumpMap = null;
33421 this.bumpScale = 1;
33422
33423 this.normalMap = null;
33424 this.normalMapType = TangentSpaceNormalMap;
33425 this.normalScale = new Vector2( 1, 1 );
33426
33427 this.displacementMap = null;
33428 this.displacementScale = 1;
33429 this.displacementBias = 0;
33430
33431 this.specularMap = null;
33432
33433 this.alphaMap = null;
33434
33435 this.envMap = null;
33436 this.combine = MultiplyOperation;
33437 this.reflectivity = 1;
33438 this.refractionRatio = 0.98;
33439
33440 this.wireframe = false;
33441 this.wireframeLinewidth = 1;
33442 this.wireframeLinecap = 'round';
33443 this.wireframeLinejoin = 'round';
33444
33445 this.skinning = false;
33446 this.morphTargets = false;
33447 this.morphNormals = false;
33448
33449 this.setValues( parameters );
33450
33451 }
33452
33453 MeshPhongMaterial.prototype = Object.create( Material.prototype );
33454 MeshPhongMaterial.prototype.constructor = MeshPhongMaterial;
33455
33456 MeshPhongMaterial.prototype.isMeshPhongMaterial = true;
33457
33458 MeshPhongMaterial.prototype.copy = function ( source ) {
33459
33460 Material.prototype.copy.call( this, source );
33461
33462 this.color.copy( source.color );
33463 this.specular.copy( source.specular );
33464 this.shininess = source.shininess;
33465
33466 this.map = source.map;
33467
33468 this.lightMap = source.lightMap;
33469 this.lightMapIntensity = source.lightMapIntensity;
33470
33471 this.aoMap = source.aoMap;
33472 this.aoMapIntensity = source.aoMapIntensity;
33473
33474 this.emissive.copy( source.emissive );
33475 this.emissiveMap = source.emissiveMap;
33476 this.emissiveIntensity = source.emissiveIntensity;
33477
33478 this.bumpMap = source.bumpMap;
33479 this.bumpScale = source.bumpScale;
33480
33481 this.normalMap = source.normalMap;
33482 this.normalMapType = source.normalMapType;
33483 this.normalScale.copy( source.normalScale );
33484
33485 this.displacementMap = source.displacementMap;
33486 this.displacementScale = source.displacementScale;
33487 this.displacementBias = source.displacementBias;
33488
33489 this.specularMap = source.specularMap;
33490
33491 this.alphaMap = source.alphaMap;
33492
33493 this.envMap = source.envMap;
33494 this.combine = source.combine;
33495 this.reflectivity = source.reflectivity;
33496 this.refractionRatio = source.refractionRatio;
33497
33498 this.wireframe = source.wireframe;
33499 this.wireframeLinewidth = source.wireframeLinewidth;
33500 this.wireframeLinecap = source.wireframeLinecap;
33501 this.wireframeLinejoin = source.wireframeLinejoin;
33502
33503 this.skinning = source.skinning;
33504 this.morphTargets = source.morphTargets;
33505 this.morphNormals = source.morphNormals;
33506
33507 return this;
33508
33509 };
33510
33511 /**
33512 * parameters = {
33513 * color: <hex>,
33514 *
33515 * map: new THREE.Texture( <Image> ),
33516 * gradientMap: new THREE.Texture( <Image> ),
33517 *
33518 * lightMap: new THREE.Texture( <Image> ),
33519 * lightMapIntensity: <float>
33520 *
33521 * aoMap: new THREE.Texture( <Image> ),
33522 * aoMapIntensity: <float>
33523 *
33524 * emissive: <hex>,
33525 * emissiveIntensity: <float>
33526 * emissiveMap: new THREE.Texture( <Image> ),
33527 *
33528 * bumpMap: new THREE.Texture( <Image> ),
33529 * bumpScale: <float>,
33530 *
33531 * normalMap: new THREE.Texture( <Image> ),
33532 * normalMapType: THREE.TangentSpaceNormalMap,
33533 * normalScale: <Vector2>,
33534 *
33535 * displacementMap: new THREE.Texture( <Image> ),
33536 * displacementScale: <float>,
33537 * displacementBias: <float>,
33538 *
33539 * alphaMap: new THREE.Texture( <Image> ),
33540 *
33541 * wireframe: <boolean>,
33542 * wireframeLinewidth: <float>,
33543 *
33544 * skinning: <bool>,
33545 * morphTargets: <bool>,
33546 * morphNormals: <bool>
33547 * }
33548 */
33549
33550 function MeshToonMaterial( parameters ) {
33551
33552 Material.call( this );
33553
33554 this.defines = { 'TOON': '' };
33555
33556 this.type = 'MeshToonMaterial';
33557
33558 this.color = new Color( 0xffffff );
33559
33560 this.map = null;
33561 this.gradientMap = null;
33562
33563 this.lightMap = null;
33564 this.lightMapIntensity = 1.0;
33565
33566 this.aoMap = null;
33567 this.aoMapIntensity = 1.0;
33568
33569 this.emissive = new Color( 0x000000 );
33570 this.emissiveIntensity = 1.0;
33571 this.emissiveMap = null;
33572
33573 this.bumpMap = null;
33574 this.bumpScale = 1;
33575
33576 this.normalMap = null;
33577 this.normalMapType = TangentSpaceNormalMap;
33578 this.normalScale = new Vector2( 1, 1 );
33579
33580 this.displacementMap = null;
33581 this.displacementScale = 1;
33582 this.displacementBias = 0;
33583
33584 this.alphaMap = null;
33585
33586 this.wireframe = false;
33587 this.wireframeLinewidth = 1;
33588 this.wireframeLinecap = 'round';
33589 this.wireframeLinejoin = 'round';
33590
33591 this.skinning = false;
33592 this.morphTargets = false;
33593 this.morphNormals = false;
33594
33595 this.setValues( parameters );
33596
33597 }
33598
33599 MeshToonMaterial.prototype = Object.create( Material.prototype );
33600 MeshToonMaterial.prototype.constructor = MeshToonMaterial;
33601
33602 MeshToonMaterial.prototype.isMeshToonMaterial = true;
33603
33604 MeshToonMaterial.prototype.copy = function ( source ) {
33605
33606 Material.prototype.copy.call( this, source );
33607
33608 this.color.copy( source.color );
33609
33610 this.map = source.map;
33611 this.gradientMap = source.gradientMap;
33612
33613 this.lightMap = source.lightMap;
33614 this.lightMapIntensity = source.lightMapIntensity;
33615
33616 this.aoMap = source.aoMap;
33617 this.aoMapIntensity = source.aoMapIntensity;
33618
33619 this.emissive.copy( source.emissive );
33620 this.emissiveMap = source.emissiveMap;
33621 this.emissiveIntensity = source.emissiveIntensity;
33622
33623 this.bumpMap = source.bumpMap;
33624 this.bumpScale = source.bumpScale;
33625
33626 this.normalMap = source.normalMap;
33627 this.normalMapType = source.normalMapType;
33628 this.normalScale.copy( source.normalScale );
33629
33630 this.displacementMap = source.displacementMap;
33631 this.displacementScale = source.displacementScale;
33632 this.displacementBias = source.displacementBias;
33633
33634 this.alphaMap = source.alphaMap;
33635
33636 this.wireframe = source.wireframe;
33637 this.wireframeLinewidth = source.wireframeLinewidth;
33638 this.wireframeLinecap = source.wireframeLinecap;
33639 this.wireframeLinejoin = source.wireframeLinejoin;
33640
33641 this.skinning = source.skinning;
33642 this.morphTargets = source.morphTargets;
33643 this.morphNormals = source.morphNormals;
33644
33645 return this;
33646
33647 };
33648
33649 /**
33650 * parameters = {
33651 * opacity: <float>,
33652 *
33653 * bumpMap: new THREE.Texture( <Image> ),
33654 * bumpScale: <float>,
33655 *
33656 * normalMap: new THREE.Texture( <Image> ),
33657 * normalMapType: THREE.TangentSpaceNormalMap,
33658 * normalScale: <Vector2>,
33659 *
33660 * displacementMap: new THREE.Texture( <Image> ),
33661 * displacementScale: <float>,
33662 * displacementBias: <float>,
33663 *
33664 * wireframe: <boolean>,
33665 * wireframeLinewidth: <float>
33666 *
33667 * skinning: <bool>,
33668 * morphTargets: <bool>,
33669 * morphNormals: <bool>
33670 * }
33671 */
33672
33673 function MeshNormalMaterial( parameters ) {
33674
33675 Material.call( this );
33676
33677 this.type = 'MeshNormalMaterial';
33678
33679 this.bumpMap = null;
33680 this.bumpScale = 1;
33681
33682 this.normalMap = null;
33683 this.normalMapType = TangentSpaceNormalMap;
33684 this.normalScale = new Vector2( 1, 1 );
33685
33686 this.displacementMap = null;
33687 this.displacementScale = 1;
33688 this.displacementBias = 0;
33689
33690 this.wireframe = false;
33691 this.wireframeLinewidth = 1;
33692
33693 this.fog = false;
33694
33695 this.skinning = false;
33696 this.morphTargets = false;
33697 this.morphNormals = false;
33698
33699 this.setValues( parameters );
33700
33701 }
33702
33703 MeshNormalMaterial.prototype = Object.create( Material.prototype );
33704 MeshNormalMaterial.prototype.constructor = MeshNormalMaterial;
33705
33706 MeshNormalMaterial.prototype.isMeshNormalMaterial = true;
33707
33708 MeshNormalMaterial.prototype.copy = function ( source ) {
33709
33710 Material.prototype.copy.call( this, source );
33711
33712 this.bumpMap = source.bumpMap;
33713 this.bumpScale = source.bumpScale;
33714
33715 this.normalMap = source.normalMap;
33716 this.normalMapType = source.normalMapType;
33717 this.normalScale.copy( source.normalScale );
33718
33719 this.displacementMap = source.displacementMap;
33720 this.displacementScale = source.displacementScale;
33721 this.displacementBias = source.displacementBias;
33722
33723 this.wireframe = source.wireframe;
33724 this.wireframeLinewidth = source.wireframeLinewidth;
33725
33726 this.skinning = source.skinning;
33727 this.morphTargets = source.morphTargets;
33728 this.morphNormals = source.morphNormals;
33729
33730 return this;
33731
33732 };
33733
33734 /**
33735 * parameters = {
33736 * color: <hex>,
33737 * opacity: <float>,
33738 *
33739 * map: new THREE.Texture( <Image> ),
33740 *
33741 * lightMap: new THREE.Texture( <Image> ),
33742 * lightMapIntensity: <float>
33743 *
33744 * aoMap: new THREE.Texture( <Image> ),
33745 * aoMapIntensity: <float>
33746 *
33747 * emissive: <hex>,
33748 * emissiveIntensity: <float>
33749 * emissiveMap: new THREE.Texture( <Image> ),
33750 *
33751 * specularMap: new THREE.Texture( <Image> ),
33752 *
33753 * alphaMap: new THREE.Texture( <Image> ),
33754 *
33755 * envMap: new THREE.CubeTexture( [posx, negx, posy, negy, posz, negz] ),
33756 * combine: THREE.Multiply,
33757 * reflectivity: <float>,
33758 * refractionRatio: <float>,
33759 *
33760 * wireframe: <boolean>,
33761 * wireframeLinewidth: <float>,
33762 *
33763 * skinning: <bool>,
33764 * morphTargets: <bool>,
33765 * morphNormals: <bool>
33766 * }
33767 */
33768
33769 function MeshLambertMaterial( parameters ) {
33770
33771 Material.call( this );
33772
33773 this.type = 'MeshLambertMaterial';
33774
33775 this.color = new Color( 0xffffff ); // diffuse
33776
33777 this.map = null;
33778
33779 this.lightMap = null;
33780 this.lightMapIntensity = 1.0;
33781
33782 this.aoMap = null;
33783 this.aoMapIntensity = 1.0;
33784
33785 this.emissive = new Color( 0x000000 );
33786 this.emissiveIntensity = 1.0;
33787 this.emissiveMap = null;
33788
33789 this.specularMap = null;
33790
33791 this.alphaMap = null;
33792
33793 this.envMap = null;
33794 this.combine = MultiplyOperation;
33795 this.reflectivity = 1;
33796 this.refractionRatio = 0.98;
33797
33798 this.wireframe = false;
33799 this.wireframeLinewidth = 1;
33800 this.wireframeLinecap = 'round';
33801 this.wireframeLinejoin = 'round';
33802
33803 this.skinning = false;
33804 this.morphTargets = false;
33805 this.morphNormals = false;
33806
33807 this.setValues( parameters );
33808
33809 }
33810
33811 MeshLambertMaterial.prototype = Object.create( Material.prototype );
33812 MeshLambertMaterial.prototype.constructor = MeshLambertMaterial;
33813
33814 MeshLambertMaterial.prototype.isMeshLambertMaterial = true;
33815
33816 MeshLambertMaterial.prototype.copy = function ( source ) {
33817
33818 Material.prototype.copy.call( this, source );
33819
33820 this.color.copy( source.color );
33821
33822 this.map = source.map;
33823
33824 this.lightMap = source.lightMap;
33825 this.lightMapIntensity = source.lightMapIntensity;
33826
33827 this.aoMap = source.aoMap;
33828 this.aoMapIntensity = source.aoMapIntensity;
33829
33830 this.emissive.copy( source.emissive );
33831 this.emissiveMap = source.emissiveMap;
33832 this.emissiveIntensity = source.emissiveIntensity;
33833
33834 this.specularMap = source.specularMap;
33835
33836 this.alphaMap = source.alphaMap;
33837
33838 this.envMap = source.envMap;
33839 this.combine = source.combine;
33840 this.reflectivity = source.reflectivity;
33841 this.refractionRatio = source.refractionRatio;
33842
33843 this.wireframe = source.wireframe;
33844 this.wireframeLinewidth = source.wireframeLinewidth;
33845 this.wireframeLinecap = source.wireframeLinecap;
33846 this.wireframeLinejoin = source.wireframeLinejoin;
33847
33848 this.skinning = source.skinning;
33849 this.morphTargets = source.morphTargets;
33850 this.morphNormals = source.morphNormals;
33851
33852 return this;
33853
33854 };
33855
33856 /**
33857 * parameters = {
33858 * color: <hex>,
33859 * opacity: <float>,
33860 *
33861 * matcap: new THREE.Texture( <Image> ),
33862 *
33863 * map: new THREE.Texture( <Image> ),
33864 *
33865 * bumpMap: new THREE.Texture( <Image> ),
33866 * bumpScale: <float>,
33867 *
33868 * normalMap: new THREE.Texture( <Image> ),
33869 * normalMapType: THREE.TangentSpaceNormalMap,
33870 * normalScale: <Vector2>,
33871 *
33872 * displacementMap: new THREE.Texture( <Image> ),
33873 * displacementScale: <float>,
33874 * displacementBias: <float>,
33875 *
33876 * alphaMap: new THREE.Texture( <Image> ),
33877 *
33878 * skinning: <bool>,
33879 * morphTargets: <bool>,
33880 * morphNormals: <bool>
33881 * }
33882 */
33883
33884 function MeshMatcapMaterial( parameters ) {
33885
33886 Material.call( this );
33887
33888 this.defines = { 'MATCAP': '' };
33889
33890 this.type = 'MeshMatcapMaterial';
33891
33892 this.color = new Color( 0xffffff ); // diffuse
33893
33894 this.matcap = null;
33895
33896 this.map = null;
33897
33898 this.bumpMap = null;
33899 this.bumpScale = 1;
33900
33901 this.normalMap = null;
33902 this.normalMapType = TangentSpaceNormalMap;
33903 this.normalScale = new Vector2( 1, 1 );
33904
33905 this.displacementMap = null;
33906 this.displacementScale = 1;
33907 this.displacementBias = 0;
33908
33909 this.alphaMap = null;
33910
33911 this.skinning = false;
33912 this.morphTargets = false;
33913 this.morphNormals = false;
33914
33915 this.setValues( parameters );
33916
33917 }
33918
33919 MeshMatcapMaterial.prototype = Object.create( Material.prototype );
33920 MeshMatcapMaterial.prototype.constructor = MeshMatcapMaterial;
33921
33922 MeshMatcapMaterial.prototype.isMeshMatcapMaterial = true;
33923
33924 MeshMatcapMaterial.prototype.copy = function ( source ) {
33925
33926 Material.prototype.copy.call( this, source );
33927
33928 this.defines = { 'MATCAP': '' };
33929
33930 this.color.copy( source.color );
33931
33932 this.matcap = source.matcap;
33933
33934 this.map = source.map;
33935
33936 this.bumpMap = source.bumpMap;
33937 this.bumpScale = source.bumpScale;
33938
33939 this.normalMap = source.normalMap;
33940 this.normalMapType = source.normalMapType;
33941 this.normalScale.copy( source.normalScale );
33942
33943 this.displacementMap = source.displacementMap;
33944 this.displacementScale = source.displacementScale;
33945 this.displacementBias = source.displacementBias;
33946
33947 this.alphaMap = source.alphaMap;
33948
33949 this.skinning = source.skinning;
33950 this.morphTargets = source.morphTargets;
33951 this.morphNormals = source.morphNormals;
33952
33953 return this;
33954
33955 };
33956
33957 /**
33958 * parameters = {
33959 * color: <hex>,
33960 * opacity: <float>,
33961 *
33962 * linewidth: <float>,
33963 *
33964 * scale: <float>,
33965 * dashSize: <float>,
33966 * gapSize: <float>
33967 * }
33968 */
33969
33970 function LineDashedMaterial( parameters ) {
33971
33972 LineBasicMaterial.call( this );
33973
33974 this.type = 'LineDashedMaterial';
33975
33976 this.scale = 1;
33977 this.dashSize = 3;
33978 this.gapSize = 1;
33979
33980 this.setValues( parameters );
33981
33982 }
33983
33984 LineDashedMaterial.prototype = Object.create( LineBasicMaterial.prototype );
33985 LineDashedMaterial.prototype.constructor = LineDashedMaterial;
33986
33987 LineDashedMaterial.prototype.isLineDashedMaterial = true;
33988
33989 LineDashedMaterial.prototype.copy = function ( source ) {
33990
33991 LineBasicMaterial.prototype.copy.call( this, source );
33992
33993 this.scale = source.scale;
33994 this.dashSize = source.dashSize;
33995 this.gapSize = source.gapSize;
33996
33997 return this;
33998
33999 };
34000
34001 var Materials = /*#__PURE__*/Object.freeze({
34002 __proto__: null,
34003 ShadowMaterial: ShadowMaterial,
34004 SpriteMaterial: SpriteMaterial,
34005 RawShaderMaterial: RawShaderMaterial,
34006 ShaderMaterial: ShaderMaterial,
34007 PointsMaterial: PointsMaterial,
34008 MeshPhysicalMaterial: MeshPhysicalMaterial,
34009 MeshStandardMaterial: MeshStandardMaterial,
34010 MeshPhongMaterial: MeshPhongMaterial,
34011 MeshToonMaterial: MeshToonMaterial,
34012 MeshNormalMaterial: MeshNormalMaterial,
34013 MeshLambertMaterial: MeshLambertMaterial,
34014 MeshDepthMaterial: MeshDepthMaterial,
34015 MeshDistanceMaterial: MeshDistanceMaterial,
34016 MeshBasicMaterial: MeshBasicMaterial,
34017 MeshMatcapMaterial: MeshMatcapMaterial,
34018 LineDashedMaterial: LineDashedMaterial,
34019 LineBasicMaterial: LineBasicMaterial,
34020 Material: Material
34021 });
34022
34023 var AnimationUtils = {
34024
34025 // same as Array.prototype.slice, but also works on typed arrays
34026 arraySlice: function ( array, from, to ) {
34027
34028 if ( AnimationUtils.isTypedArray( array ) ) {
34029
34030 // in ios9 array.subarray(from, undefined) will return empty array
34031 // but array.subarray(from) or array.subarray(from, len) is correct
34032 return new array.constructor( array.subarray( from, to !== undefined ? to : array.length ) );
34033
34034 }
34035
34036 return array.slice( from, to );
34037
34038 },
34039
34040 // converts an array to a specific type
34041 convertArray: function ( array, type, forceClone ) {
34042
34043 if ( ! array || // let 'undefined' and 'null' pass
34044 ! forceClone && array.constructor === type ) { return array; }
34045
34046 if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
34047
34048 return new type( array ); // create typed array
34049
34050 }
34051
34052 return Array.prototype.slice.call( array ); // create Array
34053
34054 },
34055
34056 isTypedArray: function ( object ) {
34057
34058 return ArrayBuffer.isView( object ) &&
34059 ! ( object instanceof DataView );
34060
34061 },
34062
34063 // returns an array by which times and values can be sorted
34064 getKeyframeOrder: function ( times ) {
34065
34066 function compareTime( i, j ) {
34067
34068 return times[ i ] - times[ j ];
34069
34070 }
34071
34072 var n = times.length;
34073 var result = new Array( n );
34074 for ( var i = 0; i !== n; ++ i ) { result[ i ] = i; }
34075
34076 result.sort( compareTime );
34077
34078 return result;
34079
34080 },
34081
34082 // uses the array previously returned by 'getKeyframeOrder' to sort data
34083 sortedArray: function ( values, stride, order ) {
34084
34085 var nValues = values.length;
34086 var result = new values.constructor( nValues );
34087
34088 for ( var i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
34089
34090 var srcOffset = order[ i ] * stride;
34091
34092 for ( var j = 0; j !== stride; ++ j ) {
34093
34094 result[ dstOffset ++ ] = values[ srcOffset + j ];
34095
34096 }
34097
34098 }
34099
34100 return result;
34101
34102 },
34103
34104 // function for parsing AOS keyframe formats
34105 flattenJSON: function ( jsonKeys, times, values, valuePropertyName ) {
34106
34107 var i = 1, key = jsonKeys[ 0 ];
34108
34109 while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
34110
34111 key = jsonKeys[ i ++ ];
34112
34113 }
34114
34115 if ( key === undefined ) { return; } // no data
34116
34117 var value = key[ valuePropertyName ];
34118 if ( value === undefined ) { return; } // no data
34119
34120 if ( Array.isArray( value ) ) {
34121
34122 do {
34123
34124 value = key[ valuePropertyName ];
34125
34126 if ( value !== undefined ) {
34127
34128 times.push( key.time );
34129 values.push.apply( values, value ); // push all elements
34130
34131 }
34132
34133 key = jsonKeys[ i ++ ];
34134
34135 } while ( key !== undefined );
34136
34137 } else if ( value.toArray !== undefined ) {
34138
34139 // ...assume THREE.Math-ish
34140
34141 do {
34142
34143 value = key[ valuePropertyName ];
34144
34145 if ( value !== undefined ) {
34146
34147 times.push( key.time );
34148 value.toArray( values, values.length );
34149
34150 }
34151
34152 key = jsonKeys[ i ++ ];
34153
34154 } while ( key !== undefined );
34155
34156 } else {
34157
34158 // otherwise push as-is
34159
34160 do {
34161
34162 value = key[ valuePropertyName ];
34163
34164 if ( value !== undefined ) {
34165
34166 times.push( key.time );
34167 values.push( value );
34168
34169 }
34170
34171 key = jsonKeys[ i ++ ];
34172
34173 } while ( key !== undefined );
34174
34175 }
34176
34177 },
34178
34179 subclip: function ( sourceClip, name, startFrame, endFrame, fps ) {
34180
34181 fps = fps || 30;
34182
34183 var clip = sourceClip.clone();
34184
34185 clip.name = name;
34186
34187 var tracks = [];
34188
34189 for ( var i = 0; i < clip.tracks.length; ++ i ) {
34190
34191 var track = clip.tracks[ i ];
34192 var valueSize = track.getValueSize();
34193
34194 var times = [];
34195 var values = [];
34196
34197 for ( var j = 0; j < track.times.length; ++ j ) {
34198
34199 var frame = track.times[ j ] * fps;
34200
34201 if ( frame < startFrame || frame >= endFrame ) { continue; }
34202
34203 times.push( track.times[ j ] );
34204
34205 for ( var k = 0; k < valueSize; ++ k ) {
34206
34207 values.push( track.values[ j * valueSize + k ] );
34208
34209 }
34210
34211 }
34212
34213 if ( times.length === 0 ) { continue; }
34214
34215 track.times = AnimationUtils.convertArray( times, track.times.constructor );
34216 track.values = AnimationUtils.convertArray( values, track.values.constructor );
34217
34218 tracks.push( track );
34219
34220 }
34221
34222 clip.tracks = tracks;
34223
34224 // find minimum .times value across all tracks in the trimmed clip
34225
34226 var minStartTime = Infinity;
34227
34228 for ( var i$1 = 0; i$1 < clip.tracks.length; ++ i$1 ) {
34229
34230 if ( minStartTime > clip.tracks[ i$1 ].times[ 0 ] ) {
34231
34232 minStartTime = clip.tracks[ i$1 ].times[ 0 ];
34233
34234 }
34235
34236 }
34237
34238 // shift all tracks such that clip begins at t=0
34239
34240 for ( var i$2 = 0; i$2 < clip.tracks.length; ++ i$2 ) {
34241
34242 clip.tracks[ i$2 ].shift( - 1 * minStartTime );
34243
34244 }
34245
34246 clip.resetDuration();
34247
34248 return clip;
34249
34250 },
34251
34252 makeClipAdditive: function ( targetClip, referenceFrame, referenceClip, fps ) {
34253
34254 if ( referenceFrame === undefined ) { referenceFrame = 0; }
34255 if ( referenceClip === undefined ) { referenceClip = targetClip; }
34256 if ( fps === undefined || fps <= 0 ) { fps = 30; }
34257
34258 var numTracks = targetClip.tracks.length;
34259 var referenceTime = referenceFrame / fps;
34260
34261 // Make each track's values relative to the values at the reference frame
34262 var loop = function ( i ) {
34263
34264 var referenceTrack = referenceClip.tracks[ i ];
34265 var referenceTrackType = referenceTrack.ValueTypeName;
34266
34267 // Skip this track if it's non-numeric
34268 if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) { return; }
34269
34270 // Find the track in the target clip whose name and type matches the reference track
34271 var targetTrack = targetClip.tracks.find( function ( track ) {
34272
34273 return track.name === referenceTrack.name
34274 && track.ValueTypeName === referenceTrackType;
34275
34276 } );
34277
34278 if ( targetTrack === undefined ) { return; }
34279
34280 var valueSize = referenceTrack.getValueSize();
34281 var lastIndex = referenceTrack.times.length - 1;
34282 var referenceValue = (void 0);
34283
34284 // Find the value to subtract out of the track
34285 if ( referenceTime <= referenceTrack.times[ 0 ] ) {
34286
34287 // Reference frame is earlier than the first keyframe, so just use the first keyframe
34288 referenceValue = AnimationUtils.arraySlice( referenceTrack.values, 0, referenceTrack.valueSize );
34289
34290 } else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {
34291
34292 // Reference frame is after the last keyframe, so just use the last keyframe
34293 var startIndex = lastIndex * valueSize;
34294 referenceValue = AnimationUtils.arraySlice( referenceTrack.values, startIndex );
34295
34296 } else {
34297
34298 // Interpolate to the reference value
34299 var interpolant = referenceTrack.createInterpolant();
34300 interpolant.evaluate( referenceTime );
34301 referenceValue = interpolant.resultBuffer;
34302
34303 }
34304
34305 // Conjugate the quaternion
34306 if ( referenceTrackType === 'quaternion' ) {
34307
34308 var referenceQuat = new Quaternion(
34309 referenceValue[ 0 ],
34310 referenceValue[ 1 ],
34311 referenceValue[ 2 ],
34312 referenceValue[ 3 ]
34313 ).normalize().conjugate();
34314 referenceQuat.toArray( referenceValue );
34315
34316 }
34317
34318 // Subtract the reference value from all of the track values
34319
34320 var numTimes = targetTrack.times.length;
34321 for ( var j = 0; j < numTimes; ++ j ) {
34322
34323 var valueStart = j * valueSize;
34324
34325 if ( referenceTrackType === 'quaternion' ) {
34326
34327 // Multiply the conjugate for quaternion track types
34328 Quaternion.multiplyQuaternionsFlat(
34329 targetTrack.values,
34330 valueStart,
34331 referenceValue,
34332 0,
34333 targetTrack.values,
34334 valueStart
34335 );
34336
34337 } else {
34338
34339 // Subtract each value for all other numeric track types
34340 for ( var k = 0; k < valueSize; ++ k ) {
34341
34342 targetTrack.values[ valueStart + k ] -= referenceValue[ k ];
34343
34344 }
34345
34346 }
34347
34348 }
34349
34350 };
34351
34352 for ( var i = 0; i < numTracks; ++ i ) loop( i );
34353
34354 targetClip.blendMode = AdditiveAnimationBlendMode;
34355
34356 return targetClip;
34357
34358 }
34359
34360 };
34361
34362 /**
34363 * Abstract base class of interpolants over parametric samples.
34364 *
34365 * The parameter domain is one dimensional, typically the time or a path
34366 * along a curve defined by the data.
34367 *
34368 * The sample values can have any dimensionality and derived classes may
34369 * apply special interpretations to the data.
34370 *
34371 * This class provides the interval seek in a Template Method, deferring
34372 * the actual interpolation to derived classes.
34373 *
34374 * Time complexity is O(1) for linear access crossing at most two points
34375 * and O(log N) for random access, where N is the number of positions.
34376 *
34377 * References:
34378 *
34379 * http://www.oodesign.com/template-method-pattern.html
34380 *
34381 */
34382
34383 function Interpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
34384
34385 this.parameterPositions = parameterPositions;
34386 this._cachedIndex = 0;
34387
34388 this.resultBuffer = resultBuffer !== undefined ?
34389 resultBuffer : new sampleValues.constructor( sampleSize );
34390 this.sampleValues = sampleValues;
34391 this.valueSize = sampleSize;
34392
34393 }
34394
34395 Object.assign( Interpolant.prototype, {
34396
34397 evaluate: function ( t ) {
34398
34399 var pp = this.parameterPositions,
34400 i1 = this._cachedIndex,
34401
34402 t1 = pp[ i1 ],
34403 t0 = pp[ i1 - 1 ];
34404
34405 validate_interval: {
34406
34407 seek: {
34408
34409 var right;
34410
34411 linear_scan: {
34412
34413 //- See http://jsperf.com/comparison-to-undefined/3
34414 //- slower code:
34415 //-
34416 //- if ( t >= t1 || t1 === undefined ) {
34417 forward_scan: if ( ! ( t < t1 ) ) {
34418
34419 for ( var giveUpAt = i1 + 2; ; ) {
34420
34421 if ( t1 === undefined ) {
34422
34423 if ( t < t0 ) { break forward_scan; }
34424
34425 // after end
34426
34427 i1 = pp.length;
34428 this._cachedIndex = i1;
34429 return this.afterEnd_( i1 - 1, t, t0 );
34430
34431 }
34432
34433 if ( i1 === giveUpAt ) { break; } // this loop
34434
34435 t0 = t1;
34436 t1 = pp[ ++ i1 ];
34437
34438 if ( t < t1 ) {
34439
34440 // we have arrived at the sought interval
34441 break seek;
34442
34443 }
34444
34445 }
34446
34447 // prepare binary search on the right side of the index
34448 right = pp.length;
34449 break linear_scan;
34450
34451 }
34452
34453 //- slower code:
34454 //- if ( t < t0 || t0 === undefined ) {
34455 if ( ! ( t >= t0 ) ) {
34456
34457 // looping?
34458
34459 var t1global = pp[ 1 ];
34460
34461 if ( t < t1global ) {
34462
34463 i1 = 2; // + 1, using the scan for the details
34464 t0 = t1global;
34465
34466 }
34467
34468 // linear reverse scan
34469
34470 for ( var giveUpAt$1 = i1 - 2; ; ) {
34471
34472 if ( t0 === undefined ) {
34473
34474 // before start
34475
34476 this._cachedIndex = 0;
34477 return this.beforeStart_( 0, t, t1 );
34478
34479 }
34480
34481 if ( i1 === giveUpAt$1 ) { break; } // this loop
34482
34483 t1 = t0;
34484 t0 = pp[ -- i1 - 1 ];
34485
34486 if ( t >= t0 ) {
34487
34488 // we have arrived at the sought interval
34489 break seek;
34490
34491 }
34492
34493 }
34494
34495 // prepare binary search on the left side of the index
34496 right = i1;
34497 i1 = 0;
34498 break linear_scan;
34499
34500 }
34501
34502 // the interval is valid
34503
34504 break validate_interval;
34505
34506 } // linear scan
34507
34508 // binary search
34509
34510 while ( i1 < right ) {
34511
34512 var mid = ( i1 + right ) >>> 1;
34513
34514 if ( t < pp[ mid ] ) {
34515
34516 right = mid;
34517
34518 } else {
34519
34520 i1 = mid + 1;
34521
34522 }
34523
34524 }
34525
34526 t1 = pp[ i1 ];
34527 t0 = pp[ i1 - 1 ];
34528
34529 // check boundary cases, again
34530
34531 if ( t0 === undefined ) {
34532
34533 this._cachedIndex = 0;
34534 return this.beforeStart_( 0, t, t1 );
34535
34536 }
34537
34538 if ( t1 === undefined ) {
34539
34540 i1 = pp.length;
34541 this._cachedIndex = i1;
34542 return this.afterEnd_( i1 - 1, t0, t );
34543
34544 }
34545
34546 } // seek
34547
34548 this._cachedIndex = i1;
34549
34550 this.intervalChanged_( i1, t0, t1 );
34551
34552 } // validate_interval
34553
34554 return this.interpolate_( i1, t0, t, t1 );
34555
34556 },
34557
34558 settings: null, // optional, subclass-specific settings structure
34559 // Note: The indirection allows central control of many interpolants.
34560
34561 // --- Protected interface
34562
34563 DefaultSettings_: {},
34564
34565 getSettings_: function () {
34566
34567 return this.settings || this.DefaultSettings_;
34568
34569 },
34570
34571 copySampleValue_: function ( index ) {
34572
34573 // copies a sample value to the result buffer
34574
34575 var result = this.resultBuffer,
34576 values = this.sampleValues,
34577 stride = this.valueSize,
34578 offset = index * stride;
34579
34580 for ( var i = 0; i !== stride; ++ i ) {
34581
34582 result[ i ] = values[ offset + i ];
34583
34584 }
34585
34586 return result;
34587
34588 },
34589
34590 // Template methods for derived classes:
34591
34592 interpolate_: function ( /* i1, t0, t, t1 */ ) {
34593
34594 throw new Error( 'call to abstract method' );
34595 // implementations shall return this.resultBuffer
34596
34597 },
34598
34599 intervalChanged_: function ( /* i1, t0, t1 */ ) {
34600
34601 // empty
34602
34603 }
34604
34605 } );
34606
34607 // DECLARE ALIAS AFTER assign prototype
34608 Object.assign( Interpolant.prototype, {
34609
34610 //( 0, t, t0 ), returns this.resultBuffer
34611 beforeStart_: Interpolant.prototype.copySampleValue_,
34612
34613 //( N-1, tN-1, t ), returns this.resultBuffer
34614 afterEnd_: Interpolant.prototype.copySampleValue_,
34615
34616 } );
34617
34618 /**
34619 * Fast and simple cubic spline interpolant.
34620 *
34621 * It was derived from a Hermitian construction setting the first derivative
34622 * at each sample position to the linear slope between neighboring positions
34623 * over their parameter interval.
34624 */
34625
34626 function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
34627
34628 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
34629
34630 this._weightPrev = - 0;
34631 this._offsetPrev = - 0;
34632 this._weightNext = - 0;
34633 this._offsetNext = - 0;
34634
34635 }
34636
34637 CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
34638
34639 constructor: CubicInterpolant,
34640
34641 DefaultSettings_: {
34642
34643 endingStart: ZeroCurvatureEnding,
34644 endingEnd: ZeroCurvatureEnding
34645
34646 },
34647
34648 intervalChanged_: function ( i1, t0, t1 ) {
34649
34650 var pp = this.parameterPositions,
34651 iPrev = i1 - 2,
34652 iNext = i1 + 1,
34653
34654 tPrev = pp[ iPrev ],
34655 tNext = pp[ iNext ];
34656
34657 if ( tPrev === undefined ) {
34658
34659 switch ( this.getSettings_().endingStart ) {
34660
34661 case ZeroSlopeEnding:
34662
34663 // f'(t0) = 0
34664 iPrev = i1;
34665 tPrev = 2 * t0 - t1;
34666
34667 break;
34668
34669 case WrapAroundEnding:
34670
34671 // use the other end of the curve
34672 iPrev = pp.length - 2;
34673 tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];
34674
34675 break;
34676
34677 default: // ZeroCurvatureEnding
34678
34679 // f''(t0) = 0 a.k.a. Natural Spline
34680 iPrev = i1;
34681 tPrev = t1;
34682
34683 }
34684
34685 }
34686
34687 if ( tNext === undefined ) {
34688
34689 switch ( this.getSettings_().endingEnd ) {
34690
34691 case ZeroSlopeEnding:
34692
34693 // f'(tN) = 0
34694 iNext = i1;
34695 tNext = 2 * t1 - t0;
34696
34697 break;
34698
34699 case WrapAroundEnding:
34700
34701 // use the other end of the curve
34702 iNext = 1;
34703 tNext = t1 + pp[ 1 ] - pp[ 0 ];
34704
34705 break;
34706
34707 default: // ZeroCurvatureEnding
34708
34709 // f''(tN) = 0, a.k.a. Natural Spline
34710 iNext = i1 - 1;
34711 tNext = t0;
34712
34713 }
34714
34715 }
34716
34717 var halfDt = ( t1 - t0 ) * 0.5,
34718 stride = this.valueSize;
34719
34720 this._weightPrev = halfDt / ( t0 - tPrev );
34721 this._weightNext = halfDt / ( tNext - t1 );
34722 this._offsetPrev = iPrev * stride;
34723 this._offsetNext = iNext * stride;
34724
34725 },
34726
34727 interpolate_: function ( i1, t0, t, t1 ) {
34728
34729 var result = this.resultBuffer,
34730 values = this.sampleValues,
34731 stride = this.valueSize,
34732
34733 o1 = i1 * stride, o0 = o1 - stride,
34734 oP = this._offsetPrev, oN = this._offsetNext,
34735 wP = this._weightPrev, wN = this._weightNext,
34736
34737 p = ( t - t0 ) / ( t1 - t0 ),
34738 pp = p * p,
34739 ppp = pp * p;
34740
34741 // evaluate polynomials
34742
34743 var sP = - wP * ppp + 2 * wP * pp - wP * p;
34744 var s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1;
34745 var s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;
34746 var sN = wN * ppp - wN * pp;
34747
34748 // combine data linearly
34749
34750 for ( var i = 0; i !== stride; ++ i ) {
34751
34752 result[ i ] =
34753 sP * values[ oP + i ] +
34754 s0 * values[ o0 + i ] +
34755 s1 * values[ o1 + i ] +
34756 sN * values[ oN + i ];
34757
34758 }
34759
34760 return result;
34761
34762 }
34763
34764 } );
34765
34766 function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
34767
34768 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
34769
34770 }
34771
34772 LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
34773
34774 constructor: LinearInterpolant,
34775
34776 interpolate_: function ( i1, t0, t, t1 ) {
34777
34778 var result = this.resultBuffer,
34779 values = this.sampleValues,
34780 stride = this.valueSize,
34781
34782 offset1 = i1 * stride,
34783 offset0 = offset1 - stride,
34784
34785 weight1 = ( t - t0 ) / ( t1 - t0 ),
34786 weight0 = 1 - weight1;
34787
34788 for ( var i = 0; i !== stride; ++ i ) {
34789
34790 result[ i ] =
34791 values[ offset0 + i ] * weight0 +
34792 values[ offset1 + i ] * weight1;
34793
34794 }
34795
34796 return result;
34797
34798 }
34799
34800 } );
34801
34802 /**
34803 *
34804 * Interpolant that evaluates to the sample value at the position preceeding
34805 * the parameter.
34806 */
34807
34808 function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
34809
34810 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
34811
34812 }
34813
34814 DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
34815
34816 constructor: DiscreteInterpolant,
34817
34818 interpolate_: function ( i1 /*, t0, t, t1 */ ) {
34819
34820 return this.copySampleValue_( i1 - 1 );
34821
34822 }
34823
34824 } );
34825
34826 function KeyframeTrack( name, times, values, interpolation ) {
34827
34828 if ( name === undefined ) { throw new Error( 'THREE.KeyframeTrack: track name is undefined' ); }
34829 if ( times === undefined || times.length === 0 ) { throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name ); }
34830
34831 this.name = name;
34832
34833 this.times = AnimationUtils.convertArray( times, this.TimeBufferType );
34834 this.values = AnimationUtils.convertArray( values, this.ValueBufferType );
34835
34836 this.setInterpolation( interpolation || this.DefaultInterpolation );
34837
34838 }
34839
34840 // Static methods
34841
34842 Object.assign( KeyframeTrack, {
34843
34844 // Serialization (in static context, because of constructor invocation
34845 // and automatic invocation of .toJSON):
34846
34847 toJSON: function ( track ) {
34848
34849 var trackType = track.constructor;
34850
34851 var json;
34852
34853 // derived classes can define a static toJSON method
34854 if ( trackType.toJSON !== undefined ) {
34855
34856 json = trackType.toJSON( track );
34857
34858 } else {
34859
34860 // by default, we assume the data can be serialized as-is
34861 json = {
34862
34863 'name': track.name,
34864 'times': AnimationUtils.convertArray( track.times, Array ),
34865 'values': AnimationUtils.convertArray( track.values, Array )
34866
34867 };
34868
34869 var interpolation = track.getInterpolation();
34870
34871 if ( interpolation !== track.DefaultInterpolation ) {
34872
34873 json.interpolation = interpolation;
34874
34875 }
34876
34877 }
34878
34879 json.type = track.ValueTypeName; // mandatory
34880
34881 return json;
34882
34883 }
34884
34885 } );
34886
34887 Object.assign( KeyframeTrack.prototype, {
34888
34889 constructor: KeyframeTrack,
34890
34891 TimeBufferType: Float32Array,
34892
34893 ValueBufferType: Float32Array,
34894
34895 DefaultInterpolation: InterpolateLinear,
34896
34897 InterpolantFactoryMethodDiscrete: function ( result ) {
34898
34899 return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result );
34900
34901 },
34902
34903 InterpolantFactoryMethodLinear: function ( result ) {
34904
34905 return new LinearInterpolant( this.times, this.values, this.getValueSize(), result );
34906
34907 },
34908
34909 InterpolantFactoryMethodSmooth: function ( result ) {
34910
34911 return new CubicInterpolant( this.times, this.values, this.getValueSize(), result );
34912
34913 },
34914
34915 setInterpolation: function ( interpolation ) {
34916
34917 var factoryMethod;
34918
34919 switch ( interpolation ) {
34920
34921 case InterpolateDiscrete:
34922
34923 factoryMethod = this.InterpolantFactoryMethodDiscrete;
34924
34925 break;
34926
34927 case InterpolateLinear:
34928
34929 factoryMethod = this.InterpolantFactoryMethodLinear;
34930
34931 break;
34932
34933 case InterpolateSmooth:
34934
34935 factoryMethod = this.InterpolantFactoryMethodSmooth;
34936
34937 break;
34938
34939 }
34940
34941 if ( factoryMethod === undefined ) {
34942
34943 var message = "unsupported interpolation for " +
34944 this.ValueTypeName + " keyframe track named " + this.name;
34945
34946 if ( this.createInterpolant === undefined ) {
34947
34948 // fall back to default, unless the default itself is messed up
34949 if ( interpolation !== this.DefaultInterpolation ) {
34950
34951 this.setInterpolation( this.DefaultInterpolation );
34952
34953 } else {
34954
34955 throw new Error( message ); // fatal, in this case
34956
34957 }
34958
34959 }
34960
34961 console.warn( 'THREE.KeyframeTrack:', message );
34962 return this;
34963
34964 }
34965
34966 this.createInterpolant = factoryMethod;
34967
34968 return this;
34969
34970 },
34971
34972 getInterpolation: function () {
34973
34974 switch ( this.createInterpolant ) {
34975
34976 case this.InterpolantFactoryMethodDiscrete:
34977
34978 return InterpolateDiscrete;
34979
34980 case this.InterpolantFactoryMethodLinear:
34981
34982 return InterpolateLinear;
34983
34984 case this.InterpolantFactoryMethodSmooth:
34985
34986 return InterpolateSmooth;
34987
34988 }
34989
34990 },
34991
34992 getValueSize: function () {
34993
34994 return this.values.length / this.times.length;
34995
34996 },
34997
34998 // move all keyframes either forwards or backwards in time
34999 shift: function ( timeOffset ) {
35000
35001 if ( timeOffset !== 0.0 ) {
35002
35003 var times = this.times;
35004
35005 for ( var i = 0, n = times.length; i !== n; ++ i ) {
35006
35007 times[ i ] += timeOffset;
35008
35009 }
35010
35011 }
35012
35013 return this;
35014
35015 },
35016
35017 // scale all keyframe times by a factor (useful for frame <-> seconds conversions)
35018 scale: function ( timeScale ) {
35019
35020 if ( timeScale !== 1.0 ) {
35021
35022 var times = this.times;
35023
35024 for ( var i = 0, n = times.length; i !== n; ++ i ) {
35025
35026 times[ i ] *= timeScale;
35027
35028 }
35029
35030 }
35031
35032 return this;
35033
35034 },
35035
35036 // removes keyframes before and after animation without changing any values within the range [startTime, endTime].
35037 // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
35038 trim: function ( startTime, endTime ) {
35039
35040 var times = this.times,
35041 nKeys = times.length;
35042
35043 var from = 0,
35044 to = nKeys - 1;
35045
35046 while ( from !== nKeys && times[ from ] < startTime ) {
35047
35048 ++ from;
35049
35050 }
35051
35052 while ( to !== - 1 && times[ to ] > endTime ) {
35053
35054 -- to;
35055
35056 }
35057
35058 ++ to; // inclusive -> exclusive bound
35059
35060 if ( from !== 0 || to !== nKeys ) {
35061
35062 // empty tracks are forbidden, so keep at least one keyframe
35063 if ( from >= to ) {
35064
35065 to = Math.max( to, 1 );
35066 from = to - 1;
35067
35068 }
35069
35070 var stride = this.getValueSize();
35071 this.times = AnimationUtils.arraySlice( times, from, to );
35072 this.values = AnimationUtils.arraySlice( this.values, from * stride, to * stride );
35073
35074 }
35075
35076 return this;
35077
35078 },
35079
35080 // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
35081 validate: function () {
35082
35083 var valid = true;
35084
35085 var valueSize = this.getValueSize();
35086 if ( valueSize - Math.floor( valueSize ) !== 0 ) {
35087
35088 console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this );
35089 valid = false;
35090
35091 }
35092
35093 var times = this.times,
35094 values = this.values,
35095
35096 nKeys = times.length;
35097
35098 if ( nKeys === 0 ) {
35099
35100 console.error( 'THREE.KeyframeTrack: Track is empty.', this );
35101 valid = false;
35102
35103 }
35104
35105 var prevTime = null;
35106
35107 for ( var i = 0; i !== nKeys; i ++ ) {
35108
35109 var currTime = times[ i ];
35110
35111 if ( typeof currTime === 'number' && isNaN( currTime ) ) {
35112
35113 console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime );
35114 valid = false;
35115 break;
35116
35117 }
35118
35119 if ( prevTime !== null && prevTime > currTime ) {
35120
35121 console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime );
35122 valid = false;
35123 break;
35124
35125 }
35126
35127 prevTime = currTime;
35128
35129 }
35130
35131 if ( values !== undefined ) {
35132
35133 if ( AnimationUtils.isTypedArray( values ) ) {
35134
35135 for ( var i$1 = 0, n = values.length; i$1 !== n; ++ i$1 ) {
35136
35137 var value = values[ i$1 ];
35138
35139 if ( isNaN( value ) ) {
35140
35141 console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i$1, value );
35142 valid = false;
35143 break;
35144
35145 }
35146
35147 }
35148
35149 }
35150
35151 }
35152
35153 return valid;
35154
35155 },
35156
35157 // removes equivalent sequential keys as common in morph target sequences
35158 // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
35159 optimize: function () {
35160
35161 // times or values may be shared with other tracks, so overwriting is unsafe
35162 var times = AnimationUtils.arraySlice( this.times ),
35163 values = AnimationUtils.arraySlice( this.values ),
35164 stride = this.getValueSize(),
35165
35166 smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
35167
35168 lastIndex = times.length - 1;
35169
35170 var writeIndex = 1;
35171
35172 for ( var i = 1; i < lastIndex; ++ i ) {
35173
35174 var keep = false;
35175
35176 var time = times[ i ];
35177 var timeNext = times[ i + 1 ];
35178
35179 // remove adjacent keyframes scheduled at the same time
35180
35181 if ( time !== timeNext && ( i !== 1 || time !== time[ 0 ] ) ) {
35182
35183 if ( ! smoothInterpolation ) {
35184
35185 // remove unnecessary keyframes same as their neighbors
35186
35187 var offset = i * stride,
35188 offsetP = offset - stride,
35189 offsetN = offset + stride;
35190
35191 for ( var j = 0; j !== stride; ++ j ) {
35192
35193 var value = values[ offset + j ];
35194
35195 if ( value !== values[ offsetP + j ] ||
35196 value !== values[ offsetN + j ] ) {
35197
35198 keep = true;
35199 break;
35200
35201 }
35202
35203 }
35204
35205 } else {
35206
35207 keep = true;
35208
35209 }
35210
35211 }
35212
35213 // in-place compaction
35214
35215 if ( keep ) {
35216
35217 if ( i !== writeIndex ) {
35218
35219 times[ writeIndex ] = times[ i ];
35220
35221 var readOffset = i * stride,
35222 writeOffset = writeIndex * stride;
35223
35224 for ( var j$1 = 0; j$1 !== stride; ++ j$1 ) {
35225
35226 values[ writeOffset + j$1 ] = values[ readOffset + j$1 ];
35227
35228 }
35229
35230 }
35231
35232 ++ writeIndex;
35233
35234 }
35235
35236 }
35237
35238 // flush last keyframe (compaction looks ahead)
35239
35240 if ( lastIndex > 0 ) {
35241
35242 times[ writeIndex ] = times[ lastIndex ];
35243
35244 for ( var readOffset$1 = lastIndex * stride, writeOffset$1 = writeIndex * stride, j$2 = 0; j$2 !== stride; ++ j$2 ) {
35245
35246 values[ writeOffset$1 + j$2 ] = values[ readOffset$1 + j$2 ];
35247
35248 }
35249
35250 ++ writeIndex;
35251
35252 }
35253
35254 if ( writeIndex !== times.length ) {
35255
35256 this.times = AnimationUtils.arraySlice( times, 0, writeIndex );
35257 this.values = AnimationUtils.arraySlice( values, 0, writeIndex * stride );
35258
35259 } else {
35260
35261 this.times = times;
35262 this.values = values;
35263
35264 }
35265
35266 return this;
35267
35268 },
35269
35270 clone: function () {
35271
35272 var times = AnimationUtils.arraySlice( this.times, 0 );
35273 var values = AnimationUtils.arraySlice( this.values, 0 );
35274
35275 var TypedKeyframeTrack = this.constructor;
35276 var track = new TypedKeyframeTrack( this.name, times, values );
35277
35278 // Interpolant argument to constructor is not saved, so copy the factory method directly.
35279 track.createInterpolant = this.createInterpolant;
35280
35281 return track;
35282
35283 }
35284
35285 } );
35286
35287 /**
35288 * A Track of Boolean keyframe values.
35289 */
35290
35291 function BooleanKeyframeTrack( name, times, values ) {
35292
35293 KeyframeTrack.call( this, name, times, values );
35294
35295 }
35296
35297 BooleanKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35298
35299 constructor: BooleanKeyframeTrack,
35300
35301 ValueTypeName: 'bool',
35302 ValueBufferType: Array,
35303
35304 DefaultInterpolation: InterpolateDiscrete,
35305
35306 InterpolantFactoryMethodLinear: undefined,
35307 InterpolantFactoryMethodSmooth: undefined
35308
35309 // Note: Actually this track could have a optimized / compressed
35310 // representation of a single value and a custom interpolant that
35311 // computes "firstValue ^ isOdd( index )".
35312
35313 } );
35314
35315 /**
35316 * A Track of keyframe values that represent color.
35317 */
35318
35319 function ColorKeyframeTrack( name, times, values, interpolation ) {
35320
35321 KeyframeTrack.call( this, name, times, values, interpolation );
35322
35323 }
35324
35325 ColorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35326
35327 constructor: ColorKeyframeTrack,
35328
35329 ValueTypeName: 'color'
35330
35331 // ValueBufferType is inherited
35332
35333 // DefaultInterpolation is inherited
35334
35335 // Note: Very basic implementation and nothing special yet.
35336 // However, this is the place for color space parameterization.
35337
35338 } );
35339
35340 /**
35341 * A Track of numeric keyframe values.
35342 */
35343
35344 function NumberKeyframeTrack( name, times, values, interpolation ) {
35345
35346 KeyframeTrack.call( this, name, times, values, interpolation );
35347
35348 }
35349
35350 NumberKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35351
35352 constructor: NumberKeyframeTrack,
35353
35354 ValueTypeName: 'number'
35355
35356 // ValueBufferType is inherited
35357
35358 // DefaultInterpolation is inherited
35359
35360 } );
35361
35362 /**
35363 * Spherical linear unit quaternion interpolant.
35364 */
35365
35366 function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
35367
35368 Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
35369
35370 }
35371
35372 QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
35373
35374 constructor: QuaternionLinearInterpolant,
35375
35376 interpolate_: function ( i1, t0, t, t1 ) {
35377
35378 var result = this.resultBuffer,
35379 values = this.sampleValues,
35380 stride = this.valueSize,
35381
35382 alpha = ( t - t0 ) / ( t1 - t0 );
35383
35384 var offset = i1 * stride;
35385
35386 for ( var end = offset + stride; offset !== end; offset += 4 ) {
35387
35388 Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha );
35389
35390 }
35391
35392 return result;
35393
35394 }
35395
35396 } );
35397
35398 /**
35399 * A Track of quaternion keyframe values.
35400 */
35401
35402 function QuaternionKeyframeTrack( name, times, values, interpolation ) {
35403
35404 KeyframeTrack.call( this, name, times, values, interpolation );
35405
35406 }
35407
35408 QuaternionKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35409
35410 constructor: QuaternionKeyframeTrack,
35411
35412 ValueTypeName: 'quaternion',
35413
35414 // ValueBufferType is inherited
35415
35416 DefaultInterpolation: InterpolateLinear,
35417
35418 InterpolantFactoryMethodLinear: function ( result ) {
35419
35420 return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result );
35421
35422 },
35423
35424 InterpolantFactoryMethodSmooth: undefined // not yet implemented
35425
35426 } );
35427
35428 /**
35429 * A Track that interpolates Strings
35430 */
35431
35432 function StringKeyframeTrack( name, times, values, interpolation ) {
35433
35434 KeyframeTrack.call( this, name, times, values, interpolation );
35435
35436 }
35437
35438 StringKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35439
35440 constructor: StringKeyframeTrack,
35441
35442 ValueTypeName: 'string',
35443 ValueBufferType: Array,
35444
35445 DefaultInterpolation: InterpolateDiscrete,
35446
35447 InterpolantFactoryMethodLinear: undefined,
35448
35449 InterpolantFactoryMethodSmooth: undefined
35450
35451 } );
35452
35453 /**
35454 * A Track of vectored keyframe values.
35455 */
35456
35457 function VectorKeyframeTrack( name, times, values, interpolation ) {
35458
35459 KeyframeTrack.call( this, name, times, values, interpolation );
35460
35461 }
35462
35463 VectorKeyframeTrack.prototype = Object.assign( Object.create( KeyframeTrack.prototype ), {
35464
35465 constructor: VectorKeyframeTrack,
35466
35467 ValueTypeName: 'vector'
35468
35469 // ValueBufferType is inherited
35470
35471 // DefaultInterpolation is inherited
35472
35473 } );
35474
35475 function AnimationClip( name, duration, tracks, blendMode ) {
35476
35477 this.name = name;
35478 this.tracks = tracks;
35479 this.duration = ( duration !== undefined ) ? duration : - 1;
35480 this.blendMode = ( blendMode !== undefined ) ? blendMode : NormalAnimationBlendMode;
35481
35482 this.uuid = MathUtils.generateUUID();
35483
35484 // this means it should figure out its duration by scanning the tracks
35485 if ( this.duration < 0 ) {
35486
35487 this.resetDuration();
35488
35489 }
35490
35491 }
35492
35493 function getTrackTypeForValueTypeName( typeName ) {
35494
35495 switch ( typeName.toLowerCase() ) {
35496
35497 case 'scalar':
35498 case 'double':
35499 case 'float':
35500 case 'number':
35501 case 'integer':
35502
35503 return NumberKeyframeTrack;
35504
35505 case 'vector':
35506 case 'vector2':
35507 case 'vector3':
35508 case 'vector4':
35509
35510 return VectorKeyframeTrack;
35511
35512 case 'color':
35513
35514 return ColorKeyframeTrack;
35515
35516 case 'quaternion':
35517
35518 return QuaternionKeyframeTrack;
35519
35520 case 'bool':
35521 case 'boolean':
35522
35523 return BooleanKeyframeTrack;
35524
35525 case 'string':
35526
35527 return StringKeyframeTrack;
35528
35529 }
35530
35531 throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );
35532
35533 }
35534
35535 function parseKeyframeTrack( json ) {
35536
35537 if ( json.type === undefined ) {
35538
35539 throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );
35540
35541 }
35542
35543 var trackType = getTrackTypeForValueTypeName( json.type );
35544
35545 if ( json.times === undefined ) {
35546
35547 var times = [], values = [];
35548
35549 AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
35550
35551 json.times = times;
35552 json.values = values;
35553
35554 }
35555
35556 // derived classes can define a static parse method
35557 if ( trackType.parse !== undefined ) {
35558
35559 return trackType.parse( json );
35560
35561 } else {
35562
35563 // by default, we assume a constructor compatible with the base
35564 return new trackType( json.name, json.times, json.values, json.interpolation );
35565
35566 }
35567
35568 }
35569
35570 Object.assign( AnimationClip, {
35571
35572 parse: function ( json ) {
35573
35574 var tracks = [],
35575 jsonTracks = json.tracks,
35576 frameTime = 1.0 / ( json.fps || 1.0 );
35577
35578 for ( var i = 0, n = jsonTracks.length; i !== n; ++ i ) {
35579
35580 tracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) );
35581
35582 }
35583
35584 return new AnimationClip( json.name, json.duration, tracks, json.blendMode );
35585
35586 },
35587
35588 toJSON: function ( clip ) {
35589
35590 var tracks = [],
35591 clipTracks = clip.tracks;
35592
35593 var json = {
35594
35595 'name': clip.name,
35596 'duration': clip.duration,
35597 'tracks': tracks,
35598 'uuid': clip.uuid,
35599 'blendMode': clip.blendMode
35600
35601 };
35602
35603 for ( var i = 0, n = clipTracks.length; i !== n; ++ i ) {
35604
35605 tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );
35606
35607 }
35608
35609 return json;
35610
35611 },
35612
35613 CreateFromMorphTargetSequence: function ( name, morphTargetSequence, fps, noLoop ) {
35614
35615 var numMorphTargets = morphTargetSequence.length;
35616 var tracks = [];
35617
35618 for ( var i = 0; i < numMorphTargets; i ++ ) {
35619
35620 var times = [];
35621 var values = [];
35622
35623 times.push(
35624 ( i + numMorphTargets - 1 ) % numMorphTargets,
35625 i,
35626 ( i + 1 ) % numMorphTargets );
35627
35628 values.push( 0, 1, 0 );
35629
35630 var order = AnimationUtils.getKeyframeOrder( times );
35631 times = AnimationUtils.sortedArray( times, 1, order );
35632 values = AnimationUtils.sortedArray( values, 1, order );
35633
35634 // if there is a key at the first frame, duplicate it as the
35635 // last frame as well for perfect loop.
35636 if ( ! noLoop && times[ 0 ] === 0 ) {
35637
35638 times.push( numMorphTargets );
35639 values.push( values[ 0 ] );
35640
35641 }
35642
35643 tracks.push(
35644 new NumberKeyframeTrack(
35645 '.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
35646 times, values
35647 ).scale( 1.0 / fps ) );
35648
35649 }
35650
35651 return new AnimationClip( name, - 1, tracks );
35652
35653 },
35654
35655 findByName: function ( objectOrClipArray, name ) {
35656
35657 var clipArray = objectOrClipArray;
35658
35659 if ( ! Array.isArray( objectOrClipArray ) ) {
35660
35661 var o = objectOrClipArray;
35662 clipArray = o.geometry && o.geometry.animations || o.animations;
35663
35664 }
35665
35666 for ( var i = 0; i < clipArray.length; i ++ ) {
35667
35668 if ( clipArray[ i ].name === name ) {
35669
35670 return clipArray[ i ];
35671
35672 }
35673
35674 }
35675
35676 return null;
35677
35678 },
35679
35680 CreateClipsFromMorphTargetSequences: function ( morphTargets, fps, noLoop ) {
35681
35682 var animationToMorphTargets = {};
35683
35684 // tested with https://regex101.com/ on trick sequences
35685 // such flamingo_flyA_003, flamingo_run1_003, crdeath0059
35686 var pattern = /^([\w-]*?)([\d]+)$/;
35687
35688 // sort morph target names into animation groups based
35689 // patterns like Walk_001, Walk_002, Run_001, Run_002
35690 for ( var i = 0, il = morphTargets.length; i < il; i ++ ) {
35691
35692 var morphTarget = morphTargets[ i ];
35693 var parts = morphTarget.name.match( pattern );
35694
35695 if ( parts && parts.length > 1 ) {
35696
35697 var name = parts[ 1 ];
35698
35699 var animationMorphTargets = animationToMorphTargets[ name ];
35700
35701 if ( ! animationMorphTargets ) {
35702
35703 animationToMorphTargets[ name ] = animationMorphTargets = [];
35704
35705 }
35706
35707 animationMorphTargets.push( morphTarget );
35708
35709 }
35710
35711 }
35712
35713 var clips = [];
35714
35715 for ( var name$1 in animationToMorphTargets ) {
35716
35717 clips.push( AnimationClip.CreateFromMorphTargetSequence( name$1, animationToMorphTargets[ name$1 ], fps, noLoop ) );
35718
35719 }
35720
35721 return clips;
35722
35723 },
35724
35725 // parse the animation.hierarchy format
35726 parseAnimation: function ( animation, bones ) {
35727
35728 if ( ! animation ) {
35729
35730 console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' );
35731 return null;
35732
35733 }
35734
35735 var addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {
35736
35737 // only return track if there are actually keys.
35738 if ( animationKeys.length !== 0 ) {
35739
35740 var times = [];
35741 var values = [];
35742
35743 AnimationUtils.flattenJSON( animationKeys, times, values, propertyName );
35744
35745 // empty keys are filtered out, so check again
35746 if ( times.length !== 0 ) {
35747
35748 destTracks.push( new trackType( trackName, times, values ) );
35749
35750 }
35751
35752 }
35753
35754 };
35755
35756 var tracks = [];
35757
35758 var clipName = animation.name || 'default';
35759 var fps = animation.fps || 30;
35760 var blendMode = animation.blendMode;
35761
35762 // automatic length determination in AnimationClip.
35763 var duration = animation.length || - 1;
35764
35765 var hierarchyTracks = animation.hierarchy || [];
35766
35767 for ( var h = 0; h < hierarchyTracks.length; h ++ ) {
35768
35769 var animationKeys = hierarchyTracks[ h ].keys;
35770
35771 // skip empty tracks
35772 if ( ! animationKeys || animationKeys.length === 0 ) { continue; }
35773
35774 // process morph targets
35775 if ( animationKeys[ 0 ].morphTargets ) {
35776
35777 // figure out all morph targets used in this track
35778 var morphTargetNames = {};
35779
35780 var k = (void 0);
35781
35782 for ( k = 0; k < animationKeys.length; k ++ ) {
35783
35784 if ( animationKeys[ k ].morphTargets ) {
35785
35786 for ( var m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {
35787
35788 morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1;
35789
35790 }
35791
35792 }
35793
35794 }
35795
35796 // create a track for each morph target with all zero
35797 // morphTargetInfluences except for the keys in which
35798 // the morphTarget is named.
35799 for ( var morphTargetName in morphTargetNames ) {
35800
35801 var times = [];
35802 var values = [];
35803
35804 for ( var m$1 = 0; m$1 !== animationKeys[ k ].morphTargets.length; ++ m$1 ) {
35805
35806 var animationKey = animationKeys[ k ];
35807
35808 times.push( animationKey.time );
35809 values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );
35810
35811 }
35812
35813 tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );
35814
35815 }
35816
35817 duration = morphTargetNames.length * ( fps || 1.0 );
35818
35819 } else {
35820
35821 // ...assume skeletal animation
35822
35823 var boneName = '.bones[' + bones[ h ].name + ']';
35824
35825 addNonemptyTrack(
35826 VectorKeyframeTrack, boneName + '.position',
35827 animationKeys, 'pos', tracks );
35828
35829 addNonemptyTrack(
35830 QuaternionKeyframeTrack, boneName + '.quaternion',
35831 animationKeys, 'rot', tracks );
35832
35833 addNonemptyTrack(
35834 VectorKeyframeTrack, boneName + '.scale',
35835 animationKeys, 'scl', tracks );
35836
35837 }
35838
35839 }
35840
35841 if ( tracks.length === 0 ) {
35842
35843 return null;
35844
35845 }
35846
35847 var clip = new AnimationClip( clipName, duration, tracks, blendMode );
35848
35849 return clip;
35850
35851 }
35852
35853 } );
35854
35855 Object.assign( AnimationClip.prototype, {
35856
35857 resetDuration: function () {
35858
35859 var tracks = this.tracks;
35860 var duration = 0;
35861
35862 for ( var i = 0, n = tracks.length; i !== n; ++ i ) {
35863
35864 var track = this.tracks[ i ];
35865
35866 duration = Math.max( duration, track.times[ track.times.length - 1 ] );
35867
35868 }
35869
35870 this.duration = duration;
35871
35872 return this;
35873
35874 },
35875
35876 trim: function () {
35877
35878 for ( var i = 0; i < this.tracks.length; i ++ ) {
35879
35880 this.tracks[ i ].trim( 0, this.duration );
35881
35882 }
35883
35884 return this;
35885
35886 },
35887
35888 validate: function () {
35889
35890 var valid = true;
35891
35892 for ( var i = 0; i < this.tracks.length; i ++ ) {
35893
35894 valid = valid && this.tracks[ i ].validate();
35895
35896 }
35897
35898 return valid;
35899
35900 },
35901
35902 optimize: function () {
35903
35904 for ( var i = 0; i < this.tracks.length; i ++ ) {
35905
35906 this.tracks[ i ].optimize();
35907
35908 }
35909
35910 return this;
35911
35912 },
35913
35914 clone: function () {
35915
35916 var tracks = [];
35917
35918 for ( var i = 0; i < this.tracks.length; i ++ ) {
35919
35920 tracks.push( this.tracks[ i ].clone() );
35921
35922 }
35923
35924 return new AnimationClip( this.name, this.duration, tracks, this.blendMode );
35925
35926 }
35927
35928 } );
35929
35930 var Cache = {
35931
35932 enabled: false,
35933
35934 files: {},
35935
35936 add: function ( key, file ) {
35937
35938 if ( this.enabled === false ) { return; }
35939
35940 // console.log( 'THREE.Cache', 'Adding key:', key );
35941
35942 this.files[ key ] = file;
35943
35944 },
35945
35946 get: function ( key ) {
35947
35948 if ( this.enabled === false ) { return; }
35949
35950 // console.log( 'THREE.Cache', 'Checking key:', key );
35951
35952 return this.files[ key ];
35953
35954 },
35955
35956 remove: function ( key ) {
35957
35958 delete this.files[ key ];
35959
35960 },
35961
35962 clear: function () {
35963
35964 this.files = {};
35965
35966 }
35967
35968 };
35969
35970 function LoadingManager( onLoad, onProgress, onError ) {
35971
35972 var scope = this;
35973
35974 var isLoading = false;
35975 var itemsLoaded = 0;
35976 var itemsTotal = 0;
35977 var urlModifier = undefined;
35978 var handlers = [];
35979
35980 // Refer to #5689 for the reason why we don't set .onStart
35981 // in the constructor
35982
35983 this.onStart = undefined;
35984 this.onLoad = onLoad;
35985 this.onProgress = onProgress;
35986 this.onError = onError;
35987
35988 this.itemStart = function ( url ) {
35989
35990 itemsTotal ++;
35991
35992 if ( isLoading === false ) {
35993
35994 if ( scope.onStart !== undefined ) {
35995
35996 scope.onStart( url, itemsLoaded, itemsTotal );
35997
35998 }
35999
36000 }
36001
36002 isLoading = true;
36003
36004 };
36005
36006 this.itemEnd = function ( url ) {
36007
36008 itemsLoaded ++;
36009
36010 if ( scope.onProgress !== undefined ) {
36011
36012 scope.onProgress( url, itemsLoaded, itemsTotal );
36013
36014 }
36015
36016 if ( itemsLoaded === itemsTotal ) {
36017
36018 isLoading = false;
36019
36020 if ( scope.onLoad !== undefined ) {
36021
36022 scope.onLoad();
36023
36024 }
36025
36026 }
36027
36028 };
36029
36030 this.itemError = function ( url ) {
36031
36032 if ( scope.onError !== undefined ) {
36033
36034 scope.onError( url );
36035
36036 }
36037
36038 };
36039
36040 this.resolveURL = function ( url ) {
36041
36042 if ( urlModifier ) {
36043
36044 return urlModifier( url );
36045
36046 }
36047
36048 return url;
36049
36050 };
36051
36052 this.setURLModifier = function ( transform ) {
36053
36054 urlModifier = transform;
36055
36056 return this;
36057
36058 };
36059
36060 this.addHandler = function ( regex, loader ) {
36061
36062 handlers.push( regex, loader );
36063
36064 return this;
36065
36066 };
36067
36068 this.removeHandler = function ( regex ) {
36069
36070 var index = handlers.indexOf( regex );
36071
36072 if ( index !== - 1 ) {
36073
36074 handlers.splice( index, 2 );
36075
36076 }
36077
36078 return this;
36079
36080 };
36081
36082 this.getHandler = function ( file ) {
36083
36084 for ( var i = 0, l = handlers.length; i < l; i += 2 ) {
36085
36086 var regex = handlers[ i ];
36087 var loader = handlers[ i + 1 ];
36088
36089 if ( regex.global ) { regex.lastIndex = 0; } // see #17920
36090
36091 if ( regex.test( file ) ) {
36092
36093 return loader;
36094
36095 }
36096
36097 }
36098
36099 return null;
36100
36101 };
36102
36103 }
36104
36105 var DefaultLoadingManager = new LoadingManager();
36106
36107 function Loader( manager ) {
36108
36109 this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
36110
36111 this.crossOrigin = 'anonymous';
36112 this.path = '';
36113 this.resourcePath = '';
36114 this.requestHeader = {};
36115
36116 }
36117
36118 Object.assign( Loader.prototype, {
36119
36120 load: function ( /* url, onLoad, onProgress, onError */ ) {},
36121
36122 loadAsync: function ( url, onProgress ) {
36123
36124 var scope = this;
36125
36126 return new Promise( function ( resolve, reject ) {
36127
36128 scope.load( url, resolve, onProgress, reject );
36129
36130 } );
36131
36132 },
36133
36134 parse: function ( /* data */ ) {},
36135
36136 setCrossOrigin: function ( crossOrigin ) {
36137
36138 this.crossOrigin = crossOrigin;
36139 return this;
36140
36141 },
36142
36143 setPath: function ( path ) {
36144
36145 this.path = path;
36146 return this;
36147
36148 },
36149
36150 setResourcePath: function ( resourcePath ) {
36151
36152 this.resourcePath = resourcePath;
36153 return this;
36154
36155 },
36156
36157 setRequestHeader: function ( requestHeader ) {
36158
36159 this.requestHeader = requestHeader;
36160 return this;
36161
36162 }
36163
36164 } );
36165
36166 var loading = {};
36167
36168 function FileLoader( manager ) {
36169
36170 Loader.call( this, manager );
36171
36172 }
36173
36174 FileLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36175
36176 constructor: FileLoader,
36177
36178 load: function ( url, onLoad, onProgress, onError ) {
36179
36180 if ( url === undefined ) { url = ''; }
36181
36182 if ( this.path !== undefined ) { url = this.path + url; }
36183
36184 url = this.manager.resolveURL( url );
36185
36186 var scope = this;
36187
36188 var cached = Cache.get( url );
36189
36190 if ( cached !== undefined ) {
36191
36192 scope.manager.itemStart( url );
36193
36194 setTimeout( function () {
36195
36196 if ( onLoad ) { onLoad( cached ); }
36197
36198 scope.manager.itemEnd( url );
36199
36200 }, 0 );
36201
36202 return cached;
36203
36204 }
36205
36206 // Check if request is duplicate
36207
36208 if ( loading[ url ] !== undefined ) {
36209
36210 loading[ url ].push( {
36211
36212 onLoad: onLoad,
36213 onProgress: onProgress,
36214 onError: onError
36215
36216 } );
36217
36218 return;
36219
36220 }
36221
36222 // Check for data: URI
36223 var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
36224 var dataUriRegexResult = url.match( dataUriRegex );
36225 var request;
36226
36227 // Safari can not handle Data URIs through XMLHttpRequest so process manually
36228 if ( dataUriRegexResult ) {
36229
36230 var mimeType = dataUriRegexResult[ 1 ];
36231 var isBase64 = !! dataUriRegexResult[ 2 ];
36232
36233 var data = dataUriRegexResult[ 3 ];
36234 data = decodeURIComponent( data );
36235
36236 if ( isBase64 ) { data = atob( data ); }
36237
36238 try {
36239
36240 var response;
36241 var responseType = ( this.responseType || '' ).toLowerCase();
36242
36243 switch ( responseType ) {
36244
36245 case 'arraybuffer':
36246 case 'blob':
36247
36248 var view = new Uint8Array( data.length );
36249
36250 for ( var i = 0; i < data.length; i ++ ) {
36251
36252 view[ i ] = data.charCodeAt( i );
36253
36254 }
36255
36256 if ( responseType === 'blob' ) {
36257
36258 response = new Blob( [ view.buffer ], { type: mimeType } );
36259
36260 } else {
36261
36262 response = view.buffer;
36263
36264 }
36265
36266 break;
36267
36268 case 'document':
36269
36270 var parser = new DOMParser();
36271 response = parser.parseFromString( data, mimeType );
36272
36273 break;
36274
36275 case 'json':
36276
36277 response = JSON.parse( data );
36278
36279 break;
36280
36281 default: // 'text' or other
36282
36283 response = data;
36284
36285 break;
36286
36287 }
36288
36289 // Wait for next browser tick like standard XMLHttpRequest event dispatching does
36290 setTimeout( function () {
36291
36292 if ( onLoad ) { onLoad( response ); }
36293
36294 scope.manager.itemEnd( url );
36295
36296 }, 0 );
36297
36298 } catch ( error ) {
36299
36300 // Wait for next browser tick like standard XMLHttpRequest event dispatching does
36301 setTimeout( function () {
36302
36303 if ( onError ) { onError( error ); }
36304
36305 scope.manager.itemError( url );
36306 scope.manager.itemEnd( url );
36307
36308 }, 0 );
36309
36310 }
36311
36312 } else {
36313
36314 // Initialise array for duplicate requests
36315
36316 loading[ url ] = [];
36317
36318 loading[ url ].push( {
36319
36320 onLoad: onLoad,
36321 onProgress: onProgress,
36322 onError: onError
36323
36324 } );
36325
36326 request = new XMLHttpRequest();
36327
36328 request.open( 'GET', url, true );
36329
36330 request.addEventListener( 'load', function ( event ) {
36331
36332 var response = this.response;
36333
36334 var callbacks = loading[ url ];
36335
36336 delete loading[ url ];
36337
36338 if ( this.status === 200 || this.status === 0 ) {
36339
36340 // Some browsers return HTTP Status 0 when using non-http protocol
36341 // e.g. 'file://' or 'data://'. Handle as success.
36342
36343 if ( this.status === 0 ) { console.warn( 'THREE.FileLoader: HTTP Status 0 received.' ); }
36344
36345 // Add to cache only on HTTP success, so that we do not cache
36346 // error response bodies as proper responses to requests.
36347 Cache.add( url, response );
36348
36349 for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36350
36351 var callback = callbacks[ i ];
36352 if ( callback.onLoad ) { callback.onLoad( response ); }
36353
36354 }
36355
36356 scope.manager.itemEnd( url );
36357
36358 } else {
36359
36360 for ( var i$1 = 0, il$1 = callbacks.length; i$1 < il$1; i$1 ++ ) {
36361
36362 var callback$1 = callbacks[ i$1 ];
36363 if ( callback$1.onError ) { callback$1.onError( event ); }
36364
36365 }
36366
36367 scope.manager.itemError( url );
36368 scope.manager.itemEnd( url );
36369
36370 }
36371
36372 }, false );
36373
36374 request.addEventListener( 'progress', function ( event ) {
36375
36376 var callbacks = loading[ url ];
36377
36378 for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36379
36380 var callback = callbacks[ i ];
36381 if ( callback.onProgress ) { callback.onProgress( event ); }
36382
36383 }
36384
36385 }, false );
36386
36387 request.addEventListener( 'error', function ( event ) {
36388
36389 var callbacks = loading[ url ];
36390
36391 delete loading[ url ];
36392
36393 for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36394
36395 var callback = callbacks[ i ];
36396 if ( callback.onError ) { callback.onError( event ); }
36397
36398 }
36399
36400 scope.manager.itemError( url );
36401 scope.manager.itemEnd( url );
36402
36403 }, false );
36404
36405 request.addEventListener( 'abort', function ( event ) {
36406
36407 var callbacks = loading[ url ];
36408
36409 delete loading[ url ];
36410
36411 for ( var i = 0, il = callbacks.length; i < il; i ++ ) {
36412
36413 var callback = callbacks[ i ];
36414 if ( callback.onError ) { callback.onError( event ); }
36415
36416 }
36417
36418 scope.manager.itemError( url );
36419 scope.manager.itemEnd( url );
36420
36421 }, false );
36422
36423 if ( this.responseType !== undefined ) { request.responseType = this.responseType; }
36424 if ( this.withCredentials !== undefined ) { request.withCredentials = this.withCredentials; }
36425
36426 if ( request.overrideMimeType ) { request.overrideMimeType( this.mimeType !== undefined ? this.mimeType : 'text/plain' ); }
36427
36428 for ( var header in this.requestHeader ) {
36429
36430 request.setRequestHeader( header, this.requestHeader[ header ] );
36431
36432 }
36433
36434 request.send( null );
36435
36436 }
36437
36438 scope.manager.itemStart( url );
36439
36440 return request;
36441
36442 },
36443
36444 setResponseType: function ( value ) {
36445
36446 this.responseType = value;
36447 return this;
36448
36449 },
36450
36451 setWithCredentials: function ( value ) {
36452
36453 this.withCredentials = value;
36454 return this;
36455
36456 },
36457
36458 setMimeType: function ( value ) {
36459
36460 this.mimeType = value;
36461 return this;
36462
36463 }
36464
36465 } );
36466
36467 function AnimationLoader( manager ) {
36468
36469 Loader.call( this, manager );
36470
36471 }
36472
36473 AnimationLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36474
36475 constructor: AnimationLoader,
36476
36477 load: function ( url, onLoad, onProgress, onError ) {
36478
36479 var scope = this;
36480
36481 var loader = new FileLoader( scope.manager );
36482 loader.setPath( scope.path );
36483 loader.setRequestHeader( scope.requestHeader );
36484 loader.load( url, function ( text ) {
36485
36486 try {
36487
36488 onLoad( scope.parse( JSON.parse( text ) ) );
36489
36490 } catch ( e ) {
36491
36492 if ( onError ) {
36493
36494 onError( e );
36495
36496 } else {
36497
36498 console.error( e );
36499
36500 }
36501
36502 scope.manager.itemError( url );
36503
36504 }
36505
36506 }, onProgress, onError );
36507
36508 },
36509
36510 parse: function ( json ) {
36511
36512 var animations = [];
36513
36514 for ( var i = 0; i < json.length; i ++ ) {
36515
36516 var clip = AnimationClip.parse( json[ i ] );
36517
36518 animations.push( clip );
36519
36520 }
36521
36522 return animations;
36523
36524 }
36525
36526 } );
36527
36528 /**
36529 * Abstract Base class to block based textures loader (dds, pvr, ...)
36530 *
36531 * Sub classes have to implement the parse() method which will be used in load().
36532 */
36533
36534 function CompressedTextureLoader( manager ) {
36535
36536 Loader.call( this, manager );
36537
36538 }
36539
36540 CompressedTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36541
36542 constructor: CompressedTextureLoader,
36543
36544 load: function ( url, onLoad, onProgress, onError ) {
36545
36546 var scope = this;
36547
36548 var images = [];
36549
36550 var texture = new CompressedTexture();
36551 texture.image = images;
36552
36553 var loader = new FileLoader( this.manager );
36554 loader.setPath( this.path );
36555 loader.setResponseType( 'arraybuffer' );
36556 loader.setRequestHeader( this.requestHeader );
36557
36558 var loaded = 0;
36559
36560 function loadTexture( i ) {
36561
36562 loader.load( url[ i ], function ( buffer ) {
36563
36564 var texDatas = scope.parse( buffer, true );
36565
36566 images[ i ] = {
36567 width: texDatas.width,
36568 height: texDatas.height,
36569 format: texDatas.format,
36570 mipmaps: texDatas.mipmaps
36571 };
36572
36573 loaded += 1;
36574
36575 if ( loaded === 6 ) {
36576
36577 if ( texDatas.mipmapCount === 1 )
36578 { texture.minFilter = LinearFilter; }
36579
36580 texture.format = texDatas.format;
36581 texture.needsUpdate = true;
36582
36583 if ( onLoad ) { onLoad( texture ); }
36584
36585 }
36586
36587 }, onProgress, onError );
36588
36589 }
36590
36591 if ( Array.isArray( url ) ) {
36592
36593 for ( var i = 0, il = url.length; i < il; ++ i ) {
36594
36595 loadTexture( i );
36596
36597 }
36598
36599 } else {
36600
36601 // compressed cubemap texture stored in a single DDS file
36602
36603 loader.load( url, function ( buffer ) {
36604
36605 var texDatas = scope.parse( buffer, true );
36606
36607 if ( texDatas.isCubemap ) {
36608
36609 var faces = texDatas.mipmaps.length / texDatas.mipmapCount;
36610
36611 for ( var f = 0; f < faces; f ++ ) {
36612
36613 images[ f ] = { mipmaps: [] };
36614
36615 for ( var i = 0; i < texDatas.mipmapCount; i ++ ) {
36616
36617 images[ f ].mipmaps.push( texDatas.mipmaps[ f * texDatas.mipmapCount + i ] );
36618 images[ f ].format = texDatas.format;
36619 images[ f ].width = texDatas.width;
36620 images[ f ].height = texDatas.height;
36621
36622 }
36623
36624 }
36625
36626 } else {
36627
36628 texture.image.width = texDatas.width;
36629 texture.image.height = texDatas.height;
36630 texture.mipmaps = texDatas.mipmaps;
36631
36632 }
36633
36634 if ( texDatas.mipmapCount === 1 ) {
36635
36636 texture.minFilter = LinearFilter;
36637
36638 }
36639
36640 texture.format = texDatas.format;
36641 texture.needsUpdate = true;
36642
36643 if ( onLoad ) { onLoad( texture ); }
36644
36645 }, onProgress, onError );
36646
36647 }
36648
36649 return texture;
36650
36651 }
36652
36653 } );
36654
36655 /**
36656 * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
36657 *
36658 * Sub classes have to implement the parse() method which will be used in load().
36659 */
36660
36661 function DataTextureLoader( manager ) {
36662
36663 Loader.call( this, manager );
36664
36665 }
36666
36667 DataTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36668
36669 constructor: DataTextureLoader,
36670
36671 load: function ( url, onLoad, onProgress, onError ) {
36672
36673 var scope = this;
36674
36675 var texture = new DataTexture();
36676
36677 var loader = new FileLoader( this.manager );
36678 loader.setResponseType( 'arraybuffer' );
36679 loader.setRequestHeader( this.requestHeader );
36680 loader.setPath( this.path );
36681 loader.load( url, function ( buffer ) {
36682
36683 var texData = scope.parse( buffer );
36684
36685 if ( ! texData ) { return; }
36686
36687 if ( texData.image !== undefined ) {
36688
36689 texture.image = texData.image;
36690
36691 } else if ( texData.data !== undefined ) {
36692
36693 texture.image.width = texData.width;
36694 texture.image.height = texData.height;
36695 texture.image.data = texData.data;
36696
36697 }
36698
36699 texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
36700 texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
36701
36702 texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
36703 texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
36704
36705 texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
36706
36707 if ( texData.format !== undefined ) {
36708
36709 texture.format = texData.format;
36710
36711 }
36712
36713 if ( texData.type !== undefined ) {
36714
36715 texture.type = texData.type;
36716
36717 }
36718
36719 if ( texData.mipmaps !== undefined ) {
36720
36721 texture.mipmaps = texData.mipmaps;
36722 texture.minFilter = LinearMipmapLinearFilter; // presumably...
36723
36724 }
36725
36726 if ( texData.mipmapCount === 1 ) {
36727
36728 texture.minFilter = LinearFilter;
36729
36730 }
36731
36732 texture.needsUpdate = true;
36733
36734 if ( onLoad ) { onLoad( texture, texData ); }
36735
36736 }, onProgress, onError );
36737
36738
36739 return texture;
36740
36741 }
36742
36743 } );
36744
36745 function ImageLoader( manager ) {
36746
36747 Loader.call( this, manager );
36748
36749 }
36750
36751 ImageLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36752
36753 constructor: ImageLoader,
36754
36755 load: function ( url, onLoad, onProgress, onError ) {
36756
36757 if ( this.path !== undefined ) { url = this.path + url; }
36758
36759 url = this.manager.resolveURL( url );
36760
36761 var scope = this;
36762
36763 var cached = Cache.get( url );
36764
36765 if ( cached !== undefined ) {
36766
36767 scope.manager.itemStart( url );
36768
36769 setTimeout( function () {
36770
36771 if ( onLoad ) { onLoad( cached ); }
36772
36773 scope.manager.itemEnd( url );
36774
36775 }, 0 );
36776
36777 return cached;
36778
36779 }
36780
36781 var image = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'img' );
36782
36783 function onImageLoad() {
36784
36785 image.removeEventListener( 'load', onImageLoad, false );
36786 image.removeEventListener( 'error', onImageError, false );
36787
36788 Cache.add( url, this );
36789
36790 if ( onLoad ) { onLoad( this ); }
36791
36792 scope.manager.itemEnd( url );
36793
36794 }
36795
36796 function onImageError( event ) {
36797
36798 image.removeEventListener( 'load', onImageLoad, false );
36799 image.removeEventListener( 'error', onImageError, false );
36800
36801 if ( onError ) { onError( event ); }
36802
36803 scope.manager.itemError( url );
36804 scope.manager.itemEnd( url );
36805
36806 }
36807
36808 image.addEventListener( 'load', onImageLoad, false );
36809 image.addEventListener( 'error', onImageError, false );
36810
36811 if ( url.substr( 0, 5 ) !== 'data:' ) {
36812
36813 if ( this.crossOrigin !== undefined ) { image.crossOrigin = this.crossOrigin; }
36814
36815 }
36816
36817 scope.manager.itemStart( url );
36818
36819 image.src = url;
36820
36821 return image;
36822
36823 }
36824
36825 } );
36826
36827 function CubeTextureLoader( manager ) {
36828
36829 Loader.call( this, manager );
36830
36831 }
36832
36833 CubeTextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36834
36835 constructor: CubeTextureLoader,
36836
36837 load: function ( urls, onLoad, onProgress, onError ) {
36838
36839 var texture = new CubeTexture();
36840
36841 var loader = new ImageLoader( this.manager );
36842 loader.setCrossOrigin( this.crossOrigin );
36843 loader.setPath( this.path );
36844
36845 var loaded = 0;
36846
36847 function loadTexture( i ) {
36848
36849 loader.load( urls[ i ], function ( image ) {
36850
36851 texture.images[ i ] = image;
36852
36853 loaded ++;
36854
36855 if ( loaded === 6 ) {
36856
36857 texture.needsUpdate = true;
36858
36859 if ( onLoad ) { onLoad( texture ); }
36860
36861 }
36862
36863 }, undefined, onError );
36864
36865 }
36866
36867 for ( var i = 0; i < urls.length; ++ i ) {
36868
36869 loadTexture( i );
36870
36871 }
36872
36873 return texture;
36874
36875 }
36876
36877 } );
36878
36879 function TextureLoader( manager ) {
36880
36881 Loader.call( this, manager );
36882
36883 }
36884
36885 TextureLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
36886
36887 constructor: TextureLoader,
36888
36889 load: function ( url, onLoad, onProgress, onError ) {
36890
36891 var texture = new Texture();
36892
36893 var loader = new ImageLoader( this.manager );
36894 loader.setCrossOrigin( this.crossOrigin );
36895 loader.setPath( this.path );
36896
36897 loader.load( url, function ( image ) {
36898
36899 texture.image = image;
36900
36901 // JPEGs can't have an alpha channel, so memory can be saved by storing them as RGB.
36902 var isJPEG = url.search( /\.jpe?g($|\?)/i ) > 0 || url.search( /^data\:image\/jpeg/ ) === 0;
36903
36904 texture.format = isJPEG ? RGBFormat : RGBAFormat;
36905 texture.needsUpdate = true;
36906
36907 if ( onLoad !== undefined ) {
36908
36909 onLoad( texture );
36910
36911 }
36912
36913 }, onProgress, onError );
36914
36915 return texture;
36916
36917 }
36918
36919 } );
36920
36921 /**
36922 * Extensible curve object.
36923 *
36924 * Some common of curve methods:
36925 * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )
36926 * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )
36927 * .getPoints(), .getSpacedPoints()
36928 * .getLength()
36929 * .updateArcLengths()
36930 *
36931 * This following curves inherit from THREE.Curve:
36932 *
36933 * -- 2D curves --
36934 * THREE.ArcCurve
36935 * THREE.CubicBezierCurve
36936 * THREE.EllipseCurve
36937 * THREE.LineCurve
36938 * THREE.QuadraticBezierCurve
36939 * THREE.SplineCurve
36940 *
36941 * -- 3D curves --
36942 * THREE.CatmullRomCurve3
36943 * THREE.CubicBezierCurve3
36944 * THREE.LineCurve3
36945 * THREE.QuadraticBezierCurve3
36946 *
36947 * A series of curves can be represented as a THREE.CurvePath.
36948 *
36949 **/
36950
36951 function Curve() {
36952
36953 this.type = 'Curve';
36954
36955 this.arcLengthDivisions = 200;
36956
36957 }
36958
36959 Object.assign( Curve.prototype, {
36960
36961 // Virtual base class method to overwrite and implement in subclasses
36962 // - t [0 .. 1]
36963
36964 getPoint: function ( /* t, optionalTarget */ ) {
36965
36966 console.warn( 'THREE.Curve: .getPoint() not implemented.' );
36967 return null;
36968
36969 },
36970
36971 // Get point at relative position in curve according to arc length
36972 // - u [0 .. 1]
36973
36974 getPointAt: function ( u, optionalTarget ) {
36975
36976 var t = this.getUtoTmapping( u );
36977 return this.getPoint( t, optionalTarget );
36978
36979 },
36980
36981 // Get sequence of points using getPoint( t )
36982
36983 getPoints: function ( divisions ) {
36984
36985 if ( divisions === undefined ) { divisions = 5; }
36986
36987 var points = [];
36988
36989 for ( var d = 0; d <= divisions; d ++ ) {
36990
36991 points.push( this.getPoint( d / divisions ) );
36992
36993 }
36994
36995 return points;
36996
36997 },
36998
36999 // Get sequence of points using getPointAt( u )
37000
37001 getSpacedPoints: function ( divisions ) {
37002
37003 if ( divisions === undefined ) { divisions = 5; }
37004
37005 var points = [];
37006
37007 for ( var d = 0; d <= divisions; d ++ ) {
37008
37009 points.push( this.getPointAt( d / divisions ) );
37010
37011 }
37012
37013 return points;
37014
37015 },
37016
37017 // Get total curve arc length
37018
37019 getLength: function () {
37020
37021 var lengths = this.getLengths();
37022 return lengths[ lengths.length - 1 ];
37023
37024 },
37025
37026 // Get list of cumulative segment lengths
37027
37028 getLengths: function ( divisions ) {
37029
37030 if ( divisions === undefined ) { divisions = this.arcLengthDivisions; }
37031
37032 if ( this.cacheArcLengths &&
37033 ( this.cacheArcLengths.length === divisions + 1 ) &&
37034 ! this.needsUpdate ) {
37035
37036 return this.cacheArcLengths;
37037
37038 }
37039
37040 this.needsUpdate = false;
37041
37042 var cache = [];
37043 var current, last = this.getPoint( 0 );
37044 var sum = 0;
37045
37046 cache.push( 0 );
37047
37048 for ( var p = 1; p <= divisions; p ++ ) {
37049
37050 current = this.getPoint( p / divisions );
37051 sum += current.distanceTo( last );
37052 cache.push( sum );
37053 last = current;
37054
37055 }
37056
37057 this.cacheArcLengths = cache;
37058
37059 return cache; // { sums: cache, sum: sum }; Sum is in the last element.
37060
37061 },
37062
37063 updateArcLengths: function () {
37064
37065 this.needsUpdate = true;
37066 this.getLengths();
37067
37068 },
37069
37070 // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
37071
37072 getUtoTmapping: function ( u, distance ) {
37073
37074 var arcLengths = this.getLengths();
37075
37076 var i = 0, il = arcLengths.length;
37077
37078 var targetArcLength; // The targeted u distance value to get
37079
37080 if ( distance ) {
37081
37082 targetArcLength = distance;
37083
37084 } else {
37085
37086 targetArcLength = u * arcLengths[ il - 1 ];
37087
37088 }
37089
37090 // binary search for the index with largest value smaller than target u distance
37091
37092 var low = 0, high = il - 1, comparison;
37093
37094 while ( low <= high ) {
37095
37096 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
37097
37098 comparison = arcLengths[ i ] - targetArcLength;
37099
37100 if ( comparison < 0 ) {
37101
37102 low = i + 1;
37103
37104 } else if ( comparison > 0 ) {
37105
37106 high = i - 1;
37107
37108 } else {
37109
37110 high = i;
37111 break;
37112
37113 // DONE
37114
37115 }
37116
37117 }
37118
37119 i = high;
37120
37121 if ( arcLengths[ i ] === targetArcLength ) {
37122
37123 return i / ( il - 1 );
37124
37125 }
37126
37127 // we could get finer grain at lengths, or use simple interpolation between two points
37128
37129 var lengthBefore = arcLengths[ i ];
37130 var lengthAfter = arcLengths[ i + 1 ];
37131
37132 var segmentLength = lengthAfter - lengthBefore;
37133
37134 // determine where we are between the 'before' and 'after' points
37135
37136 var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
37137
37138 // add that fractional amount to t
37139
37140 var t = ( i + segmentFraction ) / ( il - 1 );
37141
37142 return t;
37143
37144 },
37145
37146 // Returns a unit vector tangent at t
37147 // In case any sub curve does not implement its tangent derivation,
37148 // 2 points a small delta apart will be used to find its gradient
37149 // which seems to give a reasonable approximation
37150
37151 getTangent: function ( t, optionalTarget ) {
37152
37153 var delta = 0.0001;
37154 var t1 = t - delta;
37155 var t2 = t + delta;
37156
37157 // Capping in case of danger
37158
37159 if ( t1 < 0 ) { t1 = 0; }
37160 if ( t2 > 1 ) { t2 = 1; }
37161
37162 var pt1 = this.getPoint( t1 );
37163 var pt2 = this.getPoint( t2 );
37164
37165 var tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() );
37166
37167 tangent.copy( pt2 ).sub( pt1 ).normalize();
37168
37169 return tangent;
37170
37171 },
37172
37173 getTangentAt: function ( u, optionalTarget ) {
37174
37175 var t = this.getUtoTmapping( u );
37176 return this.getTangent( t, optionalTarget );
37177
37178 },
37179
37180 computeFrenetFrames: function ( segments, closed ) {
37181
37182 // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
37183
37184 var normal = new Vector3();
37185
37186 var tangents = [];
37187 var normals = [];
37188 var binormals = [];
37189
37190 var vec = new Vector3();
37191 var mat = new Matrix4();
37192
37193 // compute the tangent vectors for each segment on the curve
37194
37195 for ( var i = 0; i <= segments; i ++ ) {
37196
37197 var u = i / segments;
37198
37199 tangents[ i ] = this.getTangentAt( u, new Vector3() );
37200 tangents[ i ].normalize();
37201
37202 }
37203
37204 // select an initial normal vector perpendicular to the first tangent vector,
37205 // and in the direction of the minimum tangent xyz component
37206
37207 normals[ 0 ] = new Vector3();
37208 binormals[ 0 ] = new Vector3();
37209 var min = Number.MAX_VALUE;
37210 var tx = Math.abs( tangents[ 0 ].x );
37211 var ty = Math.abs( tangents[ 0 ].y );
37212 var tz = Math.abs( tangents[ 0 ].z );
37213
37214 if ( tx <= min ) {
37215
37216 min = tx;
37217 normal.set( 1, 0, 0 );
37218
37219 }
37220
37221 if ( ty <= min ) {
37222
37223 min = ty;
37224 normal.set( 0, 1, 0 );
37225
37226 }
37227
37228 if ( tz <= min ) {
37229
37230 normal.set( 0, 0, 1 );
37231
37232 }
37233
37234 vec.crossVectors( tangents[ 0 ], normal ).normalize();
37235
37236 normals[ 0 ].crossVectors( tangents[ 0 ], vec );
37237 binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );
37238
37239
37240 // compute the slowly-varying normal and binormal vectors for each segment on the curve
37241
37242 for ( var i$1 = 1; i$1 <= segments; i$1 ++ ) {
37243
37244 normals[ i$1 ] = normals[ i$1 - 1 ].clone();
37245
37246 binormals[ i$1 ] = binormals[ i$1 - 1 ].clone();
37247
37248 vec.crossVectors( tangents[ i$1 - 1 ], tangents[ i$1 ] );
37249
37250 if ( vec.length() > Number.EPSILON ) {
37251
37252 vec.normalize();
37253
37254 var theta = Math.acos( MathUtils.clamp( tangents[ i$1 - 1 ].dot( tangents[ i$1 ] ), - 1, 1 ) ); // clamp for floating pt errors
37255
37256 normals[ i$1 ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
37257
37258 }
37259
37260 binormals[ i$1 ].crossVectors( tangents[ i$1 ], normals[ i$1 ] );
37261
37262 }
37263
37264 // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
37265
37266 if ( closed === true ) {
37267
37268 var theta$1 = Math.acos( MathUtils.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );
37269 theta$1 /= segments;
37270
37271 if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {
37272
37273 theta$1 = - theta$1;
37274
37275 }
37276
37277 for ( var i$2 = 1; i$2 <= segments; i$2 ++ ) {
37278
37279 // twist a little...
37280 normals[ i$2 ].applyMatrix4( mat.makeRotationAxis( tangents[ i$2 ], theta$1 * i$2 ) );
37281 binormals[ i$2 ].crossVectors( tangents[ i$2 ], normals[ i$2 ] );
37282
37283 }
37284
37285 }
37286
37287 return {
37288 tangents: tangents,
37289 normals: normals,
37290 binormals: binormals
37291 };
37292
37293 },
37294
37295 clone: function () {
37296
37297 return new this.constructor().copy( this );
37298
37299 },
37300
37301 copy: function ( source ) {
37302
37303 this.arcLengthDivisions = source.arcLengthDivisions;
37304
37305 return this;
37306
37307 },
37308
37309 toJSON: function () {
37310
37311 var data = {
37312 metadata: {
37313 version: 4.5,
37314 type: 'Curve',
37315 generator: 'Curve.toJSON'
37316 }
37317 };
37318
37319 data.arcLengthDivisions = this.arcLengthDivisions;
37320 data.type = this.type;
37321
37322 return data;
37323
37324 },
37325
37326 fromJSON: function ( json ) {
37327
37328 this.arcLengthDivisions = json.arcLengthDivisions;
37329
37330 return this;
37331
37332 }
37333
37334 } );
37335
37336 function EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
37337
37338 Curve.call( this );
37339
37340 this.type = 'EllipseCurve';
37341
37342 this.aX = aX || 0;
37343 this.aY = aY || 0;
37344
37345 this.xRadius = xRadius || 1;
37346 this.yRadius = yRadius || 1;
37347
37348 this.aStartAngle = aStartAngle || 0;
37349 this.aEndAngle = aEndAngle || 2 * Math.PI;
37350
37351 this.aClockwise = aClockwise || false;
37352
37353 this.aRotation = aRotation || 0;
37354
37355 }
37356
37357 EllipseCurve.prototype = Object.create( Curve.prototype );
37358 EllipseCurve.prototype.constructor = EllipseCurve;
37359
37360 EllipseCurve.prototype.isEllipseCurve = true;
37361
37362 EllipseCurve.prototype.getPoint = function ( t, optionalTarget ) {
37363
37364 var point = optionalTarget || new Vector2();
37365
37366 var twoPi = Math.PI * 2;
37367 var deltaAngle = this.aEndAngle - this.aStartAngle;
37368 var samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
37369
37370 // ensures that deltaAngle is 0 .. 2 PI
37371 while ( deltaAngle < 0 ) { deltaAngle += twoPi; }
37372 while ( deltaAngle > twoPi ) { deltaAngle -= twoPi; }
37373
37374 if ( deltaAngle < Number.EPSILON ) {
37375
37376 if ( samePoints ) {
37377
37378 deltaAngle = 0;
37379
37380 } else {
37381
37382 deltaAngle = twoPi;
37383
37384 }
37385
37386 }
37387
37388 if ( this.aClockwise === true && ! samePoints ) {
37389
37390 if ( deltaAngle === twoPi ) {
37391
37392 deltaAngle = - twoPi;
37393
37394 } else {
37395
37396 deltaAngle = deltaAngle - twoPi;
37397
37398 }
37399
37400 }
37401
37402 var angle = this.aStartAngle + t * deltaAngle;
37403 var x = this.aX + this.xRadius * Math.cos( angle );
37404 var y = this.aY + this.yRadius * Math.sin( angle );
37405
37406 if ( this.aRotation !== 0 ) {
37407
37408 var cos = Math.cos( this.aRotation );
37409 var sin = Math.sin( this.aRotation );
37410
37411 var tx = x - this.aX;
37412 var ty = y - this.aY;
37413
37414 // Rotate the point about the center of the ellipse.
37415 x = tx * cos - ty * sin + this.aX;
37416 y = tx * sin + ty * cos + this.aY;
37417
37418 }
37419
37420 return point.set( x, y );
37421
37422 };
37423
37424 EllipseCurve.prototype.copy = function ( source ) {
37425
37426 Curve.prototype.copy.call( this, source );
37427
37428 this.aX = source.aX;
37429 this.aY = source.aY;
37430
37431 this.xRadius = source.xRadius;
37432 this.yRadius = source.yRadius;
37433
37434 this.aStartAngle = source.aStartAngle;
37435 this.aEndAngle = source.aEndAngle;
37436
37437 this.aClockwise = source.aClockwise;
37438
37439 this.aRotation = source.aRotation;
37440
37441 return this;
37442
37443 };
37444
37445
37446 EllipseCurve.prototype.toJSON = function () {
37447
37448 var data = Curve.prototype.toJSON.call( this );
37449
37450 data.aX = this.aX;
37451 data.aY = this.aY;
37452
37453 data.xRadius = this.xRadius;
37454 data.yRadius = this.yRadius;
37455
37456 data.aStartAngle = this.aStartAngle;
37457 data.aEndAngle = this.aEndAngle;
37458
37459 data.aClockwise = this.aClockwise;
37460
37461 data.aRotation = this.aRotation;
37462
37463 return data;
37464
37465 };
37466
37467 EllipseCurve.prototype.fromJSON = function ( json ) {
37468
37469 Curve.prototype.fromJSON.call( this, json );
37470
37471 this.aX = json.aX;
37472 this.aY = json.aY;
37473
37474 this.xRadius = json.xRadius;
37475 this.yRadius = json.yRadius;
37476
37477 this.aStartAngle = json.aStartAngle;
37478 this.aEndAngle = json.aEndAngle;
37479
37480 this.aClockwise = json.aClockwise;
37481
37482 this.aRotation = json.aRotation;
37483
37484 return this;
37485
37486 };
37487
37488 function ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
37489
37490 EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
37491
37492 this.type = 'ArcCurve';
37493
37494 }
37495
37496 ArcCurve.prototype = Object.create( EllipseCurve.prototype );
37497 ArcCurve.prototype.constructor = ArcCurve;
37498
37499 ArcCurve.prototype.isArcCurve = true;
37500
37501 /**
37502 * Centripetal CatmullRom Curve - which is useful for avoiding
37503 * cusps and self-intersections in non-uniform catmull rom curves.
37504 * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
37505 *
37506 * curve.type accepts centripetal(default), chordal and catmullrom
37507 * curve.tension is used for catmullrom which defaults to 0.5
37508 */
37509
37510
37511 /*
37512 Based on an optimized c++ solution in
37513 - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
37514 - http://ideone.com/NoEbVM
37515
37516 This CubicPoly class could be used for reusing some variables and calculations,
37517 but for three.js curve use, it could be possible inlined and flatten into a single function call
37518 which can be placed in CurveUtils.
37519 */
37520
37521 function CubicPoly() {
37522
37523 var c0 = 0, c1 = 0, c2 = 0, c3 = 0;
37524
37525 /*
37526 * Compute coefficients for a cubic polynomial
37527 * p(s) = c0 + c1*s + c2*s^2 + c3*s^3
37528 * such that
37529 * p(0) = x0, p(1) = x1
37530 * and
37531 * p'(0) = t0, p'(1) = t1.
37532 */
37533 function init( x0, x1, t0, t1 ) {
37534
37535 c0 = x0;
37536 c1 = t0;
37537 c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
37538 c3 = 2 * x0 - 2 * x1 + t0 + t1;
37539
37540 }
37541
37542 return {
37543
37544 initCatmullRom: function ( x0, x1, x2, x3, tension ) {
37545
37546 init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
37547
37548 },
37549
37550 initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {
37551
37552 // compute tangents when parameterized in [t1,t2]
37553 var t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
37554 var t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
37555
37556 // rescale tangents for parametrization in [0,1]
37557 t1 *= dt1;
37558 t2 *= dt1;
37559
37560 init( x1, x2, t1, t2 );
37561
37562 },
37563
37564 calc: function ( t ) {
37565
37566 var t2 = t * t;
37567 var t3 = t2 * t;
37568 return c0 + c1 * t + c2 * t2 + c3 * t3;
37569
37570 }
37571
37572 };
37573
37574 }
37575
37576 //
37577
37578 var tmp = new Vector3();
37579 var px = new CubicPoly(), py = new CubicPoly(), pz = new CubicPoly();
37580
37581 function CatmullRomCurve3( points, closed, curveType, tension ) {
37582
37583 Curve.call( this );
37584
37585 this.type = 'CatmullRomCurve3';
37586
37587 this.points = points || [];
37588 this.closed = closed || false;
37589 this.curveType = curveType || 'centripetal';
37590 this.tension = ( tension !== undefined ) ? tension : 0.5;
37591
37592 }
37593
37594 CatmullRomCurve3.prototype = Object.create( Curve.prototype );
37595 CatmullRomCurve3.prototype.constructor = CatmullRomCurve3;
37596
37597 CatmullRomCurve3.prototype.isCatmullRomCurve3 = true;
37598
37599 CatmullRomCurve3.prototype.getPoint = function ( t, optionalTarget ) {
37600
37601 var point = optionalTarget || new Vector3();
37602
37603 var points = this.points;
37604 var l = points.length;
37605
37606 var p = ( l - ( this.closed ? 0 : 1 ) ) * t;
37607 var intPoint = Math.floor( p );
37608 var weight = p - intPoint;
37609
37610 if ( this.closed ) {
37611
37612 intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;
37613
37614 } else if ( weight === 0 && intPoint === l - 1 ) {
37615
37616 intPoint = l - 2;
37617 weight = 1;
37618
37619 }
37620
37621 var p0, p1, p2, p3; // 4 points
37622
37623 if ( this.closed || intPoint > 0 ) {
37624
37625 p0 = points[ ( intPoint - 1 ) % l ];
37626
37627 } else {
37628
37629 // extrapolate first point
37630 tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
37631 p0 = tmp;
37632
37633 }
37634
37635 p1 = points[ intPoint % l ];
37636 p2 = points[ ( intPoint + 1 ) % l ];
37637
37638 if ( this.closed || intPoint + 2 < l ) {
37639
37640 p3 = points[ ( intPoint + 2 ) % l ];
37641
37642 } else {
37643
37644 // extrapolate last point
37645 tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
37646 p3 = tmp;
37647
37648 }
37649
37650 if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {
37651
37652 // init Centripetal / Chordal Catmull-Rom
37653 var pow = this.curveType === 'chordal' ? 0.5 : 0.25;
37654 var dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
37655 var dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
37656 var dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
37657
37658 // safety check for repeated points
37659 if ( dt1 < 1e-4 ) { dt1 = 1.0; }
37660 if ( dt0 < 1e-4 ) { dt0 = dt1; }
37661 if ( dt2 < 1e-4 ) { dt2 = dt1; }
37662
37663 px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
37664 py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
37665 pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
37666
37667 } else if ( this.curveType === 'catmullrom' ) {
37668
37669 px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );
37670 py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );
37671 pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );
37672
37673 }
37674
37675 point.set(
37676 px.calc( weight ),
37677 py.calc( weight ),
37678 pz.calc( weight )
37679 );
37680
37681 return point;
37682
37683 };
37684
37685 CatmullRomCurve3.prototype.copy = function ( source ) {
37686
37687 Curve.prototype.copy.call( this, source );
37688
37689 this.points = [];
37690
37691 for ( var i = 0, l = source.points.length; i < l; i ++ ) {
37692
37693 var point = source.points[ i ];
37694
37695 this.points.push( point.clone() );
37696
37697 }
37698
37699 this.closed = source.closed;
37700 this.curveType = source.curveType;
37701 this.tension = source.tension;
37702
37703 return this;
37704
37705 };
37706
37707 CatmullRomCurve3.prototype.toJSON = function () {
37708
37709 var data = Curve.prototype.toJSON.call( this );
37710
37711 data.points = [];
37712
37713 for ( var i = 0, l = this.points.length; i < l; i ++ ) {
37714
37715 var point = this.points[ i ];
37716 data.points.push( point.toArray() );
37717
37718 }
37719
37720 data.closed = this.closed;
37721 data.curveType = this.curveType;
37722 data.tension = this.tension;
37723
37724 return data;
37725
37726 };
37727
37728 CatmullRomCurve3.prototype.fromJSON = function ( json ) {
37729
37730 Curve.prototype.fromJSON.call( this, json );
37731
37732 this.points = [];
37733
37734 for ( var i = 0, l = json.points.length; i < l; i ++ ) {
37735
37736 var point = json.points[ i ];
37737 this.points.push( new Vector3().fromArray( point ) );
37738
37739 }
37740
37741 this.closed = json.closed;
37742 this.curveType = json.curveType;
37743 this.tension = json.tension;
37744
37745 return this;
37746
37747 };
37748
37749 /**
37750 * Bezier Curves formulas obtained from
37751 * http://en.wikipedia.org/wiki/Bézier_curve
37752 */
37753
37754 function CatmullRom( t, p0, p1, p2, p3 ) {
37755
37756 var v0 = ( p2 - p0 ) * 0.5;
37757 var v1 = ( p3 - p1 ) * 0.5;
37758 var t2 = t * t;
37759 var t3 = t * t2;
37760 return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
37761
37762 }
37763
37764 //
37765
37766 function QuadraticBezierP0( t, p ) {
37767
37768 var k = 1 - t;
37769 return k * k * p;
37770
37771 }
37772
37773 function QuadraticBezierP1( t, p ) {
37774
37775 return 2 * ( 1 - t ) * t * p;
37776
37777 }
37778
37779 function QuadraticBezierP2( t, p ) {
37780
37781 return t * t * p;
37782
37783 }
37784
37785 function QuadraticBezier( t, p0, p1, p2 ) {
37786
37787 return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +
37788 QuadraticBezierP2( t, p2 );
37789
37790 }
37791
37792 //
37793
37794 function CubicBezierP0( t, p ) {
37795
37796 var k = 1 - t;
37797 return k * k * k * p;
37798
37799 }
37800
37801 function CubicBezierP1( t, p ) {
37802
37803 var k = 1 - t;
37804 return 3 * k * k * t * p;
37805
37806 }
37807
37808 function CubicBezierP2( t, p ) {
37809
37810 return 3 * ( 1 - t ) * t * t * p;
37811
37812 }
37813
37814 function CubicBezierP3( t, p ) {
37815
37816 return t * t * t * p;
37817
37818 }
37819
37820 function CubicBezier( t, p0, p1, p2, p3 ) {
37821
37822 return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +
37823 CubicBezierP3( t, p3 );
37824
37825 }
37826
37827 function CubicBezierCurve( v0, v1, v2, v3 ) {
37828
37829 Curve.call( this );
37830
37831 this.type = 'CubicBezierCurve';
37832
37833 this.v0 = v0 || new Vector2();
37834 this.v1 = v1 || new Vector2();
37835 this.v2 = v2 || new Vector2();
37836 this.v3 = v3 || new Vector2();
37837
37838 }
37839
37840 CubicBezierCurve.prototype = Object.create( Curve.prototype );
37841 CubicBezierCurve.prototype.constructor = CubicBezierCurve;
37842
37843 CubicBezierCurve.prototype.isCubicBezierCurve = true;
37844
37845 CubicBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
37846
37847 var point = optionalTarget || new Vector2();
37848
37849 var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
37850
37851 point.set(
37852 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
37853 CubicBezier( t, v0.y, v1.y, v2.y, v3.y )
37854 );
37855
37856 return point;
37857
37858 };
37859
37860 CubicBezierCurve.prototype.copy = function ( source ) {
37861
37862 Curve.prototype.copy.call( this, source );
37863
37864 this.v0.copy( source.v0 );
37865 this.v1.copy( source.v1 );
37866 this.v2.copy( source.v2 );
37867 this.v3.copy( source.v3 );
37868
37869 return this;
37870
37871 };
37872
37873 CubicBezierCurve.prototype.toJSON = function () {
37874
37875 var data = Curve.prototype.toJSON.call( this );
37876
37877 data.v0 = this.v0.toArray();
37878 data.v1 = this.v1.toArray();
37879 data.v2 = this.v2.toArray();
37880 data.v3 = this.v3.toArray();
37881
37882 return data;
37883
37884 };
37885
37886 CubicBezierCurve.prototype.fromJSON = function ( json ) {
37887
37888 Curve.prototype.fromJSON.call( this, json );
37889
37890 this.v0.fromArray( json.v0 );
37891 this.v1.fromArray( json.v1 );
37892 this.v2.fromArray( json.v2 );
37893 this.v3.fromArray( json.v3 );
37894
37895 return this;
37896
37897 };
37898
37899 function CubicBezierCurve3( v0, v1, v2, v3 ) {
37900
37901 Curve.call( this );
37902
37903 this.type = 'CubicBezierCurve3';
37904
37905 this.v0 = v0 || new Vector3();
37906 this.v1 = v1 || new Vector3();
37907 this.v2 = v2 || new Vector3();
37908 this.v3 = v3 || new Vector3();
37909
37910 }
37911
37912 CubicBezierCurve3.prototype = Object.create( Curve.prototype );
37913 CubicBezierCurve3.prototype.constructor = CubicBezierCurve3;
37914
37915 CubicBezierCurve3.prototype.isCubicBezierCurve3 = true;
37916
37917 CubicBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
37918
37919 var point = optionalTarget || new Vector3();
37920
37921 var v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
37922
37923 point.set(
37924 CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
37925 CubicBezier( t, v0.y, v1.y, v2.y, v3.y ),
37926 CubicBezier( t, v0.z, v1.z, v2.z, v3.z )
37927 );
37928
37929 return point;
37930
37931 };
37932
37933 CubicBezierCurve3.prototype.copy = function ( source ) {
37934
37935 Curve.prototype.copy.call( this, source );
37936
37937 this.v0.copy( source.v0 );
37938 this.v1.copy( source.v1 );
37939 this.v2.copy( source.v2 );
37940 this.v3.copy( source.v3 );
37941
37942 return this;
37943
37944 };
37945
37946 CubicBezierCurve3.prototype.toJSON = function () {
37947
37948 var data = Curve.prototype.toJSON.call( this );
37949
37950 data.v0 = this.v0.toArray();
37951 data.v1 = this.v1.toArray();
37952 data.v2 = this.v2.toArray();
37953 data.v3 = this.v3.toArray();
37954
37955 return data;
37956
37957 };
37958
37959 CubicBezierCurve3.prototype.fromJSON = function ( json ) {
37960
37961 Curve.prototype.fromJSON.call( this, json );
37962
37963 this.v0.fromArray( json.v0 );
37964 this.v1.fromArray( json.v1 );
37965 this.v2.fromArray( json.v2 );
37966 this.v3.fromArray( json.v3 );
37967
37968 return this;
37969
37970 };
37971
37972 function LineCurve( v1, v2 ) {
37973
37974 Curve.call( this );
37975
37976 this.type = 'LineCurve';
37977
37978 this.v1 = v1 || new Vector2();
37979 this.v2 = v2 || new Vector2();
37980
37981 }
37982
37983 LineCurve.prototype = Object.create( Curve.prototype );
37984 LineCurve.prototype.constructor = LineCurve;
37985
37986 LineCurve.prototype.isLineCurve = true;
37987
37988 LineCurve.prototype.getPoint = function ( t, optionalTarget ) {
37989
37990 var point = optionalTarget || new Vector2();
37991
37992 if ( t === 1 ) {
37993
37994 point.copy( this.v2 );
37995
37996 } else {
37997
37998 point.copy( this.v2 ).sub( this.v1 );
37999 point.multiplyScalar( t ).add( this.v1 );
38000
38001 }
38002
38003 return point;
38004
38005 };
38006
38007 // Line curve is linear, so we can overwrite default getPointAt
38008
38009 LineCurve.prototype.getPointAt = function ( u, optionalTarget ) {
38010
38011 return this.getPoint( u, optionalTarget );
38012
38013 };
38014
38015 LineCurve.prototype.getTangent = function ( t, optionalTarget ) {
38016
38017 var tangent = optionalTarget || new Vector2();
38018
38019 tangent.copy( this.v2 ).sub( this.v1 ).normalize();
38020
38021 return tangent;
38022
38023 };
38024
38025 LineCurve.prototype.copy = function ( source ) {
38026
38027 Curve.prototype.copy.call( this, source );
38028
38029 this.v1.copy( source.v1 );
38030 this.v2.copy( source.v2 );
38031
38032 return this;
38033
38034 };
38035
38036 LineCurve.prototype.toJSON = function () {
38037
38038 var data = Curve.prototype.toJSON.call( this );
38039
38040 data.v1 = this.v1.toArray();
38041 data.v2 = this.v2.toArray();
38042
38043 return data;
38044
38045 };
38046
38047 LineCurve.prototype.fromJSON = function ( json ) {
38048
38049 Curve.prototype.fromJSON.call( this, json );
38050
38051 this.v1.fromArray( json.v1 );
38052 this.v2.fromArray( json.v2 );
38053
38054 return this;
38055
38056 };
38057
38058 function LineCurve3( v1, v2 ) {
38059
38060 Curve.call( this );
38061
38062 this.type = 'LineCurve3';
38063
38064 this.v1 = v1 || new Vector3();
38065 this.v2 = v2 || new Vector3();
38066
38067 }
38068
38069 LineCurve3.prototype = Object.create( Curve.prototype );
38070 LineCurve3.prototype.constructor = LineCurve3;
38071
38072 LineCurve3.prototype.isLineCurve3 = true;
38073
38074 LineCurve3.prototype.getPoint = function ( t, optionalTarget ) {
38075
38076 var point = optionalTarget || new Vector3();
38077
38078 if ( t === 1 ) {
38079
38080 point.copy( this.v2 );
38081
38082 } else {
38083
38084 point.copy( this.v2 ).sub( this.v1 );
38085 point.multiplyScalar( t ).add( this.v1 );
38086
38087 }
38088
38089 return point;
38090
38091 };
38092
38093 // Line curve is linear, so we can overwrite default getPointAt
38094
38095 LineCurve3.prototype.getPointAt = function ( u, optionalTarget ) {
38096
38097 return this.getPoint( u, optionalTarget );
38098
38099 };
38100
38101 LineCurve3.prototype.copy = function ( source ) {
38102
38103 Curve.prototype.copy.call( this, source );
38104
38105 this.v1.copy( source.v1 );
38106 this.v2.copy( source.v2 );
38107
38108 return this;
38109
38110 };
38111
38112 LineCurve3.prototype.toJSON = function () {
38113
38114 var data = Curve.prototype.toJSON.call( this );
38115
38116 data.v1 = this.v1.toArray();
38117 data.v2 = this.v2.toArray();
38118
38119 return data;
38120
38121 };
38122
38123 LineCurve3.prototype.fromJSON = function ( json ) {
38124
38125 Curve.prototype.fromJSON.call( this, json );
38126
38127 this.v1.fromArray( json.v1 );
38128 this.v2.fromArray( json.v2 );
38129
38130 return this;
38131
38132 };
38133
38134 function QuadraticBezierCurve( v0, v1, v2 ) {
38135
38136 Curve.call( this );
38137
38138 this.type = 'QuadraticBezierCurve';
38139
38140 this.v0 = v0 || new Vector2();
38141 this.v1 = v1 || new Vector2();
38142 this.v2 = v2 || new Vector2();
38143
38144 }
38145
38146 QuadraticBezierCurve.prototype = Object.create( Curve.prototype );
38147 QuadraticBezierCurve.prototype.constructor = QuadraticBezierCurve;
38148
38149 QuadraticBezierCurve.prototype.isQuadraticBezierCurve = true;
38150
38151 QuadraticBezierCurve.prototype.getPoint = function ( t, optionalTarget ) {
38152
38153 var point = optionalTarget || new Vector2();
38154
38155 var v0 = this.v0, v1 = this.v1, v2 = this.v2;
38156
38157 point.set(
38158 QuadraticBezier( t, v0.x, v1.x, v2.x ),
38159 QuadraticBezier( t, v0.y, v1.y, v2.y )
38160 );
38161
38162 return point;
38163
38164 };
38165
38166 QuadraticBezierCurve.prototype.copy = function ( source ) {
38167
38168 Curve.prototype.copy.call( this, source );
38169
38170 this.v0.copy( source.v0 );
38171 this.v1.copy( source.v1 );
38172 this.v2.copy( source.v2 );
38173
38174 return this;
38175
38176 };
38177
38178 QuadraticBezierCurve.prototype.toJSON = function () {
38179
38180 var data = Curve.prototype.toJSON.call( this );
38181
38182 data.v0 = this.v0.toArray();
38183 data.v1 = this.v1.toArray();
38184 data.v2 = this.v2.toArray();
38185
38186 return data;
38187
38188 };
38189
38190 QuadraticBezierCurve.prototype.fromJSON = function ( json ) {
38191
38192 Curve.prototype.fromJSON.call( this, json );
38193
38194 this.v0.fromArray( json.v0 );
38195 this.v1.fromArray( json.v1 );
38196 this.v2.fromArray( json.v2 );
38197
38198 return this;
38199
38200 };
38201
38202 function QuadraticBezierCurve3( v0, v1, v2 ) {
38203
38204 Curve.call( this );
38205
38206 this.type = 'QuadraticBezierCurve3';
38207
38208 this.v0 = v0 || new Vector3();
38209 this.v1 = v1 || new Vector3();
38210 this.v2 = v2 || new Vector3();
38211
38212 }
38213
38214 QuadraticBezierCurve3.prototype = Object.create( Curve.prototype );
38215 QuadraticBezierCurve3.prototype.constructor = QuadraticBezierCurve3;
38216
38217 QuadraticBezierCurve3.prototype.isQuadraticBezierCurve3 = true;
38218
38219 QuadraticBezierCurve3.prototype.getPoint = function ( t, optionalTarget ) {
38220
38221 var point = optionalTarget || new Vector3();
38222
38223 var v0 = this.v0, v1 = this.v1, v2 = this.v2;
38224
38225 point.set(
38226 QuadraticBezier( t, v0.x, v1.x, v2.x ),
38227 QuadraticBezier( t, v0.y, v1.y, v2.y ),
38228 QuadraticBezier( t, v0.z, v1.z, v2.z )
38229 );
38230
38231 return point;
38232
38233 };
38234
38235 QuadraticBezierCurve3.prototype.copy = function ( source ) {
38236
38237 Curve.prototype.copy.call( this, source );
38238
38239 this.v0.copy( source.v0 );
38240 this.v1.copy( source.v1 );
38241 this.v2.copy( source.v2 );
38242
38243 return this;
38244
38245 };
38246
38247 QuadraticBezierCurve3.prototype.toJSON = function () {
38248
38249 var data = Curve.prototype.toJSON.call( this );
38250
38251 data.v0 = this.v0.toArray();
38252 data.v1 = this.v1.toArray();
38253 data.v2 = this.v2.toArray();
38254
38255 return data;
38256
38257 };
38258
38259 QuadraticBezierCurve3.prototype.fromJSON = function ( json ) {
38260
38261 Curve.prototype.fromJSON.call( this, json );
38262
38263 this.v0.fromArray( json.v0 );
38264 this.v1.fromArray( json.v1 );
38265 this.v2.fromArray( json.v2 );
38266
38267 return this;
38268
38269 };
38270
38271 function SplineCurve( points ) {
38272
38273 Curve.call( this );
38274
38275 this.type = 'SplineCurve';
38276
38277 this.points = points || [];
38278
38279 }
38280
38281 SplineCurve.prototype = Object.create( Curve.prototype );
38282 SplineCurve.prototype.constructor = SplineCurve;
38283
38284 SplineCurve.prototype.isSplineCurve = true;
38285
38286 SplineCurve.prototype.getPoint = function ( t, optionalTarget ) {
38287
38288 var point = optionalTarget || new Vector2();
38289
38290 var points = this.points;
38291 var p = ( points.length - 1 ) * t;
38292
38293 var intPoint = Math.floor( p );
38294 var weight = p - intPoint;
38295
38296 var p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
38297 var p1 = points[ intPoint ];
38298 var p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
38299 var p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
38300
38301 point.set(
38302 CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ),
38303 CatmullRom( weight, p0.y, p1.y, p2.y, p3.y )
38304 );
38305
38306 return point;
38307
38308 };
38309
38310 SplineCurve.prototype.copy = function ( source ) {
38311
38312 Curve.prototype.copy.call( this, source );
38313
38314 this.points = [];
38315
38316 for ( var i = 0, l = source.points.length; i < l; i ++ ) {
38317
38318 var point = source.points[ i ];
38319
38320 this.points.push( point.clone() );
38321
38322 }
38323
38324 return this;
38325
38326 };
38327
38328 SplineCurve.prototype.toJSON = function () {
38329
38330 var data = Curve.prototype.toJSON.call( this );
38331
38332 data.points = [];
38333
38334 for ( var i = 0, l = this.points.length; i < l; i ++ ) {
38335
38336 var point = this.points[ i ];
38337 data.points.push( point.toArray() );
38338
38339 }
38340
38341 return data;
38342
38343 };
38344
38345 SplineCurve.prototype.fromJSON = function ( json ) {
38346
38347 Curve.prototype.fromJSON.call( this, json );
38348
38349 this.points = [];
38350
38351 for ( var i = 0, l = json.points.length; i < l; i ++ ) {
38352
38353 var point = json.points[ i ];
38354 this.points.push( new Vector2().fromArray( point ) );
38355
38356 }
38357
38358 return this;
38359
38360 };
38361
38362 var Curves = /*#__PURE__*/Object.freeze({
38363 __proto__: null,
38364 ArcCurve: ArcCurve,
38365 CatmullRomCurve3: CatmullRomCurve3,
38366 CubicBezierCurve: CubicBezierCurve,
38367 CubicBezierCurve3: CubicBezierCurve3,
38368 EllipseCurve: EllipseCurve,
38369 LineCurve: LineCurve,
38370 LineCurve3: LineCurve3,
38371 QuadraticBezierCurve: QuadraticBezierCurve,
38372 QuadraticBezierCurve3: QuadraticBezierCurve3,
38373 SplineCurve: SplineCurve
38374 });
38375
38376 /**************************************************************
38377 * Curved Path - a curve path is simply a array of connected
38378 * curves, but retains the api of a curve
38379 **************************************************************/
38380
38381 function CurvePath() {
38382
38383 Curve.call( this );
38384
38385 this.type = 'CurvePath';
38386
38387 this.curves = [];
38388 this.autoClose = false; // Automatically closes the path
38389
38390 }
38391
38392 CurvePath.prototype = Object.assign( Object.create( Curve.prototype ), {
38393
38394 constructor: CurvePath,
38395
38396 add: function ( curve ) {
38397
38398 this.curves.push( curve );
38399
38400 },
38401
38402 closePath: function () {
38403
38404 // Add a line curve if start and end of lines are not connected
38405 var startPoint = this.curves[ 0 ].getPoint( 0 );
38406 var endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );
38407
38408 if ( ! startPoint.equals( endPoint ) ) {
38409
38410 this.curves.push( new LineCurve( endPoint, startPoint ) );
38411
38412 }
38413
38414 },
38415
38416 // To get accurate point with reference to
38417 // entire path distance at time t,
38418 // following has to be done:
38419
38420 // 1. Length of each sub path have to be known
38421 // 2. Locate and identify type of curve
38422 // 3. Get t for the curve
38423 // 4. Return curve.getPointAt(t')
38424
38425 getPoint: function ( t ) {
38426
38427 var d = t * this.getLength();
38428 var curveLengths = this.getCurveLengths();
38429 var i = 0;
38430
38431 // To think about boundaries points.
38432
38433 while ( i < curveLengths.length ) {
38434
38435 if ( curveLengths[ i ] >= d ) {
38436
38437 var diff = curveLengths[ i ] - d;
38438 var curve = this.curves[ i ];
38439
38440 var segmentLength = curve.getLength();
38441 var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
38442
38443 return curve.getPointAt( u );
38444
38445 }
38446
38447 i ++;
38448
38449 }
38450
38451 return null;
38452
38453 // loop where sum != 0, sum > d , sum+1 <d
38454
38455 },
38456
38457 // We cannot use the default THREE.Curve getPoint() with getLength() because in
38458 // THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
38459 // getPoint() depends on getLength
38460
38461 getLength: function () {
38462
38463 var lens = this.getCurveLengths();
38464 return lens[ lens.length - 1 ];
38465
38466 },
38467
38468 // cacheLengths must be recalculated.
38469 updateArcLengths: function () {
38470
38471 this.needsUpdate = true;
38472 this.cacheLengths = null;
38473 this.getCurveLengths();
38474
38475 },
38476
38477 // Compute lengths and cache them
38478 // We cannot overwrite getLengths() because UtoT mapping uses it.
38479
38480 getCurveLengths: function () {
38481
38482 // We use cache values if curves and cache array are same length
38483
38484 if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) {
38485
38486 return this.cacheLengths;
38487
38488 }
38489
38490 // Get length of sub-curve
38491 // Push sums into cached array
38492
38493 var lengths = [];
38494 var sums = 0;
38495
38496 for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
38497
38498 sums += this.curves[ i ].getLength();
38499 lengths.push( sums );
38500
38501 }
38502
38503 this.cacheLengths = lengths;
38504
38505 return lengths;
38506
38507 },
38508
38509 getSpacedPoints: function ( divisions ) {
38510
38511 if ( divisions === undefined ) { divisions = 40; }
38512
38513 var points = [];
38514
38515 for ( var i = 0; i <= divisions; i ++ ) {
38516
38517 points.push( this.getPoint( i / divisions ) );
38518
38519 }
38520
38521 if ( this.autoClose ) {
38522
38523 points.push( points[ 0 ] );
38524
38525 }
38526
38527 return points;
38528
38529 },
38530
38531 getPoints: function ( divisions ) {
38532
38533 divisions = divisions || 12;
38534
38535 var points = [];
38536 var last;
38537
38538 for ( var i = 0, curves = this.curves; i < curves.length; i ++ ) {
38539
38540 var curve = curves[ i ];
38541 var resolution = ( curve && curve.isEllipseCurve ) ? divisions * 2
38542 : ( curve && ( curve.isLineCurve || curve.isLineCurve3 ) ) ? 1
38543 : ( curve && curve.isSplineCurve ) ? divisions * curve.points.length
38544 : divisions;
38545
38546 var pts = curve.getPoints( resolution );
38547
38548 for ( var j = 0; j < pts.length; j ++ ) {
38549
38550 var point = pts[ j ];
38551
38552 if ( last && last.equals( point ) ) { continue; } // ensures no consecutive points are duplicates
38553
38554 points.push( point );
38555 last = point;
38556
38557 }
38558
38559 }
38560
38561 if ( this.autoClose && points.length > 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) {
38562
38563 points.push( points[ 0 ] );
38564
38565 }
38566
38567 return points;
38568
38569 },
38570
38571 copy: function ( source ) {
38572
38573 Curve.prototype.copy.call( this, source );
38574
38575 this.curves = [];
38576
38577 for ( var i = 0, l = source.curves.length; i < l; i ++ ) {
38578
38579 var curve = source.curves[ i ];
38580
38581 this.curves.push( curve.clone() );
38582
38583 }
38584
38585 this.autoClose = source.autoClose;
38586
38587 return this;
38588
38589 },
38590
38591 toJSON: function () {
38592
38593 var data = Curve.prototype.toJSON.call( this );
38594
38595 data.autoClose = this.autoClose;
38596 data.curves = [];
38597
38598 for ( var i = 0, l = this.curves.length; i < l; i ++ ) {
38599
38600 var curve = this.curves[ i ];
38601 data.curves.push( curve.toJSON() );
38602
38603 }
38604
38605 return data;
38606
38607 },
38608
38609 fromJSON: function ( json ) {
38610
38611 Curve.prototype.fromJSON.call( this, json );
38612
38613 this.autoClose = json.autoClose;
38614 this.curves = [];
38615
38616 for ( var i = 0, l = json.curves.length; i < l; i ++ ) {
38617
38618 var curve = json.curves[ i ];
38619 this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) );
38620
38621 }
38622
38623 return this;
38624
38625 }
38626
38627 } );
38628
38629 function Path( points ) {
38630
38631 CurvePath.call( this );
38632
38633 this.type = 'Path';
38634
38635 this.currentPoint = new Vector2();
38636
38637 if ( points ) {
38638
38639 this.setFromPoints( points );
38640
38641 }
38642
38643 }
38644
38645 Path.prototype = Object.assign( Object.create( CurvePath.prototype ), {
38646
38647 constructor: Path,
38648
38649 setFromPoints: function ( points ) {
38650
38651 this.moveTo( points[ 0 ].x, points[ 0 ].y );
38652
38653 for ( var i = 1, l = points.length; i < l; i ++ ) {
38654
38655 this.lineTo( points[ i ].x, points[ i ].y );
38656
38657 }
38658
38659 return this;
38660
38661 },
38662
38663 moveTo: function ( x, y ) {
38664
38665 this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?
38666
38667 return this;
38668
38669 },
38670
38671 lineTo: function ( x, y ) {
38672
38673 var curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );
38674 this.curves.push( curve );
38675
38676 this.currentPoint.set( x, y );
38677
38678 return this;
38679
38680 },
38681
38682 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
38683
38684 var curve = new QuadraticBezierCurve(
38685 this.currentPoint.clone(),
38686 new Vector2( aCPx, aCPy ),
38687 new Vector2( aX, aY )
38688 );
38689
38690 this.curves.push( curve );
38691
38692 this.currentPoint.set( aX, aY );
38693
38694 return this;
38695
38696 },
38697
38698 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
38699
38700 var curve = new CubicBezierCurve(
38701 this.currentPoint.clone(),
38702 new Vector2( aCP1x, aCP1y ),
38703 new Vector2( aCP2x, aCP2y ),
38704 new Vector2( aX, aY )
38705 );
38706
38707 this.curves.push( curve );
38708
38709 this.currentPoint.set( aX, aY );
38710
38711 return this;
38712
38713 },
38714
38715 splineThru: function ( pts /*Array of Vector*/ ) {
38716
38717 var npts = [ this.currentPoint.clone() ].concat( pts );
38718
38719 var curve = new SplineCurve( npts );
38720 this.curves.push( curve );
38721
38722 this.currentPoint.copy( pts[ pts.length - 1 ] );
38723
38724 return this;
38725
38726 },
38727
38728 arc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
38729
38730 var x0 = this.currentPoint.x;
38731 var y0 = this.currentPoint.y;
38732
38733 this.absarc( aX + x0, aY + y0, aRadius,
38734 aStartAngle, aEndAngle, aClockwise );
38735
38736 return this;
38737
38738 },
38739
38740 absarc: function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
38741
38742 this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
38743
38744 return this;
38745
38746 },
38747
38748 ellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
38749
38750 var x0 = this.currentPoint.x;
38751 var y0 = this.currentPoint.y;
38752
38753 this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
38754
38755 return this;
38756
38757 },
38758
38759 absellipse: function ( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
38760
38761 var curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
38762
38763 if ( this.curves.length > 0 ) {
38764
38765 // if a previous curve is present, attempt to join
38766 var firstPoint = curve.getPoint( 0 );
38767
38768 if ( ! firstPoint.equals( this.currentPoint ) ) {
38769
38770 this.lineTo( firstPoint.x, firstPoint.y );
38771
38772 }
38773
38774 }
38775
38776 this.curves.push( curve );
38777
38778 var lastPoint = curve.getPoint( 1 );
38779 this.currentPoint.copy( lastPoint );
38780
38781 return this;
38782
38783 },
38784
38785 copy: function ( source ) {
38786
38787 CurvePath.prototype.copy.call( this, source );
38788
38789 this.currentPoint.copy( source.currentPoint );
38790
38791 return this;
38792
38793 },
38794
38795 toJSON: function () {
38796
38797 var data = CurvePath.prototype.toJSON.call( this );
38798
38799 data.currentPoint = this.currentPoint.toArray();
38800
38801 return data;
38802
38803 },
38804
38805 fromJSON: function ( json ) {
38806
38807 CurvePath.prototype.fromJSON.call( this, json );
38808
38809 this.currentPoint.fromArray( json.currentPoint );
38810
38811 return this;
38812
38813 }
38814
38815 } );
38816
38817 function Shape( points ) {
38818
38819 Path.call( this, points );
38820
38821 this.uuid = MathUtils.generateUUID();
38822
38823 this.type = 'Shape';
38824
38825 this.holes = [];
38826
38827 }
38828
38829 Shape.prototype = Object.assign( Object.create( Path.prototype ), {
38830
38831 constructor: Shape,
38832
38833 getPointsHoles: function ( divisions ) {
38834
38835 var holesPts = [];
38836
38837 for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
38838
38839 holesPts[ i ] = this.holes[ i ].getPoints( divisions );
38840
38841 }
38842
38843 return holesPts;
38844
38845 },
38846
38847 // get points of shape and holes (keypoints based on segments parameter)
38848
38849 extractPoints: function ( divisions ) {
38850
38851 return {
38852
38853 shape: this.getPoints( divisions ),
38854 holes: this.getPointsHoles( divisions )
38855
38856 };
38857
38858 },
38859
38860 copy: function ( source ) {
38861
38862 Path.prototype.copy.call( this, source );
38863
38864 this.holes = [];
38865
38866 for ( var i = 0, l = source.holes.length; i < l; i ++ ) {
38867
38868 var hole = source.holes[ i ];
38869
38870 this.holes.push( hole.clone() );
38871
38872 }
38873
38874 return this;
38875
38876 },
38877
38878 toJSON: function () {
38879
38880 var data = Path.prototype.toJSON.call( this );
38881
38882 data.uuid = this.uuid;
38883 data.holes = [];
38884
38885 for ( var i = 0, l = this.holes.length; i < l; i ++ ) {
38886
38887 var hole = this.holes[ i ];
38888 data.holes.push( hole.toJSON() );
38889
38890 }
38891
38892 return data;
38893
38894 },
38895
38896 fromJSON: function ( json ) {
38897
38898 Path.prototype.fromJSON.call( this, json );
38899
38900 this.uuid = json.uuid;
38901 this.holes = [];
38902
38903 for ( var i = 0, l = json.holes.length; i < l; i ++ ) {
38904
38905 var hole = json.holes[ i ];
38906 this.holes.push( new Path().fromJSON( hole ) );
38907
38908 }
38909
38910 return this;
38911
38912 }
38913
38914 } );
38915
38916 function Light( color, intensity ) {
38917
38918 Object3D.call( this );
38919
38920 this.type = 'Light';
38921
38922 this.color = new Color( color );
38923 this.intensity = intensity !== undefined ? intensity : 1;
38924
38925 this.receiveShadow = undefined;
38926
38927 }
38928
38929 Light.prototype = Object.assign( Object.create( Object3D.prototype ), {
38930
38931 constructor: Light,
38932
38933 isLight: true,
38934
38935 copy: function ( source ) {
38936
38937 Object3D.prototype.copy.call( this, source );
38938
38939 this.color.copy( source.color );
38940 this.intensity = source.intensity;
38941
38942 return this;
38943
38944 },
38945
38946 toJSON: function ( meta ) {
38947
38948 var data = Object3D.prototype.toJSON.call( this, meta );
38949
38950 data.object.color = this.color.getHex();
38951 data.object.intensity = this.intensity;
38952
38953 if ( this.groundColor !== undefined ) { data.object.groundColor = this.groundColor.getHex(); }
38954
38955 if ( this.distance !== undefined ) { data.object.distance = this.distance; }
38956 if ( this.angle !== undefined ) { data.object.angle = this.angle; }
38957 if ( this.decay !== undefined ) { data.object.decay = this.decay; }
38958 if ( this.penumbra !== undefined ) { data.object.penumbra = this.penumbra; }
38959
38960 if ( this.shadow !== undefined ) { data.object.shadow = this.shadow.toJSON(); }
38961
38962 return data;
38963
38964 }
38965
38966 } );
38967
38968 function HemisphereLight( skyColor, groundColor, intensity ) {
38969
38970 Light.call( this, skyColor, intensity );
38971
38972 this.type = 'HemisphereLight';
38973
38974 this.castShadow = undefined;
38975
38976 this.position.copy( Object3D.DefaultUp );
38977 this.updateMatrix();
38978
38979 this.groundColor = new Color( groundColor );
38980
38981 }
38982
38983 HemisphereLight.prototype = Object.assign( Object.create( Light.prototype ), {
38984
38985 constructor: HemisphereLight,
38986
38987 isHemisphereLight: true,
38988
38989 copy: function ( source ) {
38990
38991 Light.prototype.copy.call( this, source );
38992
38993 this.groundColor.copy( source.groundColor );
38994
38995 return this;
38996
38997 }
38998
38999 } );
39000
39001 function LightShadow( camera ) {
39002
39003 this.camera = camera;
39004
39005 this.bias = 0;
39006 this.normalBias = 0;
39007 this.radius = 1;
39008
39009 this.mapSize = new Vector2( 512, 512 );
39010
39011 this.map = null;
39012 this.mapPass = null;
39013 this.matrix = new Matrix4();
39014
39015 this.autoUpdate = true;
39016 this.needsUpdate = false;
39017
39018 this._frustum = new Frustum();
39019 this._frameExtents = new Vector2( 1, 1 );
39020
39021 this._viewportCount = 1;
39022
39023 this._viewports = [
39024
39025 new Vector4( 0, 0, 1, 1 )
39026
39027 ];
39028
39029 }
39030
39031 Object.assign( LightShadow.prototype, {
39032
39033 _projScreenMatrix: new Matrix4(),
39034
39035 _lightPositionWorld: new Vector3(),
39036
39037 _lookTarget: new Vector3(),
39038
39039 getViewportCount: function () {
39040
39041 return this._viewportCount;
39042
39043 },
39044
39045 getFrustum: function () {
39046
39047 return this._frustum;
39048
39049 },
39050
39051 updateMatrices: function ( light ) {
39052
39053 var shadowCamera = this.camera,
39054 shadowMatrix = this.matrix,
39055 projScreenMatrix = this._projScreenMatrix,
39056 lookTarget = this._lookTarget,
39057 lightPositionWorld = this._lightPositionWorld;
39058
39059 lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
39060 shadowCamera.position.copy( lightPositionWorld );
39061
39062 lookTarget.setFromMatrixPosition( light.target.matrixWorld );
39063 shadowCamera.lookAt( lookTarget );
39064 shadowCamera.updateMatrixWorld();
39065
39066 projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
39067 this._frustum.setFromProjectionMatrix( projScreenMatrix );
39068
39069 shadowMatrix.set(
39070 0.5, 0.0, 0.0, 0.5,
39071 0.0, 0.5, 0.0, 0.5,
39072 0.0, 0.0, 0.5, 0.5,
39073 0.0, 0.0, 0.0, 1.0
39074 );
39075
39076 shadowMatrix.multiply( shadowCamera.projectionMatrix );
39077 shadowMatrix.multiply( shadowCamera.matrixWorldInverse );
39078
39079 },
39080
39081 getViewport: function ( viewportIndex ) {
39082
39083 return this._viewports[ viewportIndex ];
39084
39085 },
39086
39087 getFrameExtents: function () {
39088
39089 return this._frameExtents;
39090
39091 },
39092
39093 copy: function ( source ) {
39094
39095 this.camera = source.camera.clone();
39096
39097 this.bias = source.bias;
39098 this.radius = source.radius;
39099
39100 this.mapSize.copy( source.mapSize );
39101
39102 return this;
39103
39104 },
39105
39106 clone: function () {
39107
39108 return new this.constructor().copy( this );
39109
39110 },
39111
39112 toJSON: function () {
39113
39114 var object = {};
39115
39116 if ( this.bias !== 0 ) { object.bias = this.bias; }
39117 if ( this.normalBias !== 0 ) { object.normalBias = this.normalBias; }
39118 if ( this.radius !== 1 ) { object.radius = this.radius; }
39119 if ( this.mapSize.x !== 512 || this.mapSize.y !== 512 ) { object.mapSize = this.mapSize.toArray(); }
39120
39121 object.camera = this.camera.toJSON( false ).object;
39122 delete object.camera.matrix;
39123
39124 return object;
39125
39126 }
39127
39128 } );
39129
39130 function SpotLightShadow() {
39131
39132 LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) );
39133
39134 }
39135
39136 SpotLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
39137
39138 constructor: SpotLightShadow,
39139
39140 isSpotLightShadow: true,
39141
39142 updateMatrices: function ( light ) {
39143
39144 var camera = this.camera;
39145
39146 var fov = MathUtils.RAD2DEG * 2 * light.angle;
39147 var aspect = this.mapSize.width / this.mapSize.height;
39148 var far = light.distance || camera.far;
39149
39150 if ( fov !== camera.fov || aspect !== camera.aspect || far !== camera.far ) {
39151
39152 camera.fov = fov;
39153 camera.aspect = aspect;
39154 camera.far = far;
39155 camera.updateProjectionMatrix();
39156
39157 }
39158
39159 LightShadow.prototype.updateMatrices.call( this, light );
39160
39161 }
39162
39163 } );
39164
39165 function SpotLight( color, intensity, distance, angle, penumbra, decay ) {
39166
39167 Light.call( this, color, intensity );
39168
39169 this.type = 'SpotLight';
39170
39171 this.position.copy( Object3D.DefaultUp );
39172 this.updateMatrix();
39173
39174 this.target = new Object3D();
39175
39176 Object.defineProperty( this, 'power', {
39177 get: function () {
39178
39179 // intensity = power per solid angle.
39180 // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39181 return this.intensity * Math.PI;
39182
39183 },
39184 set: function ( power ) {
39185
39186 // intensity = power per solid angle.
39187 // ref: equation (17) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39188 this.intensity = power / Math.PI;
39189
39190 }
39191 } );
39192
39193 this.distance = ( distance !== undefined ) ? distance : 0;
39194 this.angle = ( angle !== undefined ) ? angle : Math.PI / 3;
39195 this.penumbra = ( penumbra !== undefined ) ? penumbra : 0;
39196 this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2.
39197
39198 this.shadow = new SpotLightShadow();
39199
39200 }
39201
39202 SpotLight.prototype = Object.assign( Object.create( Light.prototype ), {
39203
39204 constructor: SpotLight,
39205
39206 isSpotLight: true,
39207
39208 copy: function ( source ) {
39209
39210 Light.prototype.copy.call( this, source );
39211
39212 this.distance = source.distance;
39213 this.angle = source.angle;
39214 this.penumbra = source.penumbra;
39215 this.decay = source.decay;
39216
39217 this.target = source.target.clone();
39218
39219 this.shadow = source.shadow.clone();
39220
39221 return this;
39222
39223 }
39224
39225 } );
39226
39227 function PointLightShadow() {
39228
39229 LightShadow.call( this, new PerspectiveCamera( 90, 1, 0.5, 500 ) );
39230
39231 this._frameExtents = new Vector2( 4, 2 );
39232
39233 this._viewportCount = 6;
39234
39235 this._viewports = [
39236 // These viewports map a cube-map onto a 2D texture with the
39237 // following orientation:
39238 //
39239 // xzXZ
39240 // y Y
39241 //
39242 // X - Positive x direction
39243 // x - Negative x direction
39244 // Y - Positive y direction
39245 // y - Negative y direction
39246 // Z - Positive z direction
39247 // z - Negative z direction
39248
39249 // positive X
39250 new Vector4( 2, 1, 1, 1 ),
39251 // negative X
39252 new Vector4( 0, 1, 1, 1 ),
39253 // positive Z
39254 new Vector4( 3, 1, 1, 1 ),
39255 // negative Z
39256 new Vector4( 1, 1, 1, 1 ),
39257 // positive Y
39258 new Vector4( 3, 0, 1, 1 ),
39259 // negative Y
39260 new Vector4( 1, 0, 1, 1 )
39261 ];
39262
39263 this._cubeDirections = [
39264 new Vector3( 1, 0, 0 ), new Vector3( - 1, 0, 0 ), new Vector3( 0, 0, 1 ),
39265 new Vector3( 0, 0, - 1 ), new Vector3( 0, 1, 0 ), new Vector3( 0, - 1, 0 )
39266 ];
39267
39268 this._cubeUps = [
39269 new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ), new Vector3( 0, 1, 0 ),
39270 new Vector3( 0, 1, 0 ), new Vector3( 0, 0, 1 ), new Vector3( 0, 0, - 1 )
39271 ];
39272
39273 }
39274
39275 PointLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
39276
39277 constructor: PointLightShadow,
39278
39279 isPointLightShadow: true,
39280
39281 updateMatrices: function ( light, viewportIndex ) {
39282
39283 if ( viewportIndex === undefined ) { viewportIndex = 0; }
39284
39285 var camera = this.camera,
39286 shadowMatrix = this.matrix,
39287 lightPositionWorld = this._lightPositionWorld,
39288 lookTarget = this._lookTarget,
39289 projScreenMatrix = this._projScreenMatrix;
39290
39291 lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
39292 camera.position.copy( lightPositionWorld );
39293
39294 lookTarget.copy( camera.position );
39295 lookTarget.add( this._cubeDirections[ viewportIndex ] );
39296 camera.up.copy( this._cubeUps[ viewportIndex ] );
39297 camera.lookAt( lookTarget );
39298 camera.updateMatrixWorld();
39299
39300 shadowMatrix.makeTranslation( - lightPositionWorld.x, - lightPositionWorld.y, - lightPositionWorld.z );
39301
39302 projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
39303 this._frustum.setFromProjectionMatrix( projScreenMatrix );
39304
39305 }
39306
39307 } );
39308
39309 function PointLight( color, intensity, distance, decay ) {
39310
39311 Light.call( this, color, intensity );
39312
39313 this.type = 'PointLight';
39314
39315 Object.defineProperty( this, 'power', {
39316 get: function () {
39317
39318 // intensity = power per solid angle.
39319 // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39320 return this.intensity * 4 * Math.PI;
39321
39322 },
39323 set: function ( power ) {
39324
39325 // intensity = power per solid angle.
39326 // ref: equation (15) from https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
39327 this.intensity = power / ( 4 * Math.PI );
39328
39329 }
39330 } );
39331
39332 this.distance = ( distance !== undefined ) ? distance : 0;
39333 this.decay = ( decay !== undefined ) ? decay : 1; // for physically correct lights, should be 2.
39334
39335 this.shadow = new PointLightShadow();
39336
39337 }
39338
39339 PointLight.prototype = Object.assign( Object.create( Light.prototype ), {
39340
39341 constructor: PointLight,
39342
39343 isPointLight: true,
39344
39345 copy: function ( source ) {
39346
39347 Light.prototype.copy.call( this, source );
39348
39349 this.distance = source.distance;
39350 this.decay = source.decay;
39351
39352 this.shadow = source.shadow.clone();
39353
39354 return this;
39355
39356 }
39357
39358 } );
39359
39360 function OrthographicCamera( left, right, top, bottom, near, far ) {
39361
39362 Camera.call( this );
39363
39364 this.type = 'OrthographicCamera';
39365
39366 this.zoom = 1;
39367 this.view = null;
39368
39369 this.left = ( left !== undefined ) ? left : - 1;
39370 this.right = ( right !== undefined ) ? right : 1;
39371 this.top = ( top !== undefined ) ? top : 1;
39372 this.bottom = ( bottom !== undefined ) ? bottom : - 1;
39373
39374 this.near = ( near !== undefined ) ? near : 0.1;
39375 this.far = ( far !== undefined ) ? far : 2000;
39376
39377 this.updateProjectionMatrix();
39378
39379 }
39380
39381 OrthographicCamera.prototype = Object.assign( Object.create( Camera.prototype ), {
39382
39383 constructor: OrthographicCamera,
39384
39385 isOrthographicCamera: true,
39386
39387 copy: function ( source, recursive ) {
39388
39389 Camera.prototype.copy.call( this, source, recursive );
39390
39391 this.left = source.left;
39392 this.right = source.right;
39393 this.top = source.top;
39394 this.bottom = source.bottom;
39395 this.near = source.near;
39396 this.far = source.far;
39397
39398 this.zoom = source.zoom;
39399 this.view = source.view === null ? null : Object.assign( {}, source.view );
39400
39401 return this;
39402
39403 },
39404
39405 setViewOffset: function ( fullWidth, fullHeight, x, y, width, height ) {
39406
39407 if ( this.view === null ) {
39408
39409 this.view = {
39410 enabled: true,
39411 fullWidth: 1,
39412 fullHeight: 1,
39413 offsetX: 0,
39414 offsetY: 0,
39415 width: 1,
39416 height: 1
39417 };
39418
39419 }
39420
39421 this.view.enabled = true;
39422 this.view.fullWidth = fullWidth;
39423 this.view.fullHeight = fullHeight;
39424 this.view.offsetX = x;
39425 this.view.offsetY = y;
39426 this.view.width = width;
39427 this.view.height = height;
39428
39429 this.updateProjectionMatrix();
39430
39431 },
39432
39433 clearViewOffset: function () {
39434
39435 if ( this.view !== null ) {
39436
39437 this.view.enabled = false;
39438
39439 }
39440
39441 this.updateProjectionMatrix();
39442
39443 },
39444
39445 updateProjectionMatrix: function () {
39446
39447 var dx = ( this.right - this.left ) / ( 2 * this.zoom );
39448 var dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
39449 var cx = ( this.right + this.left ) / 2;
39450 var cy = ( this.top + this.bottom ) / 2;
39451
39452 var left = cx - dx;
39453 var right = cx + dx;
39454 var top = cy + dy;
39455 var bottom = cy - dy;
39456
39457 if ( this.view !== null && this.view.enabled ) {
39458
39459 var scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom;
39460 var scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom;
39461
39462 left += scaleW * this.view.offsetX;
39463 right = left + scaleW * this.view.width;
39464 top -= scaleH * this.view.offsetY;
39465 bottom = top - scaleH * this.view.height;
39466
39467 }
39468
39469 this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far );
39470
39471 this.projectionMatrixInverse.getInverse( this.projectionMatrix );
39472
39473 },
39474
39475 toJSON: function ( meta ) {
39476
39477 var data = Object3D.prototype.toJSON.call( this, meta );
39478
39479 data.object.zoom = this.zoom;
39480 data.object.left = this.left;
39481 data.object.right = this.right;
39482 data.object.top = this.top;
39483 data.object.bottom = this.bottom;
39484 data.object.near = this.near;
39485 data.object.far = this.far;
39486
39487 if ( this.view !== null ) { data.object.view = Object.assign( {}, this.view ); }
39488
39489 return data;
39490
39491 }
39492
39493 } );
39494
39495 function DirectionalLightShadow() {
39496
39497 LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) );
39498
39499 }
39500
39501 DirectionalLightShadow.prototype = Object.assign( Object.create( LightShadow.prototype ), {
39502
39503 constructor: DirectionalLightShadow,
39504
39505 isDirectionalLightShadow: true,
39506
39507 updateMatrices: function ( light ) {
39508
39509 LightShadow.prototype.updateMatrices.call( this, light );
39510
39511 }
39512
39513 } );
39514
39515 function DirectionalLight( color, intensity ) {
39516
39517 Light.call( this, color, intensity );
39518
39519 this.type = 'DirectionalLight';
39520
39521 this.position.copy( Object3D.DefaultUp );
39522 this.updateMatrix();
39523
39524 this.target = new Object3D();
39525
39526 this.shadow = new DirectionalLightShadow();
39527
39528 }
39529
39530 DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), {
39531
39532 constructor: DirectionalLight,
39533
39534 isDirectionalLight: true,
39535
39536 copy: function ( source ) {
39537
39538 Light.prototype.copy.call( this, source );
39539
39540 this.target = source.target.clone();
39541
39542 this.shadow = source.shadow.clone();
39543
39544 return this;
39545
39546 }
39547
39548 } );
39549
39550 function AmbientLight( color, intensity ) {
39551
39552 Light.call( this, color, intensity );
39553
39554 this.type = 'AmbientLight';
39555
39556 this.castShadow = undefined;
39557
39558 }
39559
39560 AmbientLight.prototype = Object.assign( Object.create( Light.prototype ), {
39561
39562 constructor: AmbientLight,
39563
39564 isAmbientLight: true
39565
39566 } );
39567
39568 function RectAreaLight( color, intensity, width, height ) {
39569
39570 Light.call( this, color, intensity );
39571
39572 this.type = 'RectAreaLight';
39573
39574 this.width = ( width !== undefined ) ? width : 10;
39575 this.height = ( height !== undefined ) ? height : 10;
39576
39577 }
39578
39579 RectAreaLight.prototype = Object.assign( Object.create( Light.prototype ), {
39580
39581 constructor: RectAreaLight,
39582
39583 isRectAreaLight: true,
39584
39585 copy: function ( source ) {
39586
39587 Light.prototype.copy.call( this, source );
39588
39589 this.width = source.width;
39590 this.height = source.height;
39591
39592 return this;
39593
39594 },
39595
39596 toJSON: function ( meta ) {
39597
39598 var data = Light.prototype.toJSON.call( this, meta );
39599
39600 data.object.width = this.width;
39601 data.object.height = this.height;
39602
39603 return data;
39604
39605 }
39606
39607 } );
39608
39609 /**
39610 * Primary reference:
39611 * https://graphics.stanford.edu/papers/envmap/envmap.pdf
39612 *
39613 * Secondary reference:
39614 * https://www.ppsloan.org/publications/StupidSH36.pdf
39615 */
39616
39617 // 3-band SH defined by 9 coefficients
39618
39619 function SphericalHarmonics3() {
39620
39621 this.coefficients = [];
39622
39623 for ( var i = 0; i < 9; i ++ ) {
39624
39625 this.coefficients.push( new Vector3() );
39626
39627 }
39628
39629 }
39630
39631 Object.assign( SphericalHarmonics3.prototype, {
39632
39633 isSphericalHarmonics3: true,
39634
39635 set: function ( coefficients ) {
39636
39637 for ( var i = 0; i < 9; i ++ ) {
39638
39639 this.coefficients[ i ].copy( coefficients[ i ] );
39640
39641 }
39642
39643 return this;
39644
39645 },
39646
39647 zero: function () {
39648
39649 for ( var i = 0; i < 9; i ++ ) {
39650
39651 this.coefficients[ i ].set( 0, 0, 0 );
39652
39653 }
39654
39655 return this;
39656
39657 },
39658
39659 // get the radiance in the direction of the normal
39660 // target is a Vector3
39661 getAt: function ( normal, target ) {
39662
39663 // normal is assumed to be unit length
39664
39665 var x = normal.x, y = normal.y, z = normal.z;
39666
39667 var coeff = this.coefficients;
39668
39669 // band 0
39670 target.copy( coeff[ 0 ] ).multiplyScalar( 0.282095 );
39671
39672 // band 1
39673 target.addScaledVector( coeff[ 1 ], 0.488603 * y );
39674 target.addScaledVector( coeff[ 2 ], 0.488603 * z );
39675 target.addScaledVector( coeff[ 3 ], 0.488603 * x );
39676
39677 // band 2
39678 target.addScaledVector( coeff[ 4 ], 1.092548 * ( x * y ) );
39679 target.addScaledVector( coeff[ 5 ], 1.092548 * ( y * z ) );
39680 target.addScaledVector( coeff[ 6 ], 0.315392 * ( 3.0 * z * z - 1.0 ) );
39681 target.addScaledVector( coeff[ 7 ], 1.092548 * ( x * z ) );
39682 target.addScaledVector( coeff[ 8 ], 0.546274 * ( x * x - y * y ) );
39683
39684 return target;
39685
39686 },
39687
39688 // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal
39689 // target is a Vector3
39690 // https://graphics.stanford.edu/papers/envmap/envmap.pdf
39691 getIrradianceAt: function ( normal, target ) {
39692
39693 // normal is assumed to be unit length
39694
39695 var x = normal.x, y = normal.y, z = normal.z;
39696
39697 var coeff = this.coefficients;
39698
39699 // band 0
39700 target.copy( coeff[ 0 ] ).multiplyScalar( 0.886227 ); // π * 0.282095
39701
39702 // band 1
39703 target.addScaledVector( coeff[ 1 ], 2.0 * 0.511664 * y ); // ( 2 * π / 3 ) * 0.488603
39704 target.addScaledVector( coeff[ 2 ], 2.0 * 0.511664 * z );
39705 target.addScaledVector( coeff[ 3 ], 2.0 * 0.511664 * x );
39706
39707 // band 2
39708 target.addScaledVector( coeff[ 4 ], 2.0 * 0.429043 * x * y ); // ( π / 4 ) * 1.092548
39709 target.addScaledVector( coeff[ 5 ], 2.0 * 0.429043 * y * z );
39710 target.addScaledVector( coeff[ 6 ], 0.743125 * z * z - 0.247708 ); // ( π / 4 ) * 0.315392 * 3
39711 target.addScaledVector( coeff[ 7 ], 2.0 * 0.429043 * x * z );
39712 target.addScaledVector( coeff[ 8 ], 0.429043 * ( x * x - y * y ) ); // ( π / 4 ) * 0.546274
39713
39714 return target;
39715
39716 },
39717
39718 add: function ( sh ) {
39719
39720 for ( var i = 0; i < 9; i ++ ) {
39721
39722 this.coefficients[ i ].add( sh.coefficients[ i ] );
39723
39724 }
39725
39726 return this;
39727
39728 },
39729
39730 addScaledSH: function ( sh, s ) {
39731
39732 for ( var i = 0; i < 9; i ++ ) {
39733
39734 this.coefficients[ i ].addScaledVector( sh.coefficients[ i ], s );
39735
39736 }
39737
39738 return this;
39739
39740 },
39741
39742 scale: function ( s ) {
39743
39744 for ( var i = 0; i < 9; i ++ ) {
39745
39746 this.coefficients[ i ].multiplyScalar( s );
39747
39748 }
39749
39750 return this;
39751
39752 },
39753
39754 lerp: function ( sh, alpha ) {
39755
39756 for ( var i = 0; i < 9; i ++ ) {
39757
39758 this.coefficients[ i ].lerp( sh.coefficients[ i ], alpha );
39759
39760 }
39761
39762 return this;
39763
39764 },
39765
39766 equals: function ( sh ) {
39767
39768 for ( var i = 0; i < 9; i ++ ) {
39769
39770 if ( ! this.coefficients[ i ].equals( sh.coefficients[ i ] ) ) {
39771
39772 return false;
39773
39774 }
39775
39776 }
39777
39778 return true;
39779
39780 },
39781
39782 copy: function ( sh ) {
39783
39784 return this.set( sh.coefficients );
39785
39786 },
39787
39788 clone: function () {
39789
39790 return new this.constructor().copy( this );
39791
39792 },
39793
39794 fromArray: function ( array, offset ) {
39795
39796 if ( offset === undefined ) { offset = 0; }
39797
39798 var coefficients = this.coefficients;
39799
39800 for ( var i = 0; i < 9; i ++ ) {
39801
39802 coefficients[ i ].fromArray( array, offset + ( i * 3 ) );
39803
39804 }
39805
39806 return this;
39807
39808 },
39809
39810 toArray: function ( array, offset ) {
39811
39812 if ( array === undefined ) { array = []; }
39813 if ( offset === undefined ) { offset = 0; }
39814
39815 var coefficients = this.coefficients;
39816
39817 for ( var i = 0; i < 9; i ++ ) {
39818
39819 coefficients[ i ].toArray( array, offset + ( i * 3 ) );
39820
39821 }
39822
39823 return array;
39824
39825 }
39826
39827 } );
39828
39829 Object.assign( SphericalHarmonics3, {
39830
39831 // evaluate the basis functions
39832 // shBasis is an Array[ 9 ]
39833 getBasisAt: function ( normal, shBasis ) {
39834
39835 // normal is assumed to be unit length
39836
39837 var x = normal.x, y = normal.y, z = normal.z;
39838
39839 // band 0
39840 shBasis[ 0 ] = 0.282095;
39841
39842 // band 1
39843 shBasis[ 1 ] = 0.488603 * y;
39844 shBasis[ 2 ] = 0.488603 * z;
39845 shBasis[ 3 ] = 0.488603 * x;
39846
39847 // band 2
39848 shBasis[ 4 ] = 1.092548 * x * y;
39849 shBasis[ 5 ] = 1.092548 * y * z;
39850 shBasis[ 6 ] = 0.315392 * ( 3 * z * z - 1 );
39851 shBasis[ 7 ] = 1.092548 * x * z;
39852 shBasis[ 8 ] = 0.546274 * ( x * x - y * y );
39853
39854 }
39855
39856 } );
39857
39858 function LightProbe( sh, intensity ) {
39859
39860 Light.call( this, undefined, intensity );
39861
39862 this.type = 'LightProbe';
39863
39864 this.sh = ( sh !== undefined ) ? sh : new SphericalHarmonics3();
39865
39866 }
39867
39868 LightProbe.prototype = Object.assign( Object.create( Light.prototype ), {
39869
39870 constructor: LightProbe,
39871
39872 isLightProbe: true,
39873
39874 copy: function ( source ) {
39875
39876 Light.prototype.copy.call( this, source );
39877
39878 this.sh.copy( source.sh );
39879
39880 return this;
39881
39882 },
39883
39884 fromJSON: function ( json ) {
39885
39886 this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON();
39887 this.sh.fromArray( json.sh );
39888
39889 return this;
39890
39891 },
39892
39893 toJSON: function ( meta ) {
39894
39895 var data = Light.prototype.toJSON.call( this, meta );
39896
39897 data.object.sh = this.sh.toArray();
39898
39899 return data;
39900
39901 }
39902
39903 } );
39904
39905 function MaterialLoader( manager ) {
39906
39907 Loader.call( this, manager );
39908
39909 this.textures = {};
39910
39911 }
39912
39913 MaterialLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
39914
39915 constructor: MaterialLoader,
39916
39917 load: function ( url, onLoad, onProgress, onError ) {
39918
39919 var scope = this;
39920
39921 var loader = new FileLoader( scope.manager );
39922 loader.setPath( scope.path );
39923 loader.setRequestHeader( scope.requestHeader );
39924 loader.load( url, function ( text ) {
39925
39926 try {
39927
39928 onLoad( scope.parse( JSON.parse( text ) ) );
39929
39930 } catch ( e ) {
39931
39932 if ( onError ) {
39933
39934 onError( e );
39935
39936 } else {
39937
39938 console.error( e );
39939
39940 }
39941
39942 scope.manager.itemError( url );
39943
39944 }
39945
39946 }, onProgress, onError );
39947
39948 },
39949
39950 parse: function ( json ) {
39951
39952 var textures = this.textures;
39953
39954 function getTexture( name ) {
39955
39956 if ( textures[ name ] === undefined ) {
39957
39958 console.warn( 'THREE.MaterialLoader: Undefined texture', name );
39959
39960 }
39961
39962 return textures[ name ];
39963
39964 }
39965
39966 var material = new Materials[ json.type ]();
39967
39968 if ( json.uuid !== undefined ) { material.uuid = json.uuid; }
39969 if ( json.name !== undefined ) { material.name = json.name; }
39970 if ( json.color !== undefined ) { material.color.setHex( json.color ); }
39971 if ( json.roughness !== undefined ) { material.roughness = json.roughness; }
39972 if ( json.metalness !== undefined ) { material.metalness = json.metalness; }
39973 if ( json.sheen !== undefined ) { material.sheen = new Color().setHex( json.sheen ); }
39974 if ( json.emissive !== undefined ) { material.emissive.setHex( json.emissive ); }
39975 if ( json.specular !== undefined ) { material.specular.setHex( json.specular ); }
39976 if ( json.shininess !== undefined ) { material.shininess = json.shininess; }
39977 if ( json.clearcoat !== undefined ) { material.clearcoat = json.clearcoat; }
39978 if ( json.clearcoatRoughness !== undefined ) { material.clearcoatRoughness = json.clearcoatRoughness; }
39979 if ( json.fog !== undefined ) { material.fog = json.fog; }
39980 if ( json.flatShading !== undefined ) { material.flatShading = json.flatShading; }
39981 if ( json.blending !== undefined ) { material.blending = json.blending; }
39982 if ( json.combine !== undefined ) { material.combine = json.combine; }
39983 if ( json.side !== undefined ) { material.side = json.side; }
39984 if ( json.opacity !== undefined ) { material.opacity = json.opacity; }
39985 if ( json.transparent !== undefined ) { material.transparent = json.transparent; }
39986 if ( json.alphaTest !== undefined ) { material.alphaTest = json.alphaTest; }
39987 if ( json.depthTest !== undefined ) { material.depthTest = json.depthTest; }
39988 if ( json.depthWrite !== undefined ) { material.depthWrite = json.depthWrite; }
39989 if ( json.colorWrite !== undefined ) { material.colorWrite = json.colorWrite; }
39990
39991 if ( json.stencilWrite !== undefined ) { material.stencilWrite = json.stencilWrite; }
39992 if ( json.stencilWriteMask !== undefined ) { material.stencilWriteMask = json.stencilWriteMask; }
39993 if ( json.stencilFunc !== undefined ) { material.stencilFunc = json.stencilFunc; }
39994 if ( json.stencilRef !== undefined ) { material.stencilRef = json.stencilRef; }
39995 if ( json.stencilFuncMask !== undefined ) { material.stencilFuncMask = json.stencilFuncMask; }
39996 if ( json.stencilFail !== undefined ) { material.stencilFail = json.stencilFail; }
39997 if ( json.stencilZFail !== undefined ) { material.stencilZFail = json.stencilZFail; }
39998 if ( json.stencilZPass !== undefined ) { material.stencilZPass = json.stencilZPass; }
39999
40000 if ( json.wireframe !== undefined ) { material.wireframe = json.wireframe; }
40001 if ( json.wireframeLinewidth !== undefined ) { material.wireframeLinewidth = json.wireframeLinewidth; }
40002 if ( json.wireframeLinecap !== undefined ) { material.wireframeLinecap = json.wireframeLinecap; }
40003 if ( json.wireframeLinejoin !== undefined ) { material.wireframeLinejoin = json.wireframeLinejoin; }
40004
40005 if ( json.rotation !== undefined ) { material.rotation = json.rotation; }
40006
40007 if ( json.linewidth !== 1 ) { material.linewidth = json.linewidth; }
40008 if ( json.dashSize !== undefined ) { material.dashSize = json.dashSize; }
40009 if ( json.gapSize !== undefined ) { material.gapSize = json.gapSize; }
40010 if ( json.scale !== undefined ) { material.scale = json.scale; }
40011
40012 if ( json.polygonOffset !== undefined ) { material.polygonOffset = json.polygonOffset; }
40013 if ( json.polygonOffsetFactor !== undefined ) { material.polygonOffsetFactor = json.polygonOffsetFactor; }
40014 if ( json.polygonOffsetUnits !== undefined ) { material.polygonOffsetUnits = json.polygonOffsetUnits; }
40015
40016 if ( json.skinning !== undefined ) { material.skinning = json.skinning; }
40017 if ( json.morphTargets !== undefined ) { material.morphTargets = json.morphTargets; }
40018 if ( json.morphNormals !== undefined ) { material.morphNormals = json.morphNormals; }
40019 if ( json.dithering !== undefined ) { material.dithering = json.dithering; }
40020
40021 if ( json.vertexTangents !== undefined ) { material.vertexTangents = json.vertexTangents; }
40022
40023 if ( json.visible !== undefined ) { material.visible = json.visible; }
40024
40025 if ( json.toneMapped !== undefined ) { material.toneMapped = json.toneMapped; }
40026
40027 if ( json.userData !== undefined ) { material.userData = json.userData; }
40028
40029 if ( json.vertexColors !== undefined ) {
40030
40031 if ( typeof json.vertexColors === 'number' ) {
40032
40033 material.vertexColors = ( json.vertexColors > 0 ) ? true : false;
40034
40035 } else {
40036
40037 material.vertexColors = json.vertexColors;
40038
40039 }
40040
40041 }
40042
40043 // Shader Material
40044
40045 if ( json.uniforms !== undefined ) {
40046
40047 for ( var name in json.uniforms ) {
40048
40049 var uniform = json.uniforms[ name ];
40050
40051 material.uniforms[ name ] = {};
40052
40053 switch ( uniform.type ) {
40054
40055 case 't':
40056 material.uniforms[ name ].value = getTexture( uniform.value );
40057 break;
40058
40059 case 'c':
40060 material.uniforms[ name ].value = new Color().setHex( uniform.value );
40061 break;
40062
40063 case 'v2':
40064 material.uniforms[ name ].value = new Vector2().fromArray( uniform.value );
40065 break;
40066
40067 case 'v3':
40068 material.uniforms[ name ].value = new Vector3().fromArray( uniform.value );
40069 break;
40070
40071 case 'v4':
40072 material.uniforms[ name ].value = new Vector4().fromArray( uniform.value );
40073 break;
40074
40075 case 'm3':
40076 material.uniforms[ name ].value = new Matrix3().fromArray( uniform.value );
40077
40078 case 'm4':
40079 material.uniforms[ name ].value = new Matrix4().fromArray( uniform.value );
40080 break;
40081
40082 default:
40083 material.uniforms[ name ].value = uniform.value;
40084
40085 }
40086
40087 }
40088
40089 }
40090
40091 if ( json.defines !== undefined ) { material.defines = json.defines; }
40092 if ( json.vertexShader !== undefined ) { material.vertexShader = json.vertexShader; }
40093 if ( json.fragmentShader !== undefined ) { material.fragmentShader = json.fragmentShader; }
40094
40095 if ( json.extensions !== undefined ) {
40096
40097 for ( var key in json.extensions ) {
40098
40099 material.extensions[ key ] = json.extensions[ key ];
40100
40101 }
40102
40103 }
40104
40105 // Deprecated
40106
40107 if ( json.shading !== undefined ) { material.flatShading = json.shading === 1; } // THREE.FlatShading
40108
40109 // for PointsMaterial
40110
40111 if ( json.size !== undefined ) { material.size = json.size; }
40112 if ( json.sizeAttenuation !== undefined ) { material.sizeAttenuation = json.sizeAttenuation; }
40113
40114 // maps
40115
40116 if ( json.map !== undefined ) { material.map = getTexture( json.map ); }
40117 if ( json.matcap !== undefined ) { material.matcap = getTexture( json.matcap ); }
40118
40119 if ( json.alphaMap !== undefined ) { material.alphaMap = getTexture( json.alphaMap ); }
40120
40121 if ( json.bumpMap !== undefined ) { material.bumpMap = getTexture( json.bumpMap ); }
40122 if ( json.bumpScale !== undefined ) { material.bumpScale = json.bumpScale; }
40123
40124 if ( json.normalMap !== undefined ) { material.normalMap = getTexture( json.normalMap ); }
40125 if ( json.normalMapType !== undefined ) { material.normalMapType = json.normalMapType; }
40126 if ( json.normalScale !== undefined ) {
40127
40128 var normalScale = json.normalScale;
40129
40130 if ( Array.isArray( normalScale ) === false ) {
40131
40132 // Blender exporter used to export a scalar. See #7459
40133
40134 normalScale = [ normalScale, normalScale ];
40135
40136 }
40137
40138 material.normalScale = new Vector2().fromArray( normalScale );
40139
40140 }
40141
40142 if ( json.displacementMap !== undefined ) { material.displacementMap = getTexture( json.displacementMap ); }
40143 if ( json.displacementScale !== undefined ) { material.displacementScale = json.displacementScale; }
40144 if ( json.displacementBias !== undefined ) { material.displacementBias = json.displacementBias; }
40145
40146 if ( json.roughnessMap !== undefined ) { material.roughnessMap = getTexture( json.roughnessMap ); }
40147 if ( json.metalnessMap !== undefined ) { material.metalnessMap = getTexture( json.metalnessMap ); }
40148
40149 if ( json.emissiveMap !== undefined ) { material.emissiveMap = getTexture( json.emissiveMap ); }
40150 if ( json.emissiveIntensity !== undefined ) { material.emissiveIntensity = json.emissiveIntensity; }
40151
40152 if ( json.specularMap !== undefined ) { material.specularMap = getTexture( json.specularMap ); }
40153
40154 if ( json.envMap !== undefined ) { material.envMap = getTexture( json.envMap ); }
40155 if ( json.envMapIntensity !== undefined ) { material.envMapIntensity = json.envMapIntensity; }
40156
40157 if ( json.reflectivity !== undefined ) { material.reflectivity = json.reflectivity; }
40158 if ( json.refractionRatio !== undefined ) { material.refractionRatio = json.refractionRatio; }
40159
40160 if ( json.lightMap !== undefined ) { material.lightMap = getTexture( json.lightMap ); }
40161 if ( json.lightMapIntensity !== undefined ) { material.lightMapIntensity = json.lightMapIntensity; }
40162
40163 if ( json.aoMap !== undefined ) { material.aoMap = getTexture( json.aoMap ); }
40164 if ( json.aoMapIntensity !== undefined ) { material.aoMapIntensity = json.aoMapIntensity; }
40165
40166 if ( json.gradientMap !== undefined ) { material.gradientMap = getTexture( json.gradientMap ); }
40167
40168 if ( json.clearcoatMap !== undefined ) { material.clearcoatMap = getTexture( json.clearcoatMap ); }
40169 if ( json.clearcoatRoughnessMap !== undefined ) { material.clearcoatRoughnessMap = getTexture( json.clearcoatRoughnessMap ); }
40170 if ( json.clearcoatNormalMap !== undefined ) { material.clearcoatNormalMap = getTexture( json.clearcoatNormalMap ); }
40171 if ( json.clearcoatNormalScale !== undefined ) { material.clearcoatNormalScale = new Vector2().fromArray( json.clearcoatNormalScale ); }
40172
40173 if ( json.transmission !== undefined ) { material.transmission = json.transmission; }
40174 if ( json.transmissionMap !== undefined ) { material.transmissionMap = getTexture( json.transmissionMap ); }
40175
40176 return material;
40177
40178 },
40179
40180 setTextures: function ( value ) {
40181
40182 this.textures = value;
40183 return this;
40184
40185 }
40186
40187 } );
40188
40189 var LoaderUtils = {
40190
40191 decodeText: function ( array ) {
40192
40193 if ( typeof TextDecoder !== 'undefined' ) {
40194
40195 return new TextDecoder().decode( array );
40196
40197 }
40198
40199 // Avoid the String.fromCharCode.apply(null, array) shortcut, which
40200 // throws a "maximum call stack size exceeded" error for large arrays.
40201
40202 var s = '';
40203
40204 for ( var i = 0, il = array.length; i < il; i ++ ) {
40205
40206 // Implicitly assumes little-endian.
40207 s += String.fromCharCode( array[ i ] );
40208
40209 }
40210
40211 try {
40212
40213 // merges multi-byte utf-8 characters.
40214
40215 return decodeURIComponent( escape( s ) );
40216
40217 } catch ( e ) { // see #16358
40218
40219 return s;
40220
40221 }
40222
40223 },
40224
40225 extractUrlBase: function ( url ) {
40226
40227 var index = url.lastIndexOf( '/' );
40228
40229 if ( index === - 1 ) { return './'; }
40230
40231 return url.substr( 0, index + 1 );
40232
40233 }
40234
40235 };
40236
40237 function InstancedBufferGeometry() {
40238
40239 BufferGeometry.call( this );
40240
40241 this.type = 'InstancedBufferGeometry';
40242 this.instanceCount = Infinity;
40243
40244 }
40245
40246 InstancedBufferGeometry.prototype = Object.assign( Object.create( BufferGeometry.prototype ), {
40247
40248 constructor: InstancedBufferGeometry,
40249
40250 isInstancedBufferGeometry: true,
40251
40252 copy: function ( source ) {
40253
40254 BufferGeometry.prototype.copy.call( this, source );
40255
40256 this.instanceCount = source.instanceCount;
40257
40258 return this;
40259
40260 },
40261
40262 clone: function () {
40263
40264 return new this.constructor().copy( this );
40265
40266 },
40267
40268 toJSON: function () {
40269
40270 var data = BufferGeometry.prototype.toJSON.call( this );
40271
40272 data.instanceCount = this.instanceCount;
40273
40274 data.isInstancedBufferGeometry = true;
40275
40276 return data;
40277
40278 }
40279
40280 } );
40281
40282 function InstancedBufferAttribute( array, itemSize, normalized, meshPerAttribute ) {
40283
40284 if ( typeof ( normalized ) === 'number' ) {
40285
40286 meshPerAttribute = normalized;
40287
40288 normalized = false;
40289
40290 console.error( 'THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.' );
40291
40292 }
40293
40294 BufferAttribute.call( this, array, itemSize, normalized );
40295
40296 this.meshPerAttribute = meshPerAttribute || 1;
40297
40298 }
40299
40300 InstancedBufferAttribute.prototype = Object.assign( Object.create( BufferAttribute.prototype ), {
40301
40302 constructor: InstancedBufferAttribute,
40303
40304 isInstancedBufferAttribute: true,
40305
40306 copy: function ( source ) {
40307
40308 BufferAttribute.prototype.copy.call( this, source );
40309
40310 this.meshPerAttribute = source.meshPerAttribute;
40311
40312 return this;
40313
40314 },
40315
40316 toJSON: function () {
40317
40318 var data = BufferAttribute.prototype.toJSON.call( this );
40319
40320 data.meshPerAttribute = this.meshPerAttribute;
40321
40322 data.isInstancedBufferAttribute = true;
40323
40324 return data;
40325
40326 }
40327
40328 } );
40329
40330 function BufferGeometryLoader( manager ) {
40331
40332 Loader.call( this, manager );
40333
40334 }
40335
40336 BufferGeometryLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
40337
40338 constructor: BufferGeometryLoader,
40339
40340 load: function ( url, onLoad, onProgress, onError ) {
40341
40342 var scope = this;
40343
40344 var loader = new FileLoader( scope.manager );
40345 loader.setPath( scope.path );
40346 loader.setRequestHeader( scope.requestHeader );
40347 loader.load( url, function ( text ) {
40348
40349 try {
40350
40351 onLoad( scope.parse( JSON.parse( text ) ) );
40352
40353 } catch ( e ) {
40354
40355 if ( onError ) {
40356
40357 onError( e );
40358
40359 } else {
40360
40361 console.error( e );
40362
40363 }
40364
40365 scope.manager.itemError( url );
40366
40367 }
40368
40369 }, onProgress, onError );
40370
40371 },
40372
40373 parse: function ( json ) {
40374
40375 var interleavedBufferMap = {};
40376 var arrayBufferMap = {};
40377
40378 function getInterleavedBuffer( json, uuid ) {
40379
40380 if ( interleavedBufferMap[ uuid ] !== undefined ) { return interleavedBufferMap[ uuid ]; }
40381
40382 var interleavedBuffers = json.interleavedBuffers;
40383 var interleavedBuffer = interleavedBuffers[ uuid ];
40384
40385 var buffer = getArrayBuffer( json, interleavedBuffer.buffer );
40386
40387 var array = new TYPED_ARRAYS[ interleavedBuffer.type ]( buffer );
40388 var ib = new InterleavedBuffer( array, interleavedBuffer.stride );
40389 ib.uuid = interleavedBuffer.uuid;
40390
40391 interleavedBufferMap[ uuid ] = ib;
40392
40393 return ib;
40394
40395 }
40396
40397 function getArrayBuffer( json, uuid ) {
40398
40399 if ( arrayBufferMap[ uuid ] !== undefined ) { return arrayBufferMap[ uuid ]; }
40400
40401 var arrayBuffers = json.arrayBuffers;
40402 var arrayBuffer = arrayBuffers[ uuid ];
40403
40404 var ab = new Uint32Array( arrayBuffer ).buffer;
40405
40406 arrayBufferMap[ uuid ] = ab;
40407
40408 return ab;
40409
40410 }
40411
40412 var geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry();
40413
40414 var index = json.data.index;
40415
40416 if ( index !== undefined ) {
40417
40418 var typedArray = new TYPED_ARRAYS[ index.type ]( index.array );
40419 geometry.setIndex( new BufferAttribute( typedArray, 1 ) );
40420
40421 }
40422
40423 var attributes = json.data.attributes;
40424
40425 for ( var key in attributes ) {
40426
40427 var attribute = attributes[ key ];
40428 var bufferAttribute = (void 0);
40429
40430 if ( attribute.isInterleavedBufferAttribute ) {
40431
40432 var interleavedBuffer = getInterleavedBuffer( json.data, attribute.data );
40433 bufferAttribute = new InterleavedBufferAttribute( interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized );
40434
40435 } else {
40436
40437 var typedArray$1 = new TYPED_ARRAYS[ attribute.type ]( attribute.array );
40438 var bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute;
40439 bufferAttribute = new bufferAttributeConstr( typedArray$1, attribute.itemSize, attribute.normalized );
40440
40441 }
40442
40443 if ( attribute.name !== undefined ) { bufferAttribute.name = attribute.name; }
40444 geometry.setAttribute( key, bufferAttribute );
40445
40446 }
40447
40448 var morphAttributes = json.data.morphAttributes;
40449
40450 if ( morphAttributes ) {
40451
40452 for ( var key$1 in morphAttributes ) {
40453
40454 var attributeArray = morphAttributes[ key$1 ];
40455
40456 var array = [];
40457
40458 for ( var i = 0, il = attributeArray.length; i < il; i ++ ) {
40459
40460 var attribute$1 = attributeArray[ i ];
40461 var bufferAttribute$1 = (void 0);
40462
40463 if ( attribute$1.isInterleavedBufferAttribute ) {
40464
40465 var interleavedBuffer$1 = getInterleavedBuffer( json.data, attribute$1.data );
40466 bufferAttribute$1 = new InterleavedBufferAttribute( interleavedBuffer$1, attribute$1.itemSize, attribute$1.offset, attribute$1.normalized );
40467
40468 } else {
40469
40470 var typedArray$2 = new TYPED_ARRAYS[ attribute$1.type ]( attribute$1.array );
40471 bufferAttribute$1 = new BufferAttribute( typedArray$2, attribute$1.itemSize, attribute$1.normalized );
40472
40473 }
40474
40475 if ( attribute$1.name !== undefined ) { bufferAttribute$1.name = attribute$1.name; }
40476 array.push( bufferAttribute$1 );
40477
40478 }
40479
40480 geometry.morphAttributes[ key$1 ] = array;
40481
40482 }
40483
40484 }
40485
40486 var morphTargetsRelative = json.data.morphTargetsRelative;
40487
40488 if ( morphTargetsRelative ) {
40489
40490 geometry.morphTargetsRelative = true;
40491
40492 }
40493
40494 var groups = json.data.groups || json.data.drawcalls || json.data.offsets;
40495
40496 if ( groups !== undefined ) {
40497
40498 for ( var i$1 = 0, n = groups.length; i$1 !== n; ++ i$1 ) {
40499
40500 var group = groups[ i$1 ];
40501
40502 geometry.addGroup( group.start, group.count, group.materialIndex );
40503
40504 }
40505
40506 }
40507
40508 var boundingSphere = json.data.boundingSphere;
40509
40510 if ( boundingSphere !== undefined ) {
40511
40512 var center = new Vector3();
40513
40514 if ( boundingSphere.center !== undefined ) {
40515
40516 center.fromArray( boundingSphere.center );
40517
40518 }
40519
40520 geometry.boundingSphere = new Sphere( center, boundingSphere.radius );
40521
40522 }
40523
40524 if ( json.name ) { geometry.name = json.name; }
40525 if ( json.userData ) { geometry.userData = json.userData; }
40526
40527 return geometry;
40528
40529 }
40530
40531 } );
40532
40533 var TYPED_ARRAYS = {
40534 Int8Array: Int8Array,
40535 Uint8Array: Uint8Array,
40536 // Workaround for IE11 pre KB2929437. See #11440
40537 Uint8ClampedArray: typeof Uint8ClampedArray !== 'undefined' ? Uint8ClampedArray : Uint8Array,
40538 Int16Array: Int16Array,
40539 Uint16Array: Uint16Array,
40540 Int32Array: Int32Array,
40541 Uint32Array: Uint32Array,
40542 Float32Array: Float32Array,
40543 Float64Array: Float64Array
40544 };
40545
40546 function ObjectLoader( manager ) {
40547
40548 Loader.call( this, manager );
40549
40550 }
40551
40552 ObjectLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
40553
40554 constructor: ObjectLoader,
40555
40556 load: function ( url, onLoad, onProgress, onError ) {
40557
40558 var scope = this;
40559
40560 var path = ( this.path === '' ) ? LoaderUtils.extractUrlBase( url ) : this.path;
40561 this.resourcePath = this.resourcePath || path;
40562
40563 var loader = new FileLoader( scope.manager );
40564 loader.setPath( this.path );
40565 loader.setRequestHeader( this.requestHeader );
40566 loader.load( url, function ( text ) {
40567
40568 var json = null;
40569
40570 try {
40571
40572 json = JSON.parse( text );
40573
40574 } catch ( error ) {
40575
40576 if ( onError !== undefined ) { onError( error ); }
40577
40578 console.error( 'THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message );
40579
40580 return;
40581
40582 }
40583
40584 var metadata = json.metadata;
40585
40586 if ( metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry' ) {
40587
40588 console.error( 'THREE.ObjectLoader: Can\'t load ' + url );
40589 return;
40590
40591 }
40592
40593 scope.parse( json, onLoad );
40594
40595 }, onProgress, onError );
40596
40597 },
40598
40599 parse: function ( json, onLoad ) {
40600
40601 var shapes = this.parseShape( json.shapes );
40602 var geometries = this.parseGeometries( json.geometries, shapes );
40603
40604 var images = this.parseImages( json.images, function () {
40605
40606 if ( onLoad !== undefined ) { onLoad( object ); }
40607
40608 } );
40609
40610 var textures = this.parseTextures( json.textures, images );
40611 var materials = this.parseMaterials( json.materials, textures );
40612
40613 var object = this.parseObject( json.object, geometries, materials );
40614
40615 if ( json.animations ) {
40616
40617 object.animations = this.parseAnimations( json.animations );
40618
40619 }
40620
40621 if ( json.images === undefined || json.images.length === 0 ) {
40622
40623 if ( onLoad !== undefined ) { onLoad( object ); }
40624
40625 }
40626
40627 return object;
40628
40629 },
40630
40631 parseShape: function ( json ) {
40632
40633 var shapes = {};
40634
40635 if ( json !== undefined ) {
40636
40637 for ( var i = 0, l = json.length; i < l; i ++ ) {
40638
40639 var shape = new Shape().fromJSON( json[ i ] );
40640
40641 shapes[ shape.uuid ] = shape;
40642
40643 }
40644
40645 }
40646
40647 return shapes;
40648
40649 },
40650
40651 parseGeometries: function ( json, shapes ) {
40652
40653 var geometries = {};
40654 var geometryShapes;
40655
40656 if ( json !== undefined ) {
40657
40658 var bufferGeometryLoader = new BufferGeometryLoader();
40659
40660 for ( var i = 0, l = json.length; i < l; i ++ ) {
40661
40662 var geometry = (void 0);
40663 var data = json[ i ];
40664
40665 switch ( data.type ) {
40666
40667 case 'PlaneGeometry':
40668 case 'PlaneBufferGeometry':
40669
40670 geometry = new Geometries[ data.type ](
40671 data.width,
40672 data.height,
40673 data.widthSegments,
40674 data.heightSegments
40675 );
40676
40677 break;
40678
40679 case 'BoxGeometry':
40680 case 'BoxBufferGeometry':
40681 case 'CubeGeometry': // backwards compatible
40682
40683 geometry = new Geometries[ data.type ](
40684 data.width,
40685 data.height,
40686 data.depth,
40687 data.widthSegments,
40688 data.heightSegments,
40689 data.depthSegments
40690 );
40691
40692 break;
40693
40694 case 'CircleGeometry':
40695 case 'CircleBufferGeometry':
40696
40697 geometry = new Geometries[ data.type ](
40698 data.radius,
40699 data.segments,
40700 data.thetaStart,
40701 data.thetaLength
40702 );
40703
40704 break;
40705
40706 case 'CylinderGeometry':
40707 case 'CylinderBufferGeometry':
40708
40709 geometry = new Geometries[ data.type ](
40710 data.radiusTop,
40711 data.radiusBottom,
40712 data.height,
40713 data.radialSegments,
40714 data.heightSegments,
40715 data.openEnded,
40716 data.thetaStart,
40717 data.thetaLength
40718 );
40719
40720 break;
40721
40722 case 'ConeGeometry':
40723 case 'ConeBufferGeometry':
40724
40725 geometry = new Geometries[ data.type ](
40726 data.radius,
40727 data.height,
40728 data.radialSegments,
40729 data.heightSegments,
40730 data.openEnded,
40731 data.thetaStart,
40732 data.thetaLength
40733 );
40734
40735 break;
40736
40737 case 'SphereGeometry':
40738 case 'SphereBufferGeometry':
40739
40740 geometry = new Geometries[ data.type ](
40741 data.radius,
40742 data.widthSegments,
40743 data.heightSegments,
40744 data.phiStart,
40745 data.phiLength,
40746 data.thetaStart,
40747 data.thetaLength
40748 );
40749
40750 break;
40751
40752 case 'DodecahedronGeometry':
40753 case 'DodecahedronBufferGeometry':
40754 case 'IcosahedronGeometry':
40755 case 'IcosahedronBufferGeometry':
40756 case 'OctahedronGeometry':
40757 case 'OctahedronBufferGeometry':
40758 case 'TetrahedronGeometry':
40759 case 'TetrahedronBufferGeometry':
40760
40761 geometry = new Geometries[ data.type ](
40762 data.radius,
40763 data.detail
40764 );
40765
40766 break;
40767
40768 case 'RingGeometry':
40769 case 'RingBufferGeometry':
40770
40771 geometry = new Geometries[ data.type ](
40772 data.innerRadius,
40773 data.outerRadius,
40774 data.thetaSegments,
40775 data.phiSegments,
40776 data.thetaStart,
40777 data.thetaLength
40778 );
40779
40780 break;
40781
40782 case 'TorusGeometry':
40783 case 'TorusBufferGeometry':
40784
40785 geometry = new Geometries[ data.type ](
40786 data.radius,
40787 data.tube,
40788 data.radialSegments,
40789 data.tubularSegments,
40790 data.arc
40791 );
40792
40793 break;
40794
40795 case 'TorusKnotGeometry':
40796 case 'TorusKnotBufferGeometry':
40797
40798 geometry = new Geometries[ data.type ](
40799 data.radius,
40800 data.tube,
40801 data.tubularSegments,
40802 data.radialSegments,
40803 data.p,
40804 data.q
40805 );
40806
40807 break;
40808
40809 case 'TubeGeometry':
40810 case 'TubeBufferGeometry':
40811
40812 // This only works for built-in curves (e.g. CatmullRomCurve3).
40813 // User defined curves or instances of CurvePath will not be deserialized.
40814 geometry = new Geometries[ data.type ](
40815 new Curves[ data.path.type ]().fromJSON( data.path ),
40816 data.tubularSegments,
40817 data.radius,
40818 data.radialSegments,
40819 data.closed
40820 );
40821
40822 break;
40823
40824 case 'LatheGeometry':
40825 case 'LatheBufferGeometry':
40826
40827 geometry = new Geometries[ data.type ](
40828 data.points,
40829 data.segments,
40830 data.phiStart,
40831 data.phiLength
40832 );
40833
40834 break;
40835
40836 case 'PolyhedronGeometry':
40837 case 'PolyhedronBufferGeometry':
40838
40839 geometry = new Geometries[ data.type ](
40840 data.vertices,
40841 data.indices,
40842 data.radius,
40843 data.details
40844 );
40845
40846 break;
40847
40848 case 'ShapeGeometry':
40849 case 'ShapeBufferGeometry':
40850
40851 geometryShapes = [];
40852
40853 for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) {
40854
40855 var shape = shapes[ data.shapes[ j ] ];
40856
40857 geometryShapes.push( shape );
40858
40859 }
40860
40861 geometry = new Geometries[ data.type ](
40862 geometryShapes,
40863 data.curveSegments
40864 );
40865
40866 break;
40867
40868
40869 case 'ExtrudeGeometry':
40870 case 'ExtrudeBufferGeometry':
40871
40872 geometryShapes = [];
40873
40874 for ( var j$1 = 0, jl$1 = data.shapes.length; j$1 < jl$1; j$1 ++ ) {
40875
40876 var shape$1 = shapes[ data.shapes[ j$1 ] ];
40877
40878 geometryShapes.push( shape$1 );
40879
40880 }
40881
40882 var extrudePath = data.options.extrudePath;
40883
40884 if ( extrudePath !== undefined ) {
40885
40886 data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath );
40887
40888 }
40889
40890 geometry = new Geometries[ data.type ](
40891 geometryShapes,
40892 data.options
40893 );
40894
40895 break;
40896
40897 case 'BufferGeometry':
40898 case 'InstancedBufferGeometry':
40899
40900 geometry = bufferGeometryLoader.parse( data );
40901
40902 break;
40903
40904 case 'Geometry':
40905
40906 console.error( 'THREE.ObjectLoader: Loading "Geometry" is not supported anymore.' );
40907
40908 break;
40909
40910 default:
40911
40912 console.warn( 'THREE.ObjectLoader: Unsupported geometry type "' + data.type + '"' );
40913
40914 continue;
40915
40916 }
40917
40918 geometry.uuid = data.uuid;
40919
40920 if ( data.name !== undefined ) { geometry.name = data.name; }
40921 if ( geometry.isBufferGeometry === true && data.userData !== undefined ) { geometry.userData = data.userData; }
40922
40923 geometries[ data.uuid ] = geometry;
40924
40925 }
40926
40927 }
40928
40929 return geometries;
40930
40931 },
40932
40933 parseMaterials: function ( json, textures ) {
40934
40935 var cache = {}; // MultiMaterial
40936 var materials = {};
40937
40938 if ( json !== undefined ) {
40939
40940 var loader = new MaterialLoader();
40941 loader.setTextures( textures );
40942
40943 for ( var i = 0, l = json.length; i < l; i ++ ) {
40944
40945 var data = json[ i ];
40946
40947 if ( data.type === 'MultiMaterial' ) {
40948
40949 // Deprecated
40950
40951 var array = [];
40952
40953 for ( var j = 0; j < data.materials.length; j ++ ) {
40954
40955 var material = data.materials[ j ];
40956
40957 if ( cache[ material.uuid ] === undefined ) {
40958
40959 cache[ material.uuid ] = loader.parse( material );
40960
40961 }
40962
40963 array.push( cache[ material.uuid ] );
40964
40965 }
40966
40967 materials[ data.uuid ] = array;
40968
40969 } else {
40970
40971 if ( cache[ data.uuid ] === undefined ) {
40972
40973 cache[ data.uuid ] = loader.parse( data );
40974
40975 }
40976
40977 materials[ data.uuid ] = cache[ data.uuid ];
40978
40979 }
40980
40981 }
40982
40983 }
40984
40985 return materials;
40986
40987 },
40988
40989 parseAnimations: function ( json ) {
40990
40991 var animations = [];
40992
40993 for ( var i = 0; i < json.length; i ++ ) {
40994
40995 var data = json[ i ];
40996
40997 var clip = AnimationClip.parse( data );
40998
40999 if ( data.uuid !== undefined ) { clip.uuid = data.uuid; }
41000
41001 animations.push( clip );
41002
41003 }
41004
41005 return animations;
41006
41007 },
41008
41009 parseImages: function ( json, onLoad ) {
41010
41011 var scope = this;
41012 var images = {};
41013
41014 var loader;
41015
41016 function loadImage( url ) {
41017
41018 scope.manager.itemStart( url );
41019
41020 return loader.load( url, function () {
41021
41022 scope.manager.itemEnd( url );
41023
41024 }, undefined, function () {
41025
41026 scope.manager.itemError( url );
41027 scope.manager.itemEnd( url );
41028
41029 } );
41030
41031 }
41032
41033 if ( json !== undefined && json.length > 0 ) {
41034
41035 var manager = new LoadingManager( onLoad );
41036
41037 loader = new ImageLoader( manager );
41038 loader.setCrossOrigin( this.crossOrigin );
41039
41040 for ( var i = 0, il = json.length; i < il; i ++ ) {
41041
41042 var image = json[ i ];
41043 var url = image.url;
41044
41045 if ( Array.isArray( url ) ) {
41046
41047 // load array of images e.g CubeTexture
41048
41049 images[ image.uuid ] = [];
41050
41051 for ( var j = 0, jl = url.length; j < jl; j ++ ) {
41052
41053 var currentUrl = url[ j ];
41054
41055 var path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( currentUrl ) ? currentUrl : scope.resourcePath + currentUrl;
41056
41057 images[ image.uuid ].push( loadImage( path ) );
41058
41059 }
41060
41061 } else {
41062
41063 // load single image
41064
41065 var path$1 = /^(\/\/)|([a-z]+:(\/\/)?)/i.test( image.url ) ? image.url : scope.resourcePath + image.url;
41066
41067 images[ image.uuid ] = loadImage( path$1 );
41068
41069 }
41070
41071 }
41072
41073 }
41074
41075 return images;
41076
41077 },
41078
41079 parseTextures: function ( json, images ) {
41080
41081 function parseConstant( value, type ) {
41082
41083 if ( typeof value === 'number' ) { return value; }
41084
41085 console.warn( 'THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value );
41086
41087 return type[ value ];
41088
41089 }
41090
41091 var textures = {};
41092
41093 if ( json !== undefined ) {
41094
41095 for ( var i = 0, l = json.length; i < l; i ++ ) {
41096
41097 var data = json[ i ];
41098
41099 if ( data.image === undefined ) {
41100
41101 console.warn( 'THREE.ObjectLoader: No "image" specified for', data.uuid );
41102
41103 }
41104
41105 if ( images[ data.image ] === undefined ) {
41106
41107 console.warn( 'THREE.ObjectLoader: Undefined image', data.image );
41108
41109 }
41110
41111 var texture = (void 0);
41112
41113 if ( Array.isArray( images[ data.image ] ) ) {
41114
41115 texture = new CubeTexture( images[ data.image ] );
41116
41117 } else {
41118
41119 texture = new Texture( images[ data.image ] );
41120
41121 }
41122
41123 texture.needsUpdate = true;
41124
41125 texture.uuid = data.uuid;
41126
41127 if ( data.name !== undefined ) { texture.name = data.name; }
41128
41129 if ( data.mapping !== undefined ) { texture.mapping = parseConstant( data.mapping, TEXTURE_MAPPING ); }
41130
41131 if ( data.offset !== undefined ) { texture.offset.fromArray( data.offset ); }
41132 if ( data.repeat !== undefined ) { texture.repeat.fromArray( data.repeat ); }
41133 if ( data.center !== undefined ) { texture.center.fromArray( data.center ); }
41134 if ( data.rotation !== undefined ) { texture.rotation = data.rotation; }
41135
41136 if ( data.wrap !== undefined ) {
41137
41138 texture.wrapS = parseConstant( data.wrap[ 0 ], TEXTURE_WRAPPING );
41139 texture.wrapT = parseConstant( data.wrap[ 1 ], TEXTURE_WRAPPING );
41140
41141 }
41142
41143 if ( data.format !== undefined ) { texture.format = data.format; }
41144 if ( data.type !== undefined ) { texture.type = data.type; }
41145 if ( data.encoding !== undefined ) { texture.encoding = data.encoding; }
41146
41147 if ( data.minFilter !== undefined ) { texture.minFilter = parseConstant( data.minFilter, TEXTURE_FILTER ); }
41148 if ( data.magFilter !== undefined ) { texture.magFilter = parseConstant( data.magFilter, TEXTURE_FILTER ); }
41149 if ( data.anisotropy !== undefined ) { texture.anisotropy = data.anisotropy; }
41150
41151 if ( data.flipY !== undefined ) { texture.flipY = data.flipY; }
41152
41153 if ( data.premultiplyAlpha !== undefined ) { texture.premultiplyAlpha = data.premultiplyAlpha; }
41154 if ( data.unpackAlignment !== undefined ) { texture.unpackAlignment = data.unpackAlignment; }
41155
41156 textures[ data.uuid ] = texture;
41157
41158 }
41159
41160 }
41161
41162 return textures;
41163
41164 },
41165
41166 parseObject: function ( data, geometries, materials ) {
41167
41168 var object;
41169
41170 function getGeometry( name ) {
41171
41172 if ( geometries[ name ] === undefined ) {
41173
41174 console.warn( 'THREE.ObjectLoader: Undefined geometry', name );
41175
41176 }
41177
41178 return geometries[ name ];
41179
41180 }
41181
41182 function getMaterial( name ) {
41183
41184 if ( name === undefined ) { return undefined; }
41185
41186 if ( Array.isArray( name ) ) {
41187
41188 var array = [];
41189
41190 for ( var i = 0, l = name.length; i < l; i ++ ) {
41191
41192 var uuid = name[ i ];
41193
41194 if ( materials[ uuid ] === undefined ) {
41195
41196 console.warn( 'THREE.ObjectLoader: Undefined material', uuid );
41197
41198 }
41199
41200 array.push( materials[ uuid ] );
41201
41202 }
41203
41204 return array;
41205
41206 }
41207
41208 if ( materials[ name ] === undefined ) {
41209
41210 console.warn( 'THREE.ObjectLoader: Undefined material', name );
41211
41212 }
41213
41214 return materials[ name ];
41215
41216 }
41217
41218 var geometry, material;
41219
41220 switch ( data.type ) {
41221
41222 case 'Scene':
41223
41224 object = new Scene();
41225
41226 if ( data.background !== undefined ) {
41227
41228 if ( Number.isInteger( data.background ) ) {
41229
41230 object.background = new Color( data.background );
41231
41232 }
41233
41234 }
41235
41236 if ( data.fog !== undefined ) {
41237
41238 if ( data.fog.type === 'Fog' ) {
41239
41240 object.fog = new Fog( data.fog.color, data.fog.near, data.fog.far );
41241
41242 } else if ( data.fog.type === 'FogExp2' ) {
41243
41244 object.fog = new FogExp2( data.fog.color, data.fog.density );
41245
41246 }
41247
41248 }
41249
41250 break;
41251
41252 case 'PerspectiveCamera':
41253
41254 object = new PerspectiveCamera( data.fov, data.aspect, data.near, data.far );
41255
41256 if ( data.focus !== undefined ) { object.focus = data.focus; }
41257 if ( data.zoom !== undefined ) { object.zoom = data.zoom; }
41258 if ( data.filmGauge !== undefined ) { object.filmGauge = data.filmGauge; }
41259 if ( data.filmOffset !== undefined ) { object.filmOffset = data.filmOffset; }
41260 if ( data.view !== undefined ) { object.view = Object.assign( {}, data.view ); }
41261
41262 break;
41263
41264 case 'OrthographicCamera':
41265
41266 object = new OrthographicCamera( data.left, data.right, data.top, data.bottom, data.near, data.far );
41267
41268 if ( data.zoom !== undefined ) { object.zoom = data.zoom; }
41269 if ( data.view !== undefined ) { object.view = Object.assign( {}, data.view ); }
41270
41271 break;
41272
41273 case 'AmbientLight':
41274
41275 object = new AmbientLight( data.color, data.intensity );
41276
41277 break;
41278
41279 case 'DirectionalLight':
41280
41281 object = new DirectionalLight( data.color, data.intensity );
41282
41283 break;
41284
41285 case 'PointLight':
41286
41287 object = new PointLight( data.color, data.intensity, data.distance, data.decay );
41288
41289 break;
41290
41291 case 'RectAreaLight':
41292
41293 object = new RectAreaLight( data.color, data.intensity, data.width, data.height );
41294
41295 break;
41296
41297 case 'SpotLight':
41298
41299 object = new SpotLight( data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay );
41300
41301 break;
41302
41303 case 'HemisphereLight':
41304
41305 object = new HemisphereLight( data.color, data.groundColor, data.intensity );
41306
41307 break;
41308
41309 case 'LightProbe':
41310
41311 object = new LightProbe().fromJSON( data );
41312
41313 break;
41314
41315 case 'SkinnedMesh':
41316
41317 console.warn( 'THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.' );
41318
41319 case 'Mesh':
41320
41321 geometry = getGeometry( data.geometry );
41322 material = getMaterial( data.material );
41323
41324 object = new Mesh( geometry, material );
41325
41326 break;
41327
41328 case 'InstancedMesh':
41329
41330 geometry = getGeometry( data.geometry );
41331 material = getMaterial( data.material );
41332 var count = data.count;
41333 var instanceMatrix = data.instanceMatrix;
41334
41335 object = new InstancedMesh( geometry, material, count );
41336 object.instanceMatrix = new BufferAttribute( new Float32Array( instanceMatrix.array ), 16 );
41337
41338 break;
41339
41340 case 'LOD':
41341
41342 object = new LOD();
41343
41344 break;
41345
41346 case 'Line':
41347
41348 object = new Line( getGeometry( data.geometry ), getMaterial( data.material ), data.mode );
41349
41350 break;
41351
41352 case 'LineLoop':
41353
41354 object = new LineLoop( getGeometry( data.geometry ), getMaterial( data.material ) );
41355
41356 break;
41357
41358 case 'LineSegments':
41359
41360 object = new LineSegments( getGeometry( data.geometry ), getMaterial( data.material ) );
41361
41362 break;
41363
41364 case 'PointCloud':
41365 case 'Points':
41366
41367 object = new Points( getGeometry( data.geometry ), getMaterial( data.material ) );
41368
41369 break;
41370
41371 case 'Sprite':
41372
41373 object = new Sprite( getMaterial( data.material ) );
41374
41375 break;
41376
41377 case 'Group':
41378
41379 object = new Group();
41380
41381 break;
41382
41383 default:
41384
41385 object = new Object3D();
41386
41387 }
41388
41389 object.uuid = data.uuid;
41390
41391 if ( data.name !== undefined ) { object.name = data.name; }
41392
41393 if ( data.matrix !== undefined ) {
41394
41395 object.matrix.fromArray( data.matrix );
41396
41397 if ( data.matrixAutoUpdate !== undefined ) { object.matrixAutoUpdate = data.matrixAutoUpdate; }
41398 if ( object.matrixAutoUpdate ) { object.matrix.decompose( object.position, object.quaternion, object.scale ); }
41399
41400 } else {
41401
41402 if ( data.position !== undefined ) { object.position.fromArray( data.position ); }
41403 if ( data.rotation !== undefined ) { object.rotation.fromArray( data.rotation ); }
41404 if ( data.quaternion !== undefined ) { object.quaternion.fromArray( data.quaternion ); }
41405 if ( data.scale !== undefined ) { object.scale.fromArray( data.scale ); }
41406
41407 }
41408
41409 if ( data.castShadow !== undefined ) { object.castShadow = data.castShadow; }
41410 if ( data.receiveShadow !== undefined ) { object.receiveShadow = data.receiveShadow; }
41411
41412 if ( data.shadow ) {
41413
41414 if ( data.shadow.bias !== undefined ) { object.shadow.bias = data.shadow.bias; }
41415 if ( data.shadow.normalBias !== undefined ) { object.shadow.normalBias = data.shadow.normalBias; }
41416 if ( data.shadow.radius !== undefined ) { object.shadow.radius = data.shadow.radius; }
41417 if ( data.shadow.mapSize !== undefined ) { object.shadow.mapSize.fromArray( data.shadow.mapSize ); }
41418 if ( data.shadow.camera !== undefined ) { object.shadow.camera = this.parseObject( data.shadow.camera ); }
41419
41420 }
41421
41422 if ( data.visible !== undefined ) { object.visible = data.visible; }
41423 if ( data.frustumCulled !== undefined ) { object.frustumCulled = data.frustumCulled; }
41424 if ( data.renderOrder !== undefined ) { object.renderOrder = data.renderOrder; }
41425 if ( data.userData !== undefined ) { object.userData = data.userData; }
41426 if ( data.layers !== undefined ) { object.layers.mask = data.layers; }
41427
41428 if ( data.children !== undefined ) {
41429
41430 var children = data.children;
41431
41432 for ( var i = 0; i < children.length; i ++ ) {
41433
41434 object.add( this.parseObject( children[ i ], geometries, materials ) );
41435
41436 }
41437
41438 }
41439
41440 if ( data.type === 'LOD' ) {
41441
41442 if ( data.autoUpdate !== undefined ) { object.autoUpdate = data.autoUpdate; }
41443
41444 var levels = data.levels;
41445
41446 for ( var l = 0; l < levels.length; l ++ ) {
41447
41448 var level = levels[ l ];
41449 var child = object.getObjectByProperty( 'uuid', level.object );
41450
41451 if ( child !== undefined ) {
41452
41453 object.addLevel( child, level.distance );
41454
41455 }
41456
41457 }
41458
41459 }
41460
41461 return object;
41462
41463 }
41464
41465 } );
41466
41467 var TEXTURE_MAPPING = {
41468 UVMapping: UVMapping,
41469 CubeReflectionMapping: CubeReflectionMapping,
41470 CubeRefractionMapping: CubeRefractionMapping,
41471 EquirectangularReflectionMapping: EquirectangularReflectionMapping,
41472 EquirectangularRefractionMapping: EquirectangularRefractionMapping,
41473 CubeUVReflectionMapping: CubeUVReflectionMapping,
41474 CubeUVRefractionMapping: CubeUVRefractionMapping
41475 };
41476
41477 var TEXTURE_WRAPPING = {
41478 RepeatWrapping: RepeatWrapping,
41479 ClampToEdgeWrapping: ClampToEdgeWrapping,
41480 MirroredRepeatWrapping: MirroredRepeatWrapping
41481 };
41482
41483 var TEXTURE_FILTER = {
41484 NearestFilter: NearestFilter,
41485 NearestMipmapNearestFilter: NearestMipmapNearestFilter,
41486 NearestMipmapLinearFilter: NearestMipmapLinearFilter,
41487 LinearFilter: LinearFilter,
41488 LinearMipmapNearestFilter: LinearMipmapNearestFilter,
41489 LinearMipmapLinearFilter: LinearMipmapLinearFilter
41490 };
41491
41492 function ImageBitmapLoader( manager ) {
41493
41494 if ( typeof createImageBitmap === 'undefined' ) {
41495
41496 console.warn( 'THREE.ImageBitmapLoader: createImageBitmap() not supported.' );
41497
41498 }
41499
41500 if ( typeof fetch === 'undefined' ) {
41501
41502 console.warn( 'THREE.ImageBitmapLoader: fetch() not supported.' );
41503
41504 }
41505
41506 Loader.call( this, manager );
41507
41508 this.options = { premultiplyAlpha: 'none' };
41509
41510 }
41511
41512 ImageBitmapLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
41513
41514 constructor: ImageBitmapLoader,
41515
41516 isImageBitmapLoader: true,
41517
41518 setOptions: function setOptions( options ) {
41519
41520 this.options = options;
41521
41522 return this;
41523
41524 },
41525
41526 load: function ( url, onLoad, onProgress, onError ) {
41527
41528 if ( url === undefined ) { url = ''; }
41529
41530 if ( this.path !== undefined ) { url = this.path + url; }
41531
41532 url = this.manager.resolveURL( url );
41533
41534 var scope = this;
41535
41536 var cached = Cache.get( url );
41537
41538 if ( cached !== undefined ) {
41539
41540 scope.manager.itemStart( url );
41541
41542 setTimeout( function () {
41543
41544 if ( onLoad ) { onLoad( cached ); }
41545
41546 scope.manager.itemEnd( url );
41547
41548 }, 0 );
41549
41550 return cached;
41551
41552 }
41553
41554 fetch( url ).then( function ( res ) {
41555
41556 return res.blob();
41557
41558 } ).then( function ( blob ) {
41559
41560 return createImageBitmap( blob, scope.options );
41561
41562 } ).then( function ( imageBitmap ) {
41563
41564 Cache.add( url, imageBitmap );
41565
41566 if ( onLoad ) { onLoad( imageBitmap ); }
41567
41568 scope.manager.itemEnd( url );
41569
41570 } ).catch( function ( e ) {
41571
41572 if ( onError ) { onError( e ); }
41573
41574 scope.manager.itemError( url );
41575 scope.manager.itemEnd( url );
41576
41577 } );
41578
41579 scope.manager.itemStart( url );
41580
41581 }
41582
41583 } );
41584
41585 function ShapePath() {
41586
41587 this.type = 'ShapePath';
41588
41589 this.color = new Color();
41590
41591 this.subPaths = [];
41592 this.currentPath = null;
41593
41594 }
41595
41596 Object.assign( ShapePath.prototype, {
41597
41598 moveTo: function ( x, y ) {
41599
41600 this.currentPath = new Path();
41601 this.subPaths.push( this.currentPath );
41602 this.currentPath.moveTo( x, y );
41603
41604 return this;
41605
41606 },
41607
41608 lineTo: function ( x, y ) {
41609
41610 this.currentPath.lineTo( x, y );
41611
41612 return this;
41613
41614 },
41615
41616 quadraticCurveTo: function ( aCPx, aCPy, aX, aY ) {
41617
41618 this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );
41619
41620 return this;
41621
41622 },
41623
41624 bezierCurveTo: function ( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
41625
41626 this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );
41627
41628 return this;
41629
41630 },
41631
41632 splineThru: function ( pts ) {
41633
41634 this.currentPath.splineThru( pts );
41635
41636 return this;
41637
41638 },
41639
41640 toShapes: function ( isCCW, noHoles ) {
41641
41642 function toShapesNoHoles( inSubpaths ) {
41643
41644 var shapes = [];
41645
41646 for ( var i = 0, l = inSubpaths.length; i < l; i ++ ) {
41647
41648 var tmpPath = inSubpaths[ i ];
41649
41650 var tmpShape = new Shape();
41651 tmpShape.curves = tmpPath.curves;
41652
41653 shapes.push( tmpShape );
41654
41655 }
41656
41657 return shapes;
41658
41659 }
41660
41661 function isPointInsidePolygon( inPt, inPolygon ) {
41662
41663 var polyLen = inPolygon.length;
41664
41665 // inPt on polygon contour => immediate success or
41666 // toggling of inside/outside at every single! intersection point of an edge
41667 // with the horizontal line through inPt, left of inPt
41668 // not counting lowerY endpoints of edges and whole edges on that line
41669 var inside = false;
41670 for ( var p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
41671
41672 var edgeLowPt = inPolygon[ p ];
41673 var edgeHighPt = inPolygon[ q ];
41674
41675 var edgeDx = edgeHighPt.x - edgeLowPt.x;
41676 var edgeDy = edgeHighPt.y - edgeLowPt.y;
41677
41678 if ( Math.abs( edgeDy ) > Number.EPSILON ) {
41679
41680 // not parallel
41681 if ( edgeDy < 0 ) {
41682
41683 edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
41684 edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
41685
41686 }
41687
41688 if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) { continue; }
41689
41690 if ( inPt.y === edgeLowPt.y ) {
41691
41692 if ( inPt.x === edgeLowPt.x ) { return true; } // inPt is on contour ?
41693 // continue; // no intersection or edgeLowPt => doesn't count !!!
41694
41695 } else {
41696
41697 var perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
41698 if ( perpEdge === 0 ) { return true; } // inPt is on contour ?
41699 if ( perpEdge < 0 ) { continue; }
41700 inside = ! inside; // true intersection left of inPt
41701
41702 }
41703
41704 } else {
41705
41706 // parallel or collinear
41707 if ( inPt.y !== edgeLowPt.y ) { continue; } // parallel
41708 // edge lies on the same horizontal line as inPt
41709 if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
41710 ( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) { return true; } // inPt: Point on contour !
41711 // continue;
41712
41713 }
41714
41715 }
41716
41717 return inside;
41718
41719 }
41720
41721 var isClockWise = ShapeUtils.isClockWise;
41722
41723 var subPaths = this.subPaths;
41724 if ( subPaths.length === 0 ) { return []; }
41725
41726 if ( noHoles === true ) { return toShapesNoHoles( subPaths ); }
41727
41728
41729 var solid, tmpPath, tmpShape, shapes = [];
41730
41731 if ( subPaths.length === 1 ) {
41732
41733 tmpPath = subPaths[ 0 ];
41734 tmpShape = new Shape();
41735 tmpShape.curves = tmpPath.curves;
41736 shapes.push( tmpShape );
41737 return shapes;
41738
41739 }
41740
41741 var holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
41742 holesFirst = isCCW ? ! holesFirst : holesFirst;
41743
41744 // console.log("Holes first", holesFirst);
41745
41746 var betterShapeHoles = [];
41747 var newShapes = [];
41748 var newShapeHoles = [];
41749 var mainIdx = 0;
41750 var tmpPoints;
41751
41752 newShapes[ mainIdx ] = undefined;
41753 newShapeHoles[ mainIdx ] = [];
41754
41755 for ( var i = 0, l = subPaths.length; i < l; i ++ ) {
41756
41757 tmpPath = subPaths[ i ];
41758 tmpPoints = tmpPath.getPoints();
41759 solid = isClockWise( tmpPoints );
41760 solid = isCCW ? ! solid : solid;
41761
41762 if ( solid ) {
41763
41764 if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) { mainIdx ++; }
41765
41766 newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };
41767 newShapes[ mainIdx ].s.curves = tmpPath.curves;
41768
41769 if ( holesFirst ) { mainIdx ++; }
41770 newShapeHoles[ mainIdx ] = [];
41771
41772 //console.log('cw', i);
41773
41774 } else {
41775
41776 newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
41777
41778 //console.log('ccw', i);
41779
41780 }
41781
41782 }
41783
41784 // only Holes? -> probably all Shapes with wrong orientation
41785 if ( ! newShapes[ 0 ] ) { return toShapesNoHoles( subPaths ); }
41786
41787
41788 if ( newShapes.length > 1 ) {
41789
41790 var ambiguous = false;
41791 var toChange = [];
41792
41793 for ( var sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
41794
41795 betterShapeHoles[ sIdx ] = [];
41796
41797 }
41798
41799 for ( var sIdx$1 = 0, sLen$1 = newShapes.length; sIdx$1 < sLen$1; sIdx$1 ++ ) {
41800
41801 var sho = newShapeHoles[ sIdx$1 ];
41802
41803 for ( var hIdx = 0; hIdx < sho.length; hIdx ++ ) {
41804
41805 var ho = sho[ hIdx ];
41806 var hole_unassigned = true;
41807
41808 for ( var s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
41809
41810 if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
41811
41812 if ( sIdx$1 !== s2Idx ) { toChange.push( { froms: sIdx$1, tos: s2Idx, hole: hIdx } ); }
41813 if ( hole_unassigned ) {
41814
41815 hole_unassigned = false;
41816 betterShapeHoles[ s2Idx ].push( ho );
41817
41818 } else {
41819
41820 ambiguous = true;
41821
41822 }
41823
41824 }
41825
41826 }
41827
41828 if ( hole_unassigned ) {
41829
41830 betterShapeHoles[ sIdx$1 ].push( ho );
41831
41832 }
41833
41834 }
41835
41836 }
41837 // console.log("ambiguous: ", ambiguous);
41838
41839 if ( toChange.length > 0 ) {
41840
41841 // console.log("to change: ", toChange);
41842 if ( ! ambiguous ) { newShapeHoles = betterShapeHoles; }
41843
41844 }
41845
41846 }
41847
41848 var tmpHoles;
41849
41850 for ( var i$1 = 0, il = newShapes.length; i$1 < il; i$1 ++ ) {
41851
41852 tmpShape = newShapes[ i$1 ].s;
41853 shapes.push( tmpShape );
41854 tmpHoles = newShapeHoles[ i$1 ];
41855
41856 for ( var j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
41857
41858 tmpShape.holes.push( tmpHoles[ j ].h );
41859
41860 }
41861
41862 }
41863
41864 //console.log("shape", shapes);
41865
41866 return shapes;
41867
41868 }
41869
41870 } );
41871
41872 function Font( data ) {
41873
41874 this.type = 'Font';
41875
41876 this.data = data;
41877
41878 }
41879
41880 Object.assign( Font.prototype, {
41881
41882 isFont: true,
41883
41884 generateShapes: function ( text, size ) {
41885
41886 if ( size === undefined ) { size = 100; }
41887
41888 var shapes = [];
41889 var paths = createPaths( text, size, this.data );
41890
41891 for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
41892
41893 Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
41894
41895 }
41896
41897 return shapes;
41898
41899 }
41900
41901 } );
41902
41903 function createPaths( text, size, data ) {
41904
41905 var chars = Array.from ? Array.from( text ) : String( text ).split( '' ); // workaround for IE11, see #13988
41906 var scale = size / data.resolution;
41907 var line_height = ( data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness ) * scale;
41908
41909 var paths = [];
41910
41911 var offsetX = 0, offsetY = 0;
41912
41913 for ( var i = 0; i < chars.length; i ++ ) {
41914
41915 var char = chars[ i ];
41916
41917 if ( char === '\n' ) {
41918
41919 offsetX = 0;
41920 offsetY -= line_height;
41921
41922 } else {
41923
41924 var ret = createPath( char, scale, offsetX, offsetY, data );
41925 offsetX += ret.offsetX;
41926 paths.push( ret.path );
41927
41928 }
41929
41930 }
41931
41932 return paths;
41933
41934 }
41935
41936 function createPath( char, scale, offsetX, offsetY, data ) {
41937
41938 var glyph = data.glyphs[ char ] || data.glyphs[ '?' ];
41939
41940 if ( ! glyph ) {
41941
41942 console.error( 'THREE.Font: character "' + char + '" does not exists in font family ' + data.familyName + '.' );
41943
41944 return;
41945
41946 }
41947
41948 var path = new ShapePath();
41949
41950 var x, y, cpx, cpy, cpx1, cpy1, cpx2, cpy2;
41951
41952 if ( glyph.o ) {
41953
41954 var outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
41955
41956 for ( var i = 0, l = outline.length; i < l; ) {
41957
41958 var action = outline[ i ++ ];
41959
41960 switch ( action ) {
41961
41962 case 'm': // moveTo
41963
41964 x = outline[ i ++ ] * scale + offsetX;
41965 y = outline[ i ++ ] * scale + offsetY;
41966
41967 path.moveTo( x, y );
41968
41969 break;
41970
41971 case 'l': // lineTo
41972
41973 x = outline[ i ++ ] * scale + offsetX;
41974 y = outline[ i ++ ] * scale + offsetY;
41975
41976 path.lineTo( x, y );
41977
41978 break;
41979
41980 case 'q': // quadraticCurveTo
41981
41982 cpx = outline[ i ++ ] * scale + offsetX;
41983 cpy = outline[ i ++ ] * scale + offsetY;
41984 cpx1 = outline[ i ++ ] * scale + offsetX;
41985 cpy1 = outline[ i ++ ] * scale + offsetY;
41986
41987 path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
41988
41989 break;
41990
41991 case 'b': // bezierCurveTo
41992
41993 cpx = outline[ i ++ ] * scale + offsetX;
41994 cpy = outline[ i ++ ] * scale + offsetY;
41995 cpx1 = outline[ i ++ ] * scale + offsetX;
41996 cpy1 = outline[ i ++ ] * scale + offsetY;
41997 cpx2 = outline[ i ++ ] * scale + offsetX;
41998 cpy2 = outline[ i ++ ] * scale + offsetY;
41999
42000 path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
42001
42002 break;
42003
42004 }
42005
42006 }
42007
42008 }
42009
42010 return { offsetX: glyph.ha * scale, path: path };
42011
42012 }
42013
42014 function FontLoader( manager ) {
42015
42016 Loader.call( this, manager );
42017
42018 }
42019
42020 FontLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
42021
42022 constructor: FontLoader,
42023
42024 load: function ( url, onLoad, onProgress, onError ) {
42025
42026 var scope = this;
42027
42028 var loader = new FileLoader( this.manager );
42029 loader.setPath( this.path );
42030 loader.setRequestHeader( this.requestHeader );
42031 loader.load( url, function ( text ) {
42032
42033 var json;
42034
42035 try {
42036
42037 json = JSON.parse( text );
42038
42039 } catch ( e ) {
42040
42041 console.warn( 'THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead.' );
42042 json = JSON.parse( text.substring( 65, text.length - 2 ) );
42043
42044 }
42045
42046 var font = scope.parse( json );
42047
42048 if ( onLoad ) { onLoad( font ); }
42049
42050 }, onProgress, onError );
42051
42052 },
42053
42054 parse: function ( json ) {
42055
42056 return new Font( json );
42057
42058 }
42059
42060 } );
42061
42062 var _context;
42063
42064 var AudioContext = {
42065
42066 getContext: function () {
42067
42068 if ( _context === undefined ) {
42069
42070 _context = new ( window.AudioContext || window.webkitAudioContext )();
42071
42072 }
42073
42074 return _context;
42075
42076 },
42077
42078 setContext: function ( value ) {
42079
42080 _context = value;
42081
42082 }
42083
42084 };
42085
42086 function AudioLoader( manager ) {
42087
42088 Loader.call( this, manager );
42089
42090 }
42091
42092 AudioLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
42093
42094 constructor: AudioLoader,
42095
42096 load: function ( url, onLoad, onProgress, onError ) {
42097
42098 var scope = this;
42099
42100 var loader = new FileLoader( scope.manager );
42101 loader.setResponseType( 'arraybuffer' );
42102 loader.setPath( scope.path );
42103 loader.setRequestHeader( scope.requestHeader );
42104 loader.load( url, function ( buffer ) {
42105
42106 try {
42107
42108 // Create a copy of the buffer. The `decodeAudioData` method
42109 // detaches the buffer when complete, preventing reuse.
42110 var bufferCopy = buffer.slice( 0 );
42111
42112 var context = AudioContext.getContext();
42113 context.decodeAudioData( bufferCopy, function ( audioBuffer ) {
42114
42115 onLoad( audioBuffer );
42116
42117 } );
42118
42119 } catch ( e ) {
42120
42121 if ( onError ) {
42122
42123 onError( e );
42124
42125 } else {
42126
42127 console.error( e );
42128
42129 }
42130
42131 scope.manager.itemError( url );
42132
42133 }
42134
42135 }, onProgress, onError );
42136
42137 }
42138
42139 } );
42140
42141 function HemisphereLightProbe( skyColor, groundColor, intensity ) {
42142
42143 LightProbe.call( this, undefined, intensity );
42144
42145 var color1 = new Color().set( skyColor );
42146 var color2 = new Color().set( groundColor );
42147
42148 var sky = new Vector3( color1.r, color1.g, color1.b );
42149 var ground = new Vector3( color2.r, color2.g, color2.b );
42150
42151 // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI );
42152 var c0 = Math.sqrt( Math.PI );
42153 var c1 = c0 * Math.sqrt( 0.75 );
42154
42155 this.sh.coefficients[ 0 ].copy( sky ).add( ground ).multiplyScalar( c0 );
42156 this.sh.coefficients[ 1 ].copy( sky ).sub( ground ).multiplyScalar( c1 );
42157
42158 }
42159
42160 HemisphereLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), {
42161
42162 constructor: HemisphereLightProbe,
42163
42164 isHemisphereLightProbe: true,
42165
42166 copy: function ( source ) { // modifying colors not currently supported
42167
42168 LightProbe.prototype.copy.call( this, source );
42169
42170 return this;
42171
42172 },
42173
42174 toJSON: function ( meta ) {
42175
42176 var data = LightProbe.prototype.toJSON.call( this, meta );
42177
42178 // data.sh = this.sh.toArray(); // todo
42179
42180 return data;
42181
42182 }
42183
42184 } );
42185
42186 function AmbientLightProbe( color, intensity ) {
42187
42188 LightProbe.call( this, undefined, intensity );
42189
42190 var color1 = new Color().set( color );
42191
42192 // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI );
42193 this.sh.coefficients[ 0 ].set( color1.r, color1.g, color1.b ).multiplyScalar( 2 * Math.sqrt( Math.PI ) );
42194
42195 }
42196
42197 AmbientLightProbe.prototype = Object.assign( Object.create( LightProbe.prototype ), {
42198
42199 constructor: AmbientLightProbe,
42200
42201 isAmbientLightProbe: true,
42202
42203 copy: function ( source ) { // modifying color not currently supported
42204
42205 LightProbe.prototype.copy.call( this, source );
42206
42207 return this;
42208
42209 },
42210
42211 toJSON: function ( meta ) {
42212
42213 var data = LightProbe.prototype.toJSON.call( this, meta );
42214
42215 // data.sh = this.sh.toArray(); // todo
42216
42217 return data;
42218
42219 }
42220
42221 } );
42222
42223 var _eyeRight = new Matrix4();
42224 var _eyeLeft = new Matrix4();
42225
42226 function StereoCamera() {
42227
42228 this.type = 'StereoCamera';
42229
42230 this.aspect = 1;
42231
42232 this.eyeSep = 0.064;
42233
42234 this.cameraL = new PerspectiveCamera();
42235 this.cameraL.layers.enable( 1 );
42236 this.cameraL.matrixAutoUpdate = false;
42237
42238 this.cameraR = new PerspectiveCamera();
42239 this.cameraR.layers.enable( 2 );
42240 this.cameraR.matrixAutoUpdate = false;
42241
42242 this._cache = {
42243 focus: null,
42244 fov: null,
42245 aspect: null,
42246 near: null,
42247 far: null,
42248 zoom: null,
42249 eyeSep: null
42250 };
42251
42252 }
42253
42254 Object.assign( StereoCamera.prototype, {
42255
42256 update: function ( camera ) {
42257
42258 var cache = this._cache;
42259
42260 var needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov ||
42261 cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near ||
42262 cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep;
42263
42264 if ( needsUpdate ) {
42265
42266 cache.focus = camera.focus;
42267 cache.fov = camera.fov;
42268 cache.aspect = camera.aspect * this.aspect;
42269 cache.near = camera.near;
42270 cache.far = camera.far;
42271 cache.zoom = camera.zoom;
42272 cache.eyeSep = this.eyeSep;
42273
42274 // Off-axis stereoscopic effect based on
42275 // http://paulbourke.net/stereographics/stereorender/
42276
42277 var projectionMatrix = camera.projectionMatrix.clone();
42278 var eyeSepHalf = cache.eyeSep / 2;
42279 var eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus;
42280 var ymax = ( cache.near * Math.tan( MathUtils.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom;
42281 var xmin, xmax;
42282
42283 // translate xOffset
42284
42285 _eyeLeft.elements[ 12 ] = - eyeSepHalf;
42286 _eyeRight.elements[ 12 ] = eyeSepHalf;
42287
42288 // for left eye
42289
42290 xmin = - ymax * cache.aspect + eyeSepOnProjection;
42291 xmax = ymax * cache.aspect + eyeSepOnProjection;
42292
42293 projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
42294 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
42295
42296 this.cameraL.projectionMatrix.copy( projectionMatrix );
42297
42298 // for right eye
42299
42300 xmin = - ymax * cache.aspect - eyeSepOnProjection;
42301 xmax = ymax * cache.aspect - eyeSepOnProjection;
42302
42303 projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
42304 projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
42305
42306 this.cameraR.projectionMatrix.copy( projectionMatrix );
42307
42308 }
42309
42310 this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft );
42311 this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight );
42312
42313 }
42314
42315 } );
42316
42317 function Clock( autoStart ) {
42318
42319 this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
42320
42321 this.startTime = 0;
42322 this.oldTime = 0;
42323 this.elapsedTime = 0;
42324
42325 this.running = false;
42326
42327 }
42328
42329 Object.assign( Clock.prototype, {
42330
42331 start: function () {
42332
42333 this.startTime = ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732
42334
42335 this.oldTime = this.startTime;
42336 this.elapsedTime = 0;
42337 this.running = true;
42338
42339 },
42340
42341 stop: function () {
42342
42343 this.getElapsedTime();
42344 this.running = false;
42345 this.autoStart = false;
42346
42347 },
42348
42349 getElapsedTime: function () {
42350
42351 this.getDelta();
42352 return this.elapsedTime;
42353
42354 },
42355
42356 getDelta: function () {
42357
42358 var diff = 0;
42359
42360 if ( this.autoStart && ! this.running ) {
42361
42362 this.start();
42363 return 0;
42364
42365 }
42366
42367 if ( this.running ) {
42368
42369 var newTime = ( typeof performance === 'undefined' ? Date : performance ).now();
42370
42371 diff = ( newTime - this.oldTime ) / 1000;
42372 this.oldTime = newTime;
42373
42374 this.elapsedTime += diff;
42375
42376 }
42377
42378 return diff;
42379
42380 }
42381
42382 } );
42383
42384 var _position$2 = new Vector3();
42385 var _quaternion$3 = new Quaternion();
42386 var _scale$1 = new Vector3();
42387 var _orientation = new Vector3();
42388
42389 function AudioListener() {
42390
42391 Object3D.call( this );
42392
42393 this.type = 'AudioListener';
42394
42395 this.context = AudioContext.getContext();
42396
42397 this.gain = this.context.createGain();
42398 this.gain.connect( this.context.destination );
42399
42400 this.filter = null;
42401
42402 this.timeDelta = 0;
42403
42404 // private
42405
42406 this._clock = new Clock();
42407
42408 }
42409
42410 AudioListener.prototype = Object.assign( Object.create( Object3D.prototype ), {
42411
42412 constructor: AudioListener,
42413
42414 getInput: function () {
42415
42416 return this.gain;
42417
42418 },
42419
42420 removeFilter: function ( ) {
42421
42422 if ( this.filter !== null ) {
42423
42424 this.gain.disconnect( this.filter );
42425 this.filter.disconnect( this.context.destination );
42426 this.gain.connect( this.context.destination );
42427 this.filter = null;
42428
42429 }
42430
42431 return this;
42432
42433 },
42434
42435 getFilter: function () {
42436
42437 return this.filter;
42438
42439 },
42440
42441 setFilter: function ( value ) {
42442
42443 if ( this.filter !== null ) {
42444
42445 this.gain.disconnect( this.filter );
42446 this.filter.disconnect( this.context.destination );
42447
42448 } else {
42449
42450 this.gain.disconnect( this.context.destination );
42451
42452 }
42453
42454 this.filter = value;
42455 this.gain.connect( this.filter );
42456 this.filter.connect( this.context.destination );
42457
42458 return this;
42459
42460 },
42461
42462 getMasterVolume: function () {
42463
42464 return this.gain.gain.value;
42465
42466 },
42467
42468 setMasterVolume: function ( value ) {
42469
42470 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
42471
42472 return this;
42473
42474 },
42475
42476 updateMatrixWorld: function ( force ) {
42477
42478 Object3D.prototype.updateMatrixWorld.call( this, force );
42479
42480 var listener = this.context.listener;
42481 var up = this.up;
42482
42483 this.timeDelta = this._clock.getDelta();
42484
42485 this.matrixWorld.decompose( _position$2, _quaternion$3, _scale$1 );
42486
42487 _orientation.set( 0, 0, - 1 ).applyQuaternion( _quaternion$3 );
42488
42489 if ( listener.positionX ) {
42490
42491 // code path for Chrome (see #14393)
42492
42493 var endTime = this.context.currentTime + this.timeDelta;
42494
42495 listener.positionX.linearRampToValueAtTime( _position$2.x, endTime );
42496 listener.positionY.linearRampToValueAtTime( _position$2.y, endTime );
42497 listener.positionZ.linearRampToValueAtTime( _position$2.z, endTime );
42498 listener.forwardX.linearRampToValueAtTime( _orientation.x, endTime );
42499 listener.forwardY.linearRampToValueAtTime( _orientation.y, endTime );
42500 listener.forwardZ.linearRampToValueAtTime( _orientation.z, endTime );
42501 listener.upX.linearRampToValueAtTime( up.x, endTime );
42502 listener.upY.linearRampToValueAtTime( up.y, endTime );
42503 listener.upZ.linearRampToValueAtTime( up.z, endTime );
42504
42505 } else {
42506
42507 listener.setPosition( _position$2.x, _position$2.y, _position$2.z );
42508 listener.setOrientation( _orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z );
42509
42510 }
42511
42512 }
42513
42514 } );
42515
42516 function Audio( listener ) {
42517
42518 Object3D.call( this );
42519
42520 this.type = 'Audio';
42521
42522 this.listener = listener;
42523 this.context = listener.context;
42524
42525 this.gain = this.context.createGain();
42526 this.gain.connect( listener.getInput() );
42527
42528 this.autoplay = false;
42529
42530 this.buffer = null;
42531 this.detune = 0;
42532 this.loop = false;
42533 this.loopStart = 0;
42534 this.loopEnd = 0;
42535 this.offset = 0;
42536 this.duration = undefined;
42537 this.playbackRate = 1;
42538 this.isPlaying = false;
42539 this.hasPlaybackControl = true;
42540 this.sourceType = 'empty';
42541
42542 this._startedAt = 0;
42543 this._progress = 0;
42544
42545 this.filters = [];
42546
42547 }
42548
42549 Audio.prototype = Object.assign( Object.create( Object3D.prototype ), {
42550
42551 constructor: Audio,
42552
42553 getOutput: function () {
42554
42555 return this.gain;
42556
42557 },
42558
42559 setNodeSource: function ( audioNode ) {
42560
42561 this.hasPlaybackControl = false;
42562 this.sourceType = 'audioNode';
42563 this.source = audioNode;
42564 this.connect();
42565
42566 return this;
42567
42568 },
42569
42570 setMediaElementSource: function ( mediaElement ) {
42571
42572 this.hasPlaybackControl = false;
42573 this.sourceType = 'mediaNode';
42574 this.source = this.context.createMediaElementSource( mediaElement );
42575 this.connect();
42576
42577 return this;
42578
42579 },
42580
42581 setMediaStreamSource: function ( mediaStream ) {
42582
42583 this.hasPlaybackControl = false;
42584 this.sourceType = 'mediaStreamNode';
42585 this.source = this.context.createMediaStreamSource( mediaStream );
42586 this.connect();
42587
42588 return this;
42589
42590 },
42591
42592 setBuffer: function ( audioBuffer ) {
42593
42594 this.buffer = audioBuffer;
42595 this.sourceType = 'buffer';
42596
42597 if ( this.autoplay ) { this.play(); }
42598
42599 return this;
42600
42601 },
42602
42603 play: function ( delay ) {
42604
42605 if ( delay === undefined ) { delay = 0; }
42606
42607 if ( this.isPlaying === true ) {
42608
42609 console.warn( 'THREE.Audio: Audio is already playing.' );
42610 return;
42611
42612 }
42613
42614 if ( this.hasPlaybackControl === false ) {
42615
42616 console.warn( 'THREE.Audio: this Audio has no playback control.' );
42617 return;
42618
42619 }
42620
42621 this._startedAt = this.context.currentTime + delay;
42622
42623 var source = this.context.createBufferSource();
42624 source.buffer = this.buffer;
42625 source.loop = this.loop;
42626 source.loopStart = this.loopStart;
42627 source.loopEnd = this.loopEnd;
42628 source.onended = this.onEnded.bind( this );
42629 source.start( this._startedAt, this._progress + this.offset, this.duration );
42630
42631 this.isPlaying = true;
42632
42633 this.source = source;
42634
42635 this.setDetune( this.detune );
42636 this.setPlaybackRate( this.playbackRate );
42637
42638 return this.connect();
42639
42640 },
42641
42642 pause: function () {
42643
42644 if ( this.hasPlaybackControl === false ) {
42645
42646 console.warn( 'THREE.Audio: this Audio has no playback control.' );
42647 return;
42648
42649 }
42650
42651 if ( this.isPlaying === true ) {
42652
42653 // update current progress
42654
42655 this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;
42656
42657 if ( this.loop === true ) {
42658
42659 // ensure _progress does not exceed duration with looped audios
42660
42661 this._progress = this._progress % ( this.duration || this.buffer.duration );
42662
42663 }
42664
42665 this.source.stop();
42666 this.source.onended = null;
42667
42668 this.isPlaying = false;
42669
42670 }
42671
42672 return this;
42673
42674 },
42675
42676 stop: function () {
42677
42678 if ( this.hasPlaybackControl === false ) {
42679
42680 console.warn( 'THREE.Audio: this Audio has no playback control.' );
42681 return;
42682
42683 }
42684
42685 this._progress = 0;
42686
42687 this.source.stop();
42688 this.source.onended = null;
42689 this.isPlaying = false;
42690
42691 return this;
42692
42693 },
42694
42695 connect: function () {
42696
42697 if ( this.filters.length > 0 ) {
42698
42699 this.source.connect( this.filters[ 0 ] );
42700
42701 for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
42702
42703 this.filters[ i - 1 ].connect( this.filters[ i ] );
42704
42705 }
42706
42707 this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
42708
42709 } else {
42710
42711 this.source.connect( this.getOutput() );
42712
42713 }
42714
42715 return this;
42716
42717 },
42718
42719 disconnect: function () {
42720
42721 if ( this.filters.length > 0 ) {
42722
42723 this.source.disconnect( this.filters[ 0 ] );
42724
42725 for ( var i = 1, l = this.filters.length; i < l; i ++ ) {
42726
42727 this.filters[ i - 1 ].disconnect( this.filters[ i ] );
42728
42729 }
42730
42731 this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
42732
42733 } else {
42734
42735 this.source.disconnect( this.getOutput() );
42736
42737 }
42738
42739 return this;
42740
42741 },
42742
42743 getFilters: function () {
42744
42745 return this.filters;
42746
42747 },
42748
42749 setFilters: function ( value ) {
42750
42751 if ( ! value ) { value = []; }
42752
42753 if ( this.isPlaying === true ) {
42754
42755 this.disconnect();
42756 this.filters = value;
42757 this.connect();
42758
42759 } else {
42760
42761 this.filters = value;
42762
42763 }
42764
42765 return this;
42766
42767 },
42768
42769 setDetune: function ( value ) {
42770
42771 this.detune = value;
42772
42773 if ( this.source.detune === undefined ) { return; } // only set detune when available
42774
42775 if ( this.isPlaying === true ) {
42776
42777 this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );
42778
42779 }
42780
42781 return this;
42782
42783 },
42784
42785 getDetune: function () {
42786
42787 return this.detune;
42788
42789 },
42790
42791 getFilter: function () {
42792
42793 return this.getFilters()[ 0 ];
42794
42795 },
42796
42797 setFilter: function ( filter ) {
42798
42799 return this.setFilters( filter ? [ filter ] : [] );
42800
42801 },
42802
42803 setPlaybackRate: function ( value ) {
42804
42805 if ( this.hasPlaybackControl === false ) {
42806
42807 console.warn( 'THREE.Audio: this Audio has no playback control.' );
42808 return;
42809
42810 }
42811
42812 this.playbackRate = value;
42813
42814 if ( this.isPlaying === true ) {
42815
42816 this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );
42817
42818 }
42819
42820 return this;
42821
42822 },
42823
42824 getPlaybackRate: function () {
42825
42826 return this.playbackRate;
42827
42828 },
42829
42830 onEnded: function () {
42831
42832 this.isPlaying = false;
42833
42834 },
42835
42836 getLoop: function () {
42837
42838 if ( this.hasPlaybackControl === false ) {
42839
42840 console.warn( 'THREE.Audio: this Audio has no playback control.' );
42841 return false;
42842
42843 }
42844
42845 return this.loop;
42846
42847 },
42848
42849 setLoop: function ( value ) {
42850
42851 if ( this.hasPlaybackControl === false ) {
42852
42853 console.warn( 'THREE.Audio: this Audio has no playback control.' );
42854 return;
42855
42856 }
42857
42858 this.loop = value;
42859
42860 if ( this.isPlaying === true ) {
42861
42862 this.source.loop = this.loop;
42863
42864 }
42865
42866 return this;
42867
42868 },
42869
42870 setLoopStart: function ( value ) {
42871
42872 this.loopStart = value;
42873
42874 return this;
42875
42876 },
42877
42878 setLoopEnd: function ( value ) {
42879
42880 this.loopEnd = value;
42881
42882 return this;
42883
42884 },
42885
42886 getVolume: function () {
42887
42888 return this.gain.gain.value;
42889
42890 },
42891
42892 setVolume: function ( value ) {
42893
42894 this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
42895
42896 return this;
42897
42898 }
42899
42900 } );
42901
42902 var _position$3 = new Vector3();
42903 var _quaternion$4 = new Quaternion();
42904 var _scale$2 = new Vector3();
42905 var _orientation$1 = new Vector3();
42906
42907 function PositionalAudio( listener ) {
42908
42909 Audio.call( this, listener );
42910
42911 this.panner = this.context.createPanner();
42912 this.panner.panningModel = 'HRTF';
42913 this.panner.connect( this.gain );
42914
42915 }
42916
42917 PositionalAudio.prototype = Object.assign( Object.create( Audio.prototype ), {
42918
42919 constructor: PositionalAudio,
42920
42921 getOutput: function () {
42922
42923 return this.panner;
42924
42925 },
42926
42927 getRefDistance: function () {
42928
42929 return this.panner.refDistance;
42930
42931 },
42932
42933 setRefDistance: function ( value ) {
42934
42935 this.panner.refDistance = value;
42936
42937 return this;
42938
42939 },
42940
42941 getRolloffFactor: function () {
42942
42943 return this.panner.rolloffFactor;
42944
42945 },
42946
42947 setRolloffFactor: function ( value ) {
42948
42949 this.panner.rolloffFactor = value;
42950
42951 return this;
42952
42953 },
42954
42955 getDistanceModel: function () {
42956
42957 return this.panner.distanceModel;
42958
42959 },
42960
42961 setDistanceModel: function ( value ) {
42962
42963 this.panner.distanceModel = value;
42964
42965 return this;
42966
42967 },
42968
42969 getMaxDistance: function () {
42970
42971 return this.panner.maxDistance;
42972
42973 },
42974
42975 setMaxDistance: function ( value ) {
42976
42977 this.panner.maxDistance = value;
42978
42979 return this;
42980
42981 },
42982
42983 setDirectionalCone: function ( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
42984
42985 this.panner.coneInnerAngle = coneInnerAngle;
42986 this.panner.coneOuterAngle = coneOuterAngle;
42987 this.panner.coneOuterGain = coneOuterGain;
42988
42989 return this;
42990
42991 },
42992
42993 updateMatrixWorld: function ( force ) {
42994
42995 Object3D.prototype.updateMatrixWorld.call( this, force );
42996
42997 if ( this.hasPlaybackControl === true && this.isPlaying === false ) { return; }
42998
42999 this.matrixWorld.decompose( _position$3, _quaternion$4, _scale$2 );
43000
43001 _orientation$1.set( 0, 0, 1 ).applyQuaternion( _quaternion$4 );
43002
43003 var panner = this.panner;
43004
43005 if ( panner.positionX ) {
43006
43007 // code path for Chrome and Firefox (see #14393)
43008
43009 var endTime = this.context.currentTime + this.listener.timeDelta;
43010
43011 panner.positionX.linearRampToValueAtTime( _position$3.x, endTime );
43012 panner.positionY.linearRampToValueAtTime( _position$3.y, endTime );
43013 panner.positionZ.linearRampToValueAtTime( _position$3.z, endTime );
43014 panner.orientationX.linearRampToValueAtTime( _orientation$1.x, endTime );
43015 panner.orientationY.linearRampToValueAtTime( _orientation$1.y, endTime );
43016 panner.orientationZ.linearRampToValueAtTime( _orientation$1.z, endTime );
43017
43018 } else {
43019
43020 panner.setPosition( _position$3.x, _position$3.y, _position$3.z );
43021 panner.setOrientation( _orientation$1.x, _orientation$1.y, _orientation$1.z );
43022
43023 }
43024
43025 }
43026
43027 } );
43028
43029 function AudioAnalyser( audio, fftSize ) {
43030
43031 this.analyser = audio.context.createAnalyser();
43032 this.analyser.fftSize = fftSize !== undefined ? fftSize : 2048;
43033
43034 this.data = new Uint8Array( this.analyser.frequencyBinCount );
43035
43036 audio.getOutput().connect( this.analyser );
43037
43038 }
43039
43040 Object.assign( AudioAnalyser.prototype, {
43041
43042 getFrequencyData: function () {
43043
43044 this.analyser.getByteFrequencyData( this.data );
43045
43046 return this.data;
43047
43048 },
43049
43050 getAverageFrequency: function () {
43051
43052 var value = 0;
43053 var data = this.getFrequencyData();
43054
43055 for ( var i = 0; i < data.length; i ++ ) {
43056
43057 value += data[ i ];
43058
43059 }
43060
43061 return value / data.length;
43062
43063 }
43064
43065 } );
43066
43067 function PropertyMixer( binding, typeName, valueSize ) {
43068
43069 this.binding = binding;
43070 this.valueSize = valueSize;
43071
43072 var mixFunction,
43073 mixFunctionAdditive,
43074 setIdentity;
43075
43076 // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ]
43077 //
43078 // interpolators can use .buffer as their .result
43079 // the data then goes to 'incoming'
43080 //
43081 // 'accu0' and 'accu1' are used frame-interleaved for
43082 // the cumulative result and are compared to detect
43083 // changes
43084 //
43085 // 'orig' stores the original state of the property
43086 //
43087 // 'add' is used for additive cumulative results
43088 //
43089 // 'work' is optional and is only present for quaternion types. It is used
43090 // to store intermediate quaternion multiplication results
43091
43092 switch ( typeName ) {
43093
43094 case 'quaternion':
43095 mixFunction = this._slerp;
43096 mixFunctionAdditive = this._slerpAdditive;
43097 setIdentity = this._setAdditiveIdentityQuaternion;
43098
43099 this.buffer = new Float64Array( valueSize * 6 );
43100 this._workIndex = 5;
43101 break;
43102
43103 case 'string':
43104 case 'bool':
43105 mixFunction = this._select;
43106
43107 // Use the regular mix function and for additive on these types,
43108 // additive is not relevant for non-numeric types
43109 mixFunctionAdditive = this._select;
43110
43111 setIdentity = this._setAdditiveIdentityOther;
43112
43113 this.buffer = new Array( valueSize * 5 );
43114 break;
43115
43116 default:
43117 mixFunction = this._lerp;
43118 mixFunctionAdditive = this._lerpAdditive;
43119 setIdentity = this._setAdditiveIdentityNumeric;
43120
43121 this.buffer = new Float64Array( valueSize * 5 );
43122
43123 }
43124
43125 this._mixBufferRegion = mixFunction;
43126 this._mixBufferRegionAdditive = mixFunctionAdditive;
43127 this._setIdentity = setIdentity;
43128 this._origIndex = 3;
43129 this._addIndex = 4;
43130
43131 this.cumulativeWeight = 0;
43132 this.cumulativeWeightAdditive = 0;
43133
43134 this.useCount = 0;
43135 this.referenceCount = 0;
43136
43137 }
43138
43139 Object.assign( PropertyMixer.prototype, {
43140
43141 // accumulate data in the 'incoming' region into 'accu<i>'
43142 accumulate: function ( accuIndex, weight ) {
43143
43144 // note: happily accumulating nothing when weight = 0, the caller knows
43145 // the weight and shouldn't have made the call in the first place
43146
43147 var buffer = this.buffer,
43148 stride = this.valueSize,
43149 offset = accuIndex * stride + stride;
43150
43151 var currentWeight = this.cumulativeWeight;
43152
43153 if ( currentWeight === 0 ) {
43154
43155 // accuN := incoming * weight
43156
43157 for ( var i = 0; i !== stride; ++ i ) {
43158
43159 buffer[ offset + i ] = buffer[ i ];
43160
43161 }
43162
43163 currentWeight = weight;
43164
43165 } else {
43166
43167 // accuN := accuN + incoming * weight
43168
43169 currentWeight += weight;
43170 var mix = weight / currentWeight;
43171 this._mixBufferRegion( buffer, offset, 0, mix, stride );
43172
43173 }
43174
43175 this.cumulativeWeight = currentWeight;
43176
43177 },
43178
43179 // accumulate data in the 'incoming' region into 'add'
43180 accumulateAdditive: function ( weight ) {
43181
43182 var buffer = this.buffer,
43183 stride = this.valueSize,
43184 offset = stride * this._addIndex;
43185
43186 if ( this.cumulativeWeightAdditive === 0 ) {
43187
43188 // add = identity
43189
43190 this._setIdentity();
43191
43192 }
43193
43194 // add := add + incoming * weight
43195
43196 this._mixBufferRegionAdditive( buffer, offset, 0, weight, stride );
43197 this.cumulativeWeightAdditive += weight;
43198
43199 },
43200
43201 // apply the state of 'accu<i>' to the binding when accus differ
43202 apply: function ( accuIndex ) {
43203
43204 var stride = this.valueSize,
43205 buffer = this.buffer,
43206 offset = accuIndex * stride + stride,
43207
43208 weight = this.cumulativeWeight,
43209 weightAdditive = this.cumulativeWeightAdditive,
43210
43211 binding = this.binding;
43212
43213 this.cumulativeWeight = 0;
43214 this.cumulativeWeightAdditive = 0;
43215
43216 if ( weight < 1 ) {
43217
43218 // accuN := accuN + original * ( 1 - cumulativeWeight )
43219
43220 var originalValueOffset = stride * this._origIndex;
43221
43222 this._mixBufferRegion(
43223 buffer, offset, originalValueOffset, 1 - weight, stride );
43224
43225 }
43226
43227 if ( weightAdditive > 0 ) {
43228
43229 // accuN := accuN + additive accuN
43230
43231 this._mixBufferRegionAdditive( buffer, offset, this._addIndex * stride, 1, stride );
43232
43233 }
43234
43235 for ( var i = stride, e = stride + stride; i !== e; ++ i ) {
43236
43237 if ( buffer[ i ] !== buffer[ i + stride ] ) {
43238
43239 // value has changed -> update scene graph
43240
43241 binding.setValue( buffer, offset );
43242 break;
43243
43244 }
43245
43246 }
43247
43248 },
43249
43250 // remember the state of the bound property and copy it to both accus
43251 saveOriginalState: function () {
43252
43253 var binding = this.binding;
43254
43255 var buffer = this.buffer,
43256 stride = this.valueSize,
43257
43258 originalValueOffset = stride * this._origIndex;
43259
43260 binding.getValue( buffer, originalValueOffset );
43261
43262 // accu[0..1] := orig -- initially detect changes against the original
43263 for ( var i = stride, e = originalValueOffset; i !== e; ++ i ) {
43264
43265 buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];
43266
43267 }
43268
43269 // Add to identity for additive
43270 this._setIdentity();
43271
43272 this.cumulativeWeight = 0;
43273 this.cumulativeWeightAdditive = 0;
43274
43275 },
43276
43277 // apply the state previously taken via 'saveOriginalState' to the binding
43278 restoreOriginalState: function () {
43279
43280 var originalValueOffset = this.valueSize * 3;
43281 this.binding.setValue( this.buffer, originalValueOffset );
43282
43283 },
43284
43285 _setAdditiveIdentityNumeric: function () {
43286
43287 var startIndex = this._addIndex * this.valueSize;
43288 var endIndex = startIndex + this.valueSize;
43289
43290 for ( var i = startIndex; i < endIndex; i ++ ) {
43291
43292 this.buffer[ i ] = 0;
43293
43294 }
43295
43296 },
43297
43298 _setAdditiveIdentityQuaternion: function () {
43299
43300 this._setAdditiveIdentityNumeric();
43301 this.buffer[ this._addIndex * 4 + 3 ] = 1;
43302
43303 },
43304
43305 _setAdditiveIdentityOther: function () {
43306
43307 var startIndex = this._origIndex * this.valueSize;
43308 var targetIndex = this._addIndex * this.valueSize;
43309
43310 for ( var i = 0; i < this.valueSize; i ++ ) {
43311
43312 this.buffer[ targetIndex + i ] = this.buffer[ startIndex + i ];
43313
43314 }
43315
43316 },
43317
43318
43319 // mix functions
43320
43321 _select: function ( buffer, dstOffset, srcOffset, t, stride ) {
43322
43323 if ( t >= 0.5 ) {
43324
43325 for ( var i = 0; i !== stride; ++ i ) {
43326
43327 buffer[ dstOffset + i ] = buffer[ srcOffset + i ];
43328
43329 }
43330
43331 }
43332
43333 },
43334
43335 _slerp: function ( buffer, dstOffset, srcOffset, t ) {
43336
43337 Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t );
43338
43339 },
43340
43341 _slerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) {
43342
43343 var workOffset = this._workIndex * stride;
43344
43345 // Store result in intermediate buffer offset
43346 Quaternion.multiplyQuaternionsFlat( buffer, workOffset, buffer, dstOffset, buffer, srcOffset );
43347
43348 // Slerp to the intermediate result
43349 Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t );
43350
43351 },
43352
43353 _lerp: function ( buffer, dstOffset, srcOffset, t, stride ) {
43354
43355 var s = 1 - t;
43356
43357 for ( var i = 0; i !== stride; ++ i ) {
43358
43359 var j = dstOffset + i;
43360
43361 buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;
43362
43363 }
43364
43365 },
43366
43367 _lerpAdditive: function ( buffer, dstOffset, srcOffset, t, stride ) {
43368
43369 for ( var i = 0; i !== stride; ++ i ) {
43370
43371 var j = dstOffset + i;
43372
43373 buffer[ j ] = buffer[ j ] + buffer[ srcOffset + i ] * t;
43374
43375 }
43376
43377 }
43378
43379 } );
43380
43381 // Characters [].:/ are reserved for track binding syntax.
43382 var _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
43383 var _reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' );
43384
43385 // Attempts to allow node names from any language. ES5's `\w` regexp matches
43386 // only latin characters, and the unicode \p{L} is not yet supported. So
43387 // instead, we exclude reserved characters and match everything else.
43388 var _wordChar = '[^' + _RESERVED_CHARS_RE + ']';
43389 var _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']';
43390
43391 // Parent directories, delimited by '/' or ':'. Currently unused, but must
43392 // be matched to parse the rest of the track name.
43393 var _directoryRe = /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar );
43394
43395 // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
43396 var _nodeRe = /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot );
43397
43398 // Object on target node, and accessor. May not contain reserved
43399 // characters. Accessor may contain any character except closing bracket.
43400 var _objectRe = /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar );
43401
43402 // Property and accessor. May not contain reserved characters. Accessor may
43403 // contain any non-bracket characters.
43404 var _propertyRe = /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar );
43405
43406 var _trackRe = new RegExp( ''
43407 + '^'
43408 + _directoryRe
43409 + _nodeRe
43410 + _objectRe
43411 + _propertyRe
43412 + '$'
43413 );
43414
43415 var _supportedObjectNames = [ 'material', 'materials', 'bones' ];
43416
43417 function Composite( targetGroup, path, optionalParsedPath ) {
43418
43419 var parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path );
43420
43421 this._targetGroup = targetGroup;
43422 this._bindings = targetGroup.subscribe_( path, parsedPath );
43423
43424 }
43425
43426 Object.assign( Composite.prototype, {
43427
43428 getValue: function ( array, offset ) {
43429
43430 this.bind(); // bind all binding
43431
43432 var firstValidIndex = this._targetGroup.nCachedObjects_,
43433 binding = this._bindings[ firstValidIndex ];
43434
43435 // and only call .getValue on the first
43436 if ( binding !== undefined ) { binding.getValue( array, offset ); }
43437
43438 },
43439
43440 setValue: function ( array, offset ) {
43441
43442 var bindings = this._bindings;
43443
43444 for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
43445
43446 bindings[ i ].setValue( array, offset );
43447
43448 }
43449
43450 },
43451
43452 bind: function () {
43453
43454 var bindings = this._bindings;
43455
43456 for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
43457
43458 bindings[ i ].bind();
43459
43460 }
43461
43462 },
43463
43464 unbind: function () {
43465
43466 var bindings = this._bindings;
43467
43468 for ( var i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
43469
43470 bindings[ i ].unbind();
43471
43472 }
43473
43474 }
43475
43476 } );
43477
43478
43479 function PropertyBinding( rootNode, path, parsedPath ) {
43480
43481 this.path = path;
43482 this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path );
43483
43484 this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName ) || rootNode;
43485
43486 this.rootNode = rootNode;
43487
43488 }
43489
43490 Object.assign( PropertyBinding, {
43491
43492 Composite: Composite,
43493
43494 create: function ( root, path, parsedPath ) {
43495
43496 if ( ! ( root && root.isAnimationObjectGroup ) ) {
43497
43498 return new PropertyBinding( root, path, parsedPath );
43499
43500 } else {
43501
43502 return new PropertyBinding.Composite( root, path, parsedPath );
43503
43504 }
43505
43506 },
43507
43508 /**
43509 * Replaces spaces with underscores and removes unsupported characters from
43510 * node names, to ensure compatibility with parseTrackName().
43511 *
43512 * @param {string} name Node name to be sanitized.
43513 * @return {string}
43514 */
43515 sanitizeNodeName: function ( name ) {
43516
43517 return name.replace( /\s/g, '_' ).replace( _reservedRe, '' );
43518
43519 },
43520
43521 parseTrackName: function ( trackName ) {
43522
43523 var matches = _trackRe.exec( trackName );
43524
43525 if ( ! matches ) {
43526
43527 throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
43528
43529 }
43530
43531 var results = {
43532 // directoryName: matches[ 1 ], // (tschw) currently unused
43533 nodeName: matches[ 2 ],
43534 objectName: matches[ 3 ],
43535 objectIndex: matches[ 4 ],
43536 propertyName: matches[ 5 ], // required
43537 propertyIndex: matches[ 6 ]
43538 };
43539
43540 var lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
43541
43542 if ( lastDot !== undefined && lastDot !== - 1 ) {
43543
43544 var objectName = results.nodeName.substring( lastDot + 1 );
43545
43546 // Object names must be checked against an allowlist. Otherwise, there
43547 // is no way to parse 'foo.bar.baz': 'baz' must be a property, but
43548 // 'bar' could be the objectName, or part of a nodeName (which can
43549 // include '.' characters).
43550 if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) {
43551
43552 results.nodeName = results.nodeName.substring( 0, lastDot );
43553 results.objectName = objectName;
43554
43555 }
43556
43557 }
43558
43559 if ( results.propertyName === null || results.propertyName.length === 0 ) {
43560
43561 throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
43562
43563 }
43564
43565 return results;
43566
43567 },
43568
43569 findNode: function ( root, nodeName ) {
43570
43571 if ( ! nodeName || nodeName === "" || nodeName === "." || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
43572
43573 return root;
43574
43575 }
43576
43577 // search into skeleton bones.
43578 if ( root.skeleton ) {
43579
43580 var bone = root.skeleton.getBoneByName( nodeName );
43581
43582 if ( bone !== undefined ) {
43583
43584 return bone;
43585
43586 }
43587
43588 }
43589
43590 // search into node subtree.
43591 if ( root.children ) {
43592
43593 var searchNodeSubtree = function ( children ) {
43594
43595 for ( var i = 0; i < children.length; i ++ ) {
43596
43597 var childNode = children[ i ];
43598
43599 if ( childNode.name === nodeName || childNode.uuid === nodeName ) {
43600
43601 return childNode;
43602
43603 }
43604
43605 var result = searchNodeSubtree( childNode.children );
43606
43607 if ( result ) { return result; }
43608
43609 }
43610
43611 return null;
43612
43613 };
43614
43615 var subTreeNode = searchNodeSubtree( root.children );
43616
43617 if ( subTreeNode ) {
43618
43619 return subTreeNode;
43620
43621 }
43622
43623 }
43624
43625 return null;
43626
43627 }
43628
43629 } );
43630
43631 Object.assign( PropertyBinding.prototype, { // prototype, continued
43632
43633 // these are used to "bind" a nonexistent property
43634 _getValue_unavailable: function () {},
43635 _setValue_unavailable: function () {},
43636
43637 BindingType: {
43638 Direct: 0,
43639 EntireArray: 1,
43640 ArrayElement: 2,
43641 HasFromToArray: 3
43642 },
43643
43644 Versioning: {
43645 None: 0,
43646 NeedsUpdate: 1,
43647 MatrixWorldNeedsUpdate: 2
43648 },
43649
43650 GetterByBindingType: [
43651
43652 function getValue_direct( buffer, offset ) {
43653
43654 buffer[ offset ] = this.node[ this.propertyName ];
43655
43656 },
43657
43658 function getValue_array( buffer, offset ) {
43659
43660 var source = this.resolvedProperty;
43661
43662 for ( var i = 0, n = source.length; i !== n; ++ i ) {
43663
43664 buffer[ offset ++ ] = source[ i ];
43665
43666 }
43667
43668 },
43669
43670 function getValue_arrayElement( buffer, offset ) {
43671
43672 buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];
43673
43674 },
43675
43676 function getValue_toArray( buffer, offset ) {
43677
43678 this.resolvedProperty.toArray( buffer, offset );
43679
43680 }
43681
43682 ],
43683
43684 SetterByBindingTypeAndVersioning: [
43685
43686 [
43687 // Direct
43688
43689 function setValue_direct( buffer, offset ) {
43690
43691 this.targetObject[ this.propertyName ] = buffer[ offset ];
43692
43693 },
43694
43695 function setValue_direct_setNeedsUpdate( buffer, offset ) {
43696
43697 this.targetObject[ this.propertyName ] = buffer[ offset ];
43698 this.targetObject.needsUpdate = true;
43699
43700 },
43701
43702 function setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {
43703
43704 this.targetObject[ this.propertyName ] = buffer[ offset ];
43705 this.targetObject.matrixWorldNeedsUpdate = true;
43706
43707 }
43708
43709 ], [
43710
43711 // EntireArray
43712
43713 function setValue_array( buffer, offset ) {
43714
43715 var dest = this.resolvedProperty;
43716
43717 for ( var i = 0, n = dest.length; i !== n; ++ i ) {
43718
43719 dest[ i ] = buffer[ offset ++ ];
43720
43721 }
43722
43723 },
43724
43725 function setValue_array_setNeedsUpdate( buffer, offset ) {
43726
43727 var dest = this.resolvedProperty;
43728
43729 for ( var i = 0, n = dest.length; i !== n; ++ i ) {
43730
43731 dest[ i ] = buffer[ offset ++ ];
43732
43733 }
43734
43735 this.targetObject.needsUpdate = true;
43736
43737 },
43738
43739 function setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {
43740
43741 var dest = this.resolvedProperty;
43742
43743 for ( var i = 0, n = dest.length; i !== n; ++ i ) {
43744
43745 dest[ i ] = buffer[ offset ++ ];
43746
43747 }
43748
43749 this.targetObject.matrixWorldNeedsUpdate = true;
43750
43751 }
43752
43753 ], [
43754
43755 // ArrayElement
43756
43757 function setValue_arrayElement( buffer, offset ) {
43758
43759 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
43760
43761 },
43762
43763 function setValue_arrayElement_setNeedsUpdate( buffer, offset ) {
43764
43765 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
43766 this.targetObject.needsUpdate = true;
43767
43768 },
43769
43770 function setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {
43771
43772 this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
43773 this.targetObject.matrixWorldNeedsUpdate = true;
43774
43775 }
43776
43777 ], [
43778
43779 // HasToFromArray
43780
43781 function setValue_fromArray( buffer, offset ) {
43782
43783 this.resolvedProperty.fromArray( buffer, offset );
43784
43785 },
43786
43787 function setValue_fromArray_setNeedsUpdate( buffer, offset ) {
43788
43789 this.resolvedProperty.fromArray( buffer, offset );
43790 this.targetObject.needsUpdate = true;
43791
43792 },
43793
43794 function setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {
43795
43796 this.resolvedProperty.fromArray( buffer, offset );
43797 this.targetObject.matrixWorldNeedsUpdate = true;
43798
43799 }
43800
43801 ]
43802
43803 ],
43804
43805 getValue: function getValue_unbound( targetArray, offset ) {
43806
43807 this.bind();
43808 this.getValue( targetArray, offset );
43809
43810 // Note: This class uses a State pattern on a per-method basis:
43811 // 'bind' sets 'this.getValue' / 'setValue' and shadows the
43812 // prototype version of these methods with one that represents
43813 // the bound state. When the property is not found, the methods
43814 // become no-ops.
43815
43816 },
43817
43818 setValue: function getValue_unbound( sourceArray, offset ) {
43819
43820 this.bind();
43821 this.setValue( sourceArray, offset );
43822
43823 },
43824
43825 // create getter / setter pair for a property in the scene graph
43826 bind: function () {
43827
43828 var targetObject = this.node,
43829 parsedPath = this.parsedPath,
43830
43831 objectName = parsedPath.objectName,
43832 propertyName = parsedPath.propertyName,
43833 propertyIndex = parsedPath.propertyIndex;
43834
43835 if ( ! targetObject ) {
43836
43837 targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName ) || this.rootNode;
43838
43839 this.node = targetObject;
43840
43841 }
43842
43843 // set fail state so we can just 'return' on error
43844 this.getValue = this._getValue_unavailable;
43845 this.setValue = this._setValue_unavailable;
43846
43847 // ensure there is a value node
43848 if ( ! targetObject ) {
43849
43850 console.error( 'THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.' );
43851 return;
43852
43853 }
43854
43855 if ( objectName ) {
43856
43857 var objectIndex = parsedPath.objectIndex;
43858
43859 // special cases were we need to reach deeper into the hierarchy to get the face materials....
43860 switch ( objectName ) {
43861
43862 case 'materials':
43863
43864 if ( ! targetObject.material ) {
43865
43866 console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this );
43867 return;
43868
43869 }
43870
43871 if ( ! targetObject.material.materials ) {
43872
43873 console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this );
43874 return;
43875
43876 }
43877
43878 targetObject = targetObject.material.materials;
43879
43880 break;
43881
43882 case 'bones':
43883
43884 if ( ! targetObject.skeleton ) {
43885
43886 console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this );
43887 return;
43888
43889 }
43890
43891 // potential future optimization: skip this if propertyIndex is already an integer
43892 // and convert the integer string to a true integer.
43893
43894 targetObject = targetObject.skeleton.bones;
43895
43896 // support resolving morphTarget names into indices.
43897 for ( var i = 0; i < targetObject.length; i ++ ) {
43898
43899 if ( targetObject[ i ].name === objectIndex ) {
43900
43901 objectIndex = i;
43902 break;
43903
43904 }
43905
43906 }
43907
43908 break;
43909
43910 default:
43911
43912 if ( targetObject[ objectName ] === undefined ) {
43913
43914 console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this );
43915 return;
43916
43917 }
43918
43919 targetObject = targetObject[ objectName ];
43920
43921 }
43922
43923
43924 if ( objectIndex !== undefined ) {
43925
43926 if ( targetObject[ objectIndex ] === undefined ) {
43927
43928 console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject );
43929 return;
43930
43931 }
43932
43933 targetObject = targetObject[ objectIndex ];
43934
43935 }
43936
43937 }
43938
43939 // resolve property
43940 var nodeProperty = targetObject[ propertyName ];
43941
43942 if ( nodeProperty === undefined ) {
43943
43944 var nodeName = parsedPath.nodeName;
43945
43946 console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName +
43947 '.' + propertyName + ' but it wasn\'t found.', targetObject );
43948 return;
43949
43950 }
43951
43952 // determine versioning scheme
43953 var versioning = this.Versioning.None;
43954
43955 this.targetObject = targetObject;
43956
43957 if ( targetObject.needsUpdate !== undefined ) { // material
43958
43959 versioning = this.Versioning.NeedsUpdate;
43960
43961 } else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform
43962
43963 versioning = this.Versioning.MatrixWorldNeedsUpdate;
43964
43965 }
43966
43967 // determine how the property gets bound
43968 var bindingType = this.BindingType.Direct;
43969
43970 if ( propertyIndex !== undefined ) {
43971
43972 // access a sub element of the property array (only primitives are supported right now)
43973
43974 if ( propertyName === "morphTargetInfluences" ) {
43975
43976 // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
43977
43978 // support resolving morphTarget names into indices.
43979 if ( ! targetObject.geometry ) {
43980
43981 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this );
43982 return;
43983
43984 }
43985
43986 if ( targetObject.geometry.isBufferGeometry ) {
43987
43988 if ( ! targetObject.geometry.morphAttributes ) {
43989
43990 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this );
43991 return;
43992
43993 }
43994
43995 if ( targetObject.morphTargetDictionary[ propertyIndex ] !== undefined ) {
43996
43997 propertyIndex = targetObject.morphTargetDictionary[ propertyIndex ];
43998
43999 }
44000
44001
44002 } else {
44003
44004 console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences on THREE.Geometry. Use THREE.BufferGeometry instead.', this );
44005 return;
44006
44007 }
44008
44009 }
44010
44011 bindingType = this.BindingType.ArrayElement;
44012
44013 this.resolvedProperty = nodeProperty;
44014 this.propertyIndex = propertyIndex;
44015
44016 } else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {
44017
44018 // must use copy for Object3D.Euler/Quaternion
44019
44020 bindingType = this.BindingType.HasFromToArray;
44021
44022 this.resolvedProperty = nodeProperty;
44023
44024 } else if ( Array.isArray( nodeProperty ) ) {
44025
44026 bindingType = this.BindingType.EntireArray;
44027
44028 this.resolvedProperty = nodeProperty;
44029
44030 } else {
44031
44032 this.propertyName = propertyName;
44033
44034 }
44035
44036 // select getter / setter
44037 this.getValue = this.GetterByBindingType[ bindingType ];
44038 this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];
44039
44040 },
44041
44042 unbind: function () {
44043
44044 this.node = null;
44045
44046 // back to the prototype version of getValue / setValue
44047 // note: avoiding to mutate the shape of 'this' via 'delete'
44048 this.getValue = this._getValue_unbound;
44049 this.setValue = this._setValue_unbound;
44050
44051 }
44052
44053 } );
44054
44055 // DECLARE ALIAS AFTER assign prototype
44056 Object.assign( PropertyBinding.prototype, {
44057
44058 // initial state of these methods that calls 'bind'
44059 _getValue_unbound: PropertyBinding.prototype.getValue,
44060 _setValue_unbound: PropertyBinding.prototype.setValue,
44061
44062 } );
44063
44064 /**
44065 *
44066 * A group of objects that receives a shared animation state.
44067 *
44068 * Usage:
44069 *
44070 * - Add objects you would otherwise pass as 'root' to the
44071 * constructor or the .clipAction method of AnimationMixer.
44072 *
44073 * - Instead pass this object as 'root'.
44074 *
44075 * - You can also add and remove objects later when the mixer
44076 * is running.
44077 *
44078 * Note:
44079 *
44080 * Objects of this class appear as one object to the mixer,
44081 * so cache control of the individual objects must be done
44082 * on the group.
44083 *
44084 * Limitation:
44085 *
44086 * - The animated properties must be compatible among the
44087 * all objects in the group.
44088 *
44089 * - A single property can either be controlled through a
44090 * target group or directly, but not both.
44091 */
44092
44093 function AnimationObjectGroup() {
44094
44095 this.uuid = MathUtils.generateUUID();
44096
44097 // cached objects followed by the active ones
44098 this._objects = Array.prototype.slice.call( arguments );
44099
44100 this.nCachedObjects_ = 0; // threshold
44101 // note: read by PropertyBinding.Composite
44102
44103 var indices = {};
44104 this._indicesByUUID = indices; // for bookkeeping
44105
44106 for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
44107
44108 indices[ arguments[ i ].uuid ] = i;
44109
44110 }
44111
44112 this._paths = []; // inside: string
44113 this._parsedPaths = []; // inside: { we don't care, here }
44114 this._bindings = []; // inside: Array< PropertyBinding >
44115 this._bindingsIndicesByPath = {}; // inside: indices in these arrays
44116
44117 var scope = this;
44118
44119 this.stats = {
44120
44121 objects: {
44122 get total() {
44123
44124 return scope._objects.length;
44125
44126 },
44127 get inUse() {
44128
44129 return this.total - scope.nCachedObjects_;
44130
44131 }
44132 },
44133 get bindingsPerObject() {
44134
44135 return scope._bindings.length;
44136
44137 }
44138
44139 };
44140
44141 }
44142
44143 Object.assign( AnimationObjectGroup.prototype, {
44144
44145 isAnimationObjectGroup: true,
44146
44147 add: function () {
44148
44149 var objects = this._objects,
44150 indicesByUUID = this._indicesByUUID,
44151 paths = this._paths,
44152 parsedPaths = this._parsedPaths,
44153 bindings = this._bindings,
44154 nBindings = bindings.length;
44155
44156 var knownObject = undefined,
44157 nObjects = objects.length,
44158 nCachedObjects = this.nCachedObjects_;
44159
44160 for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
44161
44162 var object = arguments[ i ],
44163 uuid = object.uuid;
44164 var index = indicesByUUID[ uuid ];
44165
44166 if ( index === undefined ) {
44167
44168 // unknown object -> add it to the ACTIVE region
44169
44170 index = nObjects ++;
44171 indicesByUUID[ uuid ] = index;
44172 objects.push( object );
44173
44174 // accounting is done, now do the same for all bindings
44175
44176 for ( var j = 0, m = nBindings; j !== m; ++ j ) {
44177
44178 bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) );
44179
44180 }
44181
44182 } else if ( index < nCachedObjects ) {
44183
44184 knownObject = objects[ index ];
44185
44186 // move existing object to the ACTIVE region
44187
44188 var firstActiveIndex = -- nCachedObjects,
44189 lastCachedObject = objects[ firstActiveIndex ];
44190
44191 indicesByUUID[ lastCachedObject.uuid ] = index;
44192 objects[ index ] = lastCachedObject;
44193
44194 indicesByUUID[ uuid ] = firstActiveIndex;
44195 objects[ firstActiveIndex ] = object;
44196
44197 // accounting is done, now do the same for all bindings
44198
44199 for ( var j$1 = 0, m$1 = nBindings; j$1 !== m$1; ++ j$1 ) {
44200
44201 var bindingsForPath = bindings[ j$1 ],
44202 lastCached = bindingsForPath[ firstActiveIndex ];
44203
44204 var binding = bindingsForPath[ index ];
44205
44206 bindingsForPath[ index ] = lastCached;
44207
44208 if ( binding === undefined ) {
44209
44210 // since we do not bother to create new bindings
44211 // for objects that are cached, the binding may
44212 // or may not exist
44213
44214 binding = new PropertyBinding( object, paths[ j$1 ], parsedPaths[ j$1 ] );
44215
44216 }
44217
44218 bindingsForPath[ firstActiveIndex ] = binding;
44219
44220 }
44221
44222 } else if ( objects[ index ] !== knownObject ) {
44223
44224 console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' +
44225 'detected. Clean the caches or recreate your infrastructure when reloading scenes.' );
44226
44227 } // else the object is already where we want it to be
44228
44229 } // for arguments
44230
44231 this.nCachedObjects_ = nCachedObjects;
44232
44233 },
44234
44235 remove: function () {
44236
44237 var objects = this._objects,
44238 indicesByUUID = this._indicesByUUID,
44239 bindings = this._bindings,
44240 nBindings = bindings.length;
44241
44242 var nCachedObjects = this.nCachedObjects_;
44243
44244 for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
44245
44246 var object = arguments[ i ],
44247 uuid = object.uuid,
44248 index = indicesByUUID[ uuid ];
44249
44250 if ( index !== undefined && index >= nCachedObjects ) {
44251
44252 // move existing object into the CACHED region
44253
44254 var lastCachedIndex = nCachedObjects ++,
44255 firstActiveObject = objects[ lastCachedIndex ];
44256
44257 indicesByUUID[ firstActiveObject.uuid ] = index;
44258 objects[ index ] = firstActiveObject;
44259
44260 indicesByUUID[ uuid ] = lastCachedIndex;
44261 objects[ lastCachedIndex ] = object;
44262
44263 // accounting is done, now do the same for all bindings
44264
44265 for ( var j = 0, m = nBindings; j !== m; ++ j ) {
44266
44267 var bindingsForPath = bindings[ j ],
44268 firstActive = bindingsForPath[ lastCachedIndex ],
44269 binding = bindingsForPath[ index ];
44270
44271 bindingsForPath[ index ] = firstActive;
44272 bindingsForPath[ lastCachedIndex ] = binding;
44273
44274 }
44275
44276 }
44277
44278 } // for arguments
44279
44280 this.nCachedObjects_ = nCachedObjects;
44281
44282 },
44283
44284 // remove & forget
44285 uncache: function () {
44286
44287 var objects = this._objects,
44288 indicesByUUID = this._indicesByUUID,
44289 bindings = this._bindings,
44290 nBindings = bindings.length;
44291
44292 var nCachedObjects = this.nCachedObjects_,
44293 nObjects = objects.length;
44294
44295 for ( var i = 0, n = arguments.length; i !== n; ++ i ) {
44296
44297 var object = arguments[ i ],
44298 uuid = object.uuid,
44299 index = indicesByUUID[ uuid ];
44300
44301 if ( index !== undefined ) {
44302
44303 delete indicesByUUID[ uuid ];
44304
44305 if ( index < nCachedObjects ) {
44306
44307 // object is cached, shrink the CACHED region
44308
44309 var firstActiveIndex = -- nCachedObjects,
44310 lastCachedObject = objects[ firstActiveIndex ],
44311 lastIndex = -- nObjects,
44312 lastObject = objects[ lastIndex ];
44313
44314 // last cached object takes this object's place
44315 indicesByUUID[ lastCachedObject.uuid ] = index;
44316 objects[ index ] = lastCachedObject;
44317
44318 // last object goes to the activated slot and pop
44319 indicesByUUID[ lastObject.uuid ] = firstActiveIndex;
44320 objects[ firstActiveIndex ] = lastObject;
44321 objects.pop();
44322
44323 // accounting is done, now do the same for all bindings
44324
44325 for ( var j = 0, m = nBindings; j !== m; ++ j ) {
44326
44327 var bindingsForPath = bindings[ j ],
44328 lastCached = bindingsForPath[ firstActiveIndex ],
44329 last = bindingsForPath[ lastIndex ];
44330
44331 bindingsForPath[ index ] = lastCached;
44332 bindingsForPath[ firstActiveIndex ] = last;
44333 bindingsForPath.pop();
44334
44335 }
44336
44337 } else {
44338
44339 // object is active, just swap with the last and pop
44340
44341 var lastIndex$1 = -- nObjects,
44342 lastObject$1 = objects[ lastIndex$1 ];
44343
44344 indicesByUUID[ lastObject$1.uuid ] = index;
44345 objects[ index ] = lastObject$1;
44346 objects.pop();
44347
44348 // accounting is done, now do the same for all bindings
44349
44350 for ( var j$1 = 0, m$1 = nBindings; j$1 !== m$1; ++ j$1 ) {
44351
44352 var bindingsForPath$1 = bindings[ j$1 ];
44353
44354 bindingsForPath$1[ index ] = bindingsForPath$1[ lastIndex$1 ];
44355 bindingsForPath$1.pop();
44356
44357 }
44358
44359 } // cached or active
44360
44361 } // if object is known
44362
44363 } // for arguments
44364
44365 this.nCachedObjects_ = nCachedObjects;
44366
44367 },
44368
44369 // Internal interface used by befriended PropertyBinding.Composite:
44370
44371 subscribe_: function ( path, parsedPath ) {
44372
44373 // returns an array of bindings for the given path that is changed
44374 // according to the contained objects in the group
44375
44376 var indicesByPath = this._bindingsIndicesByPath,
44377 index = indicesByPath[ path ],
44378 bindings = this._bindings;
44379
44380 if ( index !== undefined ) { return bindings[ index ]; }
44381
44382 var paths = this._paths,
44383 parsedPaths = this._parsedPaths,
44384 objects = this._objects,
44385 nObjects = objects.length,
44386 nCachedObjects = this.nCachedObjects_,
44387 bindingsForPath = new Array( nObjects );
44388
44389 index = bindings.length;
44390
44391 indicesByPath[ path ] = index;
44392
44393 paths.push( path );
44394 parsedPaths.push( parsedPath );
44395 bindings.push( bindingsForPath );
44396
44397 for ( var i = nCachedObjects, n = objects.length; i !== n; ++ i ) {
44398
44399 var object = objects[ i ];
44400 bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath );
44401
44402 }
44403
44404 return bindingsForPath;
44405
44406 },
44407
44408 unsubscribe_: function ( path ) {
44409
44410 // tells the group to forget about a property path and no longer
44411 // update the array previously obtained with 'subscribe_'
44412
44413 var indicesByPath = this._bindingsIndicesByPath,
44414 index = indicesByPath[ path ];
44415
44416 if ( index !== undefined ) {
44417
44418 var paths = this._paths,
44419 parsedPaths = this._parsedPaths,
44420 bindings = this._bindings,
44421 lastBindingsIndex = bindings.length - 1,
44422 lastBindings = bindings[ lastBindingsIndex ],
44423 lastBindingsPath = path[ lastBindingsIndex ];
44424
44425 indicesByPath[ lastBindingsPath ] = index;
44426
44427 bindings[ index ] = lastBindings;
44428 bindings.pop();
44429
44430 parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];
44431 parsedPaths.pop();
44432
44433 paths[ index ] = paths[ lastBindingsIndex ];
44434 paths.pop();
44435
44436 }
44437
44438 }
44439
44440 } );
44441
44442 function AnimationAction( mixer, clip, localRoot, blendMode ) {
44443
44444 this._mixer = mixer;
44445 this._clip = clip;
44446 this._localRoot = localRoot || null;
44447 this.blendMode = blendMode || clip.blendMode;
44448
44449 var tracks = clip.tracks,
44450 nTracks = tracks.length,
44451 interpolants = new Array( nTracks );
44452
44453 var interpolantSettings = {
44454 endingStart: ZeroCurvatureEnding,
44455 endingEnd: ZeroCurvatureEnding
44456 };
44457
44458 for ( var i = 0; i !== nTracks; ++ i ) {
44459
44460 var interpolant = tracks[ i ].createInterpolant( null );
44461 interpolants[ i ] = interpolant;
44462 interpolant.settings = interpolantSettings;
44463
44464 }
44465
44466 this._interpolantSettings = interpolantSettings;
44467
44468 this._interpolants = interpolants; // bound by the mixer
44469
44470 // inside: PropertyMixer (managed by the mixer)
44471 this._propertyBindings = new Array( nTracks );
44472
44473 this._cacheIndex = null; // for the memory manager
44474 this._byClipCacheIndex = null; // for the memory manager
44475
44476 this._timeScaleInterpolant = null;
44477 this._weightInterpolant = null;
44478
44479 this.loop = LoopRepeat;
44480 this._loopCount = - 1;
44481
44482 // global mixer time when the action is to be started
44483 // it's set back to 'null' upon start of the action
44484 this._startTime = null;
44485
44486 // scaled local time of the action
44487 // gets clamped or wrapped to 0..clip.duration according to loop
44488 this.time = 0;
44489
44490 this.timeScale = 1;
44491 this._effectiveTimeScale = 1;
44492
44493 this.weight = 1;
44494 this._effectiveWeight = 1;
44495
44496 this.repetitions = Infinity; // no. of repetitions when looping
44497
44498 this.paused = false; // true -> zero effective time scale
44499 this.enabled = true; // false -> zero effective weight
44500
44501 this.clampWhenFinished = false;// keep feeding the last frame?
44502
44503 this.zeroSlopeAtStart = true;// for smooth interpolation w/o separate
44504 this.zeroSlopeAtEnd = true;// clips for start, loop and end
44505
44506 }
44507
44508 Object.assign( AnimationAction.prototype, {
44509
44510 // State & Scheduling
44511
44512 play: function () {
44513
44514 this._mixer._activateAction( this );
44515
44516 return this;
44517
44518 },
44519
44520 stop: function () {
44521
44522 this._mixer._deactivateAction( this );
44523
44524 return this.reset();
44525
44526 },
44527
44528 reset: function () {
44529
44530 this.paused = false;
44531 this.enabled = true;
44532
44533 this.time = 0; // restart clip
44534 this._loopCount = - 1;// forget previous loops
44535 this._startTime = null;// forget scheduling
44536
44537 return this.stopFading().stopWarping();
44538
44539 },
44540
44541 isRunning: function () {
44542
44543 return this.enabled && ! this.paused && this.timeScale !== 0 &&
44544 this._startTime === null && this._mixer._isActiveAction( this );
44545
44546 },
44547
44548 // return true when play has been called
44549 isScheduled: function () {
44550
44551 return this._mixer._isActiveAction( this );
44552
44553 },
44554
44555 startAt: function ( time ) {
44556
44557 this._startTime = time;
44558
44559 return this;
44560
44561 },
44562
44563 setLoop: function ( mode, repetitions ) {
44564
44565 this.loop = mode;
44566 this.repetitions = repetitions;
44567
44568 return this;
44569
44570 },
44571
44572 // Weight
44573
44574 // set the weight stopping any scheduled fading
44575 // although .enabled = false yields an effective weight of zero, this
44576 // method does *not* change .enabled, because it would be confusing
44577 setEffectiveWeight: function ( weight ) {
44578
44579 this.weight = weight;
44580
44581 // note: same logic as when updated at runtime
44582 this._effectiveWeight = this.enabled ? weight : 0;
44583
44584 return this.stopFading();
44585
44586 },
44587
44588 // return the weight considering fading and .enabled
44589 getEffectiveWeight: function () {
44590
44591 return this._effectiveWeight;
44592
44593 },
44594
44595 fadeIn: function ( duration ) {
44596
44597 return this._scheduleFading( duration, 0, 1 );
44598
44599 },
44600
44601 fadeOut: function ( duration ) {
44602
44603 return this._scheduleFading( duration, 1, 0 );
44604
44605 },
44606
44607 crossFadeFrom: function ( fadeOutAction, duration, warp ) {
44608
44609 fadeOutAction.fadeOut( duration );
44610 this.fadeIn( duration );
44611
44612 if ( warp ) {
44613
44614 var fadeInDuration = this._clip.duration,
44615 fadeOutDuration = fadeOutAction._clip.duration,
44616
44617 startEndRatio = fadeOutDuration / fadeInDuration,
44618 endStartRatio = fadeInDuration / fadeOutDuration;
44619
44620 fadeOutAction.warp( 1.0, startEndRatio, duration );
44621 this.warp( endStartRatio, 1.0, duration );
44622
44623 }
44624
44625 return this;
44626
44627 },
44628
44629 crossFadeTo: function ( fadeInAction, duration, warp ) {
44630
44631 return fadeInAction.crossFadeFrom( this, duration, warp );
44632
44633 },
44634
44635 stopFading: function () {
44636
44637 var weightInterpolant = this._weightInterpolant;
44638
44639 if ( weightInterpolant !== null ) {
44640
44641 this._weightInterpolant = null;
44642 this._mixer._takeBackControlInterpolant( weightInterpolant );
44643
44644 }
44645
44646 return this;
44647
44648 },
44649
44650 // Time Scale Control
44651
44652 // set the time scale stopping any scheduled warping
44653 // although .paused = true yields an effective time scale of zero, this
44654 // method does *not* change .paused, because it would be confusing
44655 setEffectiveTimeScale: function ( timeScale ) {
44656
44657 this.timeScale = timeScale;
44658 this._effectiveTimeScale = this.paused ? 0 : timeScale;
44659
44660 return this.stopWarping();
44661
44662 },
44663
44664 // return the time scale considering warping and .paused
44665 getEffectiveTimeScale: function () {
44666
44667 return this._effectiveTimeScale;
44668
44669 },
44670
44671 setDuration: function ( duration ) {
44672
44673 this.timeScale = this._clip.duration / duration;
44674
44675 return this.stopWarping();
44676
44677 },
44678
44679 syncWith: function ( action ) {
44680
44681 this.time = action.time;
44682 this.timeScale = action.timeScale;
44683
44684 return this.stopWarping();
44685
44686 },
44687
44688 halt: function ( duration ) {
44689
44690 return this.warp( this._effectiveTimeScale, 0, duration );
44691
44692 },
44693
44694 warp: function ( startTimeScale, endTimeScale, duration ) {
44695
44696 var mixer = this._mixer,
44697 now = mixer.time,
44698 timeScale = this.timeScale;
44699
44700 var interpolant = this._timeScaleInterpolant;
44701
44702 if ( interpolant === null ) {
44703
44704 interpolant = mixer._lendControlInterpolant();
44705 this._timeScaleInterpolant = interpolant;
44706
44707 }
44708
44709 var times = interpolant.parameterPositions,
44710 values = interpolant.sampleValues;
44711
44712 times[ 0 ] = now;
44713 times[ 1 ] = now + duration;
44714
44715 values[ 0 ] = startTimeScale / timeScale;
44716 values[ 1 ] = endTimeScale / timeScale;
44717
44718 return this;
44719
44720 },
44721
44722 stopWarping: function () {
44723
44724 var timeScaleInterpolant = this._timeScaleInterpolant;
44725
44726 if ( timeScaleInterpolant !== null ) {
44727
44728 this._timeScaleInterpolant = null;
44729 this._mixer._takeBackControlInterpolant( timeScaleInterpolant );
44730
44731 }
44732
44733 return this;
44734
44735 },
44736
44737 // Object Accessors
44738
44739 getMixer: function () {
44740
44741 return this._mixer;
44742
44743 },
44744
44745 getClip: function () {
44746
44747 return this._clip;
44748
44749 },
44750
44751 getRoot: function () {
44752
44753 return this._localRoot || this._mixer._root;
44754
44755 },
44756
44757 // Interna
44758
44759 _update: function ( time, deltaTime, timeDirection, accuIndex ) {
44760
44761 // called by the mixer
44762
44763 if ( ! this.enabled ) {
44764
44765 // call ._updateWeight() to update ._effectiveWeight
44766
44767 this._updateWeight( time );
44768 return;
44769
44770 }
44771
44772 var startTime = this._startTime;
44773
44774 if ( startTime !== null ) {
44775
44776 // check for scheduled start of action
44777
44778 var timeRunning = ( time - startTime ) * timeDirection;
44779 if ( timeRunning < 0 || timeDirection === 0 ) {
44780
44781 return; // yet to come / don't decide when delta = 0
44782
44783 }
44784
44785 // start
44786
44787 this._startTime = null; // unschedule
44788 deltaTime = timeDirection * timeRunning;
44789
44790 }
44791
44792 // apply time scale and advance time
44793
44794 deltaTime *= this._updateTimeScale( time );
44795 var clipTime = this._updateTime( deltaTime );
44796
44797 // note: _updateTime may disable the action resulting in
44798 // an effective weight of 0
44799
44800 var weight = this._updateWeight( time );
44801
44802 if ( weight > 0 ) {
44803
44804 var interpolants = this._interpolants;
44805 var propertyMixers = this._propertyBindings;
44806
44807 switch ( this.blendMode ) {
44808
44809 case AdditiveAnimationBlendMode:
44810
44811 for ( var j = 0, m = interpolants.length; j !== m; ++ j ) {
44812
44813 interpolants[ j ].evaluate( clipTime );
44814 propertyMixers[ j ].accumulateAdditive( weight );
44815
44816 }
44817
44818 break;
44819
44820 case NormalAnimationBlendMode:
44821 default:
44822
44823 for ( var j$1 = 0, m$1 = interpolants.length; j$1 !== m$1; ++ j$1 ) {
44824
44825 interpolants[ j$1 ].evaluate( clipTime );
44826 propertyMixers[ j$1 ].accumulate( accuIndex, weight );
44827
44828 }
44829
44830 }
44831
44832 }
44833
44834 },
44835
44836 _updateWeight: function ( time ) {
44837
44838 var weight = 0;
44839
44840 if ( this.enabled ) {
44841
44842 weight = this.weight;
44843 var interpolant = this._weightInterpolant;
44844
44845 if ( interpolant !== null ) {
44846
44847 var interpolantValue = interpolant.evaluate( time )[ 0 ];
44848
44849 weight *= interpolantValue;
44850
44851 if ( time > interpolant.parameterPositions[ 1 ] ) {
44852
44853 this.stopFading();
44854
44855 if ( interpolantValue === 0 ) {
44856
44857 // faded out, disable
44858 this.enabled = false;
44859
44860 }
44861
44862 }
44863
44864 }
44865
44866 }
44867
44868 this._effectiveWeight = weight;
44869 return weight;
44870
44871 },
44872
44873 _updateTimeScale: function ( time ) {
44874
44875 var timeScale = 0;
44876
44877 if ( ! this.paused ) {
44878
44879 timeScale = this.timeScale;
44880
44881 var interpolant = this._timeScaleInterpolant;
44882
44883 if ( interpolant !== null ) {
44884
44885 var interpolantValue = interpolant.evaluate( time )[ 0 ];
44886
44887 timeScale *= interpolantValue;
44888
44889 if ( time > interpolant.parameterPositions[ 1 ] ) {
44890
44891 this.stopWarping();
44892
44893 if ( timeScale === 0 ) {
44894
44895 // motion has halted, pause
44896 this.paused = true;
44897
44898 } else {
44899
44900 // warp done - apply final time scale
44901 this.timeScale = timeScale;
44902
44903 }
44904
44905 }
44906
44907 }
44908
44909 }
44910
44911 this._effectiveTimeScale = timeScale;
44912 return timeScale;
44913
44914 },
44915
44916 _updateTime: function ( deltaTime ) {
44917
44918 var duration = this._clip.duration;
44919 var loop = this.loop;
44920
44921 var time = this.time + deltaTime;
44922 var loopCount = this._loopCount;
44923
44924 var pingPong = ( loop === LoopPingPong );
44925
44926 if ( deltaTime === 0 ) {
44927
44928 if ( loopCount === - 1 ) { return time; }
44929
44930 return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time;
44931
44932 }
44933
44934 if ( loop === LoopOnce ) {
44935
44936 if ( loopCount === - 1 ) {
44937
44938 // just started
44939
44940 this._loopCount = 0;
44941 this._setEndings( true, true, false );
44942
44943 }
44944
44945 handle_stop: {
44946
44947 if ( time >= duration ) {
44948
44949 time = duration;
44950
44951 } else if ( time < 0 ) {
44952
44953 time = 0;
44954
44955 } else {
44956
44957 this.time = time;
44958
44959 break handle_stop;
44960
44961 }
44962
44963 if ( this.clampWhenFinished ) { this.paused = true; }
44964 else { this.enabled = false; }
44965
44966 this.time = time;
44967
44968 this._mixer.dispatchEvent( {
44969 type: 'finished', action: this,
44970 direction: deltaTime < 0 ? - 1 : 1
44971 } );
44972
44973 }
44974
44975 } else { // repetitive Repeat or PingPong
44976
44977 if ( loopCount === - 1 ) {
44978
44979 // just started
44980
44981 if ( deltaTime >= 0 ) {
44982
44983 loopCount = 0;
44984
44985 this._setEndings( true, this.repetitions === 0, pingPong );
44986
44987 } else {
44988
44989 // when looping in reverse direction, the initial
44990 // transition through zero counts as a repetition,
44991 // so leave loopCount at -1
44992
44993 this._setEndings( this.repetitions === 0, true, pingPong );
44994
44995 }
44996
44997 }
44998
44999 if ( time >= duration || time < 0 ) {
45000
45001 // wrap around
45002
45003 var loopDelta = Math.floor( time / duration ); // signed
45004 time -= duration * loopDelta;
45005
45006 loopCount += Math.abs( loopDelta );
45007
45008 var pending = this.repetitions - loopCount;
45009
45010 if ( pending <= 0 ) {
45011
45012 // have to stop (switch state, clamp time, fire event)
45013
45014 if ( this.clampWhenFinished ) { this.paused = true; }
45015 else { this.enabled = false; }
45016
45017 time = deltaTime > 0 ? duration : 0;
45018
45019 this.time = time;
45020
45021 this._mixer.dispatchEvent( {
45022 type: 'finished', action: this,
45023 direction: deltaTime > 0 ? 1 : - 1
45024 } );
45025
45026 } else {
45027
45028 // keep running
45029
45030 if ( pending === 1 ) {
45031
45032 // entering the last round
45033
45034 var atStart = deltaTime < 0;
45035 this._setEndings( atStart, ! atStart, pingPong );
45036
45037 } else {
45038
45039 this._setEndings( false, false, pingPong );
45040
45041 }
45042
45043 this._loopCount = loopCount;
45044
45045 this.time = time;
45046
45047 this._mixer.dispatchEvent( {
45048 type: 'loop', action: this, loopDelta: loopDelta
45049 } );
45050
45051 }
45052
45053 } else {
45054
45055 this.time = time;
45056
45057 }
45058
45059 if ( pingPong && ( loopCount & 1 ) === 1 ) {
45060
45061 // invert time for the "pong round"
45062
45063 return duration - time;
45064
45065 }
45066
45067 }
45068
45069 return time;
45070
45071 },
45072
45073 _setEndings: function ( atStart, atEnd, pingPong ) {
45074
45075 var settings = this._interpolantSettings;
45076
45077 if ( pingPong ) {
45078
45079 settings.endingStart = ZeroSlopeEnding;
45080 settings.endingEnd = ZeroSlopeEnding;
45081
45082 } else {
45083
45084 // assuming for LoopOnce atStart == atEnd == true
45085
45086 if ( atStart ) {
45087
45088 settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
45089
45090 } else {
45091
45092 settings.endingStart = WrapAroundEnding;
45093
45094 }
45095
45096 if ( atEnd ) {
45097
45098 settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
45099
45100 } else {
45101
45102 settings.endingEnd = WrapAroundEnding;
45103
45104 }
45105
45106 }
45107
45108 },
45109
45110 _scheduleFading: function ( duration, weightNow, weightThen ) {
45111
45112 var mixer = this._mixer, now = mixer.time;
45113 var interpolant = this._weightInterpolant;
45114
45115 if ( interpolant === null ) {
45116
45117 interpolant = mixer._lendControlInterpolant();
45118 this._weightInterpolant = interpolant;
45119
45120 }
45121
45122 var times = interpolant.parameterPositions,
45123 values = interpolant.sampleValues;
45124
45125 times[ 0 ] = now;
45126 values[ 0 ] = weightNow;
45127 times[ 1 ] = now + duration;
45128 values[ 1 ] = weightThen;
45129
45130 return this;
45131
45132 }
45133
45134 } );
45135
45136 function AnimationMixer( root ) {
45137
45138 this._root = root;
45139 this._initMemoryManager();
45140 this._accuIndex = 0;
45141
45142 this.time = 0;
45143
45144 this.timeScale = 1.0;
45145
45146 }
45147
45148 AnimationMixer.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
45149
45150 constructor: AnimationMixer,
45151
45152 _bindAction: function ( action, prototypeAction ) {
45153
45154 var root = action._localRoot || this._root,
45155 tracks = action._clip.tracks,
45156 nTracks = tracks.length,
45157 bindings = action._propertyBindings,
45158 interpolants = action._interpolants,
45159 rootUuid = root.uuid,
45160 bindingsByRoot = this._bindingsByRootAndName;
45161
45162 var bindingsByName = bindingsByRoot[ rootUuid ];
45163
45164 if ( bindingsByName === undefined ) {
45165
45166 bindingsByName = {};
45167 bindingsByRoot[ rootUuid ] = bindingsByName;
45168
45169 }
45170
45171 for ( var i = 0; i !== nTracks; ++ i ) {
45172
45173 var track = tracks[ i ],
45174 trackName = track.name;
45175
45176 var binding = bindingsByName[ trackName ];
45177
45178 if ( binding !== undefined ) {
45179
45180 bindings[ i ] = binding;
45181
45182 } else {
45183
45184 binding = bindings[ i ];
45185
45186 if ( binding !== undefined ) {
45187
45188 // existing binding, make sure the cache knows
45189
45190 if ( binding._cacheIndex === null ) {
45191
45192 ++ binding.referenceCount;
45193 this._addInactiveBinding( binding, rootUuid, trackName );
45194
45195 }
45196
45197 continue;
45198
45199 }
45200
45201 var path = prototypeAction && prototypeAction.
45202 _propertyBindings[ i ].binding.parsedPath;
45203
45204 binding = new PropertyMixer(
45205 PropertyBinding.create( root, trackName, path ),
45206 track.ValueTypeName, track.getValueSize() );
45207
45208 ++ binding.referenceCount;
45209 this._addInactiveBinding( binding, rootUuid, trackName );
45210
45211 bindings[ i ] = binding;
45212
45213 }
45214
45215 interpolants[ i ].resultBuffer = binding.buffer;
45216
45217 }
45218
45219 },
45220
45221 _activateAction: function ( action ) {
45222
45223 if ( ! this._isActiveAction( action ) ) {
45224
45225 if ( action._cacheIndex === null ) {
45226
45227 // this action has been forgotten by the cache, but the user
45228 // appears to be still using it -> rebind
45229
45230 var rootUuid = ( action._localRoot || this._root ).uuid,
45231 clipUuid = action._clip.uuid,
45232 actionsForClip = this._actionsByClip[ clipUuid ];
45233
45234 this._bindAction( action,
45235 actionsForClip && actionsForClip.knownActions[ 0 ] );
45236
45237 this._addInactiveAction( action, clipUuid, rootUuid );
45238
45239 }
45240
45241 var bindings = action._propertyBindings;
45242
45243 // increment reference counts / sort out state
45244 for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
45245
45246 var binding = bindings[ i ];
45247
45248 if ( binding.useCount ++ === 0 ) {
45249
45250 this._lendBinding( binding );
45251 binding.saveOriginalState();
45252
45253 }
45254
45255 }
45256
45257 this._lendAction( action );
45258
45259 }
45260
45261 },
45262
45263 _deactivateAction: function ( action ) {
45264
45265 if ( this._isActiveAction( action ) ) {
45266
45267 var bindings = action._propertyBindings;
45268
45269 // decrement reference counts / sort out state
45270 for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
45271
45272 var binding = bindings[ i ];
45273
45274 if ( -- binding.useCount === 0 ) {
45275
45276 binding.restoreOriginalState();
45277 this._takeBackBinding( binding );
45278
45279 }
45280
45281 }
45282
45283 this._takeBackAction( action );
45284
45285 }
45286
45287 },
45288
45289 // Memory manager
45290
45291 _initMemoryManager: function () {
45292
45293 this._actions = []; // 'nActiveActions' followed by inactive ones
45294 this._nActiveActions = 0;
45295
45296 this._actionsByClip = {};
45297 // inside:
45298 // {
45299 // knownActions: Array< AnimationAction > - used as prototypes
45300 // actionByRoot: AnimationAction - lookup
45301 // }
45302
45303
45304 this._bindings = []; // 'nActiveBindings' followed by inactive ones
45305 this._nActiveBindings = 0;
45306
45307 this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
45308
45309
45310 this._controlInterpolants = []; // same game as above
45311 this._nActiveControlInterpolants = 0;
45312
45313 var scope = this;
45314
45315 this.stats = {
45316
45317 actions: {
45318 get total() {
45319
45320 return scope._actions.length;
45321
45322 },
45323 get inUse() {
45324
45325 return scope._nActiveActions;
45326
45327 }
45328 },
45329 bindings: {
45330 get total() {
45331
45332 return scope._bindings.length;
45333
45334 },
45335 get inUse() {
45336
45337 return scope._nActiveBindings;
45338
45339 }
45340 },
45341 controlInterpolants: {
45342 get total() {
45343
45344 return scope._controlInterpolants.length;
45345
45346 },
45347 get inUse() {
45348
45349 return scope._nActiveControlInterpolants;
45350
45351 }
45352 }
45353
45354 };
45355
45356 },
45357
45358 // Memory management for AnimationAction objects
45359
45360 _isActiveAction: function ( action ) {
45361
45362 var index = action._cacheIndex;
45363 return index !== null && index < this._nActiveActions;
45364
45365 },
45366
45367 _addInactiveAction: function ( action, clipUuid, rootUuid ) {
45368
45369 var actions = this._actions,
45370 actionsByClip = this._actionsByClip;
45371
45372 var actionsForClip = actionsByClip[ clipUuid ];
45373
45374 if ( actionsForClip === undefined ) {
45375
45376 actionsForClip = {
45377
45378 knownActions: [ action ],
45379 actionByRoot: {}
45380
45381 };
45382
45383 action._byClipCacheIndex = 0;
45384
45385 actionsByClip[ clipUuid ] = actionsForClip;
45386
45387 } else {
45388
45389 var knownActions = actionsForClip.knownActions;
45390
45391 action._byClipCacheIndex = knownActions.length;
45392 knownActions.push( action );
45393
45394 }
45395
45396 action._cacheIndex = actions.length;
45397 actions.push( action );
45398
45399 actionsForClip.actionByRoot[ rootUuid ] = action;
45400
45401 },
45402
45403 _removeInactiveAction: function ( action ) {
45404
45405 var actions = this._actions,
45406 lastInactiveAction = actions[ actions.length - 1 ],
45407 cacheIndex = action._cacheIndex;
45408
45409 lastInactiveAction._cacheIndex = cacheIndex;
45410 actions[ cacheIndex ] = lastInactiveAction;
45411 actions.pop();
45412
45413 action._cacheIndex = null;
45414
45415
45416 var clipUuid = action._clip.uuid,
45417 actionsByClip = this._actionsByClip,
45418 actionsForClip = actionsByClip[ clipUuid ],
45419 knownActionsForClip = actionsForClip.knownActions,
45420
45421 lastKnownAction =
45422 knownActionsForClip[ knownActionsForClip.length - 1 ],
45423
45424 byClipCacheIndex = action._byClipCacheIndex;
45425
45426 lastKnownAction._byClipCacheIndex = byClipCacheIndex;
45427 knownActionsForClip[ byClipCacheIndex ] = lastKnownAction;
45428 knownActionsForClip.pop();
45429
45430 action._byClipCacheIndex = null;
45431
45432
45433 var actionByRoot = actionsForClip.actionByRoot,
45434 rootUuid = ( action._localRoot || this._root ).uuid;
45435
45436 delete actionByRoot[ rootUuid ];
45437
45438 if ( knownActionsForClip.length === 0 ) {
45439
45440 delete actionsByClip[ clipUuid ];
45441
45442 }
45443
45444 this._removeInactiveBindingsForAction( action );
45445
45446 },
45447
45448 _removeInactiveBindingsForAction: function ( action ) {
45449
45450 var bindings = action._propertyBindings;
45451
45452 for ( var i = 0, n = bindings.length; i !== n; ++ i ) {
45453
45454 var binding = bindings[ i ];
45455
45456 if ( -- binding.referenceCount === 0 ) {
45457
45458 this._removeInactiveBinding( binding );
45459
45460 }
45461
45462 }
45463
45464 },
45465
45466 _lendAction: function ( action ) {
45467
45468 // [ active actions | inactive actions ]
45469 // [ active actions >| inactive actions ]
45470 // s a
45471 // <-swap->
45472 // a s
45473
45474 var actions = this._actions,
45475 prevIndex = action._cacheIndex,
45476
45477 lastActiveIndex = this._nActiveActions ++,
45478
45479 firstInactiveAction = actions[ lastActiveIndex ];
45480
45481 action._cacheIndex = lastActiveIndex;
45482 actions[ lastActiveIndex ] = action;
45483
45484 firstInactiveAction._cacheIndex = prevIndex;
45485 actions[ prevIndex ] = firstInactiveAction;
45486
45487 },
45488
45489 _takeBackAction: function ( action ) {
45490
45491 // [ active actions | inactive actions ]
45492 // [ active actions |< inactive actions ]
45493 // a s
45494 // <-swap->
45495 // s a
45496
45497 var actions = this._actions,
45498 prevIndex = action._cacheIndex,
45499
45500 firstInactiveIndex = -- this._nActiveActions,
45501
45502 lastActiveAction = actions[ firstInactiveIndex ];
45503
45504 action._cacheIndex = firstInactiveIndex;
45505 actions[ firstInactiveIndex ] = action;
45506
45507 lastActiveAction._cacheIndex = prevIndex;
45508 actions[ prevIndex ] = lastActiveAction;
45509
45510 },
45511
45512 // Memory management for PropertyMixer objects
45513
45514 _addInactiveBinding: function ( binding, rootUuid, trackName ) {
45515
45516 var bindingsByRoot = this._bindingsByRootAndName,
45517 bindings = this._bindings;
45518
45519 var bindingByName = bindingsByRoot[ rootUuid ];
45520
45521 if ( bindingByName === undefined ) {
45522
45523 bindingByName = {};
45524 bindingsByRoot[ rootUuid ] = bindingByName;
45525
45526 }
45527
45528 bindingByName[ trackName ] = binding;
45529
45530 binding._cacheIndex = bindings.length;
45531 bindings.push( binding );
45532
45533 },
45534
45535 _removeInactiveBinding: function ( binding ) {
45536
45537 var bindings = this._bindings,
45538 propBinding = binding.binding,
45539 rootUuid = propBinding.rootNode.uuid,
45540 trackName = propBinding.path,
45541 bindingsByRoot = this._bindingsByRootAndName,
45542 bindingByName = bindingsByRoot[ rootUuid ],
45543
45544 lastInactiveBinding = bindings[ bindings.length - 1 ],
45545 cacheIndex = binding._cacheIndex;
45546
45547 lastInactiveBinding._cacheIndex = cacheIndex;
45548 bindings[ cacheIndex ] = lastInactiveBinding;
45549 bindings.pop();
45550
45551 delete bindingByName[ trackName ];
45552
45553 if ( Object.keys( bindingByName ).length === 0 ) {
45554
45555 delete bindingsByRoot[ rootUuid ];
45556
45557 }
45558
45559 },
45560
45561 _lendBinding: function ( binding ) {
45562
45563 var bindings = this._bindings,
45564 prevIndex = binding._cacheIndex,
45565
45566 lastActiveIndex = this._nActiveBindings ++,
45567
45568 firstInactiveBinding = bindings[ lastActiveIndex ];
45569
45570 binding._cacheIndex = lastActiveIndex;
45571 bindings[ lastActiveIndex ] = binding;
45572
45573 firstInactiveBinding._cacheIndex = prevIndex;
45574 bindings[ prevIndex ] = firstInactiveBinding;
45575
45576 },
45577
45578 _takeBackBinding: function ( binding ) {
45579
45580 var bindings = this._bindings,
45581 prevIndex = binding._cacheIndex,
45582
45583 firstInactiveIndex = -- this._nActiveBindings,
45584
45585 lastActiveBinding = bindings[ firstInactiveIndex ];
45586
45587 binding._cacheIndex = firstInactiveIndex;
45588 bindings[ firstInactiveIndex ] = binding;
45589
45590 lastActiveBinding._cacheIndex = prevIndex;
45591 bindings[ prevIndex ] = lastActiveBinding;
45592
45593 },
45594
45595
45596 // Memory management of Interpolants for weight and time scale
45597
45598 _lendControlInterpolant: function () {
45599
45600 var interpolants = this._controlInterpolants,
45601 lastActiveIndex = this._nActiveControlInterpolants ++;
45602
45603 var interpolant = interpolants[ lastActiveIndex ];
45604
45605 if ( interpolant === undefined ) {
45606
45607 interpolant = new LinearInterpolant(
45608 new Float32Array( 2 ), new Float32Array( 2 ),
45609 1, this._controlInterpolantsResultBuffer );
45610
45611 interpolant.__cacheIndex = lastActiveIndex;
45612 interpolants[ lastActiveIndex ] = interpolant;
45613
45614 }
45615
45616 return interpolant;
45617
45618 },
45619
45620 _takeBackControlInterpolant: function ( interpolant ) {
45621
45622 var interpolants = this._controlInterpolants,
45623 prevIndex = interpolant.__cacheIndex,
45624
45625 firstInactiveIndex = -- this._nActiveControlInterpolants,
45626
45627 lastActiveInterpolant = interpolants[ firstInactiveIndex ];
45628
45629 interpolant.__cacheIndex = firstInactiveIndex;
45630 interpolants[ firstInactiveIndex ] = interpolant;
45631
45632 lastActiveInterpolant.__cacheIndex = prevIndex;
45633 interpolants[ prevIndex ] = lastActiveInterpolant;
45634
45635 },
45636
45637 _controlInterpolantsResultBuffer: new Float32Array( 1 ),
45638
45639 // return an action for a clip optionally using a custom root target
45640 // object (this method allocates a lot of dynamic memory in case a
45641 // previously unknown clip/root combination is specified)
45642 clipAction: function ( clip, optionalRoot, blendMode ) {
45643
45644 var root = optionalRoot || this._root,
45645 rootUuid = root.uuid;
45646
45647 var clipObject = typeof clip === 'string' ? AnimationClip.findByName( root, clip ) : clip;
45648
45649 var clipUuid = clipObject !== null ? clipObject.uuid : clip;
45650
45651 var actionsForClip = this._actionsByClip[ clipUuid ],
45652 prototypeAction = null;
45653
45654 if ( blendMode === undefined ) {
45655
45656 if ( clipObject !== null ) {
45657
45658 blendMode = clipObject.blendMode;
45659
45660 } else {
45661
45662 blendMode = NormalAnimationBlendMode;
45663
45664 }
45665
45666 }
45667
45668 if ( actionsForClip !== undefined ) {
45669
45670 var existingAction = actionsForClip.actionByRoot[ rootUuid ];
45671
45672 if ( existingAction !== undefined && existingAction.blendMode === blendMode ) {
45673
45674 return existingAction;
45675
45676 }
45677
45678 // we know the clip, so we don't have to parse all
45679 // the bindings again but can just copy
45680 prototypeAction = actionsForClip.knownActions[ 0 ];
45681
45682 // also, take the clip from the prototype action
45683 if ( clipObject === null )
45684 { clipObject = prototypeAction._clip; }
45685
45686 }
45687
45688 // clip must be known when specified via string
45689 if ( clipObject === null ) { return null; }
45690
45691 // allocate all resources required to run it
45692 var newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode );
45693
45694 this._bindAction( newAction, prototypeAction );
45695
45696 // and make the action known to the memory manager
45697 this._addInactiveAction( newAction, clipUuid, rootUuid );
45698
45699 return newAction;
45700
45701 },
45702
45703 // get an existing action
45704 existingAction: function ( clip, optionalRoot ) {
45705
45706 var root = optionalRoot || this._root,
45707 rootUuid = root.uuid,
45708
45709 clipObject = typeof clip === 'string' ?
45710 AnimationClip.findByName( root, clip ) : clip,
45711
45712 clipUuid = clipObject ? clipObject.uuid : clip,
45713
45714 actionsForClip = this._actionsByClip[ clipUuid ];
45715
45716 if ( actionsForClip !== undefined ) {
45717
45718 return actionsForClip.actionByRoot[ rootUuid ] || null;
45719
45720 }
45721
45722 return null;
45723
45724 },
45725
45726 // deactivates all previously scheduled actions
45727 stopAllAction: function () {
45728
45729 var actions = this._actions,
45730 nActions = this._nActiveActions;
45731
45732 for ( var i = nActions - 1; i >= 0; -- i ) {
45733
45734 actions[ i ].stop();
45735
45736 }
45737
45738 return this;
45739
45740 },
45741
45742 // advance the time and update apply the animation
45743 update: function ( deltaTime ) {
45744
45745 deltaTime *= this.timeScale;
45746
45747 var actions = this._actions,
45748 nActions = this._nActiveActions,
45749
45750 time = this.time += deltaTime,
45751 timeDirection = Math.sign( deltaTime ),
45752
45753 accuIndex = this._accuIndex ^= 1;
45754
45755 // run active actions
45756
45757 for ( var i = 0; i !== nActions; ++ i ) {
45758
45759 var action = actions[ i ];
45760
45761 action._update( time, deltaTime, timeDirection, accuIndex );
45762
45763 }
45764
45765 // update scene graph
45766
45767 var bindings = this._bindings,
45768 nBindings = this._nActiveBindings;
45769
45770 for ( var i$1 = 0; i$1 !== nBindings; ++ i$1 ) {
45771
45772 bindings[ i$1 ].apply( accuIndex );
45773
45774 }
45775
45776 return this;
45777
45778 },
45779
45780 // Allows you to seek to a specific time in an animation.
45781 setTime: function ( timeInSeconds ) {
45782
45783 this.time = 0; // Zero out time attribute for AnimationMixer object;
45784 for ( var i = 0; i < this._actions.length; i ++ ) {
45785
45786 this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects.
45787
45788 }
45789
45790 return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object.
45791
45792 },
45793
45794 // return this mixer's root target object
45795 getRoot: function () {
45796
45797 return this._root;
45798
45799 },
45800
45801 // free all resources specific to a particular clip
45802 uncacheClip: function ( clip ) {
45803
45804 var actions = this._actions,
45805 clipUuid = clip.uuid,
45806 actionsByClip = this._actionsByClip,
45807 actionsForClip = actionsByClip[ clipUuid ];
45808
45809 if ( actionsForClip !== undefined ) {
45810
45811 // note: just calling _removeInactiveAction would mess up the
45812 // iteration state and also require updating the state we can
45813 // just throw away
45814
45815 var actionsToRemove = actionsForClip.knownActions;
45816
45817 for ( var i = 0, n = actionsToRemove.length; i !== n; ++ i ) {
45818
45819 var action = actionsToRemove[ i ];
45820
45821 this._deactivateAction( action );
45822
45823 var cacheIndex = action._cacheIndex,
45824 lastInactiveAction = actions[ actions.length - 1 ];
45825
45826 action._cacheIndex = null;
45827 action._byClipCacheIndex = null;
45828
45829 lastInactiveAction._cacheIndex = cacheIndex;
45830 actions[ cacheIndex ] = lastInactiveAction;
45831 actions.pop();
45832
45833 this._removeInactiveBindingsForAction( action );
45834
45835 }
45836
45837 delete actionsByClip[ clipUuid ];
45838
45839 }
45840
45841 },
45842
45843 // free all resources specific to a particular root target object
45844 uncacheRoot: function ( root ) {
45845
45846 var rootUuid = root.uuid,
45847 actionsByClip = this._actionsByClip;
45848
45849 for ( var clipUuid in actionsByClip ) {
45850
45851 var actionByRoot = actionsByClip[ clipUuid ].actionByRoot,
45852 action = actionByRoot[ rootUuid ];
45853
45854 if ( action !== undefined ) {
45855
45856 this._deactivateAction( action );
45857 this._removeInactiveAction( action );
45858
45859 }
45860
45861 }
45862
45863 var bindingsByRoot = this._bindingsByRootAndName,
45864 bindingByName = bindingsByRoot[ rootUuid ];
45865
45866 if ( bindingByName !== undefined ) {
45867
45868 for ( var trackName in bindingByName ) {
45869
45870 var binding = bindingByName[ trackName ];
45871 binding.restoreOriginalState();
45872 this._removeInactiveBinding( binding );
45873
45874 }
45875
45876 }
45877
45878 },
45879
45880 // remove a targeted clip from the cache
45881 uncacheAction: function ( clip, optionalRoot ) {
45882
45883 var action = this.existingAction( clip, optionalRoot );
45884
45885 if ( action !== null ) {
45886
45887 this._deactivateAction( action );
45888 this._removeInactiveAction( action );
45889
45890 }
45891
45892 }
45893
45894 } );
45895
45896 function Uniform( value ) {
45897
45898 if ( typeof value === 'string' ) {
45899
45900 console.warn( 'THREE.Uniform: Type parameter is no longer needed.' );
45901 value = arguments[ 1 ];
45902
45903 }
45904
45905 this.value = value;
45906
45907 }
45908
45909 Uniform.prototype.clone = function () {
45910
45911 return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );
45912
45913 };
45914
45915 function InstancedInterleavedBuffer( array, stride, meshPerAttribute ) {
45916
45917 InterleavedBuffer.call( this, array, stride );
45918
45919 this.meshPerAttribute = meshPerAttribute || 1;
45920
45921 }
45922
45923 InstancedInterleavedBuffer.prototype = Object.assign( Object.create( InterleavedBuffer.prototype ), {
45924
45925 constructor: InstancedInterleavedBuffer,
45926
45927 isInstancedInterleavedBuffer: true,
45928
45929 copy: function ( source ) {
45930
45931 InterleavedBuffer.prototype.copy.call( this, source );
45932
45933 this.meshPerAttribute = source.meshPerAttribute;
45934
45935 return this;
45936
45937 },
45938
45939 clone: function ( data ) {
45940
45941 var ib = InterleavedBuffer.prototype.clone.call( this, data );
45942
45943 ib.meshPerAttribute = this.meshPerAttribute;
45944
45945 return ib;
45946
45947 },
45948
45949 toJSON: function ( data ) {
45950
45951 var json = InterleavedBuffer.prototype.toJSON.call( this, data );
45952
45953 json.isInstancedInterleavedBuffer = true;
45954 json.meshPerAttribute = this.meshPerAttribute;
45955
45956 return json;
45957
45958 }
45959
45960 } );
45961
45962 function Raycaster( origin, direction, near, far ) {
45963
45964 this.ray = new Ray( origin, direction );
45965 // direction is assumed to be normalized (for accurate distance calculations)
45966
45967 this.near = near || 0;
45968 this.far = far || Infinity;
45969 this.camera = null;
45970 this.layers = new Layers();
45971
45972 this.params = {
45973 Mesh: {},
45974 Line: { threshold: 1 },
45975 LOD: {},
45976 Points: { threshold: 1 },
45977 Sprite: {}
45978 };
45979
45980 Object.defineProperties( this.params, {
45981 PointCloud: {
45982 get: function () {
45983
45984 console.warn( 'THREE.Raycaster: params.PointCloud has been renamed to params.Points.' );
45985 return this.Points;
45986
45987 }
45988 }
45989 } );
45990
45991 }
45992
45993 function ascSort( a, b ) {
45994
45995 return a.distance - b.distance;
45996
45997 }
45998
45999 function intersectObject( object, raycaster, intersects, recursive ) {
46000
46001 if ( object.layers.test( raycaster.layers ) ) {
46002
46003 object.raycast( raycaster, intersects );
46004
46005 }
46006
46007 if ( recursive === true ) {
46008
46009 var children = object.children;
46010
46011 for ( var i = 0, l = children.length; i < l; i ++ ) {
46012
46013 intersectObject( children[ i ], raycaster, intersects, true );
46014
46015 }
46016
46017 }
46018
46019 }
46020
46021 Object.assign( Raycaster.prototype, {
46022
46023 set: function ( origin, direction ) {
46024
46025 // direction is assumed to be normalized (for accurate distance calculations)
46026
46027 this.ray.set( origin, direction );
46028
46029 },
46030
46031 setFromCamera: function ( coords, camera ) {
46032
46033 if ( ( camera && camera.isPerspectiveCamera ) ) {
46034
46035 this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
46036 this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
46037 this.camera = camera;
46038
46039 } else if ( ( camera && camera.isOrthographicCamera ) ) {
46040
46041 this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
46042 this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
46043 this.camera = camera;
46044
46045 } else {
46046
46047 console.error( 'THREE.Raycaster: Unsupported camera type.' );
46048
46049 }
46050
46051 },
46052
46053 intersectObject: function ( object, recursive, optionalTarget ) {
46054
46055 var intersects = optionalTarget || [];
46056
46057 intersectObject( object, this, intersects, recursive );
46058
46059 intersects.sort( ascSort );
46060
46061 return intersects;
46062
46063 },
46064
46065 intersectObjects: function ( objects, recursive, optionalTarget ) {
46066
46067 var intersects = optionalTarget || [];
46068
46069 if ( Array.isArray( objects ) === false ) {
46070
46071 console.warn( 'THREE.Raycaster.intersectObjects: objects is not an Array.' );
46072 return intersects;
46073
46074 }
46075
46076 for ( var i = 0, l = objects.length; i < l; i ++ ) {
46077
46078 intersectObject( objects[ i ], this, intersects, recursive );
46079
46080 }
46081
46082 intersects.sort( ascSort );
46083
46084 return intersects;
46085
46086 }
46087
46088 } );
46089
46090 /**
46091 * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system
46092 *
46093 * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up.
46094 * The azimuthal angle (theta) is measured from the positive z-axis.
46095 */
46096
46097 var Spherical = function Spherical( radius, phi, theta ) {
46098 if ( radius === void 0 ) radius = 1;
46099 if ( phi === void 0 ) phi = 0;
46100 if ( theta === void 0 ) theta = 0;
46101
46102
46103 this.radius = radius;
46104 this.phi = phi; // polar angle
46105 this.theta = theta; // azimuthal angle
46106
46107 return this;
46108
46109 };
46110
46111 Spherical.prototype.set = function set ( radius, phi, theta ) {
46112
46113 this.radius = radius;
46114 this.phi = phi;
46115 this.theta = theta;
46116
46117 return this;
46118
46119 };
46120
46121 Spherical.prototype.clone = function clone () {
46122
46123 return new this.constructor().copy( this );
46124
46125 };
46126
46127 Spherical.prototype.copy = function copy ( other ) {
46128
46129 this.radius = other.radius;
46130 this.phi = other.phi;
46131 this.theta = other.theta;
46132
46133 return this;
46134
46135 };
46136
46137 // restrict phi to be betwee EPS and PI-EPS
46138 Spherical.prototype.makeSafe = function makeSafe () {
46139
46140 var EPS = 0.000001;
46141 this.phi = Math.max( EPS, Math.min( Math.PI - EPS, this.phi ) );
46142
46143 return this;
46144
46145 };
46146
46147 Spherical.prototype.setFromVector3 = function setFromVector3 ( v ) {
46148
46149 return this.setFromCartesianCoords( v.x, v.y, v.z );
46150
46151 };
46152
46153 Spherical.prototype.setFromCartesianCoords = function setFromCartesianCoords ( x, y, z ) {
46154
46155 this.radius = Math.sqrt( x * x + y * y + z * z );
46156
46157 if ( this.radius === 0 ) {
46158
46159 this.theta = 0;
46160 this.phi = 0;
46161
46162 } else {
46163
46164 this.theta = Math.atan2( x, z );
46165 this.phi = Math.acos( MathUtils.clamp( y / this.radius, - 1, 1 ) );
46166
46167 }
46168
46169 return this;
46170
46171 };
46172
46173 /**
46174 * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system
46175 */
46176
46177 function Cylindrical( radius, theta, y ) {
46178
46179 this.radius = ( radius !== undefined ) ? radius : 1.0; // distance from the origin to a point in the x-z plane
46180 this.theta = ( theta !== undefined ) ? theta : 0; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis
46181 this.y = ( y !== undefined ) ? y : 0; // height above the x-z plane
46182
46183 return this;
46184
46185 }
46186
46187 Object.assign( Cylindrical.prototype, {
46188
46189 set: function ( radius, theta, y ) {
46190
46191 this.radius = radius;
46192 this.theta = theta;
46193 this.y = y;
46194
46195 return this;
46196
46197 },
46198
46199 clone: function () {
46200
46201 return new this.constructor().copy( this );
46202
46203 },
46204
46205 copy: function ( other ) {
46206
46207 this.radius = other.radius;
46208 this.theta = other.theta;
46209 this.y = other.y;
46210
46211 return this;
46212
46213 },
46214
46215 setFromVector3: function ( v ) {
46216
46217 return this.setFromCartesianCoords( v.x, v.y, v.z );
46218
46219 },
46220
46221 setFromCartesianCoords: function ( x, y, z ) {
46222
46223 this.radius = Math.sqrt( x * x + z * z );
46224 this.theta = Math.atan2( x, z );
46225 this.y = y;
46226
46227 return this;
46228
46229 }
46230
46231 } );
46232
46233 var _vector$7 = new Vector2();
46234
46235 function Box2( min, max ) {
46236
46237 this.min = ( min !== undefined ) ? min : new Vector2( + Infinity, + Infinity );
46238 this.max = ( max !== undefined ) ? max : new Vector2( - Infinity, - Infinity );
46239
46240 }
46241
46242 Object.assign( Box2.prototype, {
46243
46244 set: function ( min, max ) {
46245
46246 this.min.copy( min );
46247 this.max.copy( max );
46248
46249 return this;
46250
46251 },
46252
46253 setFromPoints: function ( points ) {
46254
46255 this.makeEmpty();
46256
46257 for ( var i = 0, il = points.length; i < il; i ++ ) {
46258
46259 this.expandByPoint( points[ i ] );
46260
46261 }
46262
46263 return this;
46264
46265 },
46266
46267 setFromCenterAndSize: function ( center, size ) {
46268
46269 var halfSize = _vector$7.copy( size ).multiplyScalar( 0.5 );
46270 this.min.copy( center ).sub( halfSize );
46271 this.max.copy( center ).add( halfSize );
46272
46273 return this;
46274
46275 },
46276
46277 clone: function () {
46278
46279 return new this.constructor().copy( this );
46280
46281 },
46282
46283 copy: function ( box ) {
46284
46285 this.min.copy( box.min );
46286 this.max.copy( box.max );
46287
46288 return this;
46289
46290 },
46291
46292 makeEmpty: function () {
46293
46294 this.min.x = this.min.y = + Infinity;
46295 this.max.x = this.max.y = - Infinity;
46296
46297 return this;
46298
46299 },
46300
46301 isEmpty: function () {
46302
46303 // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
46304
46305 return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y );
46306
46307 },
46308
46309 getCenter: function ( target ) {
46310
46311 if ( target === undefined ) {
46312
46313 console.warn( 'THREE.Box2: .getCenter() target is now required' );
46314 target = new Vector2();
46315
46316 }
46317
46318 return this.isEmpty() ? target.set( 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 );
46319
46320 },
46321
46322 getSize: function ( target ) {
46323
46324 if ( target === undefined ) {
46325
46326 console.warn( 'THREE.Box2: .getSize() target is now required' );
46327 target = new Vector2();
46328
46329 }
46330
46331 return this.isEmpty() ? target.set( 0, 0 ) : target.subVectors( this.max, this.min );
46332
46333 },
46334
46335 expandByPoint: function ( point ) {
46336
46337 this.min.min( point );
46338 this.max.max( point );
46339
46340 return this;
46341
46342 },
46343
46344 expandByVector: function ( vector ) {
46345
46346 this.min.sub( vector );
46347 this.max.add( vector );
46348
46349 return this;
46350
46351 },
46352
46353 expandByScalar: function ( scalar ) {
46354
46355 this.min.addScalar( - scalar );
46356 this.max.addScalar( scalar );
46357
46358 return this;
46359
46360 },
46361
46362 containsPoint: function ( point ) {
46363
46364 return point.x < this.min.x || point.x > this.max.x ||
46365 point.y < this.min.y || point.y > this.max.y ? false : true;
46366
46367 },
46368
46369 containsBox: function ( box ) {
46370
46371 return this.min.x <= box.min.x && box.max.x <= this.max.x &&
46372 this.min.y <= box.min.y && box.max.y <= this.max.y;
46373
46374 },
46375
46376 getParameter: function ( point, target ) {
46377
46378 // This can potentially have a divide by zero if the box
46379 // has a size dimension of 0.
46380
46381 if ( target === undefined ) {
46382
46383 console.warn( 'THREE.Box2: .getParameter() target is now required' );
46384 target = new Vector2();
46385
46386 }
46387
46388 return target.set(
46389 ( point.x - this.min.x ) / ( this.max.x - this.min.x ),
46390 ( point.y - this.min.y ) / ( this.max.y - this.min.y )
46391 );
46392
46393 },
46394
46395 intersectsBox: function ( box ) {
46396
46397 // using 4 splitting planes to rule out intersections
46398
46399 return box.max.x < this.min.x || box.min.x > this.max.x ||
46400 box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
46401
46402 },
46403
46404 clampPoint: function ( point, target ) {
46405
46406 if ( target === undefined ) {
46407
46408 console.warn( 'THREE.Box2: .clampPoint() target is now required' );
46409 target = new Vector2();
46410
46411 }
46412
46413 return target.copy( point ).clamp( this.min, this.max );
46414
46415 },
46416
46417 distanceToPoint: function ( point ) {
46418
46419 var clampedPoint = _vector$7.copy( point ).clamp( this.min, this.max );
46420 return clampedPoint.sub( point ).length();
46421
46422 },
46423
46424 intersect: function ( box ) {
46425
46426 this.min.max( box.min );
46427 this.max.min( box.max );
46428
46429 return this;
46430
46431 },
46432
46433 union: function ( box ) {
46434
46435 this.min.min( box.min );
46436 this.max.max( box.max );
46437
46438 return this;
46439
46440 },
46441
46442 translate: function ( offset ) {
46443
46444 this.min.add( offset );
46445 this.max.add( offset );
46446
46447 return this;
46448
46449 },
46450
46451 equals: function ( box ) {
46452
46453 return box.min.equals( this.min ) && box.max.equals( this.max );
46454
46455 }
46456
46457 } );
46458
46459 var _startP = new Vector3();
46460 var _startEnd = new Vector3();
46461
46462 function Line3( start, end ) {
46463
46464 this.start = ( start !== undefined ) ? start : new Vector3();
46465 this.end = ( end !== undefined ) ? end : new Vector3();
46466
46467 }
46468
46469 Object.assign( Line3.prototype, {
46470
46471 set: function ( start, end ) {
46472
46473 this.start.copy( start );
46474 this.end.copy( end );
46475
46476 return this;
46477
46478 },
46479
46480 clone: function () {
46481
46482 return new this.constructor().copy( this );
46483
46484 },
46485
46486 copy: function ( line ) {
46487
46488 this.start.copy( line.start );
46489 this.end.copy( line.end );
46490
46491 return this;
46492
46493 },
46494
46495 getCenter: function ( target ) {
46496
46497 if ( target === undefined ) {
46498
46499 console.warn( 'THREE.Line3: .getCenter() target is now required' );
46500 target = new Vector3();
46501
46502 }
46503
46504 return target.addVectors( this.start, this.end ).multiplyScalar( 0.5 );
46505
46506 },
46507
46508 delta: function ( target ) {
46509
46510 if ( target === undefined ) {
46511
46512 console.warn( 'THREE.Line3: .delta() target is now required' );
46513 target = new Vector3();
46514
46515 }
46516
46517 return target.subVectors( this.end, this.start );
46518
46519 },
46520
46521 distanceSq: function () {
46522
46523 return this.start.distanceToSquared( this.end );
46524
46525 },
46526
46527 distance: function () {
46528
46529 return this.start.distanceTo( this.end );
46530
46531 },
46532
46533 at: function ( t, target ) {
46534
46535 if ( target === undefined ) {
46536
46537 console.warn( 'THREE.Line3: .at() target is now required' );
46538 target = new Vector3();
46539
46540 }
46541
46542 return this.delta( target ).multiplyScalar( t ).add( this.start );
46543
46544 },
46545
46546 closestPointToPointParameter: function ( point, clampToLine ) {
46547
46548 _startP.subVectors( point, this.start );
46549 _startEnd.subVectors( this.end, this.start );
46550
46551 var startEnd2 = _startEnd.dot( _startEnd );
46552 var startEnd_startP = _startEnd.dot( _startP );
46553
46554 var t = startEnd_startP / startEnd2;
46555
46556 if ( clampToLine ) {
46557
46558 t = MathUtils.clamp( t, 0, 1 );
46559
46560 }
46561
46562 return t;
46563
46564 },
46565
46566 closestPointToPoint: function ( point, clampToLine, target ) {
46567
46568 var t = this.closestPointToPointParameter( point, clampToLine );
46569
46570 if ( target === undefined ) {
46571
46572 console.warn( 'THREE.Line3: .closestPointToPoint() target is now required' );
46573 target = new Vector3();
46574
46575 }
46576
46577 return this.delta( target ).multiplyScalar( t ).add( this.start );
46578
46579 },
46580
46581 applyMatrix4: function ( matrix ) {
46582
46583 this.start.applyMatrix4( matrix );
46584 this.end.applyMatrix4( matrix );
46585
46586 return this;
46587
46588 },
46589
46590 equals: function ( line ) {
46591
46592 return line.start.equals( this.start ) && line.end.equals( this.end );
46593
46594 }
46595
46596 } );
46597
46598 function ImmediateRenderObject( material ) {
46599
46600 Object3D.call( this );
46601
46602 this.material = material;
46603 this.render = function ( /* renderCallback */ ) {};
46604
46605 this.hasPositions = false;
46606 this.hasNormals = false;
46607 this.hasColors = false;
46608 this.hasUvs = false;
46609
46610 this.positionArray = null;
46611 this.normalArray = null;
46612 this.colorArray = null;
46613 this.uvArray = null;
46614
46615 this.count = 0;
46616
46617 }
46618
46619 ImmediateRenderObject.prototype = Object.create( Object3D.prototype );
46620 ImmediateRenderObject.prototype.constructor = ImmediateRenderObject;
46621
46622 ImmediateRenderObject.prototype.isImmediateRenderObject = true;
46623
46624 var _vector$8 = new Vector3();
46625
46626 function SpotLightHelper( light, color ) {
46627
46628 Object3D.call( this );
46629
46630 this.light = light;
46631 this.light.updateMatrixWorld();
46632
46633 this.matrix = light.matrixWorld;
46634 this.matrixAutoUpdate = false;
46635
46636 this.color = color;
46637
46638 var geometry = new BufferGeometry();
46639
46640 var positions = [
46641 0, 0, 0, 0, 0, 1,
46642 0, 0, 0, 1, 0, 1,
46643 0, 0, 0, - 1, 0, 1,
46644 0, 0, 0, 0, 1, 1,
46645 0, 0, 0, 0, - 1, 1
46646 ];
46647
46648 for ( var i = 0, j = 1, l = 32; i < l; i ++, j ++ ) {
46649
46650 var p1 = ( i / l ) * Math.PI * 2;
46651 var p2 = ( j / l ) * Math.PI * 2;
46652
46653 positions.push(
46654 Math.cos( p1 ), Math.sin( p1 ), 1,
46655 Math.cos( p2 ), Math.sin( p2 ), 1
46656 );
46657
46658 }
46659
46660 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
46661
46662 var material = new LineBasicMaterial( { fog: false, toneMapped: false } );
46663
46664 this.cone = new LineSegments( geometry, material );
46665 this.add( this.cone );
46666
46667 this.update();
46668
46669 }
46670
46671 SpotLightHelper.prototype = Object.create( Object3D.prototype );
46672 SpotLightHelper.prototype.constructor = SpotLightHelper;
46673
46674 SpotLightHelper.prototype.dispose = function () {
46675
46676 this.cone.geometry.dispose();
46677 this.cone.material.dispose();
46678
46679 };
46680
46681 SpotLightHelper.prototype.update = function () {
46682
46683 this.light.updateMatrixWorld();
46684
46685 var coneLength = this.light.distance ? this.light.distance : 1000;
46686 var coneWidth = coneLength * Math.tan( this.light.angle );
46687
46688 this.cone.scale.set( coneWidth, coneWidth, coneLength );
46689
46690 _vector$8.setFromMatrixPosition( this.light.target.matrixWorld );
46691
46692 this.cone.lookAt( _vector$8 );
46693
46694 if ( this.color !== undefined ) {
46695
46696 this.cone.material.color.set( this.color );
46697
46698 } else {
46699
46700 this.cone.material.color.copy( this.light.color );
46701
46702 }
46703
46704 };
46705
46706 var _vector$9 = new Vector3();
46707 var _boneMatrix = new Matrix4();
46708 var _matrixWorldInv = new Matrix4();
46709
46710 function getBoneList( object ) {
46711
46712 var boneList = [];
46713
46714 if ( object && object.isBone ) {
46715
46716 boneList.push( object );
46717
46718 }
46719
46720 for ( var i = 0; i < object.children.length; i ++ ) {
46721
46722 boneList.push.apply( boneList, getBoneList( object.children[ i ] ) );
46723
46724 }
46725
46726 return boneList;
46727
46728 }
46729
46730 function SkeletonHelper( object ) {
46731
46732 var bones = getBoneList( object );
46733
46734 var geometry = new BufferGeometry();
46735
46736 var vertices = [];
46737 var colors = [];
46738
46739 var color1 = new Color( 0, 0, 1 );
46740 var color2 = new Color( 0, 1, 0 );
46741
46742 for ( var i = 0; i < bones.length; i ++ ) {
46743
46744 var bone = bones[ i ];
46745
46746 if ( bone.parent && bone.parent.isBone ) {
46747
46748 vertices.push( 0, 0, 0 );
46749 vertices.push( 0, 0, 0 );
46750 colors.push( color1.r, color1.g, color1.b );
46751 colors.push( color2.r, color2.g, color2.b );
46752
46753 }
46754
46755 }
46756
46757 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
46758 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
46759
46760 var material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } );
46761
46762 LineSegments.call( this, geometry, material );
46763
46764 this.type = 'SkeletonHelper';
46765
46766 this.root = object;
46767 this.bones = bones;
46768
46769 this.matrix = object.matrixWorld;
46770 this.matrixAutoUpdate = false;
46771
46772 }
46773
46774 SkeletonHelper.prototype = Object.create( LineSegments.prototype );
46775 SkeletonHelper.prototype.constructor = SkeletonHelper;
46776
46777 SkeletonHelper.prototype.isSkeletonHelper = true;
46778
46779 SkeletonHelper.prototype.updateMatrixWorld = function ( force ) {
46780
46781 var bones = this.bones;
46782
46783 var geometry = this.geometry;
46784 var position = geometry.getAttribute( 'position' );
46785
46786 _matrixWorldInv.getInverse( this.root.matrixWorld );
46787
46788 for ( var i = 0, j = 0; i < bones.length; i ++ ) {
46789
46790 var bone = bones[ i ];
46791
46792 if ( bone.parent && bone.parent.isBone ) {
46793
46794 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld );
46795 _vector$9.setFromMatrixPosition( _boneMatrix );
46796 position.setXYZ( j, _vector$9.x, _vector$9.y, _vector$9.z );
46797
46798 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld );
46799 _vector$9.setFromMatrixPosition( _boneMatrix );
46800 position.setXYZ( j + 1, _vector$9.x, _vector$9.y, _vector$9.z );
46801
46802 j += 2;
46803
46804 }
46805
46806 }
46807
46808 geometry.getAttribute( 'position' ).needsUpdate = true;
46809
46810 Object3D.prototype.updateMatrixWorld.call( this, force );
46811
46812 };
46813
46814 function PointLightHelper( light, sphereSize, color ) {
46815
46816 this.light = light;
46817 this.light.updateMatrixWorld();
46818
46819 this.color = color;
46820
46821 var geometry = new SphereBufferGeometry( sphereSize, 4, 2 );
46822 var material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
46823
46824 Mesh.call( this, geometry, material );
46825
46826 this.type = 'PointLightHelper';
46827
46828 this.matrix = this.light.matrixWorld;
46829 this.matrixAutoUpdate = false;
46830
46831 this.update();
46832
46833
46834 /*
46835 const distanceGeometry = new THREE.IcosahedronBufferGeometry( 1, 2 );
46836 const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );
46837
46838 this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
46839 this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );
46840
46841 const d = light.distance;
46842
46843 if ( d === 0.0 ) {
46844
46845 this.lightDistance.visible = false;
46846
46847 } else {
46848
46849 this.lightDistance.scale.set( d, d, d );
46850
46851 }
46852
46853 this.add( this.lightDistance );
46854 */
46855
46856 }
46857
46858 PointLightHelper.prototype = Object.create( Mesh.prototype );
46859 PointLightHelper.prototype.constructor = PointLightHelper;
46860
46861 PointLightHelper.prototype.dispose = function () {
46862
46863 this.geometry.dispose();
46864 this.material.dispose();
46865
46866 };
46867
46868 PointLightHelper.prototype.update = function () {
46869
46870 if ( this.color !== undefined ) {
46871
46872 this.material.color.set( this.color );
46873
46874 } else {
46875
46876 this.material.color.copy( this.light.color );
46877
46878 }
46879
46880 /*
46881 const d = this.light.distance;
46882
46883 if ( d === 0.0 ) {
46884
46885 this.lightDistance.visible = false;
46886
46887 } else {
46888
46889 this.lightDistance.visible = true;
46890 this.lightDistance.scale.set( d, d, d );
46891
46892 }
46893 */
46894
46895 };
46896
46897 var _vector$a = new Vector3();
46898 var _color1 = new Color();
46899 var _color2 = new Color();
46900
46901 function HemisphereLightHelper( light, size, color ) {
46902
46903 Object3D.call( this );
46904
46905 this.light = light;
46906 this.light.updateMatrixWorld();
46907
46908 this.matrix = light.matrixWorld;
46909 this.matrixAutoUpdate = false;
46910
46911 this.color = color;
46912
46913 var geometry = new OctahedronBufferGeometry( size );
46914 geometry.rotateY( Math.PI * 0.5 );
46915
46916 this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
46917 if ( this.color === undefined ) { this.material.vertexColors = true; }
46918
46919 var position = geometry.getAttribute( 'position' );
46920 var colors = new Float32Array( position.count * 3 );
46921
46922 geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) );
46923
46924 this.add( new Mesh( geometry, this.material ) );
46925
46926 this.update();
46927
46928 }
46929
46930 HemisphereLightHelper.prototype = Object.create( Object3D.prototype );
46931 HemisphereLightHelper.prototype.constructor = HemisphereLightHelper;
46932
46933 HemisphereLightHelper.prototype.dispose = function () {
46934
46935 this.children[ 0 ].geometry.dispose();
46936 this.children[ 0 ].material.dispose();
46937
46938 };
46939
46940 HemisphereLightHelper.prototype.update = function () {
46941
46942 var mesh = this.children[ 0 ];
46943
46944 if ( this.color !== undefined ) {
46945
46946 this.material.color.set( this.color );
46947
46948 } else {
46949
46950 var colors = mesh.geometry.getAttribute( 'color' );
46951
46952 _color1.copy( this.light.color );
46953 _color2.copy( this.light.groundColor );
46954
46955 for ( var i = 0, l = colors.count; i < l; i ++ ) {
46956
46957 var color = ( i < ( l / 2 ) ) ? _color1 : _color2;
46958
46959 colors.setXYZ( i, color.r, color.g, color.b );
46960
46961 }
46962
46963 colors.needsUpdate = true;
46964
46965 }
46966
46967 mesh.lookAt( _vector$a.setFromMatrixPosition( this.light.matrixWorld ).negate() );
46968
46969 };
46970
46971 function GridHelper( size, divisions, color1, color2 ) {
46972
46973 size = size || 10;
46974 divisions = divisions || 10;
46975 color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
46976 color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
46977
46978 var center = divisions / 2;
46979 var step = size / divisions;
46980 var halfSize = size / 2;
46981
46982 var vertices = [], colors = [];
46983
46984 for ( var i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {
46985
46986 vertices.push( - halfSize, 0, k, halfSize, 0, k );
46987 vertices.push( k, 0, - halfSize, k, 0, halfSize );
46988
46989 var color = i === center ? color1 : color2;
46990
46991 color.toArray( colors, j ); j += 3;
46992 color.toArray( colors, j ); j += 3;
46993 color.toArray( colors, j ); j += 3;
46994 color.toArray( colors, j ); j += 3;
46995
46996 }
46997
46998 var geometry = new BufferGeometry();
46999 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
47000 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
47001
47002 var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
47003
47004 LineSegments.call( this, geometry, material );
47005
47006 this.type = 'GridHelper';
47007
47008 }
47009
47010 GridHelper.prototype = Object.create( LineSegments.prototype );
47011 GridHelper.prototype.constructor = GridHelper;
47012
47013 function PolarGridHelper( radius, radials, circles, divisions, color1, color2 ) {
47014
47015 radius = radius || 10;
47016 radials = radials || 16;
47017 circles = circles || 8;
47018 divisions = divisions || 64;
47019 color1 = new Color( color1 !== undefined ? color1 : 0x444444 );
47020 color2 = new Color( color2 !== undefined ? color2 : 0x888888 );
47021
47022 var vertices = [];
47023 var colors = [];
47024
47025 // create the radials
47026
47027 for ( var i = 0; i <= radials; i ++ ) {
47028
47029 var v = ( i / radials ) * ( Math.PI * 2 );
47030
47031 var x = Math.sin( v ) * radius;
47032 var z = Math.cos( v ) * radius;
47033
47034 vertices.push( 0, 0, 0 );
47035 vertices.push( x, 0, z );
47036
47037 var color = ( i & 1 ) ? color1 : color2;
47038
47039 colors.push( color.r, color.g, color.b );
47040 colors.push( color.r, color.g, color.b );
47041
47042 }
47043
47044 // create the circles
47045
47046 for ( var i$1 = 0; i$1 <= circles; i$1 ++ ) {
47047
47048 var color$1 = ( i$1 & 1 ) ? color1 : color2;
47049
47050 var r = radius - ( radius / circles * i$1 );
47051
47052 for ( var j = 0; j < divisions; j ++ ) {
47053
47054 // first vertex
47055
47056 var v$1 = ( j / divisions ) * ( Math.PI * 2 );
47057
47058 var x$1 = Math.sin( v$1 ) * r;
47059 var z$1 = Math.cos( v$1 ) * r;
47060
47061 vertices.push( x$1, 0, z$1 );
47062 colors.push( color$1.r, color$1.g, color$1.b );
47063
47064 // second vertex
47065
47066 v$1 = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );
47067
47068 x$1 = Math.sin( v$1 ) * r;
47069 z$1 = Math.cos( v$1 ) * r;
47070
47071 vertices.push( x$1, 0, z$1 );
47072 colors.push( color$1.r, color$1.g, color$1.b );
47073
47074 }
47075
47076 }
47077
47078 var geometry = new BufferGeometry();
47079 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
47080 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
47081
47082 var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
47083
47084 LineSegments.call( this, geometry, material );
47085
47086 this.type = 'PolarGridHelper';
47087
47088 }
47089
47090 PolarGridHelper.prototype = Object.create( LineSegments.prototype );
47091 PolarGridHelper.prototype.constructor = PolarGridHelper;
47092
47093 var _v1$5 = new Vector3();
47094 var _v2$3 = new Vector3();
47095 var _v3$1 = new Vector3();
47096
47097 function DirectionalLightHelper( light, size, color ) {
47098
47099 Object3D.call( this );
47100
47101 this.light = light;
47102 this.light.updateMatrixWorld();
47103
47104 this.matrix = light.matrixWorld;
47105 this.matrixAutoUpdate = false;
47106
47107 this.color = color;
47108
47109 if ( size === undefined ) { size = 1; }
47110
47111 var geometry = new BufferGeometry();
47112 geometry.setAttribute( 'position', new Float32BufferAttribute( [
47113 - size, size, 0,
47114 size, size, 0,
47115 size, - size, 0,
47116 - size, - size, 0,
47117 - size, size, 0
47118 ], 3 ) );
47119
47120 var material = new LineBasicMaterial( { fog: false, toneMapped: false } );
47121
47122 this.lightPlane = new Line( geometry, material );
47123 this.add( this.lightPlane );
47124
47125 geometry = new BufferGeometry();
47126 geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );
47127
47128 this.targetLine = new Line( geometry, material );
47129 this.add( this.targetLine );
47130
47131 this.update();
47132
47133 }
47134
47135 DirectionalLightHelper.prototype = Object.create( Object3D.prototype );
47136 DirectionalLightHelper.prototype.constructor = DirectionalLightHelper;
47137
47138 DirectionalLightHelper.prototype.dispose = function () {
47139
47140 this.lightPlane.geometry.dispose();
47141 this.lightPlane.material.dispose();
47142 this.targetLine.geometry.dispose();
47143 this.targetLine.material.dispose();
47144
47145 };
47146
47147 DirectionalLightHelper.prototype.update = function () {
47148
47149 _v1$5.setFromMatrixPosition( this.light.matrixWorld );
47150 _v2$3.setFromMatrixPosition( this.light.target.matrixWorld );
47151 _v3$1.subVectors( _v2$3, _v1$5 );
47152
47153 this.lightPlane.lookAt( _v2$3 );
47154
47155 if ( this.color !== undefined ) {
47156
47157 this.lightPlane.material.color.set( this.color );
47158 this.targetLine.material.color.set( this.color );
47159
47160 } else {
47161
47162 this.lightPlane.material.color.copy( this.light.color );
47163 this.targetLine.material.color.copy( this.light.color );
47164
47165 }
47166
47167 this.targetLine.lookAt( _v2$3 );
47168 this.targetLine.scale.z = _v3$1.length();
47169
47170 };
47171
47172 var _vector$b = new Vector3();
47173 var _camera = new Camera();
47174
47175 /**
47176 * - shows frustum, line of sight and up of the camera
47177 * - suitable for fast updates
47178 * - based on frustum visualization in lightgl.js shadowmap example
47179 * http://evanw.github.com/lightgl.js/tests/shadowmap.html
47180 */
47181
47182 function CameraHelper( camera ) {
47183
47184 var geometry = new BufferGeometry();
47185 var material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } );
47186
47187 var vertices = [];
47188 var colors = [];
47189
47190 var pointMap = {};
47191
47192 // colors
47193
47194 var colorFrustum = new Color( 0xffaa00 );
47195 var colorCone = new Color( 0xff0000 );
47196 var colorUp = new Color( 0x00aaff );
47197 var colorTarget = new Color( 0xffffff );
47198 var colorCross = new Color( 0x333333 );
47199
47200 // near
47201
47202 addLine( 'n1', 'n2', colorFrustum );
47203 addLine( 'n2', 'n4', colorFrustum );
47204 addLine( 'n4', 'n3', colorFrustum );
47205 addLine( 'n3', 'n1', colorFrustum );
47206
47207 // far
47208
47209 addLine( 'f1', 'f2', colorFrustum );
47210 addLine( 'f2', 'f4', colorFrustum );
47211 addLine( 'f4', 'f3', colorFrustum );
47212 addLine( 'f3', 'f1', colorFrustum );
47213
47214 // sides
47215
47216 addLine( 'n1', 'f1', colorFrustum );
47217 addLine( 'n2', 'f2', colorFrustum );
47218 addLine( 'n3', 'f3', colorFrustum );
47219 addLine( 'n4', 'f4', colorFrustum );
47220
47221 // cone
47222
47223 addLine( 'p', 'n1', colorCone );
47224 addLine( 'p', 'n2', colorCone );
47225 addLine( 'p', 'n3', colorCone );
47226 addLine( 'p', 'n4', colorCone );
47227
47228 // up
47229
47230 addLine( 'u1', 'u2', colorUp );
47231 addLine( 'u2', 'u3', colorUp );
47232 addLine( 'u3', 'u1', colorUp );
47233
47234 // target
47235
47236 addLine( 'c', 't', colorTarget );
47237 addLine( 'p', 'c', colorCross );
47238
47239 // cross
47240
47241 addLine( 'cn1', 'cn2', colorCross );
47242 addLine( 'cn3', 'cn4', colorCross );
47243
47244 addLine( 'cf1', 'cf2', colorCross );
47245 addLine( 'cf3', 'cf4', colorCross );
47246
47247 function addLine( a, b, color ) {
47248
47249 addPoint( a, color );
47250 addPoint( b, color );
47251
47252 }
47253
47254 function addPoint( id, color ) {
47255
47256 vertices.push( 0, 0, 0 );
47257 colors.push( color.r, color.g, color.b );
47258
47259 if ( pointMap[ id ] === undefined ) {
47260
47261 pointMap[ id ] = [];
47262
47263 }
47264
47265 pointMap[ id ].push( ( vertices.length / 3 ) - 1 );
47266
47267 }
47268
47269 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
47270 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
47271
47272 LineSegments.call( this, geometry, material );
47273
47274 this.type = 'CameraHelper';
47275
47276 this.camera = camera;
47277 if ( this.camera.updateProjectionMatrix ) { this.camera.updateProjectionMatrix(); }
47278
47279 this.matrix = camera.matrixWorld;
47280 this.matrixAutoUpdate = false;
47281
47282 this.pointMap = pointMap;
47283
47284 this.update();
47285
47286 }
47287
47288 CameraHelper.prototype = Object.create( LineSegments.prototype );
47289 CameraHelper.prototype.constructor = CameraHelper;
47290
47291 CameraHelper.prototype.update = function () {
47292
47293 var geometry = this.geometry;
47294 var pointMap = this.pointMap;
47295
47296 var w = 1, h = 1;
47297
47298 // we need just camera projection matrix inverse
47299 // world matrix must be identity
47300
47301 _camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse );
47302
47303 // center / target
47304
47305 setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 );
47306 setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 );
47307
47308 // near
47309
47310 setPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 );
47311 setPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 );
47312 setPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 );
47313 setPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 );
47314
47315 // far
47316
47317 setPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 );
47318 setPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 );
47319 setPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 );
47320 setPoint( 'f4', pointMap, geometry, _camera, w, h, 1 );
47321
47322 // up
47323
47324 setPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 );
47325 setPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 );
47326 setPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 );
47327
47328 // cross
47329
47330 setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 );
47331 setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 );
47332 setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 );
47333 setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 );
47334
47335 setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 );
47336 setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 );
47337 setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 );
47338 setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 );
47339
47340 geometry.getAttribute( 'position' ).needsUpdate = true;
47341
47342 };
47343
47344 function setPoint( point, pointMap, geometry, camera, x, y, z ) {
47345
47346 _vector$b.set( x, y, z ).unproject( camera );
47347
47348 var points = pointMap[ point ];
47349
47350 if ( points !== undefined ) {
47351
47352 var position = geometry.getAttribute( 'position' );
47353
47354 for ( var i = 0, l = points.length; i < l; i ++ ) {
47355
47356 position.setXYZ( points[ i ], _vector$b.x, _vector$b.y, _vector$b.z );
47357
47358 }
47359
47360 }
47361
47362 }
47363
47364 var _box$3 = new Box3();
47365
47366 function BoxHelper( object, color ) {
47367
47368 this.object = object;
47369
47370 if ( color === undefined ) { color = 0xffff00; }
47371
47372 var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
47373 var positions = new Float32Array( 8 * 3 );
47374
47375 var geometry = new BufferGeometry();
47376 geometry.setIndex( new BufferAttribute( indices, 1 ) );
47377 geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
47378
47379 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
47380
47381 this.type = 'BoxHelper';
47382
47383 this.matrixAutoUpdate = false;
47384
47385 this.update();
47386
47387 }
47388
47389 BoxHelper.prototype = Object.create( LineSegments.prototype );
47390 BoxHelper.prototype.constructor = BoxHelper;
47391
47392 BoxHelper.prototype.update = function ( object ) {
47393
47394 if ( object !== undefined ) {
47395
47396 console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' );
47397
47398 }
47399
47400 if ( this.object !== undefined ) {
47401
47402 _box$3.setFromObject( this.object );
47403
47404 }
47405
47406 if ( _box$3.isEmpty() ) { return; }
47407
47408 var min = _box$3.min;
47409 var max = _box$3.max;
47410
47411 /*
47412 5____4
47413 1/___0/|
47414 | 6__|_7
47415 2/___3/
47416
47417 0: max.x, max.y, max.z
47418 1: min.x, max.y, max.z
47419 2: min.x, min.y, max.z
47420 3: max.x, min.y, max.z
47421 4: max.x, max.y, min.z
47422 5: min.x, max.y, min.z
47423 6: min.x, min.y, min.z
47424 7: max.x, min.y, min.z
47425 */
47426
47427 var position = this.geometry.attributes.position;
47428 var array = position.array;
47429
47430 array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;
47431 array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;
47432 array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;
47433 array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;
47434 array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;
47435 array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;
47436 array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;
47437 array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;
47438
47439 position.needsUpdate = true;
47440
47441 this.geometry.computeBoundingSphere();
47442
47443
47444 };
47445
47446 BoxHelper.prototype.setFromObject = function ( object ) {
47447
47448 this.object = object;
47449 this.update();
47450
47451 return this;
47452
47453 };
47454
47455 BoxHelper.prototype.copy = function ( source ) {
47456
47457 LineSegments.prototype.copy.call( this, source );
47458
47459 this.object = source.object;
47460
47461 return this;
47462
47463 };
47464
47465 function Box3Helper( box, color ) {
47466
47467 this.type = 'Box3Helper';
47468
47469 this.box = box;
47470
47471 if ( color === undefined ) { color = 0xffff00; }
47472
47473 var indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
47474
47475 var positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ];
47476
47477 var geometry = new BufferGeometry();
47478
47479 geometry.setIndex( new BufferAttribute( indices, 1 ) );
47480
47481 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
47482
47483 LineSegments.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
47484
47485 this.type = 'Box3Helper';
47486
47487 this.geometry.computeBoundingSphere();
47488
47489 }
47490
47491 Box3Helper.prototype = Object.create( LineSegments.prototype );
47492 Box3Helper.prototype.constructor = Box3Helper;
47493
47494 Box3Helper.prototype.updateMatrixWorld = function ( force ) {
47495
47496 var box = this.box;
47497
47498 if ( box.isEmpty() ) { return; }
47499
47500 box.getCenter( this.position );
47501
47502 box.getSize( this.scale );
47503
47504 this.scale.multiplyScalar( 0.5 );
47505
47506 Object3D.prototype.updateMatrixWorld.call( this, force );
47507
47508 };
47509
47510 function PlaneHelper( plane, size, hex ) {
47511
47512 this.plane = plane;
47513
47514 this.size = ( size === undefined ) ? 1 : size;
47515
47516 var color = ( hex !== undefined ) ? hex : 0xffff00;
47517
47518 var positions = [ 1, - 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 ];
47519
47520 var geometry = new BufferGeometry();
47521 geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
47522 geometry.computeBoundingSphere();
47523
47524 Line.call( this, geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
47525
47526 this.type = 'PlaneHelper';
47527
47528 //
47529
47530 var positions2 = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, 1, 1, - 1, - 1, 1, 1, - 1, 1 ];
47531
47532 var geometry2 = new BufferGeometry();
47533 geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );
47534 geometry2.computeBoundingSphere();
47535
47536 this.add( new Mesh( geometry2, new MeshBasicMaterial( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) );
47537
47538 }
47539
47540 PlaneHelper.prototype = Object.create( Line.prototype );
47541 PlaneHelper.prototype.constructor = PlaneHelper;
47542
47543 PlaneHelper.prototype.updateMatrixWorld = function ( force ) {
47544
47545 var scale = - this.plane.constant;
47546
47547 if ( Math.abs( scale ) < 1e-8 ) { scale = 1e-8; } // sign does not matter
47548
47549 this.scale.set( 0.5 * this.size, 0.5 * this.size, scale );
47550
47551 this.children[ 0 ].material.side = ( scale < 0 ) ? BackSide : FrontSide; // renderer flips side when determinant < 0; flipping not wanted here
47552
47553 this.lookAt( this.plane.normal );
47554
47555 Object3D.prototype.updateMatrixWorld.call( this, force );
47556
47557 };
47558
47559 var _axis = new Vector3();
47560 var _lineGeometry, _coneGeometry;
47561
47562 function ArrowHelper( dir, origin, length, color, headLength, headWidth ) {
47563
47564 // dir is assumed to be normalized
47565
47566 Object3D.call( this );
47567
47568 this.type = 'ArrowHelper';
47569
47570 if ( dir === undefined ) { dir = new Vector3( 0, 0, 1 ); }
47571 if ( origin === undefined ) { origin = new Vector3( 0, 0, 0 ); }
47572 if ( length === undefined ) { length = 1; }
47573 if ( color === undefined ) { color = 0xffff00; }
47574 if ( headLength === undefined ) { headLength = 0.2 * length; }
47575 if ( headWidth === undefined ) { headWidth = 0.2 * headLength; }
47576
47577 if ( _lineGeometry === undefined ) {
47578
47579 _lineGeometry = new BufferGeometry();
47580 _lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );
47581
47582 _coneGeometry = new CylinderBufferGeometry( 0, 0.5, 1, 5, 1 );
47583 _coneGeometry.translate( 0, - 0.5, 0 );
47584
47585 }
47586
47587 this.position.copy( origin );
47588
47589 this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
47590 this.line.matrixAutoUpdate = false;
47591 this.add( this.line );
47592
47593 this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) );
47594 this.cone.matrixAutoUpdate = false;
47595 this.add( this.cone );
47596
47597 this.setDirection( dir );
47598 this.setLength( length, headLength, headWidth );
47599
47600 }
47601
47602 ArrowHelper.prototype = Object.create( Object3D.prototype );
47603 ArrowHelper.prototype.constructor = ArrowHelper;
47604
47605 ArrowHelper.prototype.setDirection = function ( dir ) {
47606
47607 // dir is assumed to be normalized
47608
47609 if ( dir.y > 0.99999 ) {
47610
47611 this.quaternion.set( 0, 0, 0, 1 );
47612
47613 } else if ( dir.y < - 0.99999 ) {
47614
47615 this.quaternion.set( 1, 0, 0, 0 );
47616
47617 } else {
47618
47619 _axis.set( dir.z, 0, - dir.x ).normalize();
47620
47621 var radians = Math.acos( dir.y );
47622
47623 this.quaternion.setFromAxisAngle( _axis, radians );
47624
47625 }
47626
47627 };
47628
47629 ArrowHelper.prototype.setLength = function ( length, headLength, headWidth ) {
47630
47631 if ( headLength === undefined ) { headLength = 0.2 * length; }
47632 if ( headWidth === undefined ) { headWidth = 0.2 * headLength; }
47633
47634 this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458
47635 this.line.updateMatrix();
47636
47637 this.cone.scale.set( headWidth, headLength, headWidth );
47638 this.cone.position.y = length;
47639 this.cone.updateMatrix();
47640
47641 };
47642
47643 ArrowHelper.prototype.setColor = function ( color ) {
47644
47645 this.line.material.color.set( color );
47646 this.cone.material.color.set( color );
47647
47648 };
47649
47650 ArrowHelper.prototype.copy = function ( source ) {
47651
47652 Object3D.prototype.copy.call( this, source, false );
47653
47654 this.line.copy( source.line );
47655 this.cone.copy( source.cone );
47656
47657 return this;
47658
47659 };
47660
47661 function AxesHelper( size ) {
47662
47663 size = size || 1;
47664
47665 var vertices = [
47666 0, 0, 0, size, 0, 0,
47667 0, 0, 0, 0, size, 0,
47668 0, 0, 0, 0, 0, size
47669 ];
47670
47671 var colors = [
47672 1, 0, 0, 1, 0.6, 0,
47673 0, 1, 0, 0.6, 1, 0,
47674 0, 0, 1, 0, 0.6, 1
47675 ];
47676
47677 var geometry = new BufferGeometry();
47678 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
47679 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
47680
47681 var material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
47682
47683 LineSegments.call( this, geometry, material );
47684
47685 this.type = 'AxesHelper';
47686
47687 }
47688
47689 AxesHelper.prototype = Object.create( LineSegments.prototype );
47690 AxesHelper.prototype.constructor = AxesHelper;
47691
47692 var LOD_MIN = 4;
47693 var LOD_MAX = 8;
47694 var SIZE_MAX = Math.pow( 2, LOD_MAX );
47695
47696 // The standard deviations (radians) associated with the extra mips. These are
47697 // chosen to approximate a Trowbridge-Reitz distribution function times the
47698 // geometric shadowing function. These sigma values squared must match the
47699 // variance #defines in cube_uv_reflection_fragment.glsl.js.
47700 var EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
47701
47702 var TOTAL_LODS = LOD_MAX - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;
47703
47704 // The maximum length of the blur for loop. Smaller sigmas will use fewer
47705 // samples and exit early, but not recompile the shader.
47706 var MAX_SAMPLES = 20;
47707
47708 var ENCODINGS = {};
47709 ENCODINGS[ LinearEncoding ] = 0;
47710 ENCODINGS[ sRGBEncoding ] = 1;
47711 ENCODINGS[ RGBEEncoding ] = 2;
47712 ENCODINGS[ RGBM7Encoding ] = 3;
47713 ENCODINGS[ RGBM16Encoding ] = 4;
47714 ENCODINGS[ RGBDEncoding ] = 5;
47715 ENCODINGS[ GammaEncoding ] = 6;
47716
47717 var _flatCamera = new OrthographicCamera();
47718 var ref = _createPlanes();
47719 var _lodPlanes = ref._lodPlanes;
47720 var _sizeLods = ref._sizeLods;
47721 var _sigmas = ref._sigmas;
47722 var _oldTarget = null;
47723
47724 // Golden Ratio
47725 var PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
47726 var INV_PHI = 1 / PHI;
47727
47728 // Vertices of a dodecahedron (except the opposites, which represent the
47729 // same axis), used as axis directions evenly spread on a sphere.
47730 var _axisDirections = [
47731 new Vector3( 1, 1, 1 ),
47732 new Vector3( - 1, 1, 1 ),
47733 new Vector3( 1, 1, - 1 ),
47734 new Vector3( - 1, 1, - 1 ),
47735 new Vector3( 0, PHI, INV_PHI ),
47736 new Vector3( 0, PHI, - INV_PHI ),
47737 new Vector3( INV_PHI, 0, PHI ),
47738 new Vector3( - INV_PHI, 0, PHI ),
47739 new Vector3( PHI, INV_PHI, 0 ),
47740 new Vector3( - PHI, INV_PHI, 0 ) ];
47741
47742 /**
47743 * This class generates a Prefiltered, Mipmapped Radiance Environment Map
47744 * (PMREM) from a cubeMap environment texture. This allows different levels of
47745 * blur to be quickly accessed based on material roughness. It is packed into a
47746 * special CubeUV format that allows us to perform custom interpolation so that
47747 * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap
47748 * chain, it only goes down to the LOD_MIN level (above), and then creates extra
47749 * even more filtered 'mips' at the same LOD_MIN resolution, associated with
47750 * higher roughness levels. In this way we maintain resolution to smoothly
47751 * interpolate diffuse lighting while limiting sampling computation.
47752 */
47753
47754 function PMREMGenerator( renderer ) {
47755
47756 this._renderer = renderer;
47757 this._pingPongRenderTarget = null;
47758
47759 this._blurMaterial = _getBlurShader( MAX_SAMPLES );
47760 this._equirectShader = null;
47761 this._cubemapShader = null;
47762
47763 this._compileMaterial( this._blurMaterial );
47764
47765 }
47766
47767 PMREMGenerator.prototype = {
47768
47769 constructor: PMREMGenerator,
47770
47771 /**
47772 * Generates a PMREM from a supplied Scene, which can be faster than using an
47773 * image if networking bandwidth is low. Optional sigma specifies a blur radius
47774 * in radians to be applied to the scene before PMREM generation. Optional near
47775 * and far planes ensure the scene is rendered in its entirety (the cubeCamera
47776 * is placed at the origin).
47777 */
47778 fromScene: function ( scene, sigma, near, far ) {
47779 if ( sigma === void 0 ) sigma = 0;
47780 if ( near === void 0 ) near = 0.1;
47781 if ( far === void 0 ) far = 100;
47782
47783
47784 _oldTarget = this._renderer.getRenderTarget();
47785 var cubeUVRenderTarget = this._allocateTargets();
47786
47787 this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
47788 if ( sigma > 0 ) {
47789
47790 this._blur( cubeUVRenderTarget, 0, 0, sigma );
47791
47792 }
47793
47794 this._applyPMREM( cubeUVRenderTarget );
47795 this._cleanup( cubeUVRenderTarget );
47796
47797 return cubeUVRenderTarget;
47798
47799 },
47800
47801 /**
47802 * Generates a PMREM from an equirectangular texture, which can be either LDR
47803 * (RGBFormat) or HDR (RGBEFormat). The ideal input image size is 1k (1024 x 512),
47804 * as this matches best with the 256 x 256 cubemap output.
47805 */
47806 fromEquirectangular: function ( equirectangular ) {
47807
47808 return this._fromTexture( equirectangular );
47809
47810 },
47811
47812 /**
47813 * Generates a PMREM from an cubemap texture, which can be either LDR
47814 * (RGBFormat) or HDR (RGBEFormat). The ideal input cube size is 256 x 256,
47815 * as this matches best with the 256 x 256 cubemap output.
47816 */
47817 fromCubemap: function ( cubemap ) {
47818
47819 return this._fromTexture( cubemap );
47820
47821 },
47822
47823 /**
47824 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
47825 * your texture's network fetch for increased concurrency.
47826 */
47827 compileCubemapShader: function () {
47828
47829 if ( this._cubemapShader === null ) {
47830
47831 this._cubemapShader = _getCubemapShader();
47832 this._compileMaterial( this._cubemapShader );
47833
47834 }
47835
47836 },
47837
47838 /**
47839 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
47840 * your texture's network fetch for increased concurrency.
47841 */
47842 compileEquirectangularShader: function () {
47843
47844 if ( this._equirectShader === null ) {
47845
47846 this._equirectShader = _getEquirectShader();
47847 this._compileMaterial( this._equirectShader );
47848
47849 }
47850
47851 },
47852
47853 /**
47854 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
47855 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
47856 * one of them will cause any others to also become unusable.
47857 */
47858 dispose: function () {
47859
47860 this._blurMaterial.dispose();
47861
47862 if ( this._cubemapShader !== null ) { this._cubemapShader.dispose(); }
47863 if ( this._equirectShader !== null ) { this._equirectShader.dispose(); }
47864
47865 for ( var i = 0; i < _lodPlanes.length; i ++ ) {
47866
47867 _lodPlanes[ i ].dispose();
47868
47869 }
47870
47871 },
47872
47873 // private interface
47874
47875 _cleanup: function ( outputTarget ) {
47876
47877 this._pingPongRenderTarget.dispose();
47878 this._renderer.setRenderTarget( _oldTarget );
47879 outputTarget.scissorTest = false;
47880 _setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
47881
47882 },
47883
47884 _fromTexture: function ( texture ) {
47885
47886 _oldTarget = this._renderer.getRenderTarget();
47887 var cubeUVRenderTarget = this._allocateTargets( texture );
47888 this._textureToCubeUV( texture, cubeUVRenderTarget );
47889 this._applyPMREM( cubeUVRenderTarget );
47890 this._cleanup( cubeUVRenderTarget );
47891
47892 return cubeUVRenderTarget;
47893
47894 },
47895
47896 _allocateTargets: function ( texture ) { // warning: null texture is valid
47897
47898 var params = {
47899 magFilter: NearestFilter,
47900 minFilter: NearestFilter,
47901 generateMipmaps: false,
47902 type: UnsignedByteType,
47903 format: RGBEFormat,
47904 encoding: _isLDR( texture ) ? texture.encoding : RGBEEncoding,
47905 depthBuffer: false,
47906 stencilBuffer: false
47907 };
47908
47909 var cubeUVRenderTarget = _createRenderTarget( params );
47910 cubeUVRenderTarget.depthBuffer = texture ? false : true;
47911 this._pingPongRenderTarget = _createRenderTarget( params );
47912 return cubeUVRenderTarget;
47913
47914 },
47915
47916 _compileMaterial: function ( material ) {
47917
47918 var tmpMesh = new Mesh( _lodPlanes[ 0 ], material );
47919 this._renderer.compile( tmpMesh, _flatCamera );
47920
47921 },
47922
47923 _sceneToCubeUV: function ( scene, near, far, cubeUVRenderTarget ) {
47924
47925 var fov = 90;
47926 var aspect = 1;
47927 var cubeCamera = new PerspectiveCamera( fov, aspect, near, far );
47928 var upSign = [ 1, - 1, 1, 1, 1, 1 ];
47929 var forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ];
47930 var renderer = this._renderer;
47931
47932 var outputEncoding = renderer.outputEncoding;
47933 var toneMapping = renderer.toneMapping;
47934 var clearColor = renderer.getClearColor();
47935 var clearAlpha = renderer.getClearAlpha();
47936
47937 renderer.toneMapping = NoToneMapping;
47938 renderer.outputEncoding = LinearEncoding;
47939
47940 var background = scene.background;
47941 if ( background && background.isColor ) {
47942
47943 background.convertSRGBToLinear();
47944 // Convert linear to RGBE
47945 var maxComponent = Math.max( background.r, background.g, background.b );
47946 var fExp = Math.min( Math.max( Math.ceil( Math.log2( maxComponent ) ), - 128.0 ), 127.0 );
47947 background = background.multiplyScalar( Math.pow( 2.0, - fExp ) );
47948 var alpha = ( fExp + 128.0 ) / 255.0;
47949 renderer.setClearColor( background, alpha );
47950 scene.background = null;
47951
47952 }
47953
47954 for ( var i = 0; i < 6; i ++ ) {
47955
47956 var col = i % 3;
47957 if ( col == 0 ) {
47958
47959 cubeCamera.up.set( 0, upSign[ i ], 0 );
47960 cubeCamera.lookAt( forwardSign[ i ], 0, 0 );
47961
47962 } else if ( col == 1 ) {
47963
47964 cubeCamera.up.set( 0, 0, upSign[ i ] );
47965 cubeCamera.lookAt( 0, forwardSign[ i ], 0 );
47966
47967 } else {
47968
47969 cubeCamera.up.set( 0, upSign[ i ], 0 );
47970 cubeCamera.lookAt( 0, 0, forwardSign[ i ] );
47971
47972 }
47973
47974 _setViewport( cubeUVRenderTarget,
47975 col * SIZE_MAX, i > 2 ? SIZE_MAX : 0, SIZE_MAX, SIZE_MAX );
47976 renderer.setRenderTarget( cubeUVRenderTarget );
47977 renderer.render( scene, cubeCamera );
47978
47979 }
47980
47981 renderer.toneMapping = toneMapping;
47982 renderer.outputEncoding = outputEncoding;
47983 renderer.setClearColor( clearColor, clearAlpha );
47984
47985 },
47986
47987 _textureToCubeUV: function ( texture, cubeUVRenderTarget ) {
47988
47989 var renderer = this._renderer;
47990
47991 if ( texture.isCubeTexture ) {
47992
47993 if ( this._cubemapShader == null ) {
47994
47995 this._cubemapShader = _getCubemapShader();
47996
47997 }
47998
47999 } else {
48000
48001 if ( this._equirectShader == null ) {
48002
48003 this._equirectShader = _getEquirectShader();
48004
48005 }
48006
48007 }
48008
48009 var material = texture.isCubeTexture ? this._cubemapShader : this._equirectShader;
48010 var mesh = new Mesh( _lodPlanes[ 0 ], material );
48011
48012 var uniforms = material.uniforms;
48013
48014 uniforms[ 'envMap' ].value = texture;
48015
48016 if ( ! texture.isCubeTexture ) {
48017
48018 uniforms[ 'texelSize' ].value.set( 1.0 / texture.image.width, 1.0 / texture.image.height );
48019
48020 }
48021
48022 uniforms[ 'inputEncoding' ].value = ENCODINGS[ texture.encoding ];
48023 uniforms[ 'outputEncoding' ].value = ENCODINGS[ cubeUVRenderTarget.texture.encoding ];
48024
48025 _setViewport( cubeUVRenderTarget, 0, 0, 3 * SIZE_MAX, 2 * SIZE_MAX );
48026
48027 renderer.setRenderTarget( cubeUVRenderTarget );
48028 renderer.render( mesh, _flatCamera );
48029
48030 },
48031
48032 _applyPMREM: function ( cubeUVRenderTarget ) {
48033
48034 var renderer = this._renderer;
48035 var autoClear = renderer.autoClear;
48036 renderer.autoClear = false;
48037
48038 for ( var i = 1; i < TOTAL_LODS; i ++ ) {
48039
48040 var sigma = Math.sqrt( _sigmas[ i ] * _sigmas[ i ] - _sigmas[ i - 1 ] * _sigmas[ i - 1 ] );
48041
48042 var poleAxis = _axisDirections[ ( i - 1 ) % _axisDirections.length ];
48043
48044 this._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis );
48045
48046 }
48047
48048 renderer.autoClear = autoClear;
48049
48050 },
48051
48052 /**
48053 * This is a two-pass Gaussian blur for a cubemap. Normally this is done
48054 * vertically and horizontally, but this breaks down on a cube. Here we apply
48055 * the blur latitudinally (around the poles), and then longitudinally (towards
48056 * the poles) to approximate the orthogonally-separable blur. It is least
48057 * accurate at the poles, but still does a decent job.
48058 */
48059 _blur: function ( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) {
48060
48061 var pingPongRenderTarget = this._pingPongRenderTarget;
48062
48063 this._halfBlur(
48064 cubeUVRenderTarget,
48065 pingPongRenderTarget,
48066 lodIn,
48067 lodOut,
48068 sigma,
48069 'latitudinal',
48070 poleAxis );
48071
48072 this._halfBlur(
48073 pingPongRenderTarget,
48074 cubeUVRenderTarget,
48075 lodOut,
48076 lodOut,
48077 sigma,
48078 'longitudinal',
48079 poleAxis );
48080
48081 },
48082
48083 _halfBlur: function ( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) {
48084
48085 var renderer = this._renderer;
48086 var blurMaterial = this._blurMaterial;
48087
48088 if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) {
48089
48090 console.error(
48091 'blur direction must be either latitudinal or longitudinal!' );
48092
48093 }
48094
48095 // Number of standard deviations at which to cut off the discrete approximation.
48096 var STANDARD_DEVIATIONS = 3;
48097
48098 var blurMesh = new Mesh( _lodPlanes[ lodOut ], blurMaterial );
48099 var blurUniforms = blurMaterial.uniforms;
48100
48101 var pixels = _sizeLods[ lodIn ] - 1;
48102 var radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 );
48103 var sigmaPixels = sigmaRadians / radiansPerPixel;
48104 var samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES;
48105
48106 if ( samples > MAX_SAMPLES ) {
48107
48108 console.warn( ("sigmaRadians, " + sigmaRadians + ", is too large and will clip, as it requested " + samples + " samples when the maximum is set to " + MAX_SAMPLES) );
48109
48110 }
48111
48112 var weights = [];
48113 var sum = 0;
48114
48115 for ( var i = 0; i < MAX_SAMPLES; ++ i ) {
48116
48117 var x$1 = i / sigmaPixels;
48118 var weight = Math.exp( - x$1 * x$1 / 2 );
48119 weights.push( weight );
48120
48121 if ( i == 0 ) {
48122
48123 sum += weight;
48124
48125 } else if ( i < samples ) {
48126
48127 sum += 2 * weight;
48128
48129 }
48130
48131 }
48132
48133 for ( var i$1 = 0; i$1 < weights.length; i$1 ++ ) {
48134
48135 weights[ i$1 ] = weights[ i$1 ] / sum;
48136
48137 }
48138
48139 blurUniforms[ 'envMap' ].value = targetIn.texture;
48140 blurUniforms[ 'samples' ].value = samples;
48141 blurUniforms[ 'weights' ].value = weights;
48142 blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal';
48143
48144 if ( poleAxis ) {
48145
48146 blurUniforms[ 'poleAxis' ].value = poleAxis;
48147
48148 }
48149
48150 blurUniforms[ 'dTheta' ].value = radiansPerPixel;
48151 blurUniforms[ 'mipInt' ].value = LOD_MAX - lodIn;
48152 blurUniforms[ 'inputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
48153 blurUniforms[ 'outputEncoding' ].value = ENCODINGS[ targetIn.texture.encoding ];
48154
48155 var outputSize = _sizeLods[ lodOut ];
48156 var x = 3 * Math.max( 0, SIZE_MAX - 2 * outputSize );
48157 var y = ( lodOut === 0 ? 0 : 2 * SIZE_MAX ) + 2 * outputSize * ( lodOut > LOD_MAX - LOD_MIN ? lodOut - LOD_MAX + LOD_MIN : 0 );
48158
48159 _setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize );
48160 renderer.setRenderTarget( targetOut );
48161 renderer.render( blurMesh, _flatCamera );
48162
48163 }
48164
48165 };
48166
48167 function _isLDR( texture ) {
48168
48169 if ( texture === undefined || texture.type !== UnsignedByteType ) { return false; }
48170
48171 return texture.encoding === LinearEncoding || texture.encoding === sRGBEncoding || texture.encoding === GammaEncoding;
48172
48173 }
48174
48175 function _createPlanes() {
48176
48177 var _lodPlanes = [];
48178 var _sizeLods = [];
48179 var _sigmas = [];
48180
48181 var lod = LOD_MAX;
48182
48183 for ( var i = 0; i < TOTAL_LODS; i ++ ) {
48184
48185 var sizeLod = Math.pow( 2, lod );
48186 _sizeLods.push( sizeLod );
48187 var sigma = 1.0 / sizeLod;
48188
48189 if ( i > LOD_MAX - LOD_MIN ) {
48190
48191 sigma = EXTRA_LOD_SIGMA[ i - LOD_MAX + LOD_MIN - 1 ];
48192
48193 } else if ( i == 0 ) {
48194
48195 sigma = 0;
48196
48197 }
48198
48199 _sigmas.push( sigma );
48200
48201 var texelSize = 1.0 / ( sizeLod - 1 );
48202 var min = - texelSize / 2;
48203 var max = 1 + texelSize / 2;
48204 var uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ];
48205
48206 var cubeFaces = 6;
48207 var vertices = 6;
48208 var positionSize = 3;
48209 var uvSize = 2;
48210 var faceIndexSize = 1;
48211
48212 var position = new Float32Array( positionSize * vertices * cubeFaces );
48213 var uv = new Float32Array( uvSize * vertices * cubeFaces );
48214 var faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces );
48215
48216 for ( var face = 0; face < cubeFaces; face ++ ) {
48217
48218 var x = ( face % 3 ) * 2 / 3 - 1;
48219 var y = face > 2 ? 0 : - 1;
48220 var coordinates = [
48221 x, y, 0,
48222 x + 2 / 3, y, 0,
48223 x + 2 / 3, y + 1, 0,
48224 x, y, 0,
48225 x + 2 / 3, y + 1, 0,
48226 x, y + 1, 0
48227 ];
48228 position.set( coordinates, positionSize * vertices * face );
48229 uv.set( uv1, uvSize * vertices * face );
48230 var fill = [ face, face, face, face, face, face ];
48231 faceIndex.set( fill, faceIndexSize * vertices * face );
48232
48233 }
48234
48235 var planes = new BufferGeometry();
48236 planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );
48237 planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
48238 planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
48239 _lodPlanes.push( planes );
48240
48241 if ( lod > LOD_MIN ) {
48242
48243 lod --;
48244
48245 }
48246
48247 }
48248
48249 return { _lodPlanes: _lodPlanes, _sizeLods: _sizeLods, _sigmas: _sigmas };
48250
48251 }
48252
48253 function _createRenderTarget( params ) {
48254
48255 var cubeUVRenderTarget = new WebGLRenderTarget( 3 * SIZE_MAX, 3 * SIZE_MAX, params );
48256 cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
48257 cubeUVRenderTarget.texture.name = 'PMREM.cubeUv';
48258 cubeUVRenderTarget.scissorTest = true;
48259 return cubeUVRenderTarget;
48260
48261 }
48262
48263 function _setViewport( target, x, y, width, height ) {
48264
48265 target.viewport.set( x, y, width, height );
48266 target.scissor.set( x, y, width, height );
48267
48268 }
48269
48270 function _getBlurShader( maxSamples ) {
48271
48272 var weights = new Float32Array( maxSamples );
48273 var poleAxis = new Vector3( 0, 1, 0 );
48274 var shaderMaterial = new RawShaderMaterial( {
48275
48276 name: 'SphericalGaussianBlur',
48277
48278 defines: { 'n': maxSamples },
48279
48280 uniforms: {
48281 'envMap': { value: null },
48282 'samples': { value: 1 },
48283 'weights': { value: weights },
48284 'latitudinal': { value: false },
48285 'dTheta': { value: 0 },
48286 'mipInt': { value: 0 },
48287 'poleAxis': { value: poleAxis },
48288 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
48289 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
48290 },
48291
48292 vertexShader: _getCommonVertexShader(),
48293
48294 fragmentShader: /* glsl */("\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform int samples;\n\t\t\tuniform float weights[ n ];\n\t\t\tuniform bool latitudinal;\n\t\t\tuniform float dTheta;\n\t\t\tuniform float mipInt;\n\t\t\tuniform vec3 poleAxis;\n\n\t\t\t" + (_getEncodings()) + "\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include <cube_uv_reflection_fragment>\n\n\t\t\tvec3 getSample( float theta, vec3 axis ) {\n\n\t\t\t\tfloat cosTheta = cos( theta );\n\t\t\t\t// Rodrigues' axis-angle rotation\n\t\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross( axis, vOutputDirection ) * sin( theta )\n\t\t\t\t\t+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );\n\n\t\t\t\treturn bilinearCubeUV( envMap, sampleDirection, mipInt );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );\n\n\t\t\t\tif ( all( equal( axis, vec3( 0.0 ) ) ) ) {\n\n\t\t\t\t\taxis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );\n\n\t\t\t\t}\n\n\t\t\t\taxis = normalize( axis );\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );\n\n\t\t\t\tfor ( int i = 1; i < n; i++ ) {\n\n\t\t\t\t\tif ( i >= samples ) {\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat theta = dTheta * float( i );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( theta, axis );\n\n\t\t\t\t}\n\n\t\t\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t\t}\n\t\t"),
48295
48296 blending: NoBlending,
48297 depthTest: false,
48298 depthWrite: false
48299
48300 } );
48301
48302 return shaderMaterial;
48303
48304 }
48305
48306 function _getEquirectShader() {
48307
48308 var texelSize = new Vector2( 1, 1 );
48309 var shaderMaterial = new RawShaderMaterial( {
48310
48311 name: 'EquirectangularToCubeUV',
48312
48313 uniforms: {
48314 'envMap': { value: null },
48315 'texelSize': { value: texelSize },
48316 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
48317 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
48318 },
48319
48320 vertexShader: _getCommonVertexShader(),
48321
48322 fragmentShader: /* glsl */("\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform vec2 texelSize;\n\n\t\t\t" + (_getEncodings()) + "\n\n\t\t\t#include <common>\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tvec2 f = fract( uv / texelSize - 0.5 );\n\t\t\t\tuv -= f * texelSize;\n\t\t\t\tvec3 tl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\t\t\t\tuv.x += texelSize.x;\n\t\t\t\tvec3 tr = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\t\t\t\tuv.y += texelSize.y;\n\t\t\t\tvec3 br = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\t\t\t\tuv.x -= texelSize.x;\n\t\t\t\tvec3 bl = envMapTexelToLinear( texture2D ( envMap, uv ) ).rgb;\n\n\t\t\t\tvec3 tm = mix( tl, tr, f.x );\n\t\t\t\tvec3 bm = mix( bl, br, f.x );\n\t\t\t\tgl_FragColor.rgb = mix( tm, bm, f.y );\n\n\t\t\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t\t}\n\t\t"),
48323
48324 blending: NoBlending,
48325 depthTest: false,
48326 depthWrite: false
48327
48328 } );
48329
48330 return shaderMaterial;
48331
48332 }
48333
48334 function _getCubemapShader() {
48335
48336 var shaderMaterial = new RawShaderMaterial( {
48337
48338 name: 'CubemapToCubeUV',
48339
48340 uniforms: {
48341 'envMap': { value: null },
48342 'inputEncoding': { value: ENCODINGS[ LinearEncoding ] },
48343 'outputEncoding': { value: ENCODINGS[ LinearEncoding ] }
48344 },
48345
48346 vertexShader: _getCommonVertexShader(),
48347
48348 fragmentShader: /* glsl */("\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\t" + (_getEncodings()) + "\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb = envMapTexelToLinear( textureCube( envMap, vec3( - vOutputDirection.x, vOutputDirection.yz ) ) ).rgb;\n\t\t\t\tgl_FragColor = linearToOutputTexel( gl_FragColor );\n\n\t\t\t}\n\t\t"),
48349
48350 blending: NoBlending,
48351 depthTest: false,
48352 depthWrite: false
48353
48354 } );
48355
48356 return shaderMaterial;
48357
48358 }
48359
48360 function _getCommonVertexShader() {
48361
48362 return /* glsl */"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute vec3 position;\n\t\tattribute vec2 uv;\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t";
48363
48364 }
48365
48366 function _getEncodings() {
48367
48368 return /* glsl */"\n\n\t\tuniform int inputEncoding;\n\t\tuniform int outputEncoding;\n\n\t\t#include <encodings_pars_fragment>\n\n\t\tvec4 inputTexelToLinear( vec4 value ) {\n\n\t\t\tif ( inputEncoding == 0 ) {\n\n\t\t\t\treturn value;\n\n\t\t\t} else if ( inputEncoding == 1 ) {\n\n\t\t\t\treturn sRGBToLinear( value );\n\n\t\t\t} else if ( inputEncoding == 2 ) {\n\n\t\t\t\treturn RGBEToLinear( value );\n\n\t\t\t} else if ( inputEncoding == 3 ) {\n\n\t\t\t\treturn RGBMToLinear( value, 7.0 );\n\n\t\t\t} else if ( inputEncoding == 4 ) {\n\n\t\t\t\treturn RGBMToLinear( value, 16.0 );\n\n\t\t\t} else if ( inputEncoding == 5 ) {\n\n\t\t\t\treturn RGBDToLinear( value, 256.0 );\n\n\t\t\t} else {\n\n\t\t\t\treturn GammaToLinear( value, 2.2 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvec4 linearToOutputTexel( vec4 value ) {\n\n\t\t\tif ( outputEncoding == 0 ) {\n\n\t\t\t\treturn value;\n\n\t\t\t} else if ( outputEncoding == 1 ) {\n\n\t\t\t\treturn LinearTosRGB( value );\n\n\t\t\t} else if ( outputEncoding == 2 ) {\n\n\t\t\t\treturn LinearToRGBE( value );\n\n\t\t\t} else if ( outputEncoding == 3 ) {\n\n\t\t\t\treturn LinearToRGBM( value, 7.0 );\n\n\t\t\t} else if ( outputEncoding == 4 ) {\n\n\t\t\t\treturn LinearToRGBM( value, 16.0 );\n\n\t\t\t} else if ( outputEncoding == 5 ) {\n\n\t\t\t\treturn LinearToRGBD( value, 256.0 );\n\n\t\t\t} else {\n\n\t\t\t\treturn LinearToGamma( value, 2.2 );\n\n\t\t\t}\n\n\t\t}\n\n\t\tvec4 envMapTexelToLinear( vec4 color ) {\n\n\t\t\treturn inputTexelToLinear( color );\n\n\t\t}\n\t";
48369
48370 }
48371
48372 function Face4( a, b, c, d, normal, color, materialIndex ) {
48373
48374 console.warn( 'THREE.Face4 has been removed. A THREE.Face3 will be created instead.' );
48375 return new Face3( a, b, c, normal, color, materialIndex );
48376
48377 }
48378
48379 var LineStrip = 0;
48380 var LinePieces = 1;
48381 var NoColors = 0;
48382 var FaceColors = 1;
48383 var VertexColors = 2;
48384
48385 function MeshFaceMaterial( materials ) {
48386
48387 console.warn( 'THREE.MeshFaceMaterial has been removed. Use an Array instead.' );
48388 return materials;
48389
48390 }
48391
48392 function MultiMaterial( materials ) {
48393
48394 if ( materials === undefined ) { materials = []; }
48395
48396 console.warn( 'THREE.MultiMaterial has been removed. Use an Array instead.' );
48397 materials.isMultiMaterial = true;
48398 materials.materials = materials;
48399 materials.clone = function () {
48400
48401 return materials.slice();
48402
48403 };
48404
48405 return materials;
48406
48407 }
48408
48409 function PointCloud( geometry, material ) {
48410
48411 console.warn( 'THREE.PointCloud has been renamed to THREE.Points.' );
48412 return new Points( geometry, material );
48413
48414 }
48415
48416 function Particle( material ) {
48417
48418 console.warn( 'THREE.Particle has been renamed to THREE.Sprite.' );
48419 return new Sprite( material );
48420
48421 }
48422
48423 function ParticleSystem( geometry, material ) {
48424
48425 console.warn( 'THREE.ParticleSystem has been renamed to THREE.Points.' );
48426 return new Points( geometry, material );
48427
48428 }
48429
48430 function PointCloudMaterial( parameters ) {
48431
48432 console.warn( 'THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.' );
48433 return new PointsMaterial( parameters );
48434
48435 }
48436
48437 function ParticleBasicMaterial( parameters ) {
48438
48439 console.warn( 'THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.' );
48440 return new PointsMaterial( parameters );
48441
48442 }
48443
48444 function ParticleSystemMaterial( parameters ) {
48445
48446 console.warn( 'THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.' );
48447 return new PointsMaterial( parameters );
48448
48449 }
48450
48451 function Vertex( x, y, z ) {
48452
48453 console.warn( 'THREE.Vertex has been removed. Use THREE.Vector3 instead.' );
48454 return new Vector3( x, y, z );
48455
48456 }
48457
48458 //
48459
48460 function DynamicBufferAttribute( array, itemSize ) {
48461
48462 console.warn( 'THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setUsage( THREE.DynamicDrawUsage ) instead.' );
48463 return new BufferAttribute( array, itemSize ).setUsage( DynamicDrawUsage );
48464
48465 }
48466
48467 function Int8Attribute( array, itemSize ) {
48468
48469 console.warn( 'THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.' );
48470 return new Int8BufferAttribute( array, itemSize );
48471
48472 }
48473
48474 function Uint8Attribute( array, itemSize ) {
48475
48476 console.warn( 'THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.' );
48477 return new Uint8BufferAttribute( array, itemSize );
48478
48479 }
48480
48481 function Uint8ClampedAttribute( array, itemSize ) {
48482
48483 console.warn( 'THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.' );
48484 return new Uint8ClampedBufferAttribute( array, itemSize );
48485
48486 }
48487
48488 function Int16Attribute( array, itemSize ) {
48489
48490 console.warn( 'THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.' );
48491 return new Int16BufferAttribute( array, itemSize );
48492
48493 }
48494
48495 function Uint16Attribute( array, itemSize ) {
48496
48497 console.warn( 'THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.' );
48498 return new Uint16BufferAttribute( array, itemSize );
48499
48500 }
48501
48502 function Int32Attribute( array, itemSize ) {
48503
48504 console.warn( 'THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.' );
48505 return new Int32BufferAttribute( array, itemSize );
48506
48507 }
48508
48509 function Uint32Attribute( array, itemSize ) {
48510
48511 console.warn( 'THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.' );
48512 return new Uint32BufferAttribute( array, itemSize );
48513
48514 }
48515
48516 function Float32Attribute( array, itemSize ) {
48517
48518 console.warn( 'THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.' );
48519 return new Float32BufferAttribute( array, itemSize );
48520
48521 }
48522
48523 function Float64Attribute( array, itemSize ) {
48524
48525 console.warn( 'THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.' );
48526 return new Float64BufferAttribute( array, itemSize );
48527
48528 }
48529
48530 //
48531
48532 Curve.create = function ( construct, getPoint ) {
48533
48534 console.log( 'THREE.Curve.create() has been deprecated' );
48535
48536 construct.prototype = Object.create( Curve.prototype );
48537 construct.prototype.constructor = construct;
48538 construct.prototype.getPoint = getPoint;
48539
48540 return construct;
48541
48542 };
48543
48544 //
48545
48546 Object.assign( CurvePath.prototype, {
48547
48548 createPointsGeometry: function ( divisions ) {
48549
48550 console.warn( 'THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
48551
48552 // generate geometry from path points (for Line or Points objects)
48553
48554 var pts = this.getPoints( divisions );
48555 return this.createGeometry( pts );
48556
48557 },
48558
48559 createSpacedPointsGeometry: function ( divisions ) {
48560
48561 console.warn( 'THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
48562
48563 // generate geometry from equidistant sampling along the path
48564
48565 var pts = this.getSpacedPoints( divisions );
48566 return this.createGeometry( pts );
48567
48568 },
48569
48570 createGeometry: function ( points ) {
48571
48572 console.warn( 'THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.' );
48573
48574 var geometry = new Geometry();
48575
48576 for ( var i = 0, l = points.length; i < l; i ++ ) {
48577
48578 var point = points[ i ];
48579 geometry.vertices.push( new Vector3( point.x, point.y, point.z || 0 ) );
48580
48581 }
48582
48583 return geometry;
48584
48585 }
48586
48587 } );
48588
48589 //
48590
48591 Object.assign( Path.prototype, {
48592
48593 fromPoints: function ( points ) {
48594
48595 console.warn( 'THREE.Path: .fromPoints() has been renamed to .setFromPoints().' );
48596 return this.setFromPoints( points );
48597
48598 }
48599
48600 } );
48601
48602 //
48603
48604 function ClosedSplineCurve3( points ) {
48605
48606 console.warn( 'THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
48607
48608 CatmullRomCurve3.call( this, points );
48609 this.type = 'catmullrom';
48610 this.closed = true;
48611
48612 }
48613
48614 ClosedSplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
48615
48616 //
48617
48618 function SplineCurve3( points ) {
48619
48620 console.warn( 'THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.' );
48621
48622 CatmullRomCurve3.call( this, points );
48623 this.type = 'catmullrom';
48624
48625 }
48626
48627 SplineCurve3.prototype = Object.create( CatmullRomCurve3.prototype );
48628
48629 //
48630
48631 function Spline( points ) {
48632
48633 console.warn( 'THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.' );
48634
48635 CatmullRomCurve3.call( this, points );
48636 this.type = 'catmullrom';
48637
48638 }
48639
48640 Spline.prototype = Object.create( CatmullRomCurve3.prototype );
48641
48642 Object.assign( Spline.prototype, {
48643
48644 initFromArray: function ( /* a */ ) {
48645
48646 console.error( 'THREE.Spline: .initFromArray() has been removed.' );
48647
48648 },
48649 getControlPointsArray: function ( /* optionalTarget */ ) {
48650
48651 console.error( 'THREE.Spline: .getControlPointsArray() has been removed.' );
48652
48653 },
48654 reparametrizeByArcLength: function ( /* samplingCoef */ ) {
48655
48656 console.error( 'THREE.Spline: .reparametrizeByArcLength() has been removed.' );
48657
48658 }
48659
48660 } );
48661
48662 //
48663
48664 function AxisHelper( size ) {
48665
48666 console.warn( 'THREE.AxisHelper has been renamed to THREE.AxesHelper.' );
48667 return new AxesHelper( size );
48668
48669 }
48670
48671 function BoundingBoxHelper( object, color ) {
48672
48673 console.warn( 'THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.' );
48674 return new BoxHelper( object, color );
48675
48676 }
48677
48678 function EdgesHelper( object, hex ) {
48679
48680 console.warn( 'THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.' );
48681 return new LineSegments( new EdgesGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
48682
48683 }
48684
48685 GridHelper.prototype.setColors = function () {
48686
48687 console.error( 'THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.' );
48688
48689 };
48690
48691 SkeletonHelper.prototype.update = function () {
48692
48693 console.error( 'THREE.SkeletonHelper: update() no longer needs to be called.' );
48694
48695 };
48696
48697 function WireframeHelper( object, hex ) {
48698
48699 console.warn( 'THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.' );
48700 return new LineSegments( new WireframeGeometry( object.geometry ), new LineBasicMaterial( { color: hex !== undefined ? hex : 0xffffff } ) );
48701
48702 }
48703
48704 //
48705
48706 Object.assign( Loader.prototype, {
48707
48708 extractUrlBase: function ( url ) {
48709
48710 console.warn( 'THREE.Loader: .extractUrlBase() has been deprecated. Use THREE.LoaderUtils.extractUrlBase() instead.' );
48711 return LoaderUtils.extractUrlBase( url );
48712
48713 }
48714
48715 } );
48716
48717 Loader.Handlers = {
48718
48719 add: function ( /* regex, loader */ ) {
48720
48721 console.error( 'THREE.Loader: Handlers.add() has been removed. Use LoadingManager.addHandler() instead.' );
48722
48723 },
48724
48725 get: function ( /* file */ ) {
48726
48727 console.error( 'THREE.Loader: Handlers.get() has been removed. Use LoadingManager.getHandler() instead.' );
48728
48729 }
48730
48731 };
48732
48733 function XHRLoader( manager ) {
48734
48735 console.warn( 'THREE.XHRLoader has been renamed to THREE.FileLoader.' );
48736 return new FileLoader( manager );
48737
48738 }
48739
48740 function BinaryTextureLoader( manager ) {
48741
48742 console.warn( 'THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.' );
48743 return new DataTextureLoader( manager );
48744
48745 }
48746
48747 Object.assign( ObjectLoader.prototype, {
48748
48749 setTexturePath: function ( value ) {
48750
48751 console.warn( 'THREE.ObjectLoader: .setTexturePath() has been renamed to .setResourcePath().' );
48752 return this.setResourcePath( value );
48753
48754 }
48755
48756 } );
48757
48758 //
48759
48760 Object.assign( Box2.prototype, {
48761
48762 center: function ( optionalTarget ) {
48763
48764 console.warn( 'THREE.Box2: .center() has been renamed to .getCenter().' );
48765 return this.getCenter( optionalTarget );
48766
48767 },
48768 empty: function () {
48769
48770 console.warn( 'THREE.Box2: .empty() has been renamed to .isEmpty().' );
48771 return this.isEmpty();
48772
48773 },
48774 isIntersectionBox: function ( box ) {
48775
48776 console.warn( 'THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().' );
48777 return this.intersectsBox( box );
48778
48779 },
48780 size: function ( optionalTarget ) {
48781
48782 console.warn( 'THREE.Box2: .size() has been renamed to .getSize().' );
48783 return this.getSize( optionalTarget );
48784
48785 }
48786 } );
48787
48788 Object.assign( Box3.prototype, {
48789
48790 center: function ( optionalTarget ) {
48791
48792 console.warn( 'THREE.Box3: .center() has been renamed to .getCenter().' );
48793 return this.getCenter( optionalTarget );
48794
48795 },
48796 empty: function () {
48797
48798 console.warn( 'THREE.Box3: .empty() has been renamed to .isEmpty().' );
48799 return this.isEmpty();
48800
48801 },
48802 isIntersectionBox: function ( box ) {
48803
48804 console.warn( 'THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().' );
48805 return this.intersectsBox( box );
48806
48807 },
48808 isIntersectionSphere: function ( sphere ) {
48809
48810 console.warn( 'THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
48811 return this.intersectsSphere( sphere );
48812
48813 },
48814 size: function ( optionalTarget ) {
48815
48816 console.warn( 'THREE.Box3: .size() has been renamed to .getSize().' );
48817 return this.getSize( optionalTarget );
48818
48819 }
48820 } );
48821
48822 Object.assign( Sphere.prototype, {
48823
48824 empty: function () {
48825
48826 console.warn( 'THREE.Sphere: .empty() has been renamed to .isEmpty().' );
48827 return this.isEmpty();
48828
48829 },
48830
48831 } );
48832
48833 Frustum.prototype.setFromMatrix = function ( m ) {
48834
48835 console.warn( 'THREE.Frustum: .setFromMatrix() has been renamed to .setFromProjectionMatrix().' );
48836 return this.setFromProjectionMatrix( m );
48837
48838 };
48839
48840 Line3.prototype.center = function ( optionalTarget ) {
48841
48842 console.warn( 'THREE.Line3: .center() has been renamed to .getCenter().' );
48843 return this.getCenter( optionalTarget );
48844
48845 };
48846
48847 Object.assign( MathUtils, {
48848
48849 random16: function () {
48850
48851 console.warn( 'THREE.Math: .random16() has been deprecated. Use Math.random() instead.' );
48852 return Math.random();
48853
48854 },
48855
48856 nearestPowerOfTwo: function ( value ) {
48857
48858 console.warn( 'THREE.Math: .nearestPowerOfTwo() has been renamed to .floorPowerOfTwo().' );
48859 return MathUtils.floorPowerOfTwo( value );
48860
48861 },
48862
48863 nextPowerOfTwo: function ( value ) {
48864
48865 console.warn( 'THREE.Math: .nextPowerOfTwo() has been renamed to .ceilPowerOfTwo().' );
48866 return MathUtils.ceilPowerOfTwo( value );
48867
48868 }
48869
48870 } );
48871
48872 Object.assign( Matrix3.prototype, {
48873
48874 flattenToArrayOffset: function ( array, offset ) {
48875
48876 console.warn( "THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
48877 return this.toArray( array, offset );
48878
48879 },
48880 multiplyVector3: function ( vector ) {
48881
48882 console.warn( 'THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.' );
48883 return vector.applyMatrix3( this );
48884
48885 },
48886 multiplyVector3Array: function ( /* a */ ) {
48887
48888 console.error( 'THREE.Matrix3: .multiplyVector3Array() has been removed.' );
48889
48890 },
48891 applyToBufferAttribute: function ( attribute ) {
48892
48893 console.warn( 'THREE.Matrix3: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix3( matrix ) instead.' );
48894 return attribute.applyMatrix3( this );
48895
48896 },
48897 applyToVector3Array: function ( /* array, offset, length */ ) {
48898
48899 console.error( 'THREE.Matrix3: .applyToVector3Array() has been removed.' );
48900
48901 }
48902
48903 } );
48904
48905 Object.assign( Matrix4.prototype, {
48906
48907 extractPosition: function ( m ) {
48908
48909 console.warn( 'THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().' );
48910 return this.copyPosition( m );
48911
48912 },
48913 flattenToArrayOffset: function ( array, offset ) {
48914
48915 console.warn( "THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead." );
48916 return this.toArray( array, offset );
48917
48918 },
48919 getPosition: function () {
48920
48921 console.warn( 'THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.' );
48922 return new Vector3().setFromMatrixColumn( this, 3 );
48923
48924 },
48925 setRotationFromQuaternion: function ( q ) {
48926
48927 console.warn( 'THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().' );
48928 return this.makeRotationFromQuaternion( q );
48929
48930 },
48931 multiplyToArray: function () {
48932
48933 console.warn( 'THREE.Matrix4: .multiplyToArray() has been removed.' );
48934
48935 },
48936 multiplyVector3: function ( vector ) {
48937
48938 console.warn( 'THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
48939 return vector.applyMatrix4( this );
48940
48941 },
48942 multiplyVector4: function ( vector ) {
48943
48944 console.warn( 'THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
48945 return vector.applyMatrix4( this );
48946
48947 },
48948 multiplyVector3Array: function ( /* a */ ) {
48949
48950 console.error( 'THREE.Matrix4: .multiplyVector3Array() has been removed.' );
48951
48952 },
48953 rotateAxis: function ( v ) {
48954
48955 console.warn( 'THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.' );
48956 v.transformDirection( this );
48957
48958 },
48959 crossVector: function ( vector ) {
48960
48961 console.warn( 'THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.' );
48962 return vector.applyMatrix4( this );
48963
48964 },
48965 translate: function () {
48966
48967 console.error( 'THREE.Matrix4: .translate() has been removed.' );
48968
48969 },
48970 rotateX: function () {
48971
48972 console.error( 'THREE.Matrix4: .rotateX() has been removed.' );
48973
48974 },
48975 rotateY: function () {
48976
48977 console.error( 'THREE.Matrix4: .rotateY() has been removed.' );
48978
48979 },
48980 rotateZ: function () {
48981
48982 console.error( 'THREE.Matrix4: .rotateZ() has been removed.' );
48983
48984 },
48985 rotateByAxis: function () {
48986
48987 console.error( 'THREE.Matrix4: .rotateByAxis() has been removed.' );
48988
48989 },
48990 applyToBufferAttribute: function ( attribute ) {
48991
48992 console.warn( 'THREE.Matrix4: .applyToBufferAttribute() has been removed. Use attribute.applyMatrix4( matrix ) instead.' );
48993 return attribute.applyMatrix4( this );
48994
48995 },
48996 applyToVector3Array: function ( /* array, offset, length */ ) {
48997
48998 console.error( 'THREE.Matrix4: .applyToVector3Array() has been removed.' );
48999
49000 },
49001 makeFrustum: function ( left, right, bottom, top, near, far ) {
49002
49003 console.warn( 'THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.' );
49004 return this.makePerspective( left, right, top, bottom, near, far );
49005
49006 }
49007
49008 } );
49009
49010 Plane.prototype.isIntersectionLine = function ( line ) {
49011
49012 console.warn( 'THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().' );
49013 return this.intersectsLine( line );
49014
49015 };
49016
49017 Quaternion.prototype.multiplyVector3 = function ( vector ) {
49018
49019 console.warn( 'THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.' );
49020 return vector.applyQuaternion( this );
49021
49022 };
49023
49024 Object.assign( Ray.prototype, {
49025
49026 isIntersectionBox: function ( box ) {
49027
49028 console.warn( 'THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().' );
49029 return this.intersectsBox( box );
49030
49031 },
49032 isIntersectionPlane: function ( plane ) {
49033
49034 console.warn( 'THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().' );
49035 return this.intersectsPlane( plane );
49036
49037 },
49038 isIntersectionSphere: function ( sphere ) {
49039
49040 console.warn( 'THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().' );
49041 return this.intersectsSphere( sphere );
49042
49043 }
49044
49045 } );
49046
49047 Object.assign( Triangle.prototype, {
49048
49049 area: function () {
49050
49051 console.warn( 'THREE.Triangle: .area() has been renamed to .getArea().' );
49052 return this.getArea();
49053
49054 },
49055 barycoordFromPoint: function ( point, target ) {
49056
49057 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' );
49058 return this.getBarycoord( point, target );
49059
49060 },
49061 midpoint: function ( target ) {
49062
49063 console.warn( 'THREE.Triangle: .midpoint() has been renamed to .getMidpoint().' );
49064 return this.getMidpoint( target );
49065
49066 },
49067 normal: function ( target ) {
49068
49069 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' );
49070 return this.getNormal( target );
49071
49072 },
49073 plane: function ( target ) {
49074
49075 console.warn( 'THREE.Triangle: .plane() has been renamed to .getPlane().' );
49076 return this.getPlane( target );
49077
49078 }
49079
49080 } );
49081
49082 Object.assign( Triangle, {
49083
49084 barycoordFromPoint: function ( point, a, b, c, target ) {
49085
49086 console.warn( 'THREE.Triangle: .barycoordFromPoint() has been renamed to .getBarycoord().' );
49087 return Triangle.getBarycoord( point, a, b, c, target );
49088
49089 },
49090 normal: function ( a, b, c, target ) {
49091
49092 console.warn( 'THREE.Triangle: .normal() has been renamed to .getNormal().' );
49093 return Triangle.getNormal( a, b, c, target );
49094
49095 }
49096
49097 } );
49098
49099 Object.assign( Shape.prototype, {
49100
49101 extractAllPoints: function ( divisions ) {
49102
49103 console.warn( 'THREE.Shape: .extractAllPoints() has been removed. Use .extractPoints() instead.' );
49104 return this.extractPoints( divisions );
49105
49106 },
49107 extrude: function ( options ) {
49108
49109 console.warn( 'THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.' );
49110 return new ExtrudeGeometry( this, options );
49111
49112 },
49113 makeGeometry: function ( options ) {
49114
49115 console.warn( 'THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.' );
49116 return new ShapeGeometry( this, options );
49117
49118 }
49119
49120 } );
49121
49122 Object.assign( Vector2.prototype, {
49123
49124 fromAttribute: function ( attribute, index, offset ) {
49125
49126 console.warn( 'THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().' );
49127 return this.fromBufferAttribute( attribute, index, offset );
49128
49129 },
49130 distanceToManhattan: function ( v ) {
49131
49132 console.warn( 'THREE.Vector2: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' );
49133 return this.manhattanDistanceTo( v );
49134
49135 },
49136 lengthManhattan: function () {
49137
49138 console.warn( 'THREE.Vector2: .lengthManhattan() has been renamed to .manhattanLength().' );
49139 return this.manhattanLength();
49140
49141 }
49142
49143 } );
49144
49145 Object.assign( Vector3.prototype, {
49146
49147 setEulerFromRotationMatrix: function () {
49148
49149 console.error( 'THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.' );
49150
49151 },
49152 setEulerFromQuaternion: function () {
49153
49154 console.error( 'THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.' );
49155
49156 },
49157 getPositionFromMatrix: function ( m ) {
49158
49159 console.warn( 'THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().' );
49160 return this.setFromMatrixPosition( m );
49161
49162 },
49163 getScaleFromMatrix: function ( m ) {
49164
49165 console.warn( 'THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().' );
49166 return this.setFromMatrixScale( m );
49167
49168 },
49169 getColumnFromMatrix: function ( index, matrix ) {
49170
49171 console.warn( 'THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().' );
49172 return this.setFromMatrixColumn( matrix, index );
49173
49174 },
49175 applyProjection: function ( m ) {
49176
49177 console.warn( 'THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.' );
49178 return this.applyMatrix4( m );
49179
49180 },
49181 fromAttribute: function ( attribute, index, offset ) {
49182
49183 console.warn( 'THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().' );
49184 return this.fromBufferAttribute( attribute, index, offset );
49185
49186 },
49187 distanceToManhattan: function ( v ) {
49188
49189 console.warn( 'THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().' );
49190 return this.manhattanDistanceTo( v );
49191
49192 },
49193 lengthManhattan: function () {
49194
49195 console.warn( 'THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().' );
49196 return this.manhattanLength();
49197
49198 }
49199
49200 } );
49201
49202 Object.assign( Vector4.prototype, {
49203
49204 fromAttribute: function ( attribute, index, offset ) {
49205
49206 console.warn( 'THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().' );
49207 return this.fromBufferAttribute( attribute, index, offset );
49208
49209 },
49210 lengthManhattan: function () {
49211
49212 console.warn( 'THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().' );
49213 return this.manhattanLength();
49214
49215 }
49216
49217 } );
49218
49219 //
49220
49221 Object.assign( Geometry.prototype, {
49222
49223 computeTangents: function () {
49224
49225 console.error( 'THREE.Geometry: .computeTangents() has been removed.' );
49226
49227 },
49228 computeLineDistances: function () {
49229
49230 console.error( 'THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.' );
49231
49232 },
49233 applyMatrix: function ( matrix ) {
49234
49235 console.warn( 'THREE.Geometry: .applyMatrix() has been renamed to .applyMatrix4().' );
49236 return this.applyMatrix4( matrix );
49237
49238 }
49239
49240 } );
49241
49242 Object.assign( Object3D.prototype, {
49243
49244 getChildByName: function ( name ) {
49245
49246 console.warn( 'THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().' );
49247 return this.getObjectByName( name );
49248
49249 },
49250 renderDepth: function () {
49251
49252 console.warn( 'THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.' );
49253
49254 },
49255 translate: function ( distance, axis ) {
49256
49257 console.warn( 'THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.' );
49258 return this.translateOnAxis( axis, distance );
49259
49260 },
49261 getWorldRotation: function () {
49262
49263 console.error( 'THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.' );
49264
49265 },
49266 applyMatrix: function ( matrix ) {
49267
49268 console.warn( 'THREE.Object3D: .applyMatrix() has been renamed to .applyMatrix4().' );
49269 return this.applyMatrix4( matrix );
49270
49271 }
49272
49273 } );
49274
49275 Object.defineProperties( Object3D.prototype, {
49276
49277 eulerOrder: {
49278 get: function () {
49279
49280 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
49281 return this.rotation.order;
49282
49283 },
49284 set: function ( value ) {
49285
49286 console.warn( 'THREE.Object3D: .eulerOrder is now .rotation.order.' );
49287 this.rotation.order = value;
49288
49289 }
49290 },
49291 useQuaternion: {
49292 get: function () {
49293
49294 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
49295
49296 },
49297 set: function () {
49298
49299 console.warn( 'THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.' );
49300
49301 }
49302 }
49303
49304 } );
49305
49306 Object.assign( Mesh.prototype, {
49307
49308 setDrawMode: function () {
49309
49310 console.error( 'THREE.Mesh: .setDrawMode() has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' );
49311
49312 },
49313
49314 } );
49315
49316 Object.defineProperties( Mesh.prototype, {
49317
49318 drawMode: {
49319 get: function () {
49320
49321 console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode.' );
49322 return TrianglesDrawMode;
49323
49324 },
49325 set: function () {
49326
49327 console.error( 'THREE.Mesh: .drawMode has been removed. The renderer now always assumes THREE.TrianglesDrawMode. Transform your geometry via BufferGeometryUtils.toTrianglesDrawMode() if necessary.' );
49328
49329 }
49330 }
49331
49332 } );
49333
49334 Object.defineProperties( LOD.prototype, {
49335
49336 objects: {
49337 get: function () {
49338
49339 console.warn( 'THREE.LOD: .objects has been renamed to .levels.' );
49340 return this.levels;
49341
49342 }
49343 }
49344
49345 } );
49346
49347 Object.defineProperty( Skeleton.prototype, 'useVertexTexture', {
49348
49349 get: function () {
49350
49351 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
49352
49353 },
49354 set: function () {
49355
49356 console.warn( 'THREE.Skeleton: useVertexTexture has been removed.' );
49357
49358 }
49359
49360 } );
49361
49362 SkinnedMesh.prototype.initBones = function () {
49363
49364 console.error( 'THREE.SkinnedMesh: initBones() has been removed.' );
49365
49366 };
49367
49368 Object.defineProperty( Curve.prototype, '__arcLengthDivisions', {
49369
49370 get: function () {
49371
49372 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
49373 return this.arcLengthDivisions;
49374
49375 },
49376 set: function ( value ) {
49377
49378 console.warn( 'THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.' );
49379 this.arcLengthDivisions = value;
49380
49381 }
49382
49383 } );
49384
49385 //
49386
49387 PerspectiveCamera.prototype.setLens = function ( focalLength, filmGauge ) {
49388
49389 console.warn( "THREE.PerspectiveCamera.setLens is deprecated. " +
49390 "Use .setFocalLength and .filmGauge for a photographic setup." );
49391
49392 if ( filmGauge !== undefined ) { this.filmGauge = filmGauge; }
49393 this.setFocalLength( focalLength );
49394
49395 };
49396
49397 //
49398
49399 Object.defineProperties( Light.prototype, {
49400 onlyShadow: {
49401 set: function () {
49402
49403 console.warn( 'THREE.Light: .onlyShadow has been removed.' );
49404
49405 }
49406 },
49407 shadowCameraFov: {
49408 set: function ( value ) {
49409
49410 console.warn( 'THREE.Light: .shadowCameraFov is now .shadow.camera.fov.' );
49411 this.shadow.camera.fov = value;
49412
49413 }
49414 },
49415 shadowCameraLeft: {
49416 set: function ( value ) {
49417
49418 console.warn( 'THREE.Light: .shadowCameraLeft is now .shadow.camera.left.' );
49419 this.shadow.camera.left = value;
49420
49421 }
49422 },
49423 shadowCameraRight: {
49424 set: function ( value ) {
49425
49426 console.warn( 'THREE.Light: .shadowCameraRight is now .shadow.camera.right.' );
49427 this.shadow.camera.right = value;
49428
49429 }
49430 },
49431 shadowCameraTop: {
49432 set: function ( value ) {
49433
49434 console.warn( 'THREE.Light: .shadowCameraTop is now .shadow.camera.top.' );
49435 this.shadow.camera.top = value;
49436
49437 }
49438 },
49439 shadowCameraBottom: {
49440 set: function ( value ) {
49441
49442 console.warn( 'THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.' );
49443 this.shadow.camera.bottom = value;
49444
49445 }
49446 },
49447 shadowCameraNear: {
49448 set: function ( value ) {
49449
49450 console.warn( 'THREE.Light: .shadowCameraNear is now .shadow.camera.near.' );
49451 this.shadow.camera.near = value;
49452
49453 }
49454 },
49455 shadowCameraFar: {
49456 set: function ( value ) {
49457
49458 console.warn( 'THREE.Light: .shadowCameraFar is now .shadow.camera.far.' );
49459 this.shadow.camera.far = value;
49460
49461 }
49462 },
49463 shadowCameraVisible: {
49464 set: function () {
49465
49466 console.warn( 'THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.' );
49467
49468 }
49469 },
49470 shadowBias: {
49471 set: function ( value ) {
49472
49473 console.warn( 'THREE.Light: .shadowBias is now .shadow.bias.' );
49474 this.shadow.bias = value;
49475
49476 }
49477 },
49478 shadowDarkness: {
49479 set: function () {
49480
49481 console.warn( 'THREE.Light: .shadowDarkness has been removed.' );
49482
49483 }
49484 },
49485 shadowMapWidth: {
49486 set: function ( value ) {
49487
49488 console.warn( 'THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.' );
49489 this.shadow.mapSize.width = value;
49490
49491 }
49492 },
49493 shadowMapHeight: {
49494 set: function ( value ) {
49495
49496 console.warn( 'THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.' );
49497 this.shadow.mapSize.height = value;
49498
49499 }
49500 }
49501 } );
49502
49503 //
49504
49505 Object.defineProperties( BufferAttribute.prototype, {
49506
49507 length: {
49508 get: function () {
49509
49510 console.warn( 'THREE.BufferAttribute: .length has been deprecated. Use .count instead.' );
49511 return this.array.length;
49512
49513 }
49514 },
49515 dynamic: {
49516 get: function () {
49517
49518 console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' );
49519 return this.usage === DynamicDrawUsage;
49520
49521 },
49522 set: function ( /* value */ ) {
49523
49524 console.warn( 'THREE.BufferAttribute: .dynamic has been deprecated. Use .usage instead.' );
49525 this.setUsage( DynamicDrawUsage );
49526
49527 }
49528 }
49529
49530 } );
49531
49532 Object.assign( BufferAttribute.prototype, {
49533 setDynamic: function ( value ) {
49534
49535 console.warn( 'THREE.BufferAttribute: .setDynamic() has been deprecated. Use .setUsage() instead.' );
49536 this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage );
49537 return this;
49538
49539 },
49540 copyIndicesArray: function ( /* indices */ ) {
49541
49542 console.error( 'THREE.BufferAttribute: .copyIndicesArray() has been removed.' );
49543
49544 },
49545 setArray: function ( /* array */ ) {
49546
49547 console.error( 'THREE.BufferAttribute: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' );
49548
49549 }
49550 } );
49551
49552 Object.assign( BufferGeometry.prototype, {
49553
49554 addIndex: function ( index ) {
49555
49556 console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );
49557 this.setIndex( index );
49558
49559 },
49560 addAttribute: function ( name, attribute ) {
49561
49562 console.warn( 'THREE.BufferGeometry: .addAttribute() has been renamed to .setAttribute().' );
49563
49564 if ( ! ( attribute && attribute.isBufferAttribute ) && ! ( attribute && attribute.isInterleavedBufferAttribute ) ) {
49565
49566 console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
49567
49568 return this.setAttribute( name, new BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
49569
49570 }
49571
49572 if ( name === 'index' ) {
49573
49574 console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
49575 this.setIndex( attribute );
49576
49577 return this;
49578
49579 }
49580
49581 return this.setAttribute( name, attribute );
49582
49583 },
49584 addDrawCall: function ( start, count, indexOffset ) {
49585
49586 if ( indexOffset !== undefined ) {
49587
49588 console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );
49589
49590 }
49591
49592 console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );
49593 this.addGroup( start, count );
49594
49595 },
49596 clearDrawCalls: function () {
49597
49598 console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
49599 this.clearGroups();
49600
49601 },
49602 computeTangents: function () {
49603
49604 console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
49605
49606 },
49607 computeOffsets: function () {
49608
49609 console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.' );
49610
49611 },
49612 removeAttribute: function ( name ) {
49613
49614 console.warn( 'THREE.BufferGeometry: .removeAttribute() has been renamed to .deleteAttribute().' );
49615
49616 return this.deleteAttribute( name );
49617
49618 },
49619 applyMatrix: function ( matrix ) {
49620
49621 console.warn( 'THREE.BufferGeometry: .applyMatrix() has been renamed to .applyMatrix4().' );
49622 return this.applyMatrix4( matrix );
49623
49624 }
49625
49626 } );
49627
49628 Object.defineProperties( BufferGeometry.prototype, {
49629
49630 drawcalls: {
49631 get: function () {
49632
49633 console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );
49634 return this.groups;
49635
49636 }
49637 },
49638 offsets: {
49639 get: function () {
49640
49641 console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );
49642 return this.groups;
49643
49644 }
49645 }
49646
49647 } );
49648
49649 Object.defineProperties( InstancedBufferGeometry.prototype, {
49650
49651 maxInstancedCount: {
49652 get: function () {
49653
49654 console.warn( 'THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.' );
49655 return this.instanceCount;
49656
49657 },
49658 set: function ( value ) {
49659
49660 console.warn( 'THREE.InstancedBufferGeometry: .maxInstancedCount has been renamed to .instanceCount.' );
49661 this.instanceCount = value;
49662
49663 }
49664 }
49665
49666 } );
49667
49668 Object.defineProperties( Raycaster.prototype, {
49669
49670 linePrecision: {
49671 get: function () {
49672
49673 console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' );
49674 return this.params.Line.threshold;
49675
49676 },
49677 set: function ( value ) {
49678
49679 console.warn( 'THREE.Raycaster: .linePrecision has been deprecated. Use .params.Line.threshold instead.' );
49680 this.params.Line.threshold = value;
49681
49682 }
49683 }
49684
49685 } );
49686
49687 Object.defineProperties( InterleavedBuffer.prototype, {
49688
49689 dynamic: {
49690 get: function () {
49691
49692 console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' );
49693 return this.usage === DynamicDrawUsage;
49694
49695 },
49696 set: function ( value ) {
49697
49698 console.warn( 'THREE.InterleavedBuffer: .length has been deprecated. Use .usage instead.' );
49699 this.setUsage( value );
49700
49701 }
49702 }
49703
49704 } );
49705
49706 Object.assign( InterleavedBuffer.prototype, {
49707 setDynamic: function ( value ) {
49708
49709 console.warn( 'THREE.InterleavedBuffer: .setDynamic() has been deprecated. Use .setUsage() instead.' );
49710 this.setUsage( value === true ? DynamicDrawUsage : StaticDrawUsage );
49711 return this;
49712
49713 },
49714 setArray: function ( /* array */ ) {
49715
49716 console.error( 'THREE.InterleavedBuffer: .setArray has been removed. Use BufferGeometry .setAttribute to replace/resize attribute buffers' );
49717
49718 }
49719 } );
49720
49721 //
49722
49723 Object.assign( ExtrudeBufferGeometry.prototype, {
49724
49725 getArrays: function () {
49726
49727 console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' );
49728
49729 },
49730
49731 addShapeList: function () {
49732
49733 console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' );
49734
49735 },
49736
49737 addShape: function () {
49738
49739 console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' );
49740
49741 }
49742
49743 } );
49744
49745 //
49746
49747 Object.defineProperties( Uniform.prototype, {
49748
49749 dynamic: {
49750 set: function () {
49751
49752 console.warn( 'THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.' );
49753
49754 }
49755 },
49756 onUpdate: {
49757 value: function () {
49758
49759 console.warn( 'THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.' );
49760 return this;
49761
49762 }
49763 }
49764
49765 } );
49766
49767 //
49768
49769 Object.defineProperties( Material.prototype, {
49770
49771 wrapAround: {
49772 get: function () {
49773
49774 console.warn( 'THREE.Material: .wrapAround has been removed.' );
49775
49776 },
49777 set: function () {
49778
49779 console.warn( 'THREE.Material: .wrapAround has been removed.' );
49780
49781 }
49782 },
49783
49784 overdraw: {
49785 get: function () {
49786
49787 console.warn( 'THREE.Material: .overdraw has been removed.' );
49788
49789 },
49790 set: function () {
49791
49792 console.warn( 'THREE.Material: .overdraw has been removed.' );
49793
49794 }
49795 },
49796
49797 wrapRGB: {
49798 get: function () {
49799
49800 console.warn( 'THREE.Material: .wrapRGB has been removed.' );
49801 return new Color();
49802
49803 }
49804 },
49805
49806 shading: {
49807 get: function () {
49808
49809 console.error( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
49810
49811 },
49812 set: function ( value ) {
49813
49814 console.warn( 'THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.' );
49815 this.flatShading = ( value === FlatShading );
49816
49817 }
49818 },
49819
49820 stencilMask: {
49821 get: function () {
49822
49823 console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' );
49824 return this.stencilFuncMask;
49825
49826 },
49827 set: function ( value ) {
49828
49829 console.warn( 'THREE.' + this.type + ': .stencilMask has been removed. Use .stencilFuncMask instead.' );
49830 this.stencilFuncMask = value;
49831
49832 }
49833 }
49834
49835 } );
49836
49837 Object.defineProperties( MeshPhongMaterial.prototype, {
49838
49839 metal: {
49840 get: function () {
49841
49842 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.' );
49843 return false;
49844
49845 },
49846 set: function () {
49847
49848 console.warn( 'THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead' );
49849
49850 }
49851 }
49852
49853 } );
49854
49855 Object.defineProperties( MeshPhysicalMaterial.prototype, {
49856
49857 transparency: {
49858 get: function () {
49859
49860 console.warn( 'THREE.MeshPhysicalMaterial: .transparency has been renamed to .transmission.' );
49861 return this.transmission;
49862
49863 },
49864 set: function ( value ) {
49865
49866 console.warn( 'THREE.MeshPhysicalMaterial: .transparency has been renamed to .transmission.' );
49867 this.transmission = value;
49868
49869 }
49870 }
49871
49872 } );
49873
49874 Object.defineProperties( ShaderMaterial.prototype, {
49875
49876 derivatives: {
49877 get: function () {
49878
49879 console.warn( 'THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
49880 return this.extensions.derivatives;
49881
49882 },
49883 set: function ( value ) {
49884
49885 console.warn( 'THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.' );
49886 this.extensions.derivatives = value;
49887
49888 }
49889 }
49890
49891 } );
49892
49893 //
49894
49895 Object.assign( WebGLRenderer.prototype, {
49896
49897 clearTarget: function ( renderTarget, color, depth, stencil ) {
49898
49899 console.warn( 'THREE.WebGLRenderer: .clearTarget() has been deprecated. Use .setRenderTarget() and .clear() instead.' );
49900 this.setRenderTarget( renderTarget );
49901 this.clear( color, depth, stencil );
49902
49903 },
49904 animate: function ( callback ) {
49905
49906 console.warn( 'THREE.WebGLRenderer: .animate() is now .setAnimationLoop().' );
49907 this.setAnimationLoop( callback );
49908
49909 },
49910 getCurrentRenderTarget: function () {
49911
49912 console.warn( 'THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().' );
49913 return this.getRenderTarget();
49914
49915 },
49916 getMaxAnisotropy: function () {
49917
49918 console.warn( 'THREE.WebGLRenderer: .getMaxAnisotropy() is now .capabilities.getMaxAnisotropy().' );
49919 return this.capabilities.getMaxAnisotropy();
49920
49921 },
49922 getPrecision: function () {
49923
49924 console.warn( 'THREE.WebGLRenderer: .getPrecision() is now .capabilities.precision.' );
49925 return this.capabilities.precision;
49926
49927 },
49928 resetGLState: function () {
49929
49930 console.warn( 'THREE.WebGLRenderer: .resetGLState() is now .state.reset().' );
49931 return this.state.reset();
49932
49933 },
49934 supportsFloatTextures: function () {
49935
49936 console.warn( 'THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( \'OES_texture_float\' ).' );
49937 return this.extensions.get( 'OES_texture_float' );
49938
49939 },
49940 supportsHalfFloatTextures: function () {
49941
49942 console.warn( 'THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( \'OES_texture_half_float\' ).' );
49943 return this.extensions.get( 'OES_texture_half_float' );
49944
49945 },
49946 supportsStandardDerivatives: function () {
49947
49948 console.warn( 'THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( \'OES_standard_derivatives\' ).' );
49949 return this.extensions.get( 'OES_standard_derivatives' );
49950
49951 },
49952 supportsCompressedTextureS3TC: function () {
49953
49954 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( \'WEBGL_compressed_texture_s3tc\' ).' );
49955 return this.extensions.get( 'WEBGL_compressed_texture_s3tc' );
49956
49957 },
49958 supportsCompressedTexturePVRTC: function () {
49959
49960 console.warn( 'THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( \'WEBGL_compressed_texture_pvrtc\' ).' );
49961 return this.extensions.get( 'WEBGL_compressed_texture_pvrtc' );
49962
49963 },
49964 supportsBlendMinMax: function () {
49965
49966 console.warn( 'THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( \'EXT_blend_minmax\' ).' );
49967 return this.extensions.get( 'EXT_blend_minmax' );
49968
49969 },
49970 supportsVertexTextures: function () {
49971
49972 console.warn( 'THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.' );
49973 return this.capabilities.vertexTextures;
49974
49975 },
49976 supportsInstancedArrays: function () {
49977
49978 console.warn( 'THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( \'ANGLE_instanced_arrays\' ).' );
49979 return this.extensions.get( 'ANGLE_instanced_arrays' );
49980
49981 },
49982 enableScissorTest: function ( boolean ) {
49983
49984 console.warn( 'THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().' );
49985 this.setScissorTest( boolean );
49986
49987 },
49988 initMaterial: function () {
49989
49990 console.warn( 'THREE.WebGLRenderer: .initMaterial() has been removed.' );
49991
49992 },
49993 addPrePlugin: function () {
49994
49995 console.warn( 'THREE.WebGLRenderer: .addPrePlugin() has been removed.' );
49996
49997 },
49998 addPostPlugin: function () {
49999
50000 console.warn( 'THREE.WebGLRenderer: .addPostPlugin() has been removed.' );
50001
50002 },
50003 updateShadowMap: function () {
50004
50005 console.warn( 'THREE.WebGLRenderer: .updateShadowMap() has been removed.' );
50006
50007 },
50008 setFaceCulling: function () {
50009
50010 console.warn( 'THREE.WebGLRenderer: .setFaceCulling() has been removed.' );
50011
50012 },
50013 allocTextureUnit: function () {
50014
50015 console.warn( 'THREE.WebGLRenderer: .allocTextureUnit() has been removed.' );
50016
50017 },
50018 setTexture: function () {
50019
50020 console.warn( 'THREE.WebGLRenderer: .setTexture() has been removed.' );
50021
50022 },
50023 setTexture2D: function () {
50024
50025 console.warn( 'THREE.WebGLRenderer: .setTexture2D() has been removed.' );
50026
50027 },
50028 setTextureCube: function () {
50029
50030 console.warn( 'THREE.WebGLRenderer: .setTextureCube() has been removed.' );
50031
50032 },
50033 getActiveMipMapLevel: function () {
50034
50035 console.warn( 'THREE.WebGLRenderer: .getActiveMipMapLevel() is now .getActiveMipmapLevel().' );
50036 return this.getActiveMipmapLevel();
50037
50038 }
50039
50040 } );
50041
50042 Object.defineProperties( WebGLRenderer.prototype, {
50043
50044 shadowMapEnabled: {
50045 get: function () {
50046
50047 return this.shadowMap.enabled;
50048
50049 },
50050 set: function ( value ) {
50051
50052 console.warn( 'THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.' );
50053 this.shadowMap.enabled = value;
50054
50055 }
50056 },
50057 shadowMapType: {
50058 get: function () {
50059
50060 return this.shadowMap.type;
50061
50062 },
50063 set: function ( value ) {
50064
50065 console.warn( 'THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.' );
50066 this.shadowMap.type = value;
50067
50068 }
50069 },
50070 shadowMapCullFace: {
50071 get: function () {
50072
50073 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' );
50074 return undefined;
50075
50076 },
50077 set: function ( /* value */ ) {
50078
50079 console.warn( 'THREE.WebGLRenderer: .shadowMapCullFace has been removed. Set Material.shadowSide instead.' );
50080
50081 }
50082 },
50083 context: {
50084 get: function () {
50085
50086 console.warn( 'THREE.WebGLRenderer: .context has been removed. Use .getContext() instead.' );
50087 return this.getContext();
50088
50089 }
50090 },
50091 vr: {
50092 get: function () {
50093
50094 console.warn( 'THREE.WebGLRenderer: .vr has been renamed to .xr' );
50095 return this.xr;
50096
50097 }
50098 },
50099 gammaInput: {
50100 get: function () {
50101
50102 console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' );
50103 return false;
50104
50105 },
50106 set: function () {
50107
50108 console.warn( 'THREE.WebGLRenderer: .gammaInput has been removed. Set the encoding for textures via Texture.encoding instead.' );
50109
50110 }
50111 },
50112 gammaOutput: {
50113 get: function () {
50114
50115 console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' );
50116 return false;
50117
50118 },
50119 set: function ( value ) {
50120
50121 console.warn( 'THREE.WebGLRenderer: .gammaOutput has been removed. Set WebGLRenderer.outputEncoding instead.' );
50122 this.outputEncoding = ( value === true ) ? sRGBEncoding : LinearEncoding;
50123
50124 }
50125 },
50126 toneMappingWhitePoint: {
50127 get: function () {
50128
50129 console.warn( 'THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.' );
50130 return 1.0;
50131
50132 },
50133 set: function () {
50134
50135 console.warn( 'THREE.WebGLRenderer: .toneMappingWhitePoint has been removed.' );
50136
50137 }
50138 },
50139
50140 } );
50141
50142 Object.defineProperties( WebGLShadowMap.prototype, {
50143
50144 cullFace: {
50145 get: function () {
50146
50147 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' );
50148 return undefined;
50149
50150 },
50151 set: function ( /* cullFace */ ) {
50152
50153 console.warn( 'THREE.WebGLRenderer: .shadowMap.cullFace has been removed. Set Material.shadowSide instead.' );
50154
50155 }
50156 },
50157 renderReverseSided: {
50158 get: function () {
50159
50160 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' );
50161 return undefined;
50162
50163 },
50164 set: function () {
50165
50166 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderReverseSided has been removed. Set Material.shadowSide instead.' );
50167
50168 }
50169 },
50170 renderSingleSided: {
50171 get: function () {
50172
50173 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' );
50174 return undefined;
50175
50176 },
50177 set: function () {
50178
50179 console.warn( 'THREE.WebGLRenderer: .shadowMap.renderSingleSided has been removed. Set Material.shadowSide instead.' );
50180
50181 }
50182 }
50183
50184 } );
50185
50186 function WebGLRenderTargetCube( width, height, options ) {
50187
50188 console.warn( 'THREE.WebGLRenderTargetCube( width, height, options ) is now WebGLCubeRenderTarget( size, options ).' );
50189 return new WebGLCubeRenderTarget( width, options );
50190
50191 }
50192
50193 //
50194
50195 Object.defineProperties( WebGLRenderTarget.prototype, {
50196
50197 wrapS: {
50198 get: function () {
50199
50200 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
50201 return this.texture.wrapS;
50202
50203 },
50204 set: function ( value ) {
50205
50206 console.warn( 'THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.' );
50207 this.texture.wrapS = value;
50208
50209 }
50210 },
50211 wrapT: {
50212 get: function () {
50213
50214 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
50215 return this.texture.wrapT;
50216
50217 },
50218 set: function ( value ) {
50219
50220 console.warn( 'THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.' );
50221 this.texture.wrapT = value;
50222
50223 }
50224 },
50225 magFilter: {
50226 get: function () {
50227
50228 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
50229 return this.texture.magFilter;
50230
50231 },
50232 set: function ( value ) {
50233
50234 console.warn( 'THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.' );
50235 this.texture.magFilter = value;
50236
50237 }
50238 },
50239 minFilter: {
50240 get: function () {
50241
50242 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
50243 return this.texture.minFilter;
50244
50245 },
50246 set: function ( value ) {
50247
50248 console.warn( 'THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.' );
50249 this.texture.minFilter = value;
50250
50251 }
50252 },
50253 anisotropy: {
50254 get: function () {
50255
50256 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
50257 return this.texture.anisotropy;
50258
50259 },
50260 set: function ( value ) {
50261
50262 console.warn( 'THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.' );
50263 this.texture.anisotropy = value;
50264
50265 }
50266 },
50267 offset: {
50268 get: function () {
50269
50270 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
50271 return this.texture.offset;
50272
50273 },
50274 set: function ( value ) {
50275
50276 console.warn( 'THREE.WebGLRenderTarget: .offset is now .texture.offset.' );
50277 this.texture.offset = value;
50278
50279 }
50280 },
50281 repeat: {
50282 get: function () {
50283
50284 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
50285 return this.texture.repeat;
50286
50287 },
50288 set: function ( value ) {
50289
50290 console.warn( 'THREE.WebGLRenderTarget: .repeat is now .texture.repeat.' );
50291 this.texture.repeat = value;
50292
50293 }
50294 },
50295 format: {
50296 get: function () {
50297
50298 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
50299 return this.texture.format;
50300
50301 },
50302 set: function ( value ) {
50303
50304 console.warn( 'THREE.WebGLRenderTarget: .format is now .texture.format.' );
50305 this.texture.format = value;
50306
50307 }
50308 },
50309 type: {
50310 get: function () {
50311
50312 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
50313 return this.texture.type;
50314
50315 },
50316 set: function ( value ) {
50317
50318 console.warn( 'THREE.WebGLRenderTarget: .type is now .texture.type.' );
50319 this.texture.type = value;
50320
50321 }
50322 },
50323 generateMipmaps: {
50324 get: function () {
50325
50326 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
50327 return this.texture.generateMipmaps;
50328
50329 },
50330 set: function ( value ) {
50331
50332 console.warn( 'THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.' );
50333 this.texture.generateMipmaps = value;
50334
50335 }
50336 }
50337
50338 } );
50339
50340 //
50341
50342 Object.defineProperties( Audio.prototype, {
50343
50344 load: {
50345 value: function ( file ) {
50346
50347 console.warn( 'THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.' );
50348 var scope = this;
50349 var audioLoader = new AudioLoader();
50350 audioLoader.load( file, function ( buffer ) {
50351
50352 scope.setBuffer( buffer );
50353
50354 } );
50355 return this;
50356
50357 }
50358 },
50359 startTime: {
50360 set: function () {
50361
50362 console.warn( 'THREE.Audio: .startTime is now .play( delay ).' );
50363
50364 }
50365 }
50366
50367 } );
50368
50369 AudioAnalyser.prototype.getData = function () {
50370
50371 console.warn( 'THREE.AudioAnalyser: .getData() is now .getFrequencyData().' );
50372 return this.getFrequencyData();
50373
50374 };
50375
50376 //
50377
50378 CubeCamera.prototype.updateCubeMap = function ( renderer, scene ) {
50379
50380 console.warn( 'THREE.CubeCamera: .updateCubeMap() is now .update().' );
50381 return this.update( renderer, scene );
50382
50383 };
50384
50385 //
50386
50387 var GeometryUtils = {
50388
50389 merge: function ( geometry1, geometry2, materialIndexOffset ) {
50390
50391 console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );
50392 var matrix;
50393
50394 if ( geometry2.isMesh ) {
50395
50396 geometry2.matrixAutoUpdate && geometry2.updateMatrix();
50397
50398 matrix = geometry2.matrix;
50399 geometry2 = geometry2.geometry;
50400
50401 }
50402
50403 geometry1.merge( geometry2, matrix, materialIndexOffset );
50404
50405 },
50406
50407 center: function ( geometry ) {
50408
50409 console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );
50410 return geometry.center();
50411
50412 }
50413
50414 };
50415
50416 ImageUtils.crossOrigin = undefined;
50417
50418 ImageUtils.loadTexture = function ( url, mapping, onLoad, onError ) {
50419
50420 console.warn( 'THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.' );
50421
50422 var loader = new TextureLoader();
50423 loader.setCrossOrigin( this.crossOrigin );
50424
50425 var texture = loader.load( url, onLoad, undefined, onError );
50426
50427 if ( mapping ) { texture.mapping = mapping; }
50428
50429 return texture;
50430
50431 };
50432
50433 ImageUtils.loadTextureCube = function ( urls, mapping, onLoad, onError ) {
50434
50435 console.warn( 'THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.' );
50436
50437 var loader = new CubeTextureLoader();
50438 loader.setCrossOrigin( this.crossOrigin );
50439
50440 var texture = loader.load( urls, onLoad, undefined, onError );
50441
50442 if ( mapping ) { texture.mapping = mapping; }
50443
50444 return texture;
50445
50446 };
50447
50448 ImageUtils.loadCompressedTexture = function () {
50449
50450 console.error( 'THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.' );
50451
50452 };
50453
50454 ImageUtils.loadCompressedTextureCube = function () {
50455
50456 console.error( 'THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.' );
50457
50458 };
50459
50460 //
50461
50462 function CanvasRenderer() {
50463
50464 console.error( 'THREE.CanvasRenderer has been removed' );
50465
50466 }
50467
50468 //
50469
50470 function JSONLoader() {
50471
50472 console.error( 'THREE.JSONLoader has been removed.' );
50473
50474 }
50475
50476 //
50477
50478 var SceneUtils = {
50479
50480 createMultiMaterialObject: function ( /* geometry, materials */ ) {
50481
50482 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
50483
50484 },
50485
50486 detach: function ( /* child, parent, scene */ ) {
50487
50488 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
50489
50490 },
50491
50492 attach: function ( /* child, scene, parent */ ) {
50493
50494 console.error( 'THREE.SceneUtils has been moved to /examples/jsm/utils/SceneUtils.js' );
50495
50496 }
50497
50498 };
50499
50500 //
50501
50502 function LensFlare() {
50503
50504 console.error( 'THREE.LensFlare has been moved to /examples/jsm/objects/Lensflare.js' );
50505
50506 }
50507
50508 if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
50509
50510 /* eslint-disable no-undef */
50511 __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: {
50512 revision: REVISION,
50513 } } ) );
50514 /* eslint-enable no-undef */
50515
50516 }
50517
50518 exports.ACESFilmicToneMapping = ACESFilmicToneMapping;
50519 exports.AddEquation = AddEquation;
50520 exports.AddOperation = AddOperation;
50521 exports.AdditiveAnimationBlendMode = AdditiveAnimationBlendMode;
50522 exports.AdditiveBlending = AdditiveBlending;
50523 exports.AlphaFormat = AlphaFormat;
50524 exports.AlwaysDepth = AlwaysDepth;
50525 exports.AlwaysStencilFunc = AlwaysStencilFunc;
50526 exports.AmbientLight = AmbientLight;
50527 exports.AmbientLightProbe = AmbientLightProbe;
50528 exports.AnimationClip = AnimationClip;
50529 exports.AnimationLoader = AnimationLoader;
50530 exports.AnimationMixer = AnimationMixer;
50531 exports.AnimationObjectGroup = AnimationObjectGroup;
50532 exports.AnimationUtils = AnimationUtils;
50533 exports.ArcCurve = ArcCurve;
50534 exports.ArrayCamera = ArrayCamera;
50535 exports.ArrowHelper = ArrowHelper;
50536 exports.Audio = Audio;
50537 exports.AudioAnalyser = AudioAnalyser;
50538 exports.AudioContext = AudioContext;
50539 exports.AudioListener = AudioListener;
50540 exports.AudioLoader = AudioLoader;
50541 exports.AxesHelper = AxesHelper;
50542 exports.AxisHelper = AxisHelper;
50543 exports.BackSide = BackSide;
50544 exports.BasicDepthPacking = BasicDepthPacking;
50545 exports.BasicShadowMap = BasicShadowMap;
50546 exports.BinaryTextureLoader = BinaryTextureLoader;
50547 exports.Bone = Bone;
50548 exports.BooleanKeyframeTrack = BooleanKeyframeTrack;
50549 exports.BoundingBoxHelper = BoundingBoxHelper;
50550 exports.Box2 = Box2;
50551 exports.Box3 = Box3;
50552 exports.Box3Helper = Box3Helper;
50553 exports.BoxBufferGeometry = BoxBufferGeometry;
50554 exports.BoxGeometry = BoxGeometry;
50555 exports.BoxHelper = BoxHelper;
50556 exports.BufferAttribute = BufferAttribute;
50557 exports.BufferGeometry = BufferGeometry;
50558 exports.BufferGeometryLoader = BufferGeometryLoader;
50559 exports.ByteType = ByteType;
50560 exports.Cache = Cache;
50561 exports.Camera = Camera;
50562 exports.CameraHelper = CameraHelper;
50563 exports.CanvasRenderer = CanvasRenderer;
50564 exports.CanvasTexture = CanvasTexture;
50565 exports.CatmullRomCurve3 = CatmullRomCurve3;
50566 exports.CineonToneMapping = CineonToneMapping;
50567 exports.CircleBufferGeometry = CircleBufferGeometry;
50568 exports.CircleGeometry = CircleGeometry;
50569 exports.ClampToEdgeWrapping = ClampToEdgeWrapping;
50570 exports.Clock = Clock;
50571 exports.ClosedSplineCurve3 = ClosedSplineCurve3;
50572 exports.Color = Color;
50573 exports.ColorKeyframeTrack = ColorKeyframeTrack;
50574 exports.CompressedTexture = CompressedTexture;
50575 exports.CompressedTextureLoader = CompressedTextureLoader;
50576 exports.ConeBufferGeometry = ConeBufferGeometry;
50577 exports.ConeGeometry = ConeGeometry;
50578 exports.CubeCamera = CubeCamera;
50579 exports.CubeGeometry = BoxGeometry;
50580 exports.CubeReflectionMapping = CubeReflectionMapping;
50581 exports.CubeRefractionMapping = CubeRefractionMapping;
50582 exports.CubeTexture = CubeTexture;
50583 exports.CubeTextureLoader = CubeTextureLoader;
50584 exports.CubeUVReflectionMapping = CubeUVReflectionMapping;
50585 exports.CubeUVRefractionMapping = CubeUVRefractionMapping;
50586 exports.CubicBezierCurve = CubicBezierCurve;
50587 exports.CubicBezierCurve3 = CubicBezierCurve3;
50588 exports.CubicInterpolant = CubicInterpolant;
50589 exports.CullFaceBack = CullFaceBack;
50590 exports.CullFaceFront = CullFaceFront;
50591 exports.CullFaceFrontBack = CullFaceFrontBack;
50592 exports.CullFaceNone = CullFaceNone;
50593 exports.Curve = Curve;
50594 exports.CurvePath = CurvePath;
50595 exports.CustomBlending = CustomBlending;
50596 exports.CustomToneMapping = CustomToneMapping;
50597 exports.CylinderBufferGeometry = CylinderBufferGeometry;
50598 exports.CylinderGeometry = CylinderGeometry;
50599 exports.Cylindrical = Cylindrical;
50600 exports.DataTexture = DataTexture;
50601 exports.DataTexture2DArray = DataTexture2DArray;
50602 exports.DataTexture3D = DataTexture3D;
50603 exports.DataTextureLoader = DataTextureLoader;
50604 exports.DecrementStencilOp = DecrementStencilOp;
50605 exports.DecrementWrapStencilOp = DecrementWrapStencilOp;
50606 exports.DefaultLoadingManager = DefaultLoadingManager;
50607 exports.DepthFormat = DepthFormat;
50608 exports.DepthStencilFormat = DepthStencilFormat;
50609 exports.DepthTexture = DepthTexture;
50610 exports.DirectionalLight = DirectionalLight;
50611 exports.DirectionalLightHelper = DirectionalLightHelper;
50612 exports.DirectionalLightShadow = DirectionalLightShadow;
50613 exports.DiscreteInterpolant = DiscreteInterpolant;
50614 exports.DodecahedronBufferGeometry = DodecahedronBufferGeometry;
50615 exports.DodecahedronGeometry = DodecahedronGeometry;
50616 exports.DoubleSide = DoubleSide;
50617 exports.DstAlphaFactor = DstAlphaFactor;
50618 exports.DstColorFactor = DstColorFactor;
50619 exports.DynamicBufferAttribute = DynamicBufferAttribute;
50620 exports.DynamicCopyUsage = DynamicCopyUsage;
50621 exports.DynamicDrawUsage = DynamicDrawUsage;
50622 exports.DynamicReadUsage = DynamicReadUsage;
50623 exports.EdgesGeometry = EdgesGeometry;
50624 exports.EdgesHelper = EdgesHelper;
50625 exports.EllipseCurve = EllipseCurve;
50626 exports.EqualDepth = EqualDepth;
50627 exports.EqualStencilFunc = EqualStencilFunc;
50628 exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;
50629 exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;
50630 exports.Euler = Euler;
50631 exports.EventDispatcher = EventDispatcher;
50632 exports.ExtrudeBufferGeometry = ExtrudeBufferGeometry;
50633 exports.ExtrudeGeometry = ExtrudeGeometry;
50634 exports.Face3 = Face3;
50635 exports.Face4 = Face4;
50636 exports.FaceColors = FaceColors;
50637 exports.FileLoader = FileLoader;
50638 exports.FlatShading = FlatShading;
50639 exports.Float32Attribute = Float32Attribute;
50640 exports.Float32BufferAttribute = Float32BufferAttribute;
50641 exports.Float64Attribute = Float64Attribute;
50642 exports.Float64BufferAttribute = Float64BufferAttribute;
50643 exports.FloatType = FloatType;
50644 exports.Fog = Fog;
50645 exports.FogExp2 = FogExp2;
50646 exports.Font = Font;
50647 exports.FontLoader = FontLoader;
50648 exports.FrontSide = FrontSide;
50649 exports.Frustum = Frustum;
50650 exports.GammaEncoding = GammaEncoding;
50651 exports.Geometry = Geometry;
50652 exports.GeometryUtils = GeometryUtils;
50653 exports.GreaterDepth = GreaterDepth;
50654 exports.GreaterEqualDepth = GreaterEqualDepth;
50655 exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc;
50656 exports.GreaterStencilFunc = GreaterStencilFunc;
50657 exports.GridHelper = GridHelper;
50658 exports.Group = Group;
50659 exports.HalfFloatType = HalfFloatType;
50660 exports.HemisphereLight = HemisphereLight;
50661 exports.HemisphereLightHelper = HemisphereLightHelper;
50662 exports.HemisphereLightProbe = HemisphereLightProbe;
50663 exports.IcosahedronBufferGeometry = IcosahedronBufferGeometry;
50664 exports.IcosahedronGeometry = IcosahedronGeometry;
50665 exports.ImageBitmapLoader = ImageBitmapLoader;
50666 exports.ImageLoader = ImageLoader;
50667 exports.ImageUtils = ImageUtils;
50668 exports.ImmediateRenderObject = ImmediateRenderObject;
50669 exports.IncrementStencilOp = IncrementStencilOp;
50670 exports.IncrementWrapStencilOp = IncrementWrapStencilOp;
50671 exports.InstancedBufferAttribute = InstancedBufferAttribute;
50672 exports.InstancedBufferGeometry = InstancedBufferGeometry;
50673 exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;
50674 exports.InstancedMesh = InstancedMesh;
50675 exports.Int16Attribute = Int16Attribute;
50676 exports.Int16BufferAttribute = Int16BufferAttribute;
50677 exports.Int32Attribute = Int32Attribute;
50678 exports.Int32BufferAttribute = Int32BufferAttribute;
50679 exports.Int8Attribute = Int8Attribute;
50680 exports.Int8BufferAttribute = Int8BufferAttribute;
50681 exports.IntType = IntType;
50682 exports.InterleavedBuffer = InterleavedBuffer;
50683 exports.InterleavedBufferAttribute = InterleavedBufferAttribute;
50684 exports.Interpolant = Interpolant;
50685 exports.InterpolateDiscrete = InterpolateDiscrete;
50686 exports.InterpolateLinear = InterpolateLinear;
50687 exports.InterpolateSmooth = InterpolateSmooth;
50688 exports.InvertStencilOp = InvertStencilOp;
50689 exports.JSONLoader = JSONLoader;
50690 exports.KeepStencilOp = KeepStencilOp;
50691 exports.KeyframeTrack = KeyframeTrack;
50692 exports.LOD = LOD;
50693 exports.LatheBufferGeometry = LatheBufferGeometry;
50694 exports.LatheGeometry = LatheGeometry;
50695 exports.Layers = Layers;
50696 exports.LensFlare = LensFlare;
50697 exports.LessDepth = LessDepth;
50698 exports.LessEqualDepth = LessEqualDepth;
50699 exports.LessEqualStencilFunc = LessEqualStencilFunc;
50700 exports.LessStencilFunc = LessStencilFunc;
50701 exports.Light = Light;
50702 exports.LightProbe = LightProbe;
50703 exports.LightShadow = LightShadow;
50704 exports.Line = Line;
50705 exports.Line3 = Line3;
50706 exports.LineBasicMaterial = LineBasicMaterial;
50707 exports.LineCurve = LineCurve;
50708 exports.LineCurve3 = LineCurve3;
50709 exports.LineDashedMaterial = LineDashedMaterial;
50710 exports.LineLoop = LineLoop;
50711 exports.LinePieces = LinePieces;
50712 exports.LineSegments = LineSegments;
50713 exports.LineStrip = LineStrip;
50714 exports.LinearEncoding = LinearEncoding;
50715 exports.LinearFilter = LinearFilter;
50716 exports.LinearInterpolant = LinearInterpolant;
50717 exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;
50718 exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;
50719 exports.LinearMipmapLinearFilter = LinearMipmapLinearFilter;
50720 exports.LinearMipmapNearestFilter = LinearMipmapNearestFilter;
50721 exports.LinearToneMapping = LinearToneMapping;
50722 exports.Loader = Loader;
50723 exports.LoaderUtils = LoaderUtils;
50724 exports.LoadingManager = LoadingManager;
50725 exports.LogLuvEncoding = LogLuvEncoding;
50726 exports.LoopOnce = LoopOnce;
50727 exports.LoopPingPong = LoopPingPong;
50728 exports.LoopRepeat = LoopRepeat;
50729 exports.LuminanceAlphaFormat = LuminanceAlphaFormat;
50730 exports.LuminanceFormat = LuminanceFormat;
50731 exports.MOUSE = MOUSE;
50732 exports.Material = Material;
50733 exports.MaterialLoader = MaterialLoader;
50734 exports.Math = MathUtils;
50735 exports.MathUtils = MathUtils;
50736 exports.Matrix3 = Matrix3;
50737 exports.Matrix4 = Matrix4;
50738 exports.MaxEquation = MaxEquation;
50739 exports.Mesh = Mesh;
50740 exports.MeshBasicMaterial = MeshBasicMaterial;
50741 exports.MeshDepthMaterial = MeshDepthMaterial;
50742 exports.MeshDistanceMaterial = MeshDistanceMaterial;
50743 exports.MeshFaceMaterial = MeshFaceMaterial;
50744 exports.MeshLambertMaterial = MeshLambertMaterial;
50745 exports.MeshMatcapMaterial = MeshMatcapMaterial;
50746 exports.MeshNormalMaterial = MeshNormalMaterial;
50747 exports.MeshPhongMaterial = MeshPhongMaterial;
50748 exports.MeshPhysicalMaterial = MeshPhysicalMaterial;
50749 exports.MeshStandardMaterial = MeshStandardMaterial;
50750 exports.MeshToonMaterial = MeshToonMaterial;
50751 exports.MinEquation = MinEquation;
50752 exports.MirroredRepeatWrapping = MirroredRepeatWrapping;
50753 exports.MixOperation = MixOperation;
50754 exports.MultiMaterial = MultiMaterial;
50755 exports.MultiplyBlending = MultiplyBlending;
50756 exports.MultiplyOperation = MultiplyOperation;
50757 exports.NearestFilter = NearestFilter;
50758 exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;
50759 exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;
50760 exports.NearestMipmapLinearFilter = NearestMipmapLinearFilter;
50761 exports.NearestMipmapNearestFilter = NearestMipmapNearestFilter;
50762 exports.NeverDepth = NeverDepth;
50763 exports.NeverStencilFunc = NeverStencilFunc;
50764 exports.NoBlending = NoBlending;
50765 exports.NoColors = NoColors;
50766 exports.NoToneMapping = NoToneMapping;
50767 exports.NormalAnimationBlendMode = NormalAnimationBlendMode;
50768 exports.NormalBlending = NormalBlending;
50769 exports.NotEqualDepth = NotEqualDepth;
50770 exports.NotEqualStencilFunc = NotEqualStencilFunc;
50771 exports.NumberKeyframeTrack = NumberKeyframeTrack;
50772 exports.Object3D = Object3D;
50773 exports.ObjectLoader = ObjectLoader;
50774 exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap;
50775 exports.OctahedronBufferGeometry = OctahedronBufferGeometry;
50776 exports.OctahedronGeometry = OctahedronGeometry;
50777 exports.OneFactor = OneFactor;
50778 exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;
50779 exports.OneMinusDstColorFactor = OneMinusDstColorFactor;
50780 exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;
50781 exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;
50782 exports.OrthographicCamera = OrthographicCamera;
50783 exports.PCFShadowMap = PCFShadowMap;
50784 exports.PCFSoftShadowMap = PCFSoftShadowMap;
50785 exports.PMREMGenerator = PMREMGenerator;
50786 exports.ParametricBufferGeometry = ParametricBufferGeometry;
50787 exports.ParametricGeometry = ParametricGeometry;
50788 exports.Particle = Particle;
50789 exports.ParticleBasicMaterial = ParticleBasicMaterial;
50790 exports.ParticleSystem = ParticleSystem;
50791 exports.ParticleSystemMaterial = ParticleSystemMaterial;
50792 exports.Path = Path;
50793 exports.PerspectiveCamera = PerspectiveCamera;
50794 exports.Plane = Plane;
50795 exports.PlaneBufferGeometry = PlaneBufferGeometry;
50796 exports.PlaneGeometry = PlaneGeometry;
50797 exports.PlaneHelper = PlaneHelper;
50798 exports.PointCloud = PointCloud;
50799 exports.PointCloudMaterial = PointCloudMaterial;
50800 exports.PointLight = PointLight;
50801 exports.PointLightHelper = PointLightHelper;
50802 exports.Points = Points;
50803 exports.PointsMaterial = PointsMaterial;
50804 exports.PolarGridHelper = PolarGridHelper;
50805 exports.PolyhedronBufferGeometry = PolyhedronBufferGeometry;
50806 exports.PolyhedronGeometry = PolyhedronGeometry;
50807 exports.PositionalAudio = PositionalAudio;
50808 exports.PropertyBinding = PropertyBinding;
50809 exports.PropertyMixer = PropertyMixer;
50810 exports.QuadraticBezierCurve = QuadraticBezierCurve;
50811 exports.QuadraticBezierCurve3 = QuadraticBezierCurve3;
50812 exports.Quaternion = Quaternion;
50813 exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;
50814 exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;
50815 exports.REVISION = REVISION;
50816 exports.RGBADepthPacking = RGBADepthPacking;
50817 exports.RGBAFormat = RGBAFormat;
50818 exports.RGBAIntegerFormat = RGBAIntegerFormat;
50819 exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format;
50820 exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format;
50821 exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format;
50822 exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format;
50823 exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format;
50824 exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format;
50825 exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format;
50826 exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format;
50827 exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format;
50828 exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format;
50829 exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format;
50830 exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format;
50831 exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format;
50832 exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format;
50833 exports.RGBA_BPTC_Format = RGBA_BPTC_Format;
50834 exports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format;
50835 exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;
50836 exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;
50837 exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;
50838 exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;
50839 exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;
50840 exports.RGBDEncoding = RGBDEncoding;
50841 exports.RGBEEncoding = RGBEEncoding;
50842 exports.RGBEFormat = RGBEFormat;
50843 exports.RGBFormat = RGBFormat;
50844 exports.RGBIntegerFormat = RGBIntegerFormat;
50845 exports.RGBM16Encoding = RGBM16Encoding;
50846 exports.RGBM7Encoding = RGBM7Encoding;
50847 exports.RGB_ETC1_Format = RGB_ETC1_Format;
50848 exports.RGB_ETC2_Format = RGB_ETC2_Format;
50849 exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;
50850 exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;
50851 exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;
50852 exports.RGFormat = RGFormat;
50853 exports.RGIntegerFormat = RGIntegerFormat;
50854 exports.RawShaderMaterial = RawShaderMaterial;
50855 exports.Ray = Ray;
50856 exports.Raycaster = Raycaster;
50857 exports.RectAreaLight = RectAreaLight;
50858 exports.RedFormat = RedFormat;
50859 exports.RedIntegerFormat = RedIntegerFormat;
50860 exports.ReinhardToneMapping = ReinhardToneMapping;
50861 exports.RepeatWrapping = RepeatWrapping;
50862 exports.ReplaceStencilOp = ReplaceStencilOp;
50863 exports.ReverseSubtractEquation = ReverseSubtractEquation;
50864 exports.RingBufferGeometry = RingBufferGeometry;
50865 exports.RingGeometry = RingGeometry;
50866 exports.SRGB8_ALPHA8_ASTC_10x10_Format = SRGB8_ALPHA8_ASTC_10x10_Format;
50867 exports.SRGB8_ALPHA8_ASTC_10x5_Format = SRGB8_ALPHA8_ASTC_10x5_Format;
50868 exports.SRGB8_ALPHA8_ASTC_10x6_Format = SRGB8_ALPHA8_ASTC_10x6_Format;
50869 exports.SRGB8_ALPHA8_ASTC_10x8_Format = SRGB8_ALPHA8_ASTC_10x8_Format;
50870 exports.SRGB8_ALPHA8_ASTC_12x10_Format = SRGB8_ALPHA8_ASTC_12x10_Format;
50871 exports.SRGB8_ALPHA8_ASTC_12x12_Format = SRGB8_ALPHA8_ASTC_12x12_Format;
50872 exports.SRGB8_ALPHA8_ASTC_4x4_Format = SRGB8_ALPHA8_ASTC_4x4_Format;
50873 exports.SRGB8_ALPHA8_ASTC_5x4_Format = SRGB8_ALPHA8_ASTC_5x4_Format;
50874 exports.SRGB8_ALPHA8_ASTC_5x5_Format = SRGB8_ALPHA8_ASTC_5x5_Format;
50875 exports.SRGB8_ALPHA8_ASTC_6x5_Format = SRGB8_ALPHA8_ASTC_6x5_Format;
50876 exports.SRGB8_ALPHA8_ASTC_6x6_Format = SRGB8_ALPHA8_ASTC_6x6_Format;
50877 exports.SRGB8_ALPHA8_ASTC_8x5_Format = SRGB8_ALPHA8_ASTC_8x5_Format;
50878 exports.SRGB8_ALPHA8_ASTC_8x6_Format = SRGB8_ALPHA8_ASTC_8x6_Format;
50879 exports.SRGB8_ALPHA8_ASTC_8x8_Format = SRGB8_ALPHA8_ASTC_8x8_Format;
50880 exports.Scene = Scene;
50881 exports.SceneUtils = SceneUtils;
50882 exports.ShaderChunk = ShaderChunk;
50883 exports.ShaderLib = ShaderLib;
50884 exports.ShaderMaterial = ShaderMaterial;
50885 exports.ShadowMaterial = ShadowMaterial;
50886 exports.Shape = Shape;
50887 exports.ShapeBufferGeometry = ShapeBufferGeometry;
50888 exports.ShapeGeometry = ShapeGeometry;
50889 exports.ShapePath = ShapePath;
50890 exports.ShapeUtils = ShapeUtils;
50891 exports.ShortType = ShortType;
50892 exports.Skeleton = Skeleton;
50893 exports.SkeletonHelper = SkeletonHelper;
50894 exports.SkinnedMesh = SkinnedMesh;
50895 exports.SmoothShading = SmoothShading;
50896 exports.Sphere = Sphere;
50897 exports.SphereBufferGeometry = SphereBufferGeometry;
50898 exports.SphereGeometry = SphereGeometry;
50899 exports.Spherical = Spherical;
50900 exports.SphericalHarmonics3 = SphericalHarmonics3;
50901 exports.Spline = Spline;
50902 exports.SplineCurve = SplineCurve;
50903 exports.SplineCurve3 = SplineCurve3;
50904 exports.SpotLight = SpotLight;
50905 exports.SpotLightHelper = SpotLightHelper;
50906 exports.SpotLightShadow = SpotLightShadow;
50907 exports.Sprite = Sprite;
50908 exports.SpriteMaterial = SpriteMaterial;
50909 exports.SrcAlphaFactor = SrcAlphaFactor;
50910 exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;
50911 exports.SrcColorFactor = SrcColorFactor;
50912 exports.StaticCopyUsage = StaticCopyUsage;
50913 exports.StaticDrawUsage = StaticDrawUsage;
50914 exports.StaticReadUsage = StaticReadUsage;
50915 exports.StereoCamera = StereoCamera;
50916 exports.StreamCopyUsage = StreamCopyUsage;
50917 exports.StreamDrawUsage = StreamDrawUsage;
50918 exports.StreamReadUsage = StreamReadUsage;
50919 exports.StringKeyframeTrack = StringKeyframeTrack;
50920 exports.SubtractEquation = SubtractEquation;
50921 exports.SubtractiveBlending = SubtractiveBlending;
50922 exports.TOUCH = TOUCH;
50923 exports.TangentSpaceNormalMap = TangentSpaceNormalMap;
50924 exports.TetrahedronBufferGeometry = TetrahedronBufferGeometry;
50925 exports.TetrahedronGeometry = TetrahedronGeometry;
50926 exports.TextBufferGeometry = TextBufferGeometry;
50927 exports.TextGeometry = TextGeometry;
50928 exports.Texture = Texture;
50929 exports.TextureLoader = TextureLoader;
50930 exports.TorusBufferGeometry = TorusBufferGeometry;
50931 exports.TorusGeometry = TorusGeometry;
50932 exports.TorusKnotBufferGeometry = TorusKnotBufferGeometry;
50933 exports.TorusKnotGeometry = TorusKnotGeometry;
50934 exports.Triangle = Triangle;
50935 exports.TriangleFanDrawMode = TriangleFanDrawMode;
50936 exports.TriangleStripDrawMode = TriangleStripDrawMode;
50937 exports.TrianglesDrawMode = TrianglesDrawMode;
50938 exports.TubeBufferGeometry = TubeBufferGeometry;
50939 exports.TubeGeometry = TubeGeometry;
50940 exports.UVMapping = UVMapping;
50941 exports.Uint16Attribute = Uint16Attribute;
50942 exports.Uint16BufferAttribute = Uint16BufferAttribute;
50943 exports.Uint32Attribute = Uint32Attribute;
50944 exports.Uint32BufferAttribute = Uint32BufferAttribute;
50945 exports.Uint8Attribute = Uint8Attribute;
50946 exports.Uint8BufferAttribute = Uint8BufferAttribute;
50947 exports.Uint8ClampedAttribute = Uint8ClampedAttribute;
50948 exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;
50949 exports.Uniform = Uniform;
50950 exports.UniformsLib = UniformsLib;
50951 exports.UniformsUtils = UniformsUtils;
50952 exports.UnsignedByteType = UnsignedByteType;
50953 exports.UnsignedInt248Type = UnsignedInt248Type;
50954 exports.UnsignedIntType = UnsignedIntType;
50955 exports.UnsignedShort4444Type = UnsignedShort4444Type;
50956 exports.UnsignedShort5551Type = UnsignedShort5551Type;
50957 exports.UnsignedShort565Type = UnsignedShort565Type;
50958 exports.UnsignedShortType = UnsignedShortType;
50959 exports.VSMShadowMap = VSMShadowMap;
50960 exports.Vector2 = Vector2;
50961 exports.Vector3 = Vector3;
50962 exports.Vector4 = Vector4;
50963 exports.VectorKeyframeTrack = VectorKeyframeTrack;
50964 exports.Vertex = Vertex;
50965 exports.VertexColors = VertexColors;
50966 exports.VideoTexture = VideoTexture;
50967 exports.WebGL1Renderer = WebGL1Renderer;
50968 exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget;
50969 exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget;
50970 exports.WebGLRenderTarget = WebGLRenderTarget;
50971 exports.WebGLRenderTargetCube = WebGLRenderTargetCube;
50972 exports.WebGLRenderer = WebGLRenderer;
50973 exports.WebGLUtils = WebGLUtils;
50974 exports.WireframeGeometry = WireframeGeometry;
50975 exports.WireframeHelper = WireframeHelper;
50976 exports.WrapAroundEnding = WrapAroundEnding;
50977 exports.XHRLoader = XHRLoader;
50978 exports.ZeroCurvatureEnding = ZeroCurvatureEnding;
50979 exports.ZeroFactor = ZeroFactor;
50980 exports.ZeroSlopeEnding = ZeroSlopeEnding;
50981 exports.ZeroStencilOp = ZeroStencilOp;
50982 exports.sRGBEncoding = sRGBEncoding;
50983
50984 Object.defineProperty(exports, '__esModule', { value: true });
50985
50986})));